Current section

Files

Jump to
dream_test src dream_test@reporters@gherkin.erl
Raw

src/dream_test@reporters@gherkin.erl

-module(dream_test@reporters@gherkin).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/dream_test/reporters/gherkin.gleam").
-export([is_gherkin_result/1, format/1, report/2]).
-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(
" Gherkin-style report formatting.\n"
"\n"
" This module formats `TestResult` values with kind `GherkinScenario(_ )` in a\n"
" Cucumber-like layout (Feature → Scenario), so you can print or persist a\n"
" human-readable report for BDD runs.\n"
"\n"
" Most users won’t call this module directly—`dream_test/reporters` wires it\n"
" in automatically—but it’s useful when you want:\n"
"\n"
" - a Gherkin report as a `String` (`format`)\n"
" - to write the report using a custom function (`report`)\n"
).
-file("src/dream_test/reporters/gherkin.gleam", 106).
?DOC(
" Check if a TestResult is from a Gherkin test.\n"
"\n"
" Useful for filtering or routing results to the appropriate reporter.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" gherkin_reporter.is_gherkin_result(gherkin_result())\n"
" |> should\n"
" |> be_equal(True)\n"
" |> or_fail_with(\"expected True for gherkin results\")\n"
" ```\n"
"\n"
" ## Parameters\n"
"\n"
" - `result`: A single `TestResult` to inspect\n"
"\n"
" ## Returns\n"
"\n"
" `True` when `result.kind` is `GherkinScenario(_)`, otherwise `False`.\n"
).
-spec is_gherkin_result(dream_test@types:test_result()) -> boolean().
is_gherkin_result(Result) ->
case erlang:element(8, Result) of
{gherkin_scenario, _} ->
true;
_ ->
false
end.
-file("src/dream_test/reporters/gherkin.gleam", 135).
-spec extract_feature_name(list(binary())) -> binary().
extract_feature_name(Full_name) ->
case Full_name of
[] ->
<<"Unknown Feature"/utf8>>;
[Feature | _] ->
Feature
end.
-file("src/dream_test/reporters/gherkin.gleam", 142).
-spec format_feature_header_if_new(binary(), binary()) -> binary().
format_feature_header_if_new(Current, Previous) ->
case Current =:= Previous of
true ->
<<""/utf8>>;
false ->
erlang:list_to_binary(
[<<"Feature: "/utf8>>, Current, <<"\n"/utf8>>]
)
end.
-file("src/dream_test/reporters/gherkin.gleam", 159).
-spec format_duration(integer()) -> binary().
format_duration(Duration_ms) ->
case Duration_ms of
Ms when Ms =< 0 ->
<<""/utf8>>;
Ms@1 ->
<<<<" ("/utf8, (dream_test@timing:format_duration_ms(Ms@1))/binary>>/binary,
")"/utf8>>
end.
-file("src/dream_test/reporters/gherkin.gleam", 167).
-spec extract_scenario_name(list(binary())) -> binary().
extract_scenario_name(Full_name) ->
case lists:reverse(Full_name) of
[] ->
<<"Unknown Scenario"/utf8>>;
[Name | _] ->
Name
end.
-file("src/dream_test/reporters/gherkin.gleam", 174).
-spec status_marker(dream_test@types:status()) -> binary().
status_marker(Status) ->
case Status of
passed ->
<<"✓"/utf8>>;
failed ->
<<"✗"/utf8>>;
skipped ->
<<"-"/utf8>>;
pending ->
<<"~"/utf8>>;
timed_out ->
<<"!"/utf8>>;
setup_failed ->
<<"âš "/utf8>>
end.
-file("src/dream_test/reporters/gherkin.gleam", 218).
-spec format_failure_message(binary()) -> binary().
format_failure_message(Message) ->
case Message of
<<""/utf8>> ->
<<""/utf8>>;
_ ->
erlang:list_to_binary(
[<<" Message: "/utf8>>, Message, <<"\n"/utf8>>]
)
end.
-file("src/dream_test/reporters/gherkin.gleam", 225).
-spec format_failure_payload(
gleam@option:option(dream_test@types:failure_payload())
) -> binary().
format_failure_payload(Payload) ->
case Payload of
{some, {equality_failure, Actual, Expected}} ->
erlang:list_to_binary(
[<<" Expected: "/utf8>>,
Expected,
<<"\n"/utf8>>,
<<" Actual: "/utf8>>,
Actual,
<<"\n"/utf8>>]
);
_ ->
<<""/utf8>>
end.
-file("src/dream_test/reporters/gherkin.gleam", 211).
-spec format_one_failure(dream_test@types:assertion_failure()) -> binary().
format_one_failure(Failure) ->
Header = erlang:list_to_binary(
[<<" ✗ "/utf8>>, erlang:element(2, Failure), <<"\n"/utf8>>]
),
Message_text = format_failure_message(erlang:element(3, Failure)),
Payload_text = format_failure_payload(erlang:element(4, Failure)),
erlang:list_to_binary([Header, Message_text, Payload_text]).
-file("src/dream_test/reporters/gherkin.gleam", 197).
-spec format_all_failures(list(dream_test@types:assertion_failure()), binary()) -> binary().
format_all_failures(Failures, Accumulated) ->
case Failures of
[] ->
Accumulated;
[Failure | Rest] ->
Formatted = format_one_failure(Failure),
Updated = erlang:list_to_binary([Accumulated, Formatted]),
format_all_failures(Rest, Updated)
end.
-file("src/dream_test/reporters/gherkin.gleam", 189).
-spec format_failure_details(dream_test@types:test_result()) -> binary().
format_failure_details(Result) ->
case erlang:element(4, Result) of
failed ->
format_all_failures(erlang:element(7, Result), <<""/utf8>>);
setup_failed ->
format_all_failures(erlang:element(7, Result), <<""/utf8>>);
_ ->
<<""/utf8>>
end.
-file("src/dream_test/reporters/gherkin.gleam", 149).
-spec format_scenario(dream_test@types:test_result()) -> binary().
format_scenario(Result) ->
Scenario_name = extract_scenario_name(erlang:element(3, Result)),
Marker = status_marker(erlang:element(4, Result)),
Duration = format_duration(erlang:element(5, Result)),
Scenario_line = erlang:list_to_binary(
[<<" Scenario: "/utf8>>,
Scenario_name,
<<" "/utf8>>,
Marker,
Duration,
<<"\n"/utf8>>]
),
Failure_text = format_failure_details(Result),
erlang:list_to_binary([Scenario_line, Failure_text]).
-file("src/dream_test/reporters/gherkin.gleam", 117).
-spec format_all_results(
list(dream_test@types:test_result()),
binary(),
binary()
) -> binary().
format_all_results(Results, Previous_feature, Accumulated) ->
case Results of
[] ->
Accumulated;
[Result | Rest] ->
Feature_name = extract_feature_name(erlang:element(3, Result)),
Feature_header = format_feature_header_if_new(
Feature_name,
Previous_feature
),
Scenario_text = format_scenario(Result),
Updated = erlang:list_to_binary(
[Accumulated, Feature_header, Scenario_text]
),
format_all_results(Rest, Feature_name, Updated)
end.
-file("src/dream_test/reporters/gherkin.gleam", 271).
-spec sum_durations(list(dream_test@types:test_result()), integer()) -> integer().
sum_durations(Results, Total) ->
case Results of
[] ->
Total;
[Result | Rest] ->
sum_durations(Rest, Total + erlang:element(5, Result))
end.
-file("src/dream_test/reporters/gherkin.gleam", 294).
-spec format_summary_parts(list(binary())) -> binary().
format_summary_parts(Parts) ->
case Parts of
[] ->
<<""/utf8>>;
_ ->
erlang:list_to_binary(
[<<", "/utf8>>, gleam@string:join(Parts, <<", "/utf8>>)]
)
end.
-file("src/dream_test/reporters/gherkin.gleam", 301).
-spec add_summary_part_if_nonzero(list(binary()), integer(), binary()) -> list(binary()).
add_summary_part_if_nonzero(Parts, Count, Label) ->
case Count of
0 ->
Parts;
_ ->
[erlang:list_to_binary([erlang:integer_to_binary(Count), Label]) |
Parts]
end.
-file("src/dream_test/reporters/gherkin.gleam", 278).
-spec build_summary_suffix(integer(), integer(), integer(), integer()) -> binary().
build_summary_suffix(Skipped, Pending, Timed_out, Setup_failed) ->
Parts = begin
_pipe = [],
_pipe@1 = add_summary_part_if_nonzero(
_pipe,
Skipped,
<<" skipped"/utf8>>
),
_pipe@2 = add_summary_part_if_nonzero(
_pipe@1,
Pending,
<<" pending"/utf8>>
),
_pipe@3 = add_summary_part_if_nonzero(
_pipe@2,
Timed_out,
<<" timed out"/utf8>>
),
add_summary_part_if_nonzero(
_pipe@3,
Setup_failed,
<<" setup failed"/utf8>>
)
end,
format_summary_parts(Parts).
-file("src/dream_test/reporters/gherkin.gleam", 330).
-spec increment_if_matches(
dream_test@types:status(),
dream_test@types:status(),
integer()
) -> integer().
increment_if_matches(Status, Wanted, Count) ->
case Status =:= Wanted of
true ->
Count + 1;
false ->
Count
end.
-file("src/dream_test/reporters/gherkin.gleam", 316).
-spec count_matching_status(
list(dream_test@types:test_result()),
dream_test@types:status(),
integer()
) -> integer().
count_matching_status(Results, Wanted, Count) ->
case Results of
[] ->
Count;
[Result | Rest] ->
Next_count = increment_if_matches(
erlang:element(4, Result),
Wanted,
Count
),
count_matching_status(Rest, Wanted, Next_count)
end.
-file("src/dream_test/reporters/gherkin.gleam", 312).
-spec count_by_status(
list(dream_test@types:test_result()),
dream_test@types:status()
) -> integer().
count_by_status(Results, Wanted) ->
count_matching_status(Results, Wanted, 0).
-file("src/dream_test/reporters/gherkin.gleam", 246).
-spec format_summary(list(dream_test@types:test_result())) -> binary().
format_summary(Results) ->
Total = erlang:length(Results),
Failed = count_by_status(Results, failed),
Skipped = count_by_status(Results, skipped),
Pending = count_by_status(Results, pending),
Timed_out = count_by_status(Results, timed_out),
Setup_failed = count_by_status(Results, setup_failed),
Passed = ((((Total - Failed) - Skipped) - Pending) - Timed_out) - Setup_failed,
Total_duration = sum_durations(Results, 0),
erlang:list_to_binary(
[<<"Summary: "/utf8>>,
erlang:integer_to_binary(Total),
<<" run, "/utf8>>,
erlang:integer_to_binary(Failed),
<<" failed, "/utf8>>,
erlang:integer_to_binary(Passed),
<<" passed"/utf8>>,
build_summary_suffix(Skipped, Pending, Timed_out, Setup_failed),
<<" in "/utf8>>,
dream_test@timing:format_duration_ms(Total_duration),
<<"\n"/utf8>>]
).
-file("src/dream_test/reporters/gherkin.gleam", 52).
?DOC(
" Format test results as a Gherkin-style report string.\n"
"\n"
" Returns the complete report including:\n"
" - Feature name as header\n"
" - Scenario names with status markers\n"
" - Summary with scenario counts\n"
"\n"
" Use this when you need the report as a string.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" gherkin_reporter.format(sample_results())\n"
" |> should\n"
" |> match_snapshot(\"./test/snapshots/gherkin_format_report.snap\")\n"
" |> or_fail_with(\"expected formatted report snapshot match\")\n"
" ```\n"
"\n"
" ## Parameters\n"
"\n"
" - `results`: The test results to format\n"
"\n"
" ## Returns\n"
"\n"
" The formatted report as a `String`.\n"
).
-spec format(list(dream_test@types:test_result())) -> binary().
format(Results) ->
Formatted_results = format_all_results(Results, <<""/utf8>>, <<""/utf8>>),
Summary_text = format_summary(Results),
erlang:list_to_binary([Formatted_results, <<"\n"/utf8>>, Summary_text]).
-file("src/dream_test/reporters/gherkin.gleam", 78).
?DOC(
" Print test results using a provided writer function.\n"
"\n"
" This is the main entry point for Gherkin test runs.\n"
"\n"
" ## Example\n"
"\n"
" ```gleam\n"
" let results = runner.new([tests()]) |> runner.run()\n"
" gherkin_reporter.report(results, io.print)\n"
" ```\n"
"\n"
" ## Parameters\n"
"\n"
" - `results`: List of test results from the runner\n"
" - `write`: Function that handles the formatted output string\n"
"\n"
" ## Returns\n"
"\n"
" Returns the input results unchanged, enabling pipeline composition.\n"
).
-spec report(list(dream_test@types:test_result()), fun((binary()) -> nil)) -> list(dream_test@types:test_result()).
report(Results, Write) ->
Write(format(Results)),
Results.