-module(dream_test@types). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/dream_test/types.gleam"). -export([to_assertion_result/1, root/3, status_from_failures/1]). -export_type([status/0, test_kind/0, failure_payload/0, assertion_failure/0, assertion_result/0, match_result/1, module_coverage/0, coverage_summary/0, test_result/0, root/1, node_/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " Core types for dream_test.\n" "\n" " This module defines the data structures used throughout the framework.\n" " Most users won’t need to construct these values directly—`dream_test/unit`,\n" " `dream_test/runner`, and the reporter modules create them for you.\n" "\n" " You *will* want to read this module if you are:\n" "\n" " - writing custom matchers (you’ll work with `MatchResult(a)` and `AssertionFailure`)\n" " - building a custom reporter (you’ll consume `TestResult`)\n" " - filtering results in CI (you’ll inspect `TestResult.tags`, `TestResult.status`, etc.)\n" "\n" " ## Type Overview\n" "\n" " | Type | Purpose |\n" " |--------------------|--------------------------------------------------|\n" " | `Status` | Test outcome (Passed, Failed, etc.) |\n" " | `TestKind` | Type of test (Unit, Integration, Gherkin) |\n" " | `TestResult` | Complete result of running a test |\n" " | `AssertionResult` | Pass/fail result of an assertion chain |\n" " | `MatchResult(a)` | Intermediate result during assertion chaining |\n" " | `AssertionFailure` | Details about a failed assertion |\n" "\n" " ## For Custom Matcher Authors\n" "\n" " If you're writing custom matchers, you'll work with `MatchResult(a)`:\n" "\n" " ```gleam\n" " pub fn be_even(result) {\n" " case result {\n" " // If already failed, propagate the failure\n" " MatchFailed(failure) -> MatchFailed(failure)\n" " // Otherwise, check our condition\n" " MatchOk(value) -> check_even(value)\n" " }\n" " }\n" "\n" " fn check_even(value) {\n" " case value % 2 == 0 {\n" " True -> MatchOk(value)\n" " False ->\n" " MatchFailed(AssertionFailure(\n" " operator: \"be_even\",\n" " message: \"\",\n" " payload: Some(CustomMatcherFailure(\n" " actual: int.to_string(value),\n" " description: \"expected an even number\",\n" " )),\n" " ))\n" " }\n" " }\n" " ```\n" " =============================================================================\n" " Unified tree model (Root/Node)\n" " =============================================================================\n" "\n" " Dream Test compiles all unit/context/gherkin tests into a single tree model\n" " that the executor runs.\n" "\n" " - `Root(context)` holds the initial seed value and a single root `Node`.\n" " - `Node(context)` represents groups, tests, and lifecycle hooks.\n" "\n" ). -type status() :: passed | failed | skipped | pending | timed_out | setup_failed. -type test_kind() :: unit | integration | {gherkin_scenario, binary()}. -type failure_payload() :: {equality_failure, binary(), binary()} | {boolean_failure, boolean(), boolean()} | {option_failure, binary(), boolean()} | {result_failure, binary(), boolean()} | {collection_failure, binary(), binary(), binary()} | {comparison_failure, binary(), binary(), binary()} | {string_match_failure, binary(), binary(), binary()} | {snapshot_failure, binary(), binary(), binary(), boolean()} | {custom_matcher_failure, binary(), binary()}. -type assertion_failure() :: {assertion_failure, binary(), binary(), gleam@option:option(failure_payload())}. -type assertion_result() :: assertion_ok | {assertion_failed, assertion_failure()} | assertion_skipped. -type match_result(FJH) :: {match_ok, FJH} | {match_failed, assertion_failure()}. -type module_coverage() :: {module_coverage, binary(), float(), integer(), integer()}. -type coverage_summary() :: {coverage_summary, list(module_coverage())}. -type test_result() :: {test_result, binary(), list(binary()), status(), integer(), list(binary()), list(assertion_failure()), test_kind()}. -type root(FJI) :: {root, FJI, node_(FJI)}. -type node_(FJJ) :: {group, binary(), list(binary()), list(node_(FJJ))} | {test, binary(), list(binary()), test_kind(), fun((FJJ) -> {ok, assertion_result()} | {error, binary()}), gleam@option:option(integer())} | {before_all, fun((FJJ) -> {ok, FJJ} | {error, binary()})} | {before_each, fun((FJJ) -> {ok, FJJ} | {error, binary()})} | {after_each, fun((FJJ) -> {ok, nil} | {error, binary()})} | {after_all, fun((FJJ) -> {ok, nil} | {error, binary()})}. -file("src/dream_test/types.gleam", 265). ?DOC( " Convert a MatchResult to an AssertionResult.\n" "\n" " This discards the value and returns just the pass/fail status.\n" " Used internally by `or_fail_with`.\n" "\n" " ## Parameters\n" "\n" " - `result`: the `MatchResult(a)` you want to collapse into pass/fail\n" "\n" " ## Returns\n" "\n" " - `MatchOk(_)` becomes `AssertionOk`\n" " - `MatchFailed(failure)` becomes `AssertionFailed(failure)`\n" "\n" " ## Example\n" "\n" " ```gleam\n" " types.to_assertion_result(types.MatchOk(1))\n" " |> should\n" " |> be_equal(types.AssertionOk)\n" " |> or_fail_with(\"expected MatchOk -> AssertionOk\")\n" " ```\n" ). -spec to_assertion_result(match_result(any())) -> assertion_result(). to_assertion_result(Result) -> case Result of {match_ok, _} -> assertion_ok; {match_failed, Failure} -> {assertion_failed, Failure} end. -file("src/dream_test/types.gleam", 380). ?DOC( " Construct a root suite with a single top-level group.\n" "\n" " This is primarily a low-level helper; most users should start from\n" " `dream_test/unit.describe` or `dream_test/unit_context.describe`.\n" "\n" " ## Parameters\n" "\n" " - `name`: name of the top-level group\n" " - `seed`: the initial context value stored in the `Root`\n" " - `children`: children under the top-level group\n" "\n" " ## Returns\n" "\n" " A `Root(context)` containing a `Group(name: name, ...)` at the top.\n" ). -spec root(binary(), FJQ, list(node_(FJQ))) -> root(FJQ). root(Name, Seed, Children) -> {root, Seed, {group, Name, [], Children}}. -file("src/dream_test/types.gleam", 413). ?DOC( " Derive a Status from a list of failures.\n" "\n" " Returns `Passed` if there are no failures, `Failed` otherwise.\n" "\n" " This helper is used when a test body (or hook) accumulates a list of\n" " `AssertionFailure`s and needs to compute a summary status.\n" "\n" " ## Parameters\n" "\n" " - `failures`: assertion failures accumulated while running a test\n" "\n" " ## Returns\n" "\n" " - `Passed` when `failures` is empty\n" " - `Failed` otherwise\n" "\n" " ## Example\n" "\n" " ```gleam\n" " types.status_from_failures([])\n" " |> should\n" " |> be_equal(types.Passed)\n" " |> or_fail_with(\"expected Passed for empty failures\")\n" " ```\n" ). -spec status_from_failures(list(assertion_failure())) -> status(). status_from_failures(Failures) -> case Failures of [] -> passed; _ -> failed end.