Gizra / elm-debouncer

The most comprehensive debouncer for Elm
MIT License
13 stars 3 forks source link

Write tests #5

Open rgrempel opened 6 years ago

rgrempel commented 6 years ago

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.

amitaibu commented 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

rgrempel commented 6 years ago

Oh, those are very interesting indeed! Will check them out!

rgrempel commented 6 years ago

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 ...

... 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.

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.