Current section
Files
Jump to
Current section
Files
src/dream_test@matchers.erl
-module(dream_test@matchers).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/dream_test/matchers.gleam").
-export([should/1, or_fail_with/2, fail_with/1, succeed/0]).
-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(
" Matcher API for Dream Test.\n"
"\n"
" Matchers are small functions you pipe values through to produce the value a\n"
" Dream Test `it(...)` body returns: `Result(AssertionResult, String)`.\n"
"\n"
" You’ll typically:\n"
"\n"
" - Start with `should` (wrap a value for matching)\n"
" - Apply one or more matchers (like `be_equal`, `be_some`, `contain_string`)\n"
" - Finish with `or_fail_with(\"...\")` to produce the final test result\n"
"\n"
" ## Available Matchers\n"
"\n"
" | Category | Matchers |\n"
" |----------------|-------------------------------------------------------------|\n"
" | **Equality** | `be_equal`, `not_equal` |\n"
" | **Boolean** | `be_true`, `be_false` |\n"
" | **Option** | `be_some`, `be_none` |\n"
" | **Result** | `be_ok`, `be_error` |\n"
" | **Collections**| `contain`, `not_contain`, `have_length`, `be_empty` |\n"
" | **Comparison** | `be_greater_than`, `be_less_than`, `be_at_least`, `be_at_most`, `be_between`, `be_in_range`, `be_greater_than_float`, `be_less_than_float` |\n"
" | **String** | `start_with`, `end_with`, `contain_string`, `match_regex` |\n"
" | **Snapshot** | `match_snapshot`, `match_snapshot_inspect` |\n"
"\n"
" ## Chaining Matchers\n"
"\n"
" Some matchers “unwrap” values:\n"
" - `be_some()` turns `Option(a)` into `a`\n"
" - `be_ok()` turns `Result(a, e)` into `a`\n"
"\n"
" That’s why you can chain checks after them.\n"
"\n"
" ## Explicit failures\n"
"\n"
" Sometimes you need to explicitly return “pass” or “fail” from a branch of a\n"
" `case` expression. Use `succeed()` / `fail_with(\"...\")` for that.\n"
"\n"
" ## Imports\n"
"\n"
" You can import individual matchers, or import the whole module and qualify\n"
" with `matchers.`. The examples in these docs assume you imported the matcher\n"
" functions you’re using.\n"
).
-file("src/dream_test/matchers.gleam", 81).
?DOC(
" Start a matcher chain.\n"
"\n"
" This wraps a value so it can be piped through matchers.\n"
" Every matcher chain starts with `should`.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" True\n"
" |> should\n"
" |> be_true()\n"
" |> or_fail_with(\"expected True\")\n"
" ```\n"
"\n"
" ## Parameters\n"
"\n"
" - `value`: any value you want to make assertions about\n"
"\n"
" ## Returns\n"
"\n"
" A `MatchResult(a)` containing `value`. Subsequent matchers will either:\n"
" - preserve this value (for “checking” matchers), or\n"
" - transform it (for “unwrapping” matchers like `be_some` / `be_ok`).\n"
).
-spec should(HZF) -> dream_test@types:match_result(HZF).
should(Value) ->
{match_ok, Value}.
-file("src/dream_test/matchers.gleam", 808).
-spec or_fail_with_assertion(dream_test@types:match_result(any()), binary()) -> dream_test@types:assertion_result().
or_fail_with_assertion(Result, Message) ->
case Result of
{match_ok, _} ->
assertion_ok;
{match_failed, Failure} ->
{assertion_failed,
{assertion_failure,
erlang:element(2, Failure),
Message,
erlang:element(4, Failure)}}
end.
-file("src/dream_test/matchers.gleam", 801).
?DOC(
" Complete a matcher chain and provide a failure message.\n"
"\n"
" This is the **terminal operation** that ends every matcher chain. It\n"
" converts the `MatchResult` into an `AssertionResult` that the test runner\n"
" understands.\n"
"\n"
" If the matcher passed, returns `AssertionOk`. If it failed, returns\n"
" `AssertionFailed` with the provided message.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" 2 + 3\n"
" |> should\n"
" |> be_equal(5)\n"
" |> or_fail_with(\"2 + 3 should equal 5\")\n"
" ```\n"
"\n"
" ## Parameters\n"
"\n"
" - `result`: the `MatchResult(a)` produced by `should` and matchers\n"
" - `message`: message to show if the chain failed\n"
"\n"
" ## Returns\n"
"\n"
" A `Result(AssertionResult, String)` so test bodies can return it directly:\n"
"\n"
" - `Ok(AssertionOk)` when the chain passed\n"
" - `Ok(AssertionFailed(...))` when the chain failed\n"
"\n"
" (This function currently never returns `Error`, but the `Result` shape keeps\n"
" test bodies uniform for `dream_test/unit`: `fn() { ... } -> Result(AssertionResult, String)`.)\n"
"\n"
" ## Writing Good Messages\n"
"\n"
" Good failure messages explain **what should have happened**:\n"
" - ✓ \"User should be authenticated after login\"\n"
" - ✓ \"Cart total should include tax\"\n"
" - ✗ \"wrong\"\n"
" - ✗ \"failed\"\n"
).
-spec or_fail_with(dream_test@types:match_result(any()), binary()) -> {ok,
dream_test@types:assertion_result()} |
{error, binary()}.
or_fail_with(Result, Message) ->
{ok, or_fail_with_assertion(Result, Message)}.
-file("src/dream_test/matchers.gleam", 846).
?DOC(
" Explicitly fail a test with a message.\n"
"\n"
" Use this when you need to fail a test in a conditional branch where\n"
" the normal matcher chain doesn't apply.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" Ok(case 1 + 1 {\n"
" 2 -> succeed()\n"
" _ -> fail_with(\"expected 1 + 1 to be 2\")\n"
" })\n"
" ```\n"
"\n"
" ## When to Use\n"
"\n"
" - In `case` branches that represent unexpected states\n"
" - When testing that something does NOT happen\n"
" - As a placeholder for unimplemented test branches\n"
"\n"
" ## Returns\n"
"\n"
" An `AssertionResult` you can wrap in `Ok(...)` from a test body.\n"
"\n"
" If you want to abort a test immediately (rather than “failing a matcher”),\n"
" return `Error(\"...\")` from the test body instead.\n"
).
-spec fail_with(binary()) -> dream_test@types:assertion_result().
fail_with(Message) ->
{assertion_failed, {assertion_failure, <<"fail_with"/utf8>>, Message, none}}.
-file("src/dream_test/matchers.gleam", 878).
?DOC(
" Explicitly mark a matcher chain as successful.\n"
"\n"
" Use this when you need to explicitly succeed in a conditional branch,\n"
" as the counterpart to `fail_with`.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" Ok(case 1 + 1 {\n"
" 2 -> succeed()\n"
" _ -> fail_with(\"expected 1 + 1 to be 2\")\n"
" })\n"
" ```\n"
"\n"
" ## When to Use\n"
"\n"
" - In `case` branches where success is the expected outcome\n"
" - When all branches of a case must return an `AssertionResult`\n"
" - To make intent explicit rather than relying on implicit success\n"
"\n"
" ## Returns\n"
"\n"
" `AssertionOk`.\n"
).
-spec succeed() -> dream_test@types:assertion_result().
succeed() ->
assertion_ok.