stellar_prune/build/packages/gleeunit/src/gleeunit.gleam
2025-11-30 15:44:22 +01:00

86 lines
1.9 KiB
Gleam

import gleam/list
import gleam/result
import gleam/string
/// Find and run all test functions for the current project using Erlang's EUnit
/// test framework, or a custom JavaScript test runner.
///
/// Any Erlang or Gleam function in the `test` directory with a name ending in
/// `_test` is considered a test function and will be run.
///
/// A test that panics is considered a failure.
///
pub fn main() -> Nil {
do_main()
}
@external(javascript, "./gleeunit_ffi.mjs", "main")
fn do_main() -> Nil {
let options = [
Verbose,
NoTty,
Report(#(GleeunitProgress, [Colored(True)])),
ScaleTimeouts(10),
]
let result =
find_files(matching: "**/*.{erl,gleam}", in: "test")
|> list.map(gleam_to_erlang_module_name)
|> list.map(dangerously_convert_string_to_atom(_, Utf8))
|> run_eunit(options)
let code = case result {
Ok(_) -> 0
Error(_) -> 1
}
halt(code)
}
@external(erlang, "erlang", "halt")
fn halt(a: Int) -> Nil
fn gleam_to_erlang_module_name(path: String) -> String {
case string.ends_with(path, ".gleam") {
True ->
path
|> string.replace(".gleam", "")
|> string.replace("/", "@")
False ->
path
|> string.split("/")
|> list.last
|> result.unwrap(path)
|> string.replace(".erl", "")
}
}
@external(erlang, "gleeunit_ffi", "find_files")
fn find_files(matching matching: String, in in: String) -> List(String)
type Atom
type Encoding {
Utf8
}
@external(erlang, "erlang", "binary_to_atom")
fn dangerously_convert_string_to_atom(a: String, b: Encoding) -> Atom
type ReportModuleName {
GleeunitProgress
}
type GleeunitProgressOption {
Colored(Bool)
}
type EunitOption {
Verbose
NoTty
Report(#(ReportModuleName, List(GleeunitProgressOption)))
ScaleTimeouts(Int)
}
@external(erlang, "gleeunit_ffi", "run_eunit")
fn run_eunit(a: List(Atom), b: List(EunitOption)) -> Result(Nil, a)