-module(showtime@reports@formatter). -compile(no_auto_import). -export([create_test_report/1]). -export_type([module_and_test/0, unified_error/0]). -type module_and_test() :: {module_and_test_run, binary(), showtime@common@test_suite:test_run()}. -type unified_error() :: {unified_error, gleam@option:option(showtime@tests@meta:meta()), binary(), binary(), binary(), binary(), list(showtime@common@test_result:trace())}. -spec create_test_report( gleam@map:map_(binary(), gleam@map:map_(binary(), showtime@common@test_suite:test_run())) ) -> binary(). create_test_report(Test_results) -> All_test_runs = begin _pipe = Test_results, _pipe@1 = gleam@map:values(_pipe), gleam@list:flat_map(_pipe@1, fun gleam@map:values/1) end, Failed_test_runs = begin _pipe@2 = Test_results, _pipe@3 = gleam@map:to_list(_pipe@2), gleam@list:flat_map( _pipe@3, fun(Entry) -> {Module_name, Test_module_results} = Entry, _pipe@4 = Test_module_results, _pipe@5 = gleam@map:values(_pipe@4), gleam@list:filter_map(_pipe@5, fun(Test_run) -> case Test_run of {completed_test_run, _, _, Result} -> case Result of {error, _} -> {ok, {module_and_test_run, Module_name, Test_run}}; {ok, _} -> {error, nil}; {ok, {ignored, _}} -> {error, nil} end; _ -> _pipe@6 = Test_run, gleam@io:debug(_pipe@6), {error, nil} end end) end ) end, Ignored_test_runs = begin _pipe@7 = Test_results, _pipe@8 = gleam@map:to_list(_pipe@7), gleam@list:flat_map( _pipe@8, fun(Entry@1) -> {Module_name@1, Test_module_results@1} = Entry@1, _pipe@9 = Test_module_results@1, _pipe@10 = gleam@map:values(_pipe@9), gleam@list:filter_map( _pipe@10, fun(Test_run@1) -> case Test_run@1 of {completed_test_run, Test_function, _, Result@1} -> case Result@1 of {ok, {ignored, Reason}} -> {ok, {<<<>/binary, (erlang:element( 2, Test_function ))/binary>>, Reason}}; _ -> {error, nil} end; _ -> {error, nil} end end ) end ) end, Failed_tests_report = begin _pipe@11 = Failed_test_runs, _pipe@12 = gleam@list:filter_map( _pipe@11, fun(Module_and_test_run) -> case erlang:element(3, Module_and_test_run) of {completed_test_run, Test_function@1, _, Result@2} -> case Result@2 of {error, Exception} -> case erlang:element(3, Exception) of {assert_equal, Reason_details} -> {ok, format_reason( erlang_error_to_unified( Reason_details, <<"Assert equal"/utf8>>, erlang:element( 2, erlang:element( 4, Exception ) ) ), erlang:element( 2, Module_and_test_run ), erlang:element( 2, Test_function@1 ) )}; {gleam_error, Reason@1} -> {ok, format_reason( gleam_error_to_unified( Reason@1, erlang:element( 2, erlang:element( 4, Exception ) ) ), erlang:element( 2, Module_and_test_run ), erlang:element( 2, Test_function@1 ) )}; Other -> gleam@io:println( <<"Other: "/utf8, (gleam@string:inspect(Other))/binary>> ), true = case false of true -> false; _assert_fail -> erlang:error( #{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"showtime/reports/formatter"/utf8>>, function => <<"create_test_report"/utf8>>, line => 115} ) end, {error, nil} end; _ -> {error, nil} end; _ -> {error, nil} end end ), gleam@list:fold( _pipe@12, [], fun(Rows, Test_rows) -> gleam@list:append(Rows, Test_rows) end ) end, All_test_execution_time_reports = begin _pipe@13 = All_test_runs, gleam@list:filter_map(_pipe@13, fun(Test_run@2) -> case Test_run@2 of {completed_test_run, Test_function@2, Total_time, _} -> {ok, <<<<<<(erlang:element(2, Test_function@2))/binary, ": "/utf8>>/binary, (gleam@int:to_string(Total_time))/binary>>/binary, " ms"/utf8>>}; _ -> {error, nil} end end) end, _ = begin _pipe@14 = All_test_execution_time_reports, gleam@string:join(_pipe@14, <<"\n"/utf8>>) end, All_tests_count = begin _pipe@15 = All_test_runs, gleam@list:length(_pipe@15) end, Ignored_tests_count = begin _pipe@16 = Ignored_test_runs, gleam@list:length(_pipe@16) end, Failed_tests_count = begin _pipe@17 = Failed_test_runs, gleam@list:length(_pipe@17) end, Passed = showtime@reports@styles:passed_style( <<(gleam@int:to_string( (All_tests_count - Failed_tests_count) - Ignored_tests_count ))/binary, " passed"/utf8>> ), Failed = showtime@reports@styles:failed_style( <<(gleam@int:to_string(Failed_tests_count))/binary, " failed"/utf8>> ), Ignored = case Ignored_tests_count of 0 -> <<""/utf8>>; _ -> <<", "/utf8, (showtime@reports@styles:ignored_style( <<(gleam@int:to_string(Ignored_tests_count))/binary, " ignored"/utf8>> ))/binary>> end, Failed_tests_table = begin _pipe@18 = {table, none, Failed_tests_report}, _pipe@19 = showtime@reports@table:align_table(_pipe@18), showtime@reports@table:to_string(_pipe@19) end, <<<<<<<<<<<<"\n"/utf8, Failed_tests_table/binary>>/binary, "\n"/utf8>>/binary, Passed/binary>>/binary, ", "/utf8>>/binary, Failed/binary>>/binary, Ignored/binary>>. -spec erlang_error_to_unified( list(showtime@common@test_result:reason_detail()), binary(), list(showtime@common@test_result:trace()) ) -> unified_error(). erlang_error_to_unified(Error_details, Message, Stacktrace) -> _pipe = Error_details, gleam@list:fold( _pipe, {unified_error, none, <<"not_set"/utf8>>, Message, <<""/utf8>>, <<""/utf8>>, Stacktrace}, fun(Unified, Reason) -> case Reason of {expression, Expression} -> erlang:setelement(3, Unified, Expression); {expected, Value} -> erlang:setelement( 5, Unified, showtime@reports@styles:expected_highlight( gleam@string:inspect(Value) ) ); {value, Value@1} -> erlang:setelement( 6, Unified, showtime@reports@styles:got_highlight( gleam@string:inspect(Value@1) ) ); _ -> Unified end end ). -spec gleam_error_to_unified( showtime@common@test_result:gleam_error_detail(), list(showtime@common@test_result:trace()) ) -> unified_error(). gleam_error_to_unified(Gleam_error, Stacktrace) -> case Gleam_error of {assert, _, _, _, _, Value} -> Result = gleam@dynamic:unsafe_coerce(Value), {error, Assertion} = case Result of {error, _} -> Result; _assert_fail -> erlang:error(#{gleam_error => assert, message => <<"Assertion pattern match failed"/utf8>>, value => _assert_fail, module => <<"showtime/reports/formatter"/utf8>>, function => <<"gleam_error_to_unified"/utf8>>, line => 199}) end, case Assertion of {eq, Got, Expected, Meta} -> {Expected@1, Got@1} = showtime@reports@compare:compare( Expected, Got ), {unified_error, Meta, <<"assert"/utf8>>, <<"Assert equal"/utf8>>, Expected@1, Got@1, Stacktrace}; {not_eq, Got@2, Expected@2} -> {unified_error, none, <<"assert"/utf8>>, <<"Assert not equal"/utf8>>, <<(showtime@reports@styles:not_style(<<"not "/utf8>>))/binary, (gleam@string:inspect(Expected@2))/binary>>, gleam@string:inspect(Got@2), Stacktrace} end end. -spec format_reason(unified_error(), binary(), binary()) -> list(list(showtime@reports@table:col())). format_reason(Error, Module, Function) -> Meta@1 = case erlang:element(2, Error) of {some, Meta} -> {some, [{align_right, {styled_content, showtime@reports@styles:heading_style( <<"Description"/utf8>> )}, 2}, {separator, <<": "/utf8>>}, {align_left, {content, erlang:element(2, Meta)}, 0}]}; none -> none end, Stacktrace = begin _pipe = erlang:element(7, Error), gleam@list:map(_pipe, fun(Trace) -> case Trace of {trace, Function@1, _, _} -> Function@1; {trace_module, Module@1, Function@2, _, _} -> <<<>/binary, Function@2/binary>> end end) end, Stacktrace_rows = case Stacktrace of [] -> []; [First | Rest] -> First_row = {some, [{align_right, {styled_content, showtime@reports@styles:heading_style( <<"Stacktrace"/utf8>> )}, 2}, {separator, <<": "/utf8>>}, {align_left, {styled_content, showtime@reports@styles:stacktrace_style(First)}, 0}]}, Rest_rows = begin _pipe@1 = Rest, gleam@list:map( _pipe@1, fun(Row) -> {some, [{align_right, {content, <<""/utf8>>}, 2}, {separator, <<" "/utf8>>}, {align_left, {styled_content, showtime@reports@styles:stacktrace_style( Row )}, 0}]} end ) end, [First_row | Rest_rows] end, Arrow = <<(gleam@string:join( gleam@list:repeat( <<"-"/utf8>>, (gleam@string:length(Module) + 1) + (gleam@string:length(Function) div 2) ), <<""/utf8>> ))/binary, "⌄"/utf8>>, Standard_table_rows = [{some, [{align_right, {styled_content, showtime@reports@styles:error_style(<<"Error"/utf8>>)}, 2}, {separator, <<": "/utf8>>}, {align_left, {content, Arrow}, 0}]}, {some, [{align_right, {styled_content, showtime@reports@styles:heading_style(<<"Test"/utf8>>)}, 2}, {separator, <<": "/utf8>>}, {align_left, {styled_content, <<<>/binary, (showtime@reports@styles:function_style(Function))/binary>>}, 0}]}, Meta@1, {some, [{align_right, {styled_content, showtime@reports@styles:heading_style( <<"Expected"/utf8>> )}, 2}, {separator, <<": "/utf8>>}, {align_left, {styled_content, erlang:element(5, Error)}, 0}]}, {some, [{align_right, {styled_content, showtime@reports@styles:heading_style(<<"Got"/utf8>>)}, 2}, {separator, <<": "/utf8>>}, {align_left, {styled_content, erlang:element(6, Error)}, 0}]}], _pipe@2 = Standard_table_rows, _pipe@3 = gleam@list:append(_pipe@2, Stacktrace_rows), _pipe@4 = gleam@list:append( _pipe@3, [{some, [{align_right, {content, <<""/utf8>>}, 0}, {align_right, {content, <<""/utf8>>}, 0}, {align_right, {content, <<""/utf8>>}, 0}]}] ), gleam@list:filter_map( _pipe@4, fun(Row@1) -> gleam@option:to_result(Row@1, nil) end ).