Current section
Files
Jump to
Current section
Files
src/metamon@config.erl
-module(metamon@config).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/metamon/config.gleam").
-export([default_config/0, with_runs/2, with_seed/2, with_max_size/2, with_shrink_limit/2, with_max_edges/2, with_regression_file/2, with_diff_enabled/2, with_output_format/2, with_runs_or_panic/2, with_max_size_or_panic/2, with_shrink_limit_or_panic/2, with_max_edges_or_panic/2, with_regression_file_or_panic/2, runs/1, seed/1, max_size/1, shrink_limit/1, max_edges/1, regression_file/1, diff_enabled/1, output_format/1]).
-export_type([config_error/0, output_format/0, config/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(
" Configuration for property and metamorphic runs. Construct via\n"
" `default_config()` and the `with_*` builders. All builders that\n"
" validate input return a `Result` so misconfiguration is visible\n"
" at the type level (no silent fallback).\n"
).
-type config_error() :: {non_positive, binary(), integer()} |
{invalid_path, binary(), binary()}.
-type output_format() :: text | json.
-opaque config() :: {config,
integer(),
metamon@generator@seed:seed(),
integer(),
integer(),
integer(),
gleam@option:option(binary()),
boolean(),
output_format()}.
-file("src/metamon/config.gleam", 42).
?DOC(" Default configuration: 100 runs, max_size 99, random seed, etc.\n").
-spec default_config() -> config().
default_config() ->
{config,
100,
metamon@generator@seed:random_seed(),
99,
1024,
16,
none,
true,
text}.
-file("src/metamon/config.gleam", 56).
?DOC(" Override the number of successful runs.\n").
-spec with_runs(config(), integer()) -> {ok, config()} | {error, config_error()}.
with_runs(C, N) ->
case N =< 0 of
true ->
{error, {non_positive, <<"runs"/utf8>>, N}};
false ->
{ok,
{config,
N,
erlang:element(3, C),
erlang:element(4, C),
erlang:element(5, C),
erlang:element(6, C),
erlang:element(7, C),
erlang:element(8, C),
erlang:element(9, C)}}
end.
-file("src/metamon/config.gleam", 64).
?DOC(" Override the seed.\n").
-spec with_seed(config(), metamon@generator@seed:seed()) -> config().
with_seed(C, S) ->
{config,
erlang:element(2, C),
S,
erlang:element(4, C),
erlang:element(5, C),
erlang:element(6, C),
erlang:element(7, C),
erlang:element(8, C),
erlang:element(9, C)}.
-file("src/metamon/config.gleam", 69).
?DOC(" Override `max_size`.\n").
-spec with_max_size(config(), integer()) -> {ok, config()} |
{error, config_error()}.
with_max_size(C, N) ->
case N =< 0 of
true ->
{error, {non_positive, <<"max_size"/utf8>>, N}};
false ->
{ok,
{config,
erlang:element(2, C),
erlang:element(3, C),
N,
erlang:element(5, C),
erlang:element(6, C),
erlang:element(7, C),
erlang:element(8, C),
erlang:element(9, C)}}
end.
-file("src/metamon/config.gleam", 77).
?DOC(" Override the shrink limit.\n").
-spec with_shrink_limit(config(), integer()) -> {ok, config()} |
{error, config_error()}.
with_shrink_limit(C, N) ->
case N =< 0 of
true ->
{error, {non_positive, <<"shrink_limit"/utf8>>, N}};
false ->
{ok,
{config,
erlang:element(2, C),
erlang:element(3, C),
erlang:element(4, C),
N,
erlang:element(6, C),
erlang:element(7, C),
erlang:element(8, C),
erlang:element(9, C)}}
end.
-file("src/metamon/config.gleam", 85).
?DOC(" Override the cap on the size of edge cartesian products.\n").
-spec with_max_edges(config(), integer()) -> {ok, config()} |
{error, config_error()}.
with_max_edges(C, N) ->
case N =< 0 of
true ->
{error, {non_positive, <<"max_edges"/utf8>>, N}};
false ->
{ok,
{config,
erlang:element(2, C),
erlang:element(3, C),
erlang:element(4, C),
erlang:element(5, C),
N,
erlang:element(7, C),
erlang:element(8, C),
erlang:element(9, C)}}
end.
-file("src/metamon/config.gleam", 108).
?DOC(
" Set a regression file path. The file is created on first failure\n"
" and read on every subsequent run.\n"
"\n"
" File format (TOML-flavoured, schema version 1) is documented in\n"
" `metamon/internal/regression`. A version mismatch (a file written\n"
" by a newer metamon) makes the runner skip replay rather than\n"
" silently mis-parse forward-incompatible content; legacy v0 files\n"
" without a `schema_version` header are still accepted.\n"
"\n"
" Concurrency: each call to `record_regression_for` reads the file,\n"
" appends one entry, and writes back. Concurrent test workers\n"
" pointed at the same path can lose entries; use distinct paths per\n"
" worker if you run properties in parallel within the same process\n"
" (especially on the JavaScript target — on the BEAM, gleeunit's\n"
" per-test process isolation already serialises file access for the\n"
" tests themselves, but custom drivers should still split paths).\n"
).
-spec with_regression_file(config(), binary()) -> {ok, config()} |
{error, config_error()}.
with_regression_file(C, Path) ->
case Path of
<<""/utf8>> ->
{error, {invalid_path, Path, <<"empty"/utf8>>}};
_ ->
{ok,
{config,
erlang:element(2, C),
erlang:element(3, C),
erlang:element(4, C),
erlang:element(5, C),
erlang:element(6, C),
{some, Path},
erlang:element(8, C),
erlang:element(9, C)}}
end.
-file("src/metamon/config.gleam", 119).
?DOC(" Enable or disable structural diff in failure output.\n").
-spec with_diff_enabled(config(), boolean()) -> config().
with_diff_enabled(C, Enabled) ->
{config,
erlang:element(2, C),
erlang:element(3, C),
erlang:element(4, C),
erlang:element(5, C),
erlang:element(6, C),
erlang:element(7, C),
Enabled,
erlang:element(9, C)}.
-file("src/metamon/config.gleam", 126).
?DOC(
" Choose the failure-report output format. `Text` is the default;\n"
" `Json` produces a single-line JSON object suitable for piping\n"
" into CI dashboards or LLM-driven analysis.\n"
).
-spec with_output_format(config(), output_format()) -> config().
with_output_format(C, Fmt) ->
{config,
erlang:element(2, C),
erlang:element(3, C),
erlang:element(4, C),
erlang:element(5, C),
erlang:element(6, C),
erlang:element(7, C),
erlang:element(8, C),
Fmt}.
-file("src/metamon/config.gleam", 181).
-spec describe_error(config_error()) -> binary().
describe_error(E) ->
case E of
{non_positive, Field, Value} ->
<<<<<<Field/binary, " must be > 0 (got "/utf8>>/binary,
(erlang:integer_to_binary(Value))/binary>>/binary,
")"/utf8>>;
{invalid_path, Path, Reason} ->
<<<<<<<<"regression_file path is "/utf8, Reason/binary>>/binary,
" (got \""/utf8>>/binary,
Path/binary>>/binary,
"\")"/utf8>>
end.
-file("src/metamon/config.gleam", 174).
-spec unwrap_or_panic(binary(), {ok, config()} | {error, config_error()}) -> config().
unwrap_or_panic(Name, Result) ->
case Result of
{ok, C} ->
C;
{error, E} ->
erlang:error(#{gleam_error => panic,
message => (<<<<<<"metamon."/utf8, Name/binary>>/binary,
": "/utf8>>/binary,
(describe_error(E))/binary>>),
file => <<?FILEPATH/utf8>>,
module => <<"metamon/config"/utf8>>,
function => <<"unwrap_or_panic"/utf8>>,
line => 177})
end.
-file("src/metamon/config.gleam", 143).
?DOC(
" Like `with_runs`, but panics with a structured message on invalid\n"
" input. Intended for hard-coded test configuration where the bound\n"
" is statically known.\n"
).
-spec with_runs_or_panic(config(), integer()) -> config().
with_runs_or_panic(C, N) ->
unwrap_or_panic(<<"with_runs_or_panic"/utf8>>, with_runs(C, N)).
-file("src/metamon/config.gleam", 149).
?DOC(
" Like `with_max_size`, but panics with a structured message on\n"
" invalid input. Intended for hard-coded test configuration.\n"
).
-spec with_max_size_or_panic(config(), integer()) -> config().
with_max_size_or_panic(C, N) ->
unwrap_or_panic(<<"with_max_size_or_panic"/utf8>>, with_max_size(C, N)).
-file("src/metamon/config.gleam", 155).
?DOC(
" Like `with_shrink_limit`, but panics with a structured message on\n"
" invalid input. Intended for hard-coded test configuration.\n"
).
-spec with_shrink_limit_or_panic(config(), integer()) -> config().
with_shrink_limit_or_panic(C, N) ->
unwrap_or_panic(
<<"with_shrink_limit_or_panic"/utf8>>,
with_shrink_limit(C, N)
).
-file("src/metamon/config.gleam", 161).
?DOC(
" Like `with_max_edges`, but panics with a structured message on\n"
" invalid input. Intended for hard-coded test configuration.\n"
).
-spec with_max_edges_or_panic(config(), integer()) -> config().
with_max_edges_or_panic(C, N) ->
unwrap_or_panic(<<"with_max_edges_or_panic"/utf8>>, with_max_edges(C, N)).
-file("src/metamon/config.gleam", 167).
?DOC(
" Like `with_regression_file`, but panics with a structured message\n"
" on invalid input. Intended for hard-coded test configuration.\n"
).
-spec with_regression_file_or_panic(config(), binary()) -> config().
with_regression_file_or_panic(C, Path) ->
unwrap_or_panic(
<<"with_regression_file_or_panic"/utf8>>,
with_regression_file(C, Path)
).
-file("src/metamon/config.gleam", 193).
?DOC(" The number of successful runs the runner targets per property.\n").
-spec runs(config()) -> integer().
runs(C) ->
erlang:element(2, C).
-file("src/metamon/config.gleam", 199).
?DOC(
" The seed used to drive the deterministic PRNG. `with_seed`\n"
" pins this to a fixed value for reproducibility.\n"
).
-spec seed(config()) -> metamon@generator@seed:seed().
seed(C) ->
erlang:element(3, C).
-file("src/metamon/config.gleam", 205).
?DOC(
" Upper bound on the `Range` size parameter; controls the\n"
" complexity ramp from the first run to the last.\n"
).
-spec max_size(config()) -> integer().
max_size(C) ->
erlang:element(4, C).
-file("src/metamon/config.gleam", 211).
?DOC(
" Maximum number of shrink steps the runner attempts on a single\n"
" failure before giving up.\n"
).
-spec shrink_limit(config()) -> integer().
shrink_limit(C) ->
erlang:element(5, C).
-file("src/metamon/config.gleam", 217).
?DOC(
" Cap on the size of the cartesian-product edge sets that\n"
" combinators like `tuple2` / `map2` build up.\n"
).
-spec max_edges(config()) -> integer().
max_edges(C) ->
erlang:element(6, C).
-file("src/metamon/config.gleam", 222).
?DOC(" Path to the regression file; `None` disables the feature.\n").
-spec regression_file(config()) -> gleam@option:option(binary()).
regression_file(C) ->
erlang:element(7, C).
-file("src/metamon/config.gleam", 227).
?DOC(" Whether structural diff is shown in failure output.\n").
-spec diff_enabled(config()) -> boolean().
diff_enabled(C) ->
erlang:element(8, C).
-file("src/metamon/config.gleam", 232).
?DOC(" Selected failure-report format (`Text` or `Json`).\n").
-spec output_format(config()) -> output_format().
output_format(C) ->
erlang:element(9, C).