Hey folks. I’m trying write a unit test that dispatches an event. The event is dispatched like this in the view ns:
(r/dispatch [:timeline/init (r-dom/dom-node comp) {}])
I need to use dom-node
because the event creates a new object (a timeline from the vis js lib, to be more precise: https://visjs.github.io/vis-timeline/docs/timeline/)
The issue is that I don’t know how to simulate this dom-node
in the unit test. I tried to use (.getElementById js/document “app”)
and pass it to :timeline/init
but it gets nil
.If you test in a browser, you can always create a new element. But since this particular event ends up mutating something in the DOM in an explicit way, such a test might affect other tests.
Ah, actually, I might be wrong, because by default that element is not inserted:
https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement
But you might need to insert it into the document if vis-timeline
expects it to be there.
To be more specific, the event does this:
(new vis/Timeline
node
items-dataset
groups-dataset
(clj->js opts))
where node
is something coming from the event parameters (when it’s called from the view, (r-dom/dom-node comp)
).
This inserts timeline
in the document as a child of node
.Ideally, you should do it in an effect handler, not an event handler.
Yeah, I considered that. But setting it as an effect wouldn’t solve the original issue of the test, right? I’m not sure I got your previous suggestion.
It would allow you test the event handler in isolation, if it does any relevant work apart from calling (new ...)
.
My previous suggestion is to use document.createElement
instead of document.getElementById
.
Only for tests, of course.
Got it. Yeah, the event does other things too. I’ll see what I can do. Thanks.
There is some discussion in the #lsp about adding code navigation to re-frame registry and a few questions are popping up. Light testing shows that the two scenarios below work in re-frame, but it is unclear whether they are defined behavior:
1. Is it specified whether you are allowed to register the same id
to different kinds? (e.g. Could I register :start
as a subscription and a coeffect?)
2. Is it specified whether id
's need to be keywords? For example, registering 'a-symbol
as an event handler works.
confirmed
Great idea. That would avoid our situation where our own wrapper tries to launch without the data, then our wrapper gets confused because it did not anticipate this use case. I actually sorted things out before noticing the "new thing" use case, in which no data is expected. So I have to distinguish those two with a payload that includes :create-or-modify indicator in some form. Thx for the simple solution! 🙏
I am humbled, @p-himik and @emccue. Thanks so much for these. I am totally going with a solution in which the modal looks for :team-editor-data or some such, and chained dispatch sees to it that the modal gets one complete delivery when everything is ready for the modal. And it turns out I missed the "new team" use case, in which no http-get of any existing team will be needed. So there will just be a single payload indicating "create" or "edit", and various paths will end by adding that to app db, just as your examples suggest. Bravo #re-frame!
1. You can. All handler kinds are independent. You can use :start
as a subscription ID, an event ID, an effect ID, a coeffect ID - all at the same time.
2. IDs can be anything.