aboutsummaryrefslogtreecommitdiff
path: root/aoc2023/build/packages/adglent/src/showtime
diff options
context:
space:
mode:
Diffstat (limited to 'aoc2023/build/packages/adglent/src/showtime')
-rw-r--r--aoc2023/build/packages/adglent/src/showtime/internal/common/cli.gleam5
-rw-r--r--aoc2023/build/packages/adglent/src/showtime/internal/common/common_event_handler.gleam101
-rw-r--r--aoc2023/build/packages/adglent/src/showtime/internal/common/test_result.gleam119
-rw-r--r--aoc2023/build/packages/adglent/src/showtime/internal/common/test_suite.gleam63
-rw-r--r--aoc2023/build/packages/adglent/src/showtime/internal/erlang/discover.gleam167
-rw-r--r--aoc2023/build/packages/adglent/src/showtime/internal/erlang/event_handler.gleam91
-rw-r--r--aoc2023/build/packages/adglent/src/showtime/internal/erlang/module_handler.gleam43
-rw-r--r--aoc2023/build/packages/adglent/src/showtime/internal/erlang/runner.gleam59
-rw-r--r--aoc2023/build/packages/adglent/src/showtime/internal/reports/compare.gleam42
-rw-r--r--aoc2023/build/packages/adglent/src/showtime/internal/reports/formatter.gleam480
-rw-r--r--aoc2023/build/packages/adglent/src/showtime/internal/reports/styles.gleam84
-rw-r--r--aoc2023/build/packages/adglent/src/showtime/internal/reports/table.gleam148
-rw-r--r--aoc2023/build/packages/adglent/src/showtime/tests/meta.gleam3
-rw-r--r--aoc2023/build/packages/adglent/src/showtime/tests/should.gleam113
-rw-r--r--aoc2023/build/packages/adglent/src/showtime/tests/test.gleam57
15 files changed, 0 insertions, 1575 deletions
diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/common/cli.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/common/cli.gleam
deleted file mode 100644
index 1c03211..0000000
--- a/aoc2023/build/packages/adglent/src/showtime/internal/common/cli.gleam
+++ /dev/null
@@ -1,5 +0,0 @@
-pub type Capture {
- Yes
- No
- Mixed
-}
diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/common/common_event_handler.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/common/common_event_handler.gleam
deleted file mode 100644
index b90af14..0000000
--- a/aoc2023/build/packages/adglent/src/showtime/internal/common/common_event_handler.gleam
+++ /dev/null
@@ -1,101 +0,0 @@
-import gleam/map.{type Map}
-import showtime/internal/common/test_suite.{
- type TestEvent, type TestRun, CompletedTestRun, EndTest, EndTestRun,
- EndTestSuite, OngoingTestRun, StartTest, StartTestRun, StartTestSuite,
-}
-
-pub type TestState {
- NotStarted
- Running
- Finished(num_modules: Int)
-}
-
-pub type HandlerState {
- HandlerState(
- test_state: TestState,
- num_done: Int,
- events: Map(String, Map(String, TestRun)),
- )
-}
-
-// This is the common event-handler (shared between erlang/JS targets)
-// The main strategy is to collect the test-results in a map of maps:
-// module_name ->
-// test_name -> test_result
-// It will also keep track of if it is running (i.e. did it receive the EndTestRun)
-// so that the caller can determine when to print test-results
-pub fn handle_event(
- msg: TestEvent,
- system_time: fn() -> Int,
- state: HandlerState,
-) {
- let test_state = state.test_state
- let num_done = state.num_done
- let events = state.events
- let #(updated_test_state, updated_num_done, updated_events) = case msg {
- StartTestRun -> #(Running, num_done, events)
- StartTestSuite(module) -> {
- let maybe_module_events = map.get(events, module.name)
- let new_events = case maybe_module_events {
- Ok(_) -> events
- Error(_) ->
- events
- |> map.insert(module.name, map.new())
- }
- #(test_state, num_done, new_events)
- }
- StartTest(module, test) -> {
- let current_time = system_time()
- let maybe_module_events = map.get(events, module.name)
- let new_events = case maybe_module_events {
- Ok(module_events) -> {
- let maybe_test_event = map.get(module_events, test.name)
- case maybe_test_event {
- Error(_) ->
- events
- |> map.insert(
- module.name,
- module_events
- |> map.insert(test.name, OngoingTestRun(test, current_time)),
- )
- Ok(_) -> events
- }
- }
- Error(_) -> events
- }
- #(test_state, num_done, new_events)
- }
- EndTest(module, test, result) -> {
- let current_time = system_time()
- let maybe_module_events = map.get(events, module.name)
- let new_events = case maybe_module_events {
- Ok(module_events) -> {
- let maybe_test_run =
- module_events
- |> map.get(test.name)
- let updated_module_events = case maybe_test_run {
- Ok(OngoingTestRun(test_function, started_at)) ->
- module_events
- |> map.insert(
- test.name,
- CompletedTestRun(
- test_function,
- current_time - started_at,
- result,
- ),
- )
- Error(_) -> module_events
- }
- events
- |> map.insert(module.name, updated_module_events)
- }
- Error(_) -> events
- }
- #(test_state, num_done, new_events)
- }
- EndTestSuite(_) -> #(test_state, num_done + 1, events)
- EndTestRun(num_modules) -> #(Finished(num_modules), num_done, events)
- _ -> #(Running, num_done, events)
- }
- HandlerState(updated_test_state, updated_num_done, updated_events)
-}
diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/common/test_result.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/common/test_result.gleam
deleted file mode 100644
index a1d6bd9..0000000
--- a/aoc2023/build/packages/adglent/src/showtime/internal/common/test_result.gleam
+++ /dev/null
@@ -1,119 +0,0 @@
-import gleam/dynamic.{type Dynamic}
-import gleam/map.{type Map}
-
-// These are all the types used for test-results
-// NOTE: These are heavily used in the erlang/js ffi:s
-// so any changes here are likely to break the ffi:s unless
-// the corresponding change is introduced there
-//
-// Futhermore this has some erlang related names that should
-// probably be cleaned up, but it is used by both the ffi:s
-
-// Currently only one reason, but could be possible to support
-// more reasons in the future
-pub type IgnoreReason {
- Ignore
-}
-
-// This is the return value from running the test-function
-// or ignored if the test was ignored
-pub type TestReturn {
- TestFunctionReturn(value: Dynamic, output_buffer: List(String))
- Ignored(reason: IgnoreReason)
-}
-
-// All data about an exception in the test function is captured
-// in this type.
-// This is also where the data about the assertions will end up (in reason)
-pub type Exception {
- ErlangException(
- class: Class,
- reason: Reason,
- stacktrace: TraceList,
- output_buffer: List(String),
- )
-}
-
-// Alias for the test-result which is either a TestResult (passed test, ignored or a test-definition)
-// or an Exception (failed test)
-pub type TestResult =
- Result(TestReturn, Exception)
-
-// Reason is either an assert equal (which is if the error was produced by gleeunit should)
-// TODO: Add other asserts
-// or it is a gleam error meaning that is was produced by showtime should
-// TODO: Rename GleamError to ShowtimeError
-pub type Reason {
- AssertEqual(details: List(ReasonDetail))
- AssertNotEqual(details: List(ReasonDetail))
- AssertMatch(details: List(ReasonDetail))
- GleamError(details: GleamErrorDetail)
- GleamAssert(value: Dynamic, line_no: Int)
- GenericException(value: Dynamic)
-}
-
-// ReasonDetail is the union-type used in erlang-exceptions where the reason
-// is a list of such details
-pub type ReasonDetail {
- Module(name: String)
- ReasonLine(line_no: Int)
- Expression(expression: String)
- Expected(value: Dynamic)
- Value(value: Dynamic)
- Pattern(pattern: String)
-}
-
-// Gleam error detail is produced by showtime should and will hold all the information
-// about the assertion (both expected and got)
-pub type GleamErrorDetail {
- LetAssert(
- module: String,
- function: String,
- line_no: Int,
- message: String,
- value: Dynamic,
- )
-}
-
-// Class is a part of standard erlang exceptions, but also used on js-side
-// TODO: Extend to include a JS specific constructor
-pub type Class {
- ErlangError
- Exit
- Throw
-}
-
-// The trace list is part of the standard erlang exception, but is also
-// emulated on js-side.
-// TODO: Maybe we need a js-version that contain some js-specific trace-elements
-pub type TraceList {
- TraceList(traces: List(Trace))
-}
-
-// Trace are the elements in the trace list in an erlang exception
-// TODO: Maybe add a js-specific trace (since arity is not really a js attribute)
-pub type Trace {
- Trace(function: String, arity: Arity, extra_info: List(ExtraInfo))
- TraceModule(
- module: String,
- function: String,
- arity: Arity,
- extra_info: List(ExtraInfo),
- )
-}
-
-// Extra info holds information about the file and line
-// as well as some dynamic data in a map
-// This is currently not used in the reporter
-pub type ExtraInfo {
- ErrorInfo(error_info: Map(Dynamic, Dynamic))
- File(filename: String)
- Line(line_no: Int)
-}
-
-// Arity is the erlang type for arity
-// Can be either a number, or a list of arguments
-pub type Arity {
- Num(arity: Int)
- ArgList(arg_list: List(Dynamic))
-}
diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/common/test_suite.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/common/test_suite.gleam
deleted file mode 100644
index eb58d64..0000000
--- a/aoc2023/build/packages/adglent/src/showtime/internal/common/test_suite.gleam
+++ /dev/null
@@ -1,63 +0,0 @@
-import gleam/option.{type Option}
-import showtime/internal/common/test_result.{type TestResult}
-import showtime/internal/common/cli.{type Capture}
-
-// The state (and result) of a test function
-pub type TestRun {
- OngoingTestRun(test_function: TestFunction, started_at: Int)
- CompletedTestRun(
- test_function: TestFunction,
- total_time: Int,
- result: TestResult,
- )
-}
-
-// A test module (found by discovery)
-pub type TestModule {
- TestModule(name: String, path: Option(String))
-}
-
-// A test function
-pub type TestFunction {
- TestFunction(name: String)
-}
-
-// A test suite is a test module together with the test functions
-// that were collected from that module
-pub type TestSuite {
- TestSuite(module: TestModule, tests: List(TestFunction))
-}
-
-// Test event for the event handler
-pub type TestEvent {
- StartTestRun
- StartTestSuite(test_module: TestModule)
- StartTest(test_module: TestModule, test_function: TestFunction)
- EndTest(
- test_module: TestModule,
- test_function: TestFunction,
- result: TestResult,
- )
- EndTestSuite(test_module: TestModule)
- EndTestRun(num_modules: Int)
-}
-
-// Interface for the module handler
-pub type TestModuleHandler =
- fn(TestModule) -> Nil
-
-// Interface for the event handler
-pub type TestEventHandler =
- fn(TestEvent) -> Nil
-
-// Interface for the module collector
-pub type ModuleCollector =
- fn(TestModuleHandler) -> List(TestModule)
-
-// Interface for the function collector
-pub type TestFunctionCollector =
- fn(TestModule) -> TestSuite
-
-// Interface for the test runner
-pub type TestRunner =
- fn(TestSuite, TestEventHandler, List(String), Capture) -> Nil
diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/discover.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/erlang/discover.gleam
deleted file mode 100644
index ecb752d..0000000
--- a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/discover.gleam
+++ /dev/null
@@ -1,167 +0,0 @@
-@target(erlang)
-import gleam/io
-@target(erlang)
-import gleam/dynamic.{type Dynamic}
-@target(erlang)
-import gleam/list
-@target(erlang)
-import gleam/string
-@target(erlang)
-import gleam/int
-@target(erlang)
-import gleam/option.{type Option, None, Some}
-@target(erlang)
-import gleam/erlang/atom.{type Atom}
-@target(erlang)
-import showtime/internal/common/test_suite.{
- type TestModule, type TestModuleHandler, type TestSuite, TestFunction,
- TestModule, TestSuite,
-}
-import simplifile
-
-// Module collector for erlang
-// Will search the test folder for files ending with _test and notify
-// the module handler about each module it finds
-@target(erlang)
-pub fn collect_modules(
- test_module_handler: TestModuleHandler,
- only_modules: Option(List(String)),
-) -> List(TestModule) {
- collect_modules_in_folder("./test", test_module_handler, only_modules)
-}
-
-@target(erlang)
-fn collect_modules_in_folder(
- path: String,
- test_module_handler: TestModuleHandler,
- only_modules: Option(List(String)),
-) {
- let module_prefix = get_module_prefix(path)
- let assert Ok(files) = simplifile.read_directory(path)
- let test_modules_in_folder =
- files
- |> list.filter(string.ends_with(_, "_test.gleam"))
- |> list.filter_map(fn(test_module_file) {
- let module_name =
- module_prefix <> {
- test_module_file
- |> string.replace(".gleam", "")
- }
- case only_modules {
- Some(only_modules_list) -> {
- let module_in_list =
- only_modules_list
- |> list.any(fn(only_module_name) {
- only_module_name == module_name
- |> string.replace("@", "/")
- })
- case module_in_list {
- True -> {
- let test_module = TestModule(module_name, Some(test_module_file))
- test_module_handler(test_module)
- Ok(test_module)
- }
-
- False -> Error(Nil)
- }
- }
- None -> {
- let test_module = TestModule(module_name, Some(test_module_file))
- test_module_handler(test_module)
- Ok(test_module)
- }
- }
- })
- let test_modules_in_subfolders =
- files
- |> list.map(fn(filename) { path <> "/" <> filename })
- |> list.filter(fn(file) { simplifile.is_directory(file) })
- |> list.fold(
- [],
- fn(modules, subfolder) {
- modules
- |> list.append(collect_modules_in_folder(
- subfolder,
- test_module_handler,
- only_modules,
- ))
- },
- )
- test_modules_in_folder
- |> list.append(test_modules_in_subfolders)
-}
-
-@target(erlang)
-fn get_module_prefix(path) {
- let path_without_test =
- path
- |> string.replace("./test", "")
-
- let path_without_leading_slash = case
- string.starts_with(path_without_test, "/")
- {
- True -> string.drop_left(path_without_test, 1)
- False -> path_without_test
- }
- let module_prefix =
- path_without_leading_slash
- |> string.replace("/", "@")
- case string.length(module_prefix) {
- 0 -> module_prefix
- _ -> module_prefix <> "@"
- }
-}
-
-// Test function collector for erlang
-// Uses erlang `apply` to run `module_info` for the test module
-// and collects all the exports ending with _test into a `TestSuite`
-@target(erlang)
-pub fn collect_test_functions(module: TestModule) -> TestSuite {
- let test_functions: List(#(Atom, Int)) =
- apply(
- atom.create_from_string(module.name),
- atom.create_from_string("module_info"),
- [dynamic.from(atom.create_from_string("exports"))],
- )
- |> dynamic.unsafe_coerce()
-
- let test_functions_filtered =
- test_functions
- |> list.map(fn(entry) {
- let assert #(name, arity) = entry
- #(
- name
- |> atom.to_string(),
- arity,
- )
- })
- |> list.filter_map(fn(entry) {
- let assert #(name, arity) = entry
- case string.ends_with(name, "_test") {
- True ->
- case arity {
- 0 -> Ok(name)
- _ -> {
- io.println(
- "WARNING: function \"" <> name <> "\" has arity: " <> int.to_string(
- arity,
- ) <> " - cannot be used as test (needs to be 0)",
- )
- Error("Wrong arity")
- }
- }
- False -> Error("Non matching name")
- }
- })
- |> list.filter(string.ends_with(_, "_test"))
- |> list.map(fn(function_name) { TestFunction(function_name) })
- TestSuite(module, test_functions_filtered)
-}
-
-@target(erlang)
-@external(erlang, "erlang", "apply")
-fn apply(
- module module: Atom,
- function function: Atom,
- args args: List(Dynamic),
-) -> Dynamic
diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/event_handler.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/erlang/event_handler.gleam
deleted file mode 100644
index 62a9caf..0000000
--- a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/event_handler.gleam
+++ /dev/null
@@ -1,91 +0,0 @@
-@target(erlang)
-import gleam/io
-@target(erlang)
-import gleam/otp/actor.{Continue, Stop}
-@target(erlang)
-import gleam/erlang/process.{type Subject, Normal}
-@target(erlang)
-import gleam/map
-@target(erlang)
-import showtime/internal/common/test_suite.{type TestEvent, EndTestRun}
-@target(erlang)
-import showtime/internal/common/common_event_handler.{
- Finished, HandlerState, NotStarted, handle_event,
-}
-@target(erlang)
-import showtime/internal/reports/formatter.{create_test_report}
-@target(erlang)
-import gleam/erlang.{Millisecond}
-@target(erlang)
-import gleam/option.{None}
-
-@target(erlang)
-type EventHandlerMessage {
- EventHandlerMessage(test_event: TestEvent, reply_to: Subject(Int))
-}
-
-// Starts an actor that receives test events and forwards the to the event handler
-// When handler updates the state to `Finished` the actor will wait until handler
-// reports that all modules are done and the stop
-@target(erlang)
-pub fn start() {
- let assert Ok(subject) =
- actor.start(
- #(NotStarted, 0, map.new()),
- fn(msg: EventHandlerMessage, state) {
- let EventHandlerMessage(test_event, reply_to) = msg
- let #(test_state, num_done, events) = state
- let updated_state =
- handle_event(
- test_event,
- system_time,
- HandlerState(test_state, num_done, events),
- )
- case updated_state {
- HandlerState(Finished(num_modules), num_done, events) if num_done == num_modules -> {
- let #(test_report, num_failed) = create_test_report(events)
- io.println(test_report)
- process.send(reply_to, num_failed)
- Stop(Normal)
- }
- HandlerState(test_state, num_done, events) ->
- Continue(#(test_state, num_done, events), None)
- }
- },
- )
- let parent_subject = process.new_subject()
-
- let selector =
- process.new_selector()
- |> process.selecting(parent_subject, fn(x) { x })
-
- // Returns a callback that can receive test events
- fn(test_event: TestEvent) {
- case test_event {
- EndTestRun(..) -> {
- // When EndTestRun has been received the callback will wait until the
- // actor has stopped
- // TODO: Use a timeout?
- process.send(subject, EventHandlerMessage(test_event, parent_subject))
- let num_failed = process.select_forever(selector)
- case num_failed > 0 {
- True -> halt(1)
- False -> halt(0)
- }
- }
-
- // Normally just send the test event to the actor
- _ ->
- process.send(subject, EventHandlerMessage(test_event, parent_subject))
- }
- }
-}
-
-@target(erlang)
-@external(erlang, "erlang", "halt")
-fn halt(a: Int) -> Nil
-
-@target(erlang)
-fn system_time() {
- erlang.system_time(Millisecond)
-}
diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/module_handler.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/erlang/module_handler.gleam
deleted file mode 100644
index 88cc251..0000000
--- a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/module_handler.gleam
+++ /dev/null
@@ -1,43 +0,0 @@
-@target(erlang)
-import gleam/otp/actor.{Continue}
-@target(erlang)
-import gleam/erlang/process
-@target(erlang)
-import showtime/internal/common/test_suite.{
- type TestEventHandler, type TestFunctionCollector, type TestModule,
- type TestRunner, EndTestSuite, StartTestSuite,
-}
-@target(erlang)
-import showtime/internal/common/cli.{type Capture}
-@target(erlang)
-import gleam/option.{None}
-
-@target(erlang)
-pub fn start(
- test_event_handler: TestEventHandler,
- test_function_collector: TestFunctionCollector,
- run_test_suite: TestRunner,
- ignore_tags: List(String),
- capture: Capture,
-) {
- let assert Ok(subject) =
- actor.start(
- Nil,
- fn(module: TestModule, state) {
- process.start(
- fn() {
- let test_suite = test_function_collector(module)
- test_event_handler(StartTestSuite(module))
- run_test_suite(test_suite, test_event_handler, ignore_tags, capture)
- test_event_handler(EndTestSuite(module))
- },
- False,
- )
- Continue(state, None)
- },
- )
- fn(test_module: TestModule) {
- process.send(subject, test_module)
- Nil
- }
-}
diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/runner.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/erlang/runner.gleam
deleted file mode 100644
index ebbf426..0000000
--- a/aoc2023/build/packages/adglent/src/showtime/internal/erlang/runner.gleam
+++ /dev/null
@@ -1,59 +0,0 @@
-@target(erlang)
-import gleam/list
-@target(erlang)
-import gleam/erlang/atom.{type Atom}
-@target(erlang)
-import showtime/internal/common/test_suite.{
- type TestEventHandler, type TestSuite, EndTest, StartTest,
-}
-@target(erlang)
-import showtime/internal/common/test_result.{type TestResult}
-@target(erlang)
-import showtime/internal/common/cli.{type Capture}
-
-// Runs all tests in a test suite
-@target(erlang)
-pub fn run_test_suite(
- test_suite: TestSuite,
- test_event_handler: TestEventHandler,
- ignore_tags: List(String),
- capture: Capture,
-) {
- test_suite.tests
- |> list.each(fn(test) {
- test_event_handler(StartTest(test_suite.module, test))
- let result =
- run_test(test_suite.module.name, test.name, ignore_tags, capture)
- test_event_handler(EndTest(test_suite.module, test, result))
- })
-}
-
-// Wrapper around the ffi function that converts names to atoms
-@target(erlang)
-pub fn run_test(
- module_name: String,
- test_name: String,
- ignore_tags: List(String),
- capture: Capture,
-) -> TestResult {
- let result =
- run_test_ffi(
- atom.create_from_string(module_name),
- atom.create_from_string(test_name),
- ignore_tags,
- capture,
- )
- result
-}
-
-// Calls ffi for running a test function
-// The ffi will take care of mapping the result and exception to the data-types
-// used in gleam
-@target(erlang)
-@external(erlang, "showtime_ffi", "run_test")
-fn run_test_ffi(
- module module: Atom,
- function function: Atom,
- ignore_tags ignore_tags: List(String),
- capture capture: Capture,
-) -> TestResult
diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/reports/compare.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/reports/compare.gleam
deleted file mode 100644
index 5ccddee..0000000
--- a/aoc2023/build/packages/adglent/src/showtime/internal/reports/compare.gleam
+++ /dev/null
@@ -1,42 +0,0 @@
-import gleam/dynamic.{type Dynamic}
-import gleam/string
-import showtime/internal/reports/styles.{expected_highlight, got_highlight}
-import gap.{compare_lists, compare_strings}
-import gap/styling.{from_comparison, highlight, to_styled_comparison}
-
-pub fn compare(expected: Dynamic, got: Dynamic) -> #(String, String) {
- let expected_as_list =
- expected
- |> dynamic.list(dynamic.dynamic)
- let got_as_list =
- got
- |> dynamic.list(dynamic.dynamic)
- let expected_as_string =
- expected
- |> dynamic.string()
- let got_as_string =
- got
- |> dynamic.string()
- case expected_as_list, got_as_list, expected_as_string, got_as_string {
- Ok(expected_list), Ok(got_list), _, _ -> {
- let comparison =
- compare_lists(expected_list, got_list)
- |> from_comparison()
- |> highlight(expected_highlight, got_highlight, fn(item) { item })
- |> to_styled_comparison()
- #(comparison.first, comparison.second)
- }
- _, _, Ok(expected_string), Ok(got_string) -> {
- let comparison =
- compare_strings(expected_string, got_string)
- |> from_comparison()
- |> highlight(expected_highlight, got_highlight, fn(item) { item })
- |> to_styled_comparison()
- #(comparison.first, comparison.second)
- }
- _, _, _, _ -> #(
- expected_highlight(string.inspect(expected)),
- got_highlight(string.inspect(got)),
- )
- }
-}
diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/reports/formatter.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/reports/formatter.gleam
deleted file mode 100644
index 8c1a6ac..0000000
--- a/aoc2023/build/packages/adglent/src/showtime/internal/reports/formatter.gleam
+++ /dev/null
@@ -1,480 +0,0 @@
-import gleam/io
-import gleam/int
-import gleam/list
-import gleam/string
-import gleam/option.{type Option, None, Some}
-import gleam/map.{type Map}
-import gleam/dynamic.{type Dynamic}
-import showtime/internal/common/test_result.{
- type GleamErrorDetail, type ReasonDetail, type Trace, AssertEqual, AssertMatch,
- AssertNotEqual, Expected, Expression, GenericException, GleamAssert,
- GleamError, Ignored, LetAssert, Pattern, Trace, TraceModule, Value,
-}
-import showtime/internal/common/test_suite.{type TestRun, CompletedTestRun}
-import showtime/tests/should.{type Assertion, Eq, Fail, IsError, IsOk, NotEq}
-import showtime/internal/reports/styles.{
- error_style, expected_highlight, failed_style, function_style, got_highlight,
- heading_style, ignored_style, not_style, passed_style, stacktrace_style,
-}
-import showtime/internal/reports/compare.{compare}
-import showtime/internal/reports/table.{
- AlignLeft, AlignLeftOverflow, AlignRight, Content, Separator, StyledContent,
- Table, align_table, to_string,
-}
-import showtime/tests/meta.{type Meta}
-
-type GleeUnitAssertionType {
- GleeUnitAssertEqual(message: String)
- GleeUnitAssertNotEqual(message: String)
- GleeUnitAssertMatch(message: String)
-}
-
-type ModuleAndTest {
- ModuleAndTestRun(module_name: String, test_run: TestRun)
-}
-
-type UnifiedError {
- UnifiedError(
- meta: Option(Meta),
- reason: String,
- message: String,
- expected: String,
- got: String,
- line: Option(Int),
- stacktrace: List(Trace),
- )
-}
-
-pub fn create_test_report(test_results: Map(String, Map(String, TestRun))) {
- let all_test_runs =
- test_results
- |> map.values()
- |> list.flat_map(map.values)
- let failed_test_runs =
- test_results
- |> map.to_list()
- |> list.flat_map(fn(entry) {
- let #(module_name, test_module_results) = entry
- test_module_results
- |> map.values()
- |> list.filter_map(fn(test_run) {
- case test_run {
- CompletedTestRun(_test_function, _, result) ->
- case result {
- Error(_) -> Ok(ModuleAndTestRun(module_name, test_run))
- Ok(Ignored(_)) -> Error(Nil)
- Ok(_) -> Error(Nil)
- }
- _ -> {
- test_run
- |> io.debug()
- Error(Nil)
- }
- }
- })
- })
-
- let ignored_test_runs =
- test_results
- |> map.to_list()
- |> list.flat_map(fn(entry) {
- let #(module_name, test_module_results) = entry
- test_module_results
- |> map.values()
- |> list.filter_map(fn(test_run) {
- case test_run {
- CompletedTestRun(test_function, _, result) ->
- case result {
- Ok(Ignored(reason)) ->
- Ok(#(module_name <> "." <> test_function.name, reason))
- _ -> Error(Nil)
- }
- _ -> Error(Nil)
- }
- })
- })
-
- let failed_tests_report =
- failed_test_runs
- |> list.filter_map(fn(module_and_test_run) {
- case module_and_test_run.test_run {
- CompletedTestRun(test_function, _total_time, result) ->
- case result {
- Error(exception) ->
- case exception.reason {
- AssertEqual(reason_details) ->
- Ok(format_reason(
- erlang_error_to_unified(
- reason_details,
- GleeUnitAssertEqual("Assert equal"),
- exception.stacktrace.traces,
- ),
- module_and_test_run.module_name,
- test_function.name,
- exception.output_buffer,
- ))
- AssertNotEqual(reason_details) ->
- Ok(format_reason(
- erlang_error_to_unified(
- reason_details,
- GleeUnitAssertNotEqual("Assert not equal"),
- exception.stacktrace.traces,
- ),
- module_and_test_run.module_name,
- test_function.name,
- exception.output_buffer,
- ))
- AssertMatch(reason_details) ->
- Ok(format_reason(
- erlang_error_to_unified(
- reason_details,
- GleeUnitAssertMatch("Assert match"),
- exception.stacktrace.traces,
- ),
- module_and_test_run.module_name,
- test_function.name,
- exception.output_buffer,
- ))
- GleamError(reason) ->
- Ok(format_reason(
- gleam_error_to_unified(reason, exception.stacktrace.traces),
- module_and_test_run.module_name,
- test_function.name,
- exception.output_buffer,
- ))
- // GleamAssert(value) -> Error(Nil)
- GleamAssert(value, line_no) ->
- Ok(format_reason(
- UnifiedError(
- None,
- "gleam assert",
- "Assert failed",
- "Patterns should match",
- error_style(string.inspect(value)),
- Some(line_no),
- exception.stacktrace.traces,
- ),
- module_and_test_run.module_name,
- test_function.name,
- exception.output_buffer,
- ))
- GenericException(value) ->
- Ok(format_reason(
- UnifiedError(
- None,
- "generic exception",
- "Test function threw an exception",
- "Exception in test function",
- error_style(string.inspect(value)),
- None,
- exception.stacktrace.traces,
- ),
- module_and_test_run.module_name,
- test_function.name,
- exception.output_buffer,
- ))
- other -> {
- io.println("Other: " <> string.inspect(other))
- panic
- Error(Nil)
- }
- }
- _ -> Error(Nil)
- }
- _ -> Error(Nil)
- }
- })
- |> list.fold([], fn(rows, test_rows) { list.append(rows, test_rows) })
-
- let all_test_execution_time_reports =
- all_test_runs
- |> list.filter_map(fn(test_run) {
- case test_run {
- CompletedTestRun(test_function, total_time, _) ->
- Ok(test_function.name <> ": " <> int.to_string(total_time) <> " ms")
- _ -> Error(Nil)
- }
- })
- let _execution_times_report =
- all_test_execution_time_reports
- |> string.join("\n")
-
- let all_tests_count =
- all_test_runs
- |> list.length()
- let ignored_tests_count =
- ignored_test_runs
- |> list.length()
- let failed_tests_count =
- failed_test_runs
- |> list.length()
-
- let passed =
- passed_style(
- int.to_string(all_tests_count - failed_tests_count - ignored_tests_count) <> " passed",
- )
- let failed = failed_style(int.to_string(failed_tests_count) <> " failed")
- let ignored = case ignored_tests_count {
- 0 -> ""
- _ -> ", " <> ignored_style(int.to_string(ignored_tests_count) <> " ignored")
- }
-
- let failed_tests_table =
- Table(None, failed_tests_report)
- |> align_table()
- |> to_string()
-
- let test_report =
- "\n" <> failed_tests_table <> "\n" <> passed <> ", " <> failed <> ignored
- #(test_report, failed_tests_count)
-}
-
-fn erlang_error_to_unified(
- error_details: List(ReasonDetail),
- assertion_type: GleeUnitAssertionType,
- stacktrace: List(Trace),
-) {
- error_details
- |> list.fold(
- UnifiedError(
- None,
- "not_set",
- assertion_type.message,
- "",
- "",
- None,
- stacktrace,
- ),
- fn(unified, reason) {
- case reason {
- Expression(expression) -> UnifiedError(..unified, reason: expression)
- Expected(value) ->
- case assertion_type {
- GleeUnitAssertEqual(_messaged) ->
- UnifiedError(
- ..unified,
- expected: expected_highlight(string.inspect(value)),
- )
- _ -> unified
- }
- Value(value) ->
- case assertion_type {
- GleeUnitAssertNotEqual(_message) ->
- UnifiedError(
- ..unified,
- expected: not_style("not ") <> string.inspect(value),
- got: got_highlight(string.inspect(value)),
- )
- _ ->
- UnifiedError(..unified, got: got_highlight(string.inspect(value)))
- }
- Pattern(pattern) ->
- case pattern {
- "{ ok , _ }" ->
- UnifiedError(..unified, expected: expected_highlight("Ok(_)"))
- "{ error , _ }" ->
- UnifiedError(..unified, expected: expected_highlight("Error(_)"))
- _ -> unified
- }
- _ -> unified
- }
- },
- )
-}
-
-fn gleam_error_to_unified(
- gleam_error: GleamErrorDetail,
- stacktrace: List(Trace),
-) -> UnifiedError {
- case gleam_error {
- LetAssert(_module, _function, _line_no, _message, value) -> {
- let result: Result(Dynamic, Assertion(Dynamic, Dynamic)) =
- dynamic.unsafe_coerce(value)
- let assert Error(assertion) = result
- case assertion {
- Eq(got, expected, meta) -> {
- let #(expected, got) = compare(expected, got)
- UnifiedError(
- meta,
- "assert",
- "Assert equal",
- expected,
- got,
- None,
- stacktrace,
- )
- }
- NotEq(got, expected, meta) ->
- UnifiedError(
- meta,
- "assert",
- "Assert not equal",
- not_style("not ") <> string.inspect(expected),
- string.inspect(got),
- None,
- stacktrace,
- )
- IsOk(got, meta) ->
- UnifiedError(
- meta,
- "assert",
- "Assert is Ok",
- expected_highlight("Ok(_)"),
- got_highlight(string.inspect(got)),
- None,
- stacktrace,
- )
- IsError(got, meta) ->
- UnifiedError(
- meta,
- "assert",
- "Assert is Ok",
- expected_highlight("Error(_)"),
- got_highlight(string.inspect(got)),
- None,
- stacktrace,
- )
- Fail(meta) ->
- UnifiedError(
- meta,
- "assert",
- "Assert is Ok",
- got_highlight("should.fail()"),
- got_highlight("N/A - test always expected to fail"),
- None,
- stacktrace,
- )
- }
- }
- }
-}
-
-fn format_reason(
- error: UnifiedError,
- module: String,
- function: String,
- output_buffer: List(String),
-) {
- let meta = case error.meta {
- Some(meta) ->
- Some([
- AlignRight(StyledContent(heading_style("Description")), 2),
- Separator(": "),
- AlignLeft(Content(meta.description), 0),
- ])
-
- None -> None
- }
-
- let stacktrace =
- error.stacktrace
- |> list.map(fn(trace) {
- case trace {
- Trace(function, _, _) if function == "" -> "(anonymous)"
- TraceModule(module, function, _, _) if function == "" ->
- module <> "." <> "(anonymous)"
- Trace(function, _, _) -> function
- TraceModule(module, function, _, _) -> module <> "." <> function
- }
- })
- let stacktrace_rows = case stacktrace {
- [] -> []
- [first, ..rest] -> {
- let first_row =
- Some([
- AlignRight(StyledContent(heading_style("Stacktrace")), 2),
- Separator(": "),
- AlignLeft(StyledContent(stacktrace_style(first)), 0),
- ])
- let rest_rows =
- rest
- |> list.map(fn(row) {
- Some([
- AlignRight(Content(""), 2),
- Separator(" "),
- AlignLeft(StyledContent(stacktrace_style(row)), 0),
- ])
- })
- [first_row, ..rest_rows]
- }
- }
-
- let output_rows = case
- output_buffer
- |> list.reverse()
- |> list.map(fn(row) { string.trim_right(row) })
- {
- [] -> []
- [first, ..rest] -> {
- let first_row =
- Some([
- AlignRight(StyledContent(heading_style("Output")), 2),
- Separator(": "),
- AlignLeftOverflow(StyledContent(stacktrace_style(first)), 0),
- ])
- let rest_rows =
- rest
- |> list.map(fn(row) {
- Some([
- AlignRight(Content(""), 2),
- Separator(" "),
- AlignLeftOverflow(StyledContent(stacktrace_style(row)), 0),
- ])
- })
- [first_row, ..rest_rows]
- }
- }
-
- let line =
- error.line
- |> option.map(fn(line) { ":" <> int.to_string(line) })
- |> option.unwrap("")
-
- let arrow =
- string.join(
- list.repeat(
- "-",
- string.length(module) + 1 + {
- string.length(function) + string.length(line)
- } / 2,
- ),
- "",
- ) <> "⌄"
- let standard_table_rows = [
- Some([
- AlignRight(StyledContent(error_style("Failed")), 2),
- Separator(": "),
- AlignLeft(Content(arrow), 0),
- ]),
- Some([
- AlignRight(StyledContent(heading_style("Test")), 2),
- Separator(": "),
- AlignLeft(
- StyledContent(module <> "." <> function_style(function <> line)),
- 0,
- ),
- ]),
- meta,
- Some([
- AlignRight(StyledContent(heading_style("Expected")), 2),
- Separator(": "),
- AlignLeftOverflow(StyledContent(error.expected), 0),
- ]),
- Some([
- AlignRight(StyledContent(heading_style("Got")), 2),
- Separator(": "),
- AlignLeftOverflow(StyledContent(error.got), 0),
- ]),
- ]
- standard_table_rows
- |> list.append(stacktrace_rows)
- |> list.append(output_rows)
- |> list.append([
- Some([
- AlignRight(Content(""), 0),
- AlignRight(Content(""), 0),
- AlignRight(Content(""), 0),
- ]),
- ])
- |> list.filter_map(fn(row) { option.to_result(row, Nil) })
-}
diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/reports/styles.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/reports/styles.gleam
deleted file mode 100644
index b051dd3..0000000
--- a/aoc2023/build/packages/adglent/src/showtime/internal/reports/styles.gleam
+++ /dev/null
@@ -1,84 +0,0 @@
-import gleam_community/ansi
-import gleam/list
-import gleam/string
-import gleam/bit_array
-
-pub fn passed_style(text) {
- bold_green(text)
-}
-
-pub fn failed_style(text) {
- bold_red(text)
-}
-
-pub fn ignored_style(text) {
- bold_yellow(text)
-}
-
-pub fn error_style(text) {
- bold_red(text)
-}
-
-pub fn expected_highlight(text) {
- bold_green(text)
-}
-
-pub fn got_highlight(text) {
- bold_red(text)
-}
-
-pub fn not_style(text) {
- ansi.bold(text)
-}
-
-pub fn module_style(text: String) {
- ansi.cyan(text)
-}
-
-pub fn heading_style(text: String) {
- ansi.cyan(text)
-}
-
-pub fn function_style(text: String) {
- bold_cyan(text)
-}
-
-pub fn stacktrace_style(text: String) {
- text
-}
-
-fn bold_red(text: String) {
- ansi.bold(ansi.red(text))
-}
-
-fn bold_green(text) {
- ansi.bold(ansi.green(text))
-}
-
-fn bold_yellow(text) {
- ansi.bold(ansi.yellow(text))
-}
-
-fn bold_cyan(text) {
- ansi.bold(ansi.cyan(text))
-}
-
-pub fn strip_style(text) {
- let #(new_text, _) =
- text
- |> string.to_graphemes()
- |> list.fold(
- #("", False),
- fn(acc, char) {
- let #(str, removing) = acc
- let bit_char = bit_array.from_string(char)
- case bit_char, removing {
- <<0x1b>>, _ -> #(str, True)
- <<0x6d>>, True -> #(str, False)
- _, True -> #(str, True)
- _, False -> #(str <> char, False)
- }
- },
- )
- new_text
-}
diff --git a/aoc2023/build/packages/adglent/src/showtime/internal/reports/table.gleam b/aoc2023/build/packages/adglent/src/showtime/internal/reports/table.gleam
deleted file mode 100644
index f8bc00c..0000000
--- a/aoc2023/build/packages/adglent/src/showtime/internal/reports/table.gleam
+++ /dev/null
@@ -1,148 +0,0 @@
-import gleam/list
-import gleam/string
-import gleam/int
-import gleam/option.{type Option}
-import showtime/internal/reports/styles.{strip_style}
-
-pub type Content {
- Content(unstyled_text: String)
- StyledContent(styled_text: String)
-}
-
-pub type Col {
- AlignRight(content: Content, margin: Int)
- AlignLeft(content: Content, margin: Int)
- AlignRightOverflow(content: Content, margin: Int)
- AlignLeftOverflow(content: Content, margin: Int)
- Separator(char: String)
- Aligned(content: String)
-}
-
-pub type Table {
- Table(header: Option(String), rows: List(List(Col)))
-}
-
-pub fn to_string(table: Table) -> String {
- let rows =
- table.rows
- |> list.map(fn(row) {
- row
- |> list.filter_map(fn(col) {
- case col {
- Separator(char) -> Ok(char)
- Aligned(content) -> Ok(content)
- _ -> Error(Nil)
- }
- })
- |> string.join("")
- })
- |> string.join("\n")
- let header =
- table.header
- |> option.map(fn(header) { header <> "\n" })
- |> option.unwrap("")
- header <> rows
-}
-
-pub fn align_table(table: Table) -> Table {
- let cols =
- table.rows
- |> list.transpose()
- let col_width =
- cols
- |> list.map(fn(col) {
- col
- |> list.map(fn(content) {
- case content {
- AlignRight(Content(unstyled), _) -> unstyled
- AlignRight(StyledContent(styled), _) -> strip_style(styled)
- AlignLeft(Content(unstyled), _) -> unstyled
- AlignLeft(StyledContent(styled), _) -> strip_style(styled)
- AlignLeftOverflow(_, _) -> ""
- AlignRightOverflow(_, _) -> ""
- Separator(char) -> char
- Aligned(content) -> content
- }
- })
- |> list.fold(0, fn(max, str) { int.max(max, string.length(str)) })
- })
- let aligned_col =
- cols
- |> list.zip(col_width)
- |> list.map(fn(col_and_width) {
- let #(col, width) = col_and_width
- col
- |> list.map(fn(content) {
- case content {
- AlignRight(Content(unstyled), margin) ->
- Aligned(pad_left(
- unstyled,
- width + margin - string.length(unstyled),
- " ",
- ))
- AlignRight(StyledContent(styled), margin) ->
- Aligned(pad_left(
- styled,
- width + margin - string.length(strip_style(styled)),
- " ",
- ))
- AlignRightOverflow(Content(unstyled), margin) ->
- Aligned(pad_left(
- unstyled,
- width + margin - string.length(unstyled),
- " ",
- ))
- AlignRightOverflow(StyledContent(styled), margin) ->
- Aligned(pad_left(
- styled,
- width + margin - string.length(strip_style(styled)),
- " ",
- ))
- AlignLeft(Content(unstyled), margin) ->
- Aligned(pad_right(
- unstyled,
- width + margin - string.length(unstyled),
- " ",
- ))
- AlignLeft(StyledContent(styled), margin) ->
- Aligned(pad_right(
- styled,
- width + margin - string.length(strip_style(styled)),
- " ",
- ))
- AlignLeftOverflow(Content(unstyled), margin) ->
- Aligned(pad_right(
- unstyled,
- width + margin - string.length(unstyled),
- " ",
- ))
- AlignLeftOverflow(StyledContent(styled), margin) ->
- Aligned(pad_right(
- styled,
- width + margin - string.length(strip_style(styled)),
- " ",
- ))
- Separator(char) -> Separator(char)
- Aligned(content) -> Aligned(content)
- }
- })
- })
- let aligned_rows =
- aligned_col
- |> list.transpose()
- Table(..table, rows: aligned_rows)
-}
-
-fn pad_left(str: String, num: Int, char: String) {
- let padding =
- list.repeat(char, num)
- |> string.join("")
- padding <> str
-}
-
-fn pad_right(str: String, num: Int, char: String) {
- let padding =
- list.repeat(char, num)
- |> string.join("")
- str <> padding
-}
diff --git a/aoc2023/build/packages/adglent/src/showtime/tests/meta.gleam b/aoc2023/build/packages/adglent/src/showtime/tests/meta.gleam
deleted file mode 100644
index cbba414..0000000
--- a/aoc2023/build/packages/adglent/src/showtime/tests/meta.gleam
+++ /dev/null
@@ -1,3 +0,0 @@
-pub type Meta {
- Meta(description: String, tags: List(String))
-}
diff --git a/aoc2023/build/packages/adglent/src/showtime/tests/should.gleam b/aoc2023/build/packages/adglent/src/showtime/tests/should.gleam
deleted file mode 100644
index 71578c7..0000000
--- a/aoc2023/build/packages/adglent/src/showtime/tests/should.gleam
+++ /dev/null
@@ -1,113 +0,0 @@
-import gleam/option.{type Option, None, Some}
-import showtime/tests/meta.{type Meta}
-
-pub type Assertion(t, e) {
- Eq(a: t, b: t, meta: Option(Meta))
- NotEq(a: t, b: t, meta: Option(Meta))
- IsOk(a: Result(t, e), meta: Option(Meta))
- IsError(a: Result(t, e), meta: Option(Meta))
- Fail(meta: Option(Meta))
-}
-
-pub fn equal(a: t, b: t) {
- evaluate(Eq(a, b, None))
-}
-
-pub fn equal_meta(a: t, b: t, meta: Meta) {
- evaluate(Eq(a, b, Some(meta)))
-}
-
-pub fn not_equal(a: t, b: t) {
- evaluate(NotEq(a, b, None))
-}
-
-pub fn not_equal_meta(a: t, b: t, meta: Meta) {
- evaluate(NotEq(a, b, Some(meta)))
-}
-
-pub fn be_ok(a: Result(o, e)) {
- evaluate(IsOk(a, None))
- let assert Ok(value) = a
- value
-}
-
-pub fn be_ok_meta(a: Result(o, e), meta: Meta) {
- evaluate(IsOk(a, Some(meta)))
-}
-
-pub fn be_error(a: Result(o, e)) {
- evaluate(IsError(a, None))
- let assert Error(value) = a
- value
-}
-
-pub fn be_error_meta(a: Result(o, e), meta: Meta) {
- evaluate(IsError(a, Some(meta)))
-}
-
-pub fn fail() {
- evaluate(Fail(None))
-}
-
-pub fn fail_meta(meta: Meta) {
- evaluate(Fail(Some(meta)))
-}
-
-pub fn be_true(a: Bool) {
- a
- |> equal(True)
-}
-
-pub fn be_true_meta(a: Bool, meta: Meta) {
- a
- |> equal_meta(True, meta)
-}
-
-pub fn be_false(a: Bool) {
- a
- |> equal(False)
-}
-
-pub fn be_false_meta(a: Bool, meta: Meta) {
- a
- |> equal_meta(False, meta)
-}
-
-@external(erlang, "showtime_ffi", "gleam_error")
-fn gleam_error(value: Result(Nil, Assertion(a, b))) -> Nil
-
-pub fn evaluate(assertion) -> Nil {
- case assertion {
- Eq(a, b, _meta) ->
- case a == b {
- True -> Nil
- False -> {
- gleam_error(Error(assertion))
- }
- }
- NotEq(a, b, _meta) ->
- case a != b {
- True -> Nil
- False -> {
- gleam_error(Error(assertion))
- }
- }
- IsOk(a, _meta) ->
- case a {
- Ok(_) -> Nil
- Error(_) -> {
- gleam_error(Error(assertion))
- }
- }
- IsError(a, _meta) ->
- case a {
- Error(_) -> Nil
- Ok(_) -> {
- gleam_error(Error(assertion))
- }
- }
- Fail(_meta) -> {
- gleam_error(Error(assertion))
- }
- }
-}
diff --git a/aoc2023/build/packages/adglent/src/showtime/tests/test.gleam b/aoc2023/build/packages/adglent/src/showtime/tests/test.gleam
deleted file mode 100644
index 730f943..0000000
--- a/aoc2023/build/packages/adglent/src/showtime/tests/test.gleam
+++ /dev/null
@@ -1,57 +0,0 @@
-import showtime/tests/should
-import showtime/tests/meta.{type Meta}
-import gleam/io
-
-pub type Test {
- Test(meta: Meta, test_function: fn() -> Nil)
-}
-
-pub type MetaShould(t) {
- MetaShould(equal: fn(t, t) -> Nil, not_equal: fn(t, t) -> Nil)
-}
-
-pub fn test(meta: Meta, test_function: fn(Meta) -> Nil) {
- Test(meta, fn() { test_function(meta) })
-}
-
-pub fn with_meta(meta: Meta, test_function: fn(MetaShould(a)) -> Nil) {
- Test(
- meta,
- fn() {
- test_function(MetaShould(
- fn(a, b) { equal(a, b, meta) },
- fn(a, b) { not_equal(a, b, meta) },
- ))
- },
- )
-}
-
-pub fn equal(a: t, b: t, meta: Meta) {
- io.debug(a)
- io.debug(b)
- should.equal_meta(a, b, meta)
-}
-
-pub fn not_equal(a: t, b: t, meta: Meta) {
- should.equal_meta(a, b, meta)
-}
-
-pub fn be_ok(a: Result(o, e), meta: Meta) {
- should.be_ok_meta(a, meta)
-}
-
-pub fn be_error(a: Result(o, e), meta: Meta) {
- should.be_error_meta(a, meta)
-}
-
-pub fn fail(meta: Meta) {
- should.fail_meta(meta)
-}
-
-pub fn be_true(a: Bool, meta: Meta) {
- should.be_true_meta(a, meta)
-}
-
-pub fn be_false(a: Bool, meta: Meta) {
- should.be_false_meta(a, meta)
-}