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)