Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load external data into Elm test suite

I am writing an Elm test suite and want to check a function's output using a list of known good input/output pairs, stored in an external file. I can choose the format of the external file, so I could use JSON for example, but I need to keep it separate because it is accessed from other languages. (I am basically ensuring that the Elm version of the function matches other versions).

I do not want to hard-code the values into the Elm test module. Is there a way to do this with Elm and elm-test?

like image 638
spookylukey Avatar asked Jan 22 '18 09:01

spookylukey


1 Answers

I have come up with the following answer to my own question, which seems reasonable and satisfies all my requirements, but perhaps there is something better.

  1. Create an Elm Native module - see this tutorial.

  2. Inside it, load the data using any Node javascript functions e.g. fs = require('fs') and JSON.parse etc.

  3. Return the data as a simple Javascript object e.g. nested arrays of numbers etc.

  4. In the Elm test suite, this data will need to be handled as a Json Value, and decoded using Json.Decode.decodeValue

The full solution might look like this (Elm 0.18) - adapted from my real solution:

In tests/my_function_test_data.json:

[
    [0, 1, 2],
    [3, 4, 5]
]

In tests/Native/TestData.js:

var _user$project$Native_TestData = function () {
    var fs = require('fs');
    var path = require('path');
    var jsonPath = path.join(__dirname, '..', 'my_function_test_data.json');
    var myFunctionTestData = JSON.parse(fs.readFileSync(jsonPath, 'utf8'));
    return {
        myFunctionTestData: myFunctionTestData
    }
}();

In tests/MyTests.elm:

import Native.TestData

myFunctionTestData : List (List Float)
myFunctionTestData =
    JD.decodeValue (JD.list (JD.list JD.float)) Native.TestData.myFunctionTestData
        |> \v -> case v of
                     Ok val ->
                         val
                     Err msg ->
                         Debug.crash msg

This approach can be expanded in various ways (e.g. different formats, or pass a parameter to the native module to determine which file to load), and it avoids needing an extra step to generate source code modules.

like image 99
spookylukey Avatar answered Oct 10 '22 19:10

spookylukey