diff options
author | Sergey Prokhorov <seriy.pr@gmail.com> | 2020-02-12 16:15:20 +0100 |
---|---|---|
committer | Sergey Prokhorov <seriy.pr@gmail.com> | 2020-02-27 19:37:06 +0100 |
commit | 1916f4fe0659aa8da5d3a0739f367a229a14230d (patch) | |
tree | 8f6aa9a9709c2e9f832233df6dc8f03c928c7e30 /lib/eunit | |
parent | 8eefeda8d81996bfe8249017fa0be2595eb64cff (diff) | |
download | erlang-1916f4fe0659aa8da5d3a0739f367a229a14230d.tar.gz |
Add print_depth option to eunit:test
It can be set to change the max print depth of exceptions generated
by eunit test suites. Current hardcoded limit of 20 can be considered
too small in many cases.
Diffstat (limited to 'lib/eunit')
-rw-r--r-- | lib/eunit/src/eunit.erl | 2 | ||||
-rw-r--r-- | lib/eunit/src/eunit_lib.erl | 44 | ||||
-rw-r--r-- | lib/eunit/src/eunit_tty.erl | 53 |
3 files changed, 54 insertions, 45 deletions
diff --git a/lib/eunit/src/eunit.erl b/lib/eunit/src/eunit.erl index 1ace85ffde..0238885708 100644 --- a/lib/eunit/src/eunit.erl +++ b/lib/eunit/src/eunit.erl @@ -133,6 +133,8 @@ test(Tests) -> %% <dl> %% <dt>`verbose'</dt> %% <dd>Displays more details about the running tests.</dd> +%% <dt>`print_depth'</dt> +%% <dd>Maximum depth to which terms are printed in case of error.</dd> %% </dl> %% %% Options in the environment variable EUNIT are also included last in diff --git a/lib/eunit/src/eunit_lib.erl b/lib/eunit/src/eunit_lib.erl index 771541354c..5b7d90ab0d 100644 --- a/lib/eunit/src/eunit_lib.erl +++ b/lib/eunit/src/eunit_lib.erl @@ -35,9 +35,10 @@ -export([dlist_next/1, uniq/1, fun_parent/1, is_string/1, command/1, command/2, command/3, trie_new/0, trie_store/2, trie_match/2, split_node/1, consult_file/1, list_dir/1, format_exit_term/1, - format_exception/1, format_exception/2, format_error/1, + format_exception/1, format_exception/2, format_error/1, format_error/2, is_not_test/1]). +-define(DEFAULT_DEPTH, 20). %% Type definitions for describing exceptions %% @@ -56,7 +57,7 @@ %% --------------------------------------------------------------------- %% Formatting of error descriptors format_exception(Exception) -> - format_exception(Exception, 20). + format_exception(Exception, ?DEFAULT_DEPTH). format_exception({Class,Term,Trace}, Depth) when is_atom(Class), is_list(Trace) -> @@ -159,38 +160,41 @@ is_op(erlang, F, A) -> is_op(_M, _F, _A) -> false. -format_error({bad_test, Term}) -> - error_msg("bad test descriptor", "~tP", [Term, 15]); -format_error({bad_generator, {{M,F,A}, Term}}) -> +format_error(Error) -> + format_error(Error, ?DEFAULT_DEPTH). + +format_error({bad_test, Term}, Depth) -> + error_msg("bad test descriptor", "~tP", [Term, Depth]); +format_error({bad_generator, {{M,F,A}, Term}}, Depth) -> error_msg(io_lib:format("result from generator ~w:~tw/~w is not a test", [M,F,A]), - "~tP", [Term, 15]); -format_error({generator_failed, {{M,F,A}, Exception}}) -> + "~tP", [Term, Depth]); +format_error({generator_failed, {{M,F,A}, Exception}}, Depth) -> error_msg(io_lib:format("test generator ~w:~tw/~w failed",[M,F,A]), - "~ts", [format_exception(Exception)]); -format_error({no_such_function, {M,F,A}}) + "~ts", [format_exception(Exception, Depth)]); +format_error({no_such_function, {M,F,A}}, _) when is_atom(M), is_atom(F), is_integer(A) -> error_msg(io_lib:format("no such function: ~w:~tw/~w", [M,F,A]), "", []); -format_error({module_not_found, M}) -> +format_error({module_not_found, M}, _) -> error_msg("test module not found", "~tp", [M]); -format_error({application_not_found, A}) when is_atom(A) -> +format_error({application_not_found, A}, _) when is_atom(A) -> error_msg("application not found", "~w", [A]); -format_error({file_read_error, {_R, Msg, F}}) -> +format_error({file_read_error, {_R, Msg, F}}, _) -> error_msg("error reading file", "~ts: ~ts", [Msg, F]); -format_error({setup_failed, Exception}) -> +format_error({setup_failed, Exception}, Depth) -> error_msg("context setup failed", "~ts", - [format_exception(Exception)]); -format_error({cleanup_failed, Exception}) -> + [format_exception(Exception, Depth)]); +format_error({cleanup_failed, Exception}, Depth) -> error_msg("context cleanup failed", "~ts", - [format_exception(Exception)]); -format_error({{bad_instantiator, {{M,F,A}, Term}}, _DummyException}) -> + [format_exception(Exception, Depth)]); +format_error({{bad_instantiator, {{M,F,A}, Term}}, _DummyException}, Depth) -> error_msg(io_lib:format("result from instantiator ~w:~tw/~w is not a test", [M,F,A]), - "~tP", [Term, 15]); -format_error({instantiation_failed, Exception}) -> + "~tP", [Term, Depth]); +format_error({instantiation_failed, Exception}, Depth) -> error_msg("instantiation of subtests failed", "~ts", - [format_exception(Exception)]). + [format_exception(Exception, Depth)]). error_msg(Title, Fmt, Args) -> Msg = io_lib:format("**"++Fmt, Args), % gets indentation right diff --git a/lib/eunit/src/eunit_tty.erl b/lib/eunit/src/eunit_tty.erl index 2c9a598628..ca6aa3b525 100644 --- a/lib/eunit/src/eunit_tty.erl +++ b/lib/eunit/src/eunit_tty.erl @@ -38,7 +38,8 @@ terminate/2]). -record(state, {verbose = false, - indent = 0 + indent = 0, + print_depth = 20 }). start() -> @@ -48,7 +49,9 @@ start(Options) -> eunit_listener:start(?MODULE, Options). init(Options) -> - St = #state{verbose = proplists:get_bool(verbose, Options)}, + PrintDepth = proplists:get_value(print_depth, Options, 20), + St = #state{verbose = proplists:get_bool(verbose, Options), + print_depth = PrintDepth}, put(no_tty, proplists:get_bool(no_tty, Options)), receive {start, _Reference} -> @@ -89,8 +92,8 @@ terminate({ok, Data}, St) -> end, sync_end(error) end; -terminate({error, Reason}, _St) -> - fwrite("Internal error: ~tP.\n", [Reason, 25]), +terminate({error, Reason}, #state{print_depth = Depth}) -> + fwrite("Internal error: ~tP.\n", [Reason, Depth]), sync_end(error). sync_end(Result) -> @@ -147,7 +150,7 @@ handle_end(test, Data, St) -> if St#state.verbose -> ok; true -> print_test_begin(St#state.indent, Data) end, - print_test_error(Status, Data), + print_test_error(Status, Data, St), St end. @@ -161,10 +164,10 @@ handle_cancel(group, Data, St) -> Reason -> Desc = proplists:get_value(desc, Data), if Desc =/= "", Desc =/= undefined, St#state.verbose -> - print_group_cancel(I, Reason); + print_group_cancel(I, Reason, St); true -> print_group_start(I, Desc), - print_group_cancel(I, Reason) + print_group_cancel(I, Reason, St) end, St#state{indent = I - 1} end; @@ -173,7 +176,7 @@ handle_cancel(test, Data, St) -> if St#state.verbose -> ok; true -> print_test_begin(St#state.indent, Data) end, - print_test_cancel(proplists:get_value(reason, Data)), + print_test_cancel(proplists:get_value(reason, Data), St), St. @@ -218,9 +221,9 @@ print_test_end(Data) -> end, fwrite("~tsok\n", [T]). -print_test_error({error, Exception}, Data) -> +print_test_error({error, Exception}, Data, #state{print_depth = Depth}) -> Output = proplists:get_value(output, Data), - fwrite("*failed*\n~ts", [eunit_lib:format_exception(Exception)]), + fwrite("*failed*\n~ts", [eunit_lib:format_exception(Exception, Depth)]), case Output of <<>> -> fwrite("\n\n"); @@ -229,7 +232,7 @@ print_test_error({error, Exception}, Data) -> _ -> fwrite(" output:<<\"~ts\">>\n\n", [Output]) end; -print_test_error({skipped, Reason}, _) -> +print_test_error({skipped, Reason}, _, St) -> fwrite("*did not run*\n::~ts\n", [format_skipped(Reason)]). format_skipped({module_not_found, M}) -> @@ -237,29 +240,29 @@ format_skipped({module_not_found, M}) -> format_skipped({no_such_function, {M,F,A}}) -> io_lib:fwrite("no such function: ~w:~tw/~w", [M,F,A]). -print_test_cancel(Reason) -> - fwrite(format_cancel(Reason)). +print_test_cancel(Reason, #state{print_depth = Depth}) -> + fwrite(format_cancel(Reason, Depth)). -print_group_cancel(_I, {blame, _}) -> +print_group_cancel(_I, {blame, _}, _) -> ok; -print_group_cancel(I, Reason) -> +print_group_cancel(I, Reason, #state{print_depth = Depth}) -> indent(I), - fwrite(format_cancel(Reason)). + fwrite(format_cancel(Reason, Depth)). -format_cancel(undefined) -> +format_cancel(undefined, _) -> "*skipped*\n"; -format_cancel(timeout) -> +format_cancel(timeout, _) -> "*timed out*\n"; -format_cancel({startup, Reason}) -> +format_cancel({startup, Reason}, Depth) -> io_lib:fwrite("*could not start test process*\n::~tP\n\n", - [Reason, 15]); -format_cancel({blame, _SubId}) -> + [Reason, Depth]); +format_cancel({blame, _SubId}, _) -> "*cancelled because of subtask*\n"; -format_cancel({exit, Reason}) -> +format_cancel({exit, Reason}, Depth) -> io_lib:fwrite("*unexpected termination of test process*\n::~tP\n\n", - [Reason, 15]); -format_cancel({abort, Reason}) -> - eunit_lib:format_error(Reason). + [Reason, Depth]); +format_cancel({abort, Reason}, Depth) -> + eunit_lib:format_error(Reason, Depth). fwrite(String) -> fwrite(String, []). |