testbldr
This library is a dead simple set of utilities for building test suites programatically. Most of the time it makes sense to have one test signature per test, and have those tests automatically discovered and run. Other times you may want to read test cases in from files, json responses, etc. This library is for the second case.
import testbldr
import testbldr/should
import gleam/list
import gleam/int
import gleam/json
import gleam/dynamic
pub fn main() {
// Lets say you have some test
// cases in a json file. Here's an example of building a test suite
// from them
// The function we're testing
let double = fn(x) { x * 2 }
// Test cases given as json
let test_cases =
"[
{
\"name\": \"1 doubled is 2\",
\"input\": 1,
\"expected_output\": 2
},
{
\"name\": \"3 doubled is 6\",
\"input\": 3,
\"expected_output\": 6
}
]"
testbldr.demonstrate(
that: "Our doubling function works",
with:
{
// Decode our tests cases from the JSON. If it doesn't decode
// correctly we crash the whole thing because it's a test suite
let assert Ok(test_cases) = test_cases_from_json(test_cases)
// Map over our tests cases to start transforming them
use test_case <- list.map(test_cases)
// Give each test the name specified in the json, to be printed
// properly on test run
use <- testbldr.named(test_case.name)
// The thing we're actually testing
double(test_case.input)
|> should.equal(test_case.expected_output)
},
)
}
/// Something to parse our JSON test cases into
type TestCase {
TestCase(name: String, input: Int, expected_output: Int)
}
/// Decode our list of test cases
fn test_cases_from_json(
input: String,
) -> Result(List(TestCase), json.DecodeError) {
let test_decoder =
dynamic.decode3(
TestCase,
dynamic.field("name", of: dynamic.string),
dynamic.field("input", of: dynamic.int),
dynamic.field("expected_output", of: dynamic.int),
)
json.decode(from: input, using: dynamic.list(test_decoder))
}