-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([format/1, report/2, is_gherkin_result/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( " 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", 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", 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", 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", 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", 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", 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", 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", 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", 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", 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", 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", 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", 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", 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. -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.