expert-experiments

This commit is contained in:
Alexander Heldt
2025-11-08 19:32:36 +01:00
parent 0d5036c5c4
commit 760f5ef4a6
10 changed files with 441 additions and 0 deletions

View File

@@ -0,0 +1,143 @@
import exercism/should
import exercism/test_runner
import expert_experiments
import gleam/erlang/process
import gleam/list
pub fn main() {
test_runner.main()
}
fn mutable_yielder(elements: List(t)) -> fn() -> t {
let subject = process.new_subject()
list.each(elements, fn(element) { process.send(subject, element) })
fn() {
case process.receive(subject, 0) {
Ok(element) -> element
Error(_) -> panic as "Callback called too many times"
}
}
}
fn logger() -> #(fn(String) -> Nil, fn() -> List(String)) {
let subject = process.new_subject()
let writer = fn(message) { process.send(subject, message) }
let reader = fn() { read_all(subject, []) }
#(writer, reader)
}
fn read_all(
subject: process.Subject(String),
read: List(String),
) -> List(String) {
case process.receive(subject, 0) {
Ok(message) -> read_all(subject, [message, ..read])
Error(_) -> list.reverse(read)
}
}
pub fn with_retry_pass_test() {
let function = mutable_yielder([Ok("First"), Error("Second")])
{
use <- expert_experiments.with_retry
function()
}
|> should.equal(Ok("First"))
}
pub fn with_retry_fail_fail_test() {
let function = mutable_yielder([Error("First"), Error("Second")])
{
use <- expert_experiments.with_retry
function()
}
|> should.equal(Error("Second"))
}
pub fn with_retry_fail_pass_test() {
let function = mutable_yielder([Error("First"), Ok("Second")])
{
use <- expert_experiments.with_retry
function()
}
|> should.equal(Ok("Second"))
}
pub fn record_timing_pass_test() {
let #(writer, reader) = logger()
{
use <- expert_experiments.record_timing(fn() { writer("timer") })
writer("experiment")
Ok(0)
}
|> should.equal(Ok(0))
reader()
|> should.equal(["timer", "experiment", "timer"])
}
pub fn record_timing_fail_test() {
let #(writer, reader) = logger()
{
use <- expert_experiments.record_timing(fn() { writer("timer") })
writer("experiment")
Error(Nil)
}
|> should.equal(Error(Nil))
reader()
|> should.equal(["timer", "experiment", "timer"])
}
pub fn run_experiment_fail_test() {
{
let setup = fn() { Error("Setup failed") }
let action = fn(_) { panic as "Should not run action" }
use _, _ <- expert_experiments.run_experiment("Experiment 1", setup, action)
panic as "Should not run record"
}
|> should.equal(Error("Setup failed"))
}
pub fn run_experiment_pass_fail_test() {
{
let setup = fn() { Ok(1) }
let action = fn(x) {
should.equal(x, 1)
Error("Action failed")
}
use _, _ <- expert_experiments.run_experiment("Experiment 1", setup, action)
panic as "Should not run record"
}
|> should.equal(Error("Action failed"))
}
pub fn run_experiment_pass_pass_fail_test() {
{
let setup = fn() { Ok(1) }
let action = fn(x) {
should.equal(x, 1)
Ok("2")
}
use x, y <- expert_experiments.run_experiment("Experiment 1", setup, action)
should.equal(x, 1)
should.equal(y, "2")
Error("Record failed")
}
|> should.equal(Error("Record failed"))
}
pub fn run_experiment_pass_pass_pass_test() {
{
let setup = fn() { Ok(1) }
let action = fn(x) {
should.equal(x, 1)
Ok("2")
}
use x, y <- expert_experiments.run_experiment("Experiment 1", setup, action)
should.equal(x, 1)
should.equal(y, "2")
Ok("Success!")
}
|> should.equal(Ok(#("Experiment 1", "Success!")))
}