diff options
author | inoas <mail@inoas.com> | 2023-01-22 17:37:02 +0100 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2023-01-23 10:04:21 +0000 |
commit | 870e9d4f2b55887c965991ac0661b30e5a161251 (patch) | |
tree | d16d825069e6cf8ab7622b6382c5f97bd70b7b99 /test/eunit_progress.erl | |
parent | e6d553af85c42681fe948f2fad5a326cdc0701ce (diff) | |
download | gleam_stdlib-870e9d4f2b55887c965991ac0661b30e5a161251.tar.gz gleam_stdlib-870e9d4f2b55887c965991ac0661b30e5a161251.zip |
backport eunit_progress from gleeunit
Diffstat (limited to 'test/eunit_progress.erl')
-rw-r--r-- | test/eunit_progress.erl | 133 |
1 files changed, 75 insertions, 58 deletions
diff --git a/test/eunit_progress.erl b/test/eunit_progress.erl index 153130f..77939fd 100644 --- a/test/eunit_progress.erl +++ b/test/eunit_progress.erl @@ -1,31 +1,12 @@ -%% eunit_formatters https://github.com/seancribbs/eunit_formatters -%% Changes made to the original code: -%% - Embedded binomial_heap.erl file contents into current file. -%% - ignore warnings for heap implementation to keep complete implementation. -%% - removed "namespaced_dicts" dependant preprocessor directive, -%% as it does not apply for our project, we just assume OTP version >= 17. -%% This is because the previous verison uses rebar, and we won't do that. - -%% Copyright 2014 Sean Cribbs -%% -%% Licensed under the Apache License, Version 2.0 (the "License"); -%% you may not use this file except in compliance with the License. -%% You may obtain a copy of the License at -%% -%% http://www.apache.org/licenses/LICENSE-2.0 -%% -%% Unless required by applicable law or agreed to in writing, software -%% distributed under the License is distributed on an "AS IS" BASIS, -%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -%% See the License for the specific language governing permissions and -%% limitations under the License. +%% Except for its module name, this file is verbatim copy of gleeunit 0.10.0's <https://raw.githubusercontent.com/lpil/gleeunit/main/src/gleeunit_progress.erl> +%% A formatter adapted from Sean Cribb's https://github.com/seancribbs/eunit_formatters %% @doc A listener/reporter for eunit that prints '.' for each %% success, 'F' for each failure, and 'E' for each error. It can also %% optionally summarize the failures at the end. -compile({nowarn_unused_function, [insert/2, to_list/1, to_list/2, size/1]}). --module(eunit_progress). +-module(eunit_progress). % Renamed from gleeunit_progress -behaviour(eunit_listener). -define(NOTEST, true). -include_lib("eunit/include/eunit.hrl"). @@ -292,12 +273,53 @@ print_failure_fun(#state{status=Status}=State) -> Count + 1 end. +print_gleam_location(#{function := Function, line := Line, module := Module }, State) -> + X = indent(5, "location: ~s.~s:~p~n", [Module, Function, Line]), + print_colored(X, ?CYAN, State); +print_gleam_location(_, _) -> + ok. + +inspect(X) -> + gleam@string:inspect(X). + +print_gleam_failure_reason( + #{gleam_error := assert, message := Message, value := Value}, + State +) -> + print_colored(indent(5, "~s~n", [Message]), ?RED, State), + print_colored(indent(5, " value: ", []), ?RED, State), + print_colored(indent(0, "~s~n", [inspect(Value)]), ?RESET, State); +print_gleam_failure_reason( + #{gleam_error := todo, message := Message}, + State +) -> + print_colored(indent(5, "todo expression run~n", []), ?RED, State), + print_colored(indent(5, " message: ", []), ?RED, State), + print_colored(indent(0, "~s~n", [Message]), ?RESET, State); +print_gleam_failure_reason(Error, State) -> + print_colored(indent(5, "~p~n", [Error]), ?RED, State). + +% New Gleeunit specific formatters +print_failure_reason( + {error, {error, #{gleam_error := _} = Error, Stack}}, Output, State +) when is_list(Stack) -> + print_gleam_failure_reason(Error, State), + print_gleam_location(Error, State), + print_stack(Stack, State), + print_failure_output(5, Output, State); +print_failure_reason({error, {error, {case_clause, Value}, Stack}}, Output, State) when is_list(Stack) -> + print_colored(indent(5, "No case clause matched~n", []), ?RED, State), + print_colored(indent(5, "Value: ", []), ?CYAN, State), + print_colored(indent(0, "~s~n", [inspect(Value)]), ?RESET, State), + print_stack(Stack, State), + print_failure_output(5, Output, State); +% From the original Erlang version print_failure_reason({skipped, Reason}, _Output, State) -> print_colored(io_lib:format(" ~ts~n", [format_pending_reason(Reason)]), ?RED, State); -print_failure_reason({error, {_Class, Term, Stack}}, Output, State) when +print_failure_reason({error, {_Class, Term, _}}, Output, State) when is_tuple(Term), tuple_size(Term) == 2, is_list(element(2, Term)) -> - print_assertion_failure(Term, Stack, Output, State), + print_assertion_failure(Term, State), print_failure_output(5, Output, State); print_failure_reason({error, {error, Error, Stack}}, Output, State) when is_list(Stack) -> print_colored(indent(5, "Failure: ~p~n", [Error]), ?RED, State), @@ -307,15 +329,19 @@ print_failure_reason({error, Reason}, Output, State) -> print_colored(indent(5, "Failure: ~p~n", [Reason]), ?RED, State), print_failure_output(5, Output, State). +gleam_format_module_name(Module) -> + string:replace(atom_to_list(Module), "@", "/", all). + print_stack(Stack, State) -> - print_colored(indent(5, "Stacktrace:~n", []), ?CYAN, State), + print_colored(indent(5, "stacktrace:~n", []), ?CYAN, State), print_stackframes(Stack, State). print_stackframes([{eunit_test, _, _, _} | Stack], State) -> print_stackframes(Stack, State); print_stackframes([{eunit_proc, _, _, _} | Stack], State) -> print_stackframes(Stack, State); print_stackframes([{Module, Function, _Arity, _Location} | Stack], State) -> - print_colored(indent(7, "~p.~p~n", [Module, Function]), ?CYAN, State), + GleamModule = gleam_format_module_name(Module), + print_colored(indent(7, "~s.~p~n", [GleamModule, Function]), ?CYAN, State), print_stackframes(Stack, State); print_stackframes([], _State) -> ok. @@ -324,19 +350,11 @@ print_stackframes([], _State) -> print_failure_output(_, <<>>, _) -> ok; print_failure_output(_, undefined, _) -> ok; print_failure_output(Indent, Output, State) -> - print_colored(indent(Indent, "Output: ~ts", [Output]), ?CYAN, State). + print_colored(indent(Indent, "output: ~ts", [Output]), ?CYAN, State). -print_assertion_failure({Type, Props}, Stack, Output, State) -> +print_assertion_failure({Type, Props}, State) -> FailureDesc = format_assertion_failure(Type, Props, 5), - {M,F,A,Loc} = lists:last(Stack), - LocationText = io_lib:format(" %% ~ts:~p:in `~ts`", [proplists:get_value(file, Loc), - proplists:get_value(line, Loc), - format_function_name(M,F,A)]), print_colored(FailureDesc, ?RED, State), - io:nl(), - print_colored(LocationText, ?CYAN, State), - io:nl(), - print_failure_output(5, Output, State), io:nl(). print_pending(#state{skips=[]}) -> @@ -432,8 +450,9 @@ print_colored(Text, _Color, #state{colored=false}) -> %%------------------------------------------ %% Generic data formatters %%------------------------------------------ -format_function_name(M, F, A) -> - io_lib:format("~ts:~ts/~p", [M, F, A]). +format_function_name(M, F) -> + M1 = gleam_format_module_name(M), + io_lib:format("~ts.~ts", [M1, F]). format_optional_result(0, _) -> []; @@ -441,7 +460,7 @@ format_optional_result(Count, Text) -> io_lib:format(", ~p ~ts", [Count, Text]). format_test_identifier(Data) -> - {Mod, Fun, Arity} = proplists:get_value(source, Data), + {Mod, Fun, _} = proplists:get_value(source, Data), Line = case proplists:get_value(line, Data) of 0 -> ""; L -> io_lib:format(":~p", [L]) @@ -450,7 +469,7 @@ format_test_identifier(Data) -> undefined -> ""; DescText -> io_lib:format(": ~ts", [DescText]) end, - io_lib:format("~ts~ts~ts", [format_function_name(Mod, Fun, Arity), Line, Desc]). + io_lib:format("~ts~ts~ts", [format_function_name(Mod, Fun), Line, Desc]). format_time(undefined) -> "? seconds"; @@ -458,9 +477,11 @@ format_time(Time) -> io_lib:format("~.3f seconds", [Time / 1000]). format_pending_reason({module_not_found, M}) -> - io_lib:format("Module '~ts' missing", [M]); -format_pending_reason({no_such_function, {M,F,A}}) -> - io_lib:format("Function ~ts undefined", [format_function_name(M,F,A)]); + M1 = gleam_format_module_name(M), + io_lib:format("Module '~ts' missing", [M1]); +format_pending_reason({no_such_function, {M,F,_}}) -> + M1 = gleam_format_module_name(M), + io_lib:format("Function ~ts undefined", [format_function_name(M1,F)]); format_pending_reason({exit, Reason}) -> io_lib:format("Related process exited with reason: ~p", [Reason]); format_pending_reason(Reason) -> @@ -485,8 +506,8 @@ format_assertion_failure(Type, Props, I) when Type =:= assertion_failed end]; HasHamcrestProps -> [indent(I, "Failure: ?assertThat(~p)~n", [proplists:get_value(matcher, Props)]), - indent(I, " expected: ~p~n", [proplists:get_value(expected, Props)]), - indent(I, " got: ~p", [proplists:get_value(actual, Props)])]; + indent(I, " expected: ~p~n", [inspect(proplists:get_value(expected, Props))]), + indent(I, " got: ~p", [inspect(proplists:get_value(actual, Props))])]; true -> [indent(I, "Failure: unknown assert: ~p", [Props])] end; @@ -511,22 +532,18 @@ format_assertion_failure(Type, Props, I) when Type =:= assertNotMatch_failed format_assertion_failure(Type, Props, I) when Type =:= assertEqual_failed ; Type =:= assertEqual -> - Expr = proplists:get_value(expression, Props), - Expected = proplists:get_value(expected, Props), - Value = proplists:get_value(value, Props), - [indent(I, "Failure: ?assertEqual(~w, ~ts)~n", [Expected, - Expr]), - indent(I, " expected: ~p~n", [Expected]), - indent(I, " got: ~p", [Value])]; + Expected = inspect(proplists:get_value(expected, Props)), + Value = inspect(proplists:get_value(value, Props)), + [indent(I, "Values were not equal~n", []), + indent(I, "expected: ~s~n", [Expected]), + indent(I, " got: ~s", [Value])]; format_assertion_failure(Type, Props, I) when Type =:= assertNotEqual_failed ; Type =:= assertNotEqual -> - Expr = proplists:get_value(expression, Props), - Value = proplists:get_value(value, Props), - [indent(I, "Failure: ?assertNotEqual(~p, ~ts)~n", - [Value, Expr]), - indent(I, " expected not: == ~p~n", [Value]), - indent(I, " got: ~p", [Value])]; + Value = inspect(proplists:get_value(value, Props)), + [indent(I, "Values were equal~n", []), + indent(I, "expected: not ~s~n,", [Value]), + indent(I, " got: ~s", [Value])]; format_assertion_failure(Type, Props, I) when Type =:= assertException_failed ; Type =:= assertException -> |