mpizenberg/elm-test-runner/1.0.0

NOTE: the latest version is 6.0.1

ElmTestRunner.Runner

Main module for a test runner worker.

Create a main test runner worker

worker : Ports Msg -> Test -> Program Flags Model Msg

Create a test runner worker. Some specific ports(ish) are required as arguments, as well as the "master" test concatenating all tests (CF SeededRunners.fromTest).

The main Elm module calling this one will typically look like the example below. In that code, {{ user_imports }} and {{ tests }} are to be replaced by the list of needed imports from user code and the list of tests to run.

port module Runner exposing (main)


{{ user_imports }}
import Test
import ElmTestRunner.Runner exposing (Flags, Model, Msg)
import Json.Encode exposing (Value)


port askNbTests : (Value -> msg) -> Sub msg
port sendNbTests : { type_ : String, nbTests : Int } -> Cmd msg
port receiveRunTest : (Int -> msg) -> Sub msg
port sendResult : { type_ : String, id: Int, result : Value } -> Cmd msg


main : Program Flags Model Msg
main =
    [ {{ tests }} ]
        |> Test.concat
        |> ElmTestRunner.Runner.worker
            { askNbTests = askNbTests
            , sendNbTests = \nb -> sendNbTests { type_ = "nbTests", nbTests = nb }
            , receiveRunTest = receiveRunTest
            , sendResult = \id res -> sendResult { type_ = "result", id = id, result = res }
            }

It can later be spawned as a Node worker with a tiny bit of JS similar to:

const { parentPort } = require("worker_threads");
const { Elm } = require("./Runner.elm.js");

// Start the Elm app
const flags = { initialSeed: ..., fuzzRuns: ... };
const app = Elm.Runner.init({ flags: flags });

// Communication between Elm runner worker and Supervisor via port
app.ports.outgoing.subscribe((msg) => parentPort.postMessage(msg));
parentPort.on("message", (msg) => app.ports.incoming.send(msg));
type alias Ports msg =
{ askNbTests : (Value -> msg) -> Sub msg
, sendNbTests : Int -> Cmd msg
, receiveRunTest : (Int -> msg) -> Sub msg
, sendResult : Int -> Value -> Cmd msg
}

Ports(ish) required by the worker program to function. They aren't exactly ports (sendResult isn't a valid port for example) but will basically be wrapped by an actual port in the main Elm caller module.

Internal types for function signatures

type alias Flags =
{ initialSeed : Int
, fuzzRuns : Int
}

The initial random seed and the number of fuzz runs are passed as flags.

type alias Model =
{ ports : Ports Msg
, testRunners : SeededRunners
}

Main model. Exposed for usage in type definitions.

type Msg

Internal messages.