Current section

Files

Jump to
dream_test src dream_test@types.erl
Raw

src/dream_test@types.erl

-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, test_info/0, suite_info/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 test_info() :: {test_info,
binary(),
list(binary()),
list(binary()),
test_kind(),
gleam@option:option(binary())}.
-type suite_info() :: {suite_info,
binary(),
list(test_info()),
gleam@option:option(binary())}.
-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()),
gleam@option:option(binary())} |
{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", 420).
?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", 453).
?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.