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?
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.
Create an Elm Native module - see this tutorial.
Inside it, load the data using any Node javascript functions e.g. fs = require('fs')
and JSON.parse
etc.
Return the data as a simple Javascript object e.g. nested arrays of numbers etc.
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.