Open rgrempel opened 6 years ago
However, you can't test tasks that way
Maybe http://package.elm-lang.org/packages/rogeriochaves/elm-testable/latest
which runs through a sequence of messages and then checks whether the appropriate results occur
Maybe http://package.elm-lang.org/packages/Janiczek/elm-architecture-test/latest
Oh, those are very interesting indeed! Will check them out!
rogeriochaves/elm-testable is very clever -- essentially, it creates "mock" versions of tasks & commands that you can use. For tests, you can use the mocked versions. For your real app, there are functions to turn the mocked versions into the real things.
That's very clever, but it is a bit intrusive -- it means that you have to actually use elm-testable
in your real package code (not just the testing code) -- unless I'm missing something. That would be fine in some contexts, but isn't really ideal in a package.
elm-architecture-test
is pretty neat -- the main limitation for present purposes is that it ignores the cmd
that your update function returns ... so, it's fundamentally not asynchronous. So, it can't handle actually performing the Process.sleep
.
However, it does lead to a train of thought.
The messages that the Debouncer
can handle are:
type Msg
= ProvideInput i
| InputProvidedAt i Time
| CheckNow
| Check Time
Now, these are essentially two pairs of messages ...
ProvideInput i
and InputProvidedAt i Time
CheckNow
and Check Time
... and, in both cases, all that the first message in the pair does is set up a task that will get the current time and then call the second message in the pair.
So, there's no real need to test ProvideInput i
and CheckNow
-- they are entirely straightforward. Instead, one could test InputProvidedAt i Time
and Check Time
, simply by supplying whatever Time
value you want to test, and see if it does the right thing. That is, there's no need to actually execute the Process.sleep
in the test -- just provide the interesting times and see if the right thing happens.
This would require a bit of re-structuring of the code, but in a pattern that I think would actually be a nice pattern.
One would have to export InputProvidedAt i Time
and Check Time
in order to test them. But that could be done in an Internal
module which isn't in the exposed-modules
... so, it would be exposed for testing, but not for clients to use.
The update
function would need to become a thin wrapper around an internal function which, instead of actually issuing the Process.sleep
commands, returns a list of times for future checks. That way, one could test the internal function to see whether the list of times for future checks is correct.
Basically, this would mean having an internal function which has all the logic of update
except the actual conversion to a Cmd. That way, it's easy to test the logic. In fact, one could use elm-architecture-test
to do it.
I should write some tests!
It may be possible to test some things in the usual way (i.e. via elm-test). However, you can't test tasks that way, and the logic here is heavily task-oriented.
Probably the easiest option is to write a little testing app, which runs through a sequence of messages and then checks whether the appropriate results occur. Something like this:
https://github.com/fredcy/localstorage/blob/master/test/TestHtml2.elm
... though it would be a little different.