Test.Runner.Effectful

Functions for running Gren integration tests that depend on the actual results of tasks.

Running Tests

run : Test -> Program a

Create a program that runs your effectful Test suite.

This will normally be used as your main function:

main =
    run <|
        await (Task.succeed "hi") "my test" <| \val ->
            test "my test" <| \_ ->
                Expect.equal "hi" val
await : Task error a -> String -> (a -> Test) -> Test

Lets you wait for a task to resolve before running a test.

Use this by wrapping a test from the core test package:

await Time.now "Current time" <| \now ->
    Test.test "is not Jan 1, 1970" <| \_ ->
        Expect.notEqual (Time.millisToPosix 0) now

If the task fails, the inner test won't run and the test suite will fail. If you want to test the error condition of a task, use awaitError.

awaitError : Task error a -> String -> (error -> Test) -> Test

Test tasks that you expect to fail:

awaitError (Task.fail "oopsy") "An expected failure" <| \error ->
    test "is an oopsy" \_ ->
        Expect.equal "oopsy" error

If the task does not fail, the inner test won't run and the test suite will fail.

join : Array Test -> Test

Group an array of Tests into one.

These can be nested.

pure : Test -> Test

Wrap a non-effectful test to include it in your effectful test suite.

pure <|
    test "test that doesn't need a task" <| \_ ->
        Expect.equal True True

Accessing the Environment and Subsystems

Sometimes tasks might require a permission value from a subsystem like the FileSystem or HttpClient.

Or maybe you need the Node.Environment to check the platform or incoming command line arguments.

You can do that by replacing run with init and thenRun. It would look like this:

main : Effectful.Program a
main = 
    init <| \env ->
        Init.await FileSystem.initialize <| \fsPerm->
        Init.await HttpClient.initialize <| \httpPerm->
            thenRun env <|
                await (myTask fsPerm httpPerm) "my task" <| \val ->
                    test "my test" <| \_ ->
                        Expect.equal "something" val
init : (Environment -> Task (Cmd a)) -> Program a

Allows you to wait for Init tasks before running tests.

The body of the innermost init task should contain a call to thenRun. See above for an example.

thenRun : Environment -> Test -> Task (Cmd a)

Define a Test suite that should run after initializing subsystems.

The semantics of this functino are equivalent to run, except it gives you an Init task

Type aliases

type alias Program a = SimpleProgram a

Type alias for a program that runs your effectful Test suite.

type alias Test = Task Never Test

Type alias for an "effectful test".

This is just a task that always resolves to a core test.

Normally you'd get this by wrapping a test from the core test package with a call to await or one of the similar functions in this package.

Tests can be combined with other tests using join, and turned into a runnable program with run.

Tests from the core package can be turned into an effectful test directly with pure.