Packages

Property-based testing and metamorphic testing combinator library for Gleam

Current section

Files

Jump to
metamon src metamon@transform@list.erl
Raw

src/metamon@transform@list.erl

-module(metamon@transform@list).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/metamon/transform/list.gleam").
-export([reverse/0, dedupe/0, prepend/1, append/1, shuffle/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(
" Standard `Transform(List(a))` constructors used in metamorphic\n"
" relations. Each transform is named and deterministic.\n"
).
-file("src/metamon/transform/list.gleam", 10).
?DOC(" Reverse the list.\n").
-spec reverse() -> metamon@transform:transform(list(any())).
reverse() ->
metamon@transform:new(<<"list.reverse"/utf8>>, fun lists:reverse/1).
-file("src/metamon/transform/list.gleam", 23).
-spec loop_dedupe(list(HOA), list(HOA), list(HOA)) -> list(HOA).
loop_dedupe(Items, Seen, Acc) ->
case Items of
[] ->
lists:reverse(Acc);
[First | Rest] ->
case gleam@list:contains(Seen, First) of
true ->
loop_dedupe(Rest, Seen, Acc);
false ->
loop_dedupe(Rest, [First | Seen], [First | Acc])
end
end.
-file("src/metamon/transform/list.gleam", 19).
-spec dedupe_keep_first(list(HNX)) -> list(HNX).
dedupe_keep_first(Items) ->
loop_dedupe(Items, [], []).
-file("src/metamon/transform/list.gleam", 15).
?DOC(" Drop duplicates, keeping the first occurrence of each element.\n").
-spec dedupe() -> metamon@transform:transform(list(any())).
dedupe() ->
metamon@transform:new(<<"list.dedupe"/utf8>>, fun dedupe_keep_first/1).
-file("src/metamon/transform/list.gleam", 35).
?DOC(" Prepend `value` to the list.\n").
-spec prepend(HOF) -> metamon@transform:transform(list(HOF)).
prepend(Value) ->
metamon@transform:new(
<<"list.prepend"/utf8>>,
fun(Items) -> [Value | Items] end
).
-file("src/metamon/transform/list.gleam", 40).
?DOC(" Append `value` to the list.\n").
-spec append(HOI) -> metamon@transform:transform(list(HOI)).
append(Value) ->
metamon@transform:new(
<<"list.append"/utf8>>,
fun(Items) -> lists:append(Items, [Value]) end
).
-file("src/metamon/transform/list.gleam", 62).
-spec assign_keys_and_sort(list(HOR), metamon@generator@seed:seed(), integer()) -> list(HOR).
assign_keys_and_sort(Items, S, Length) ->
Keyed = gleam@list:fold(
Items,
{S, []},
fun(Acc, Value) ->
{State, Keyed_acc} = Acc,
{Key, Next_state} = metamon@generator@seed:next_int_in(
State,
0,
Length * 100
),
{Next_state, [{Key, Value} | Keyed_acc]}
end
),
{_, With_keys} = Keyed,
_pipe = With_keys,
_pipe@1 = gleam@list:sort(
_pipe,
fun(Left, Right) ->
gleam@int:compare(erlang:element(1, Left), erlang:element(1, Right))
end
),
gleam@list:map(_pipe@1, fun(Pair) -> erlang:element(2, Pair) end).
-file("src/metamon/transform/list.gleam", 54).
-spec shuffle_with(list(HOO), metamon@generator@seed:seed()) -> list(HOO).
shuffle_with(Items, S) ->
Length = erlang:length(Items),
case Length =< 1 of
true ->
Items;
false ->
assign_keys_and_sort(Items, S, Length)
end.
-file("src/metamon/transform/list.gleam", 48).
?DOC(
" A deterministic shuffle parametrised by a seed integer. The same\n"
" integer always produces the same permutation. Implemented as a\n"
" stable sort by random keys (Knuth's \"decorate, sort, undecorate\"\n"
" pattern).\n"
).
-spec shuffle(integer()) -> metamon@transform:transform(list(any())).
shuffle(Seed_value) ->
metamon@transform:new(
<<<<"list.shuffle("/utf8,
(erlang:integer_to_binary(Seed_value))/binary>>/binary,
")"/utf8>>,
fun(Items) ->
shuffle_with(Items, metamon@generator@seed:seed(Seed_value))
end
).