aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKlas Johansson <[email protected]>2012-02-12 18:24:53 +0100
committerFredrik Gustafsson <[email protected]>2012-08-10 10:57:21 +0200
commitfea574bac8464f07a72862e1a4f92e9b62e464e4 (patch)
treeca94a13cafe1f338581e07f784ecb10d2c8db0ca
parent6f5900f9b136ae9aa6b89877727f6dac9e782ea6 (diff)
downloadotp-fea574bac8464f07a72862e1a4f92e9b62e464e4.tar.gz
otp-fea574bac8464f07a72862e1a4f92e9b62e464e4.tar.bz2
otp-fea574bac8464f07a72862e1a4f92e9b62e464e4.zip
Make EUnit print stacktraces with location information
The format of stacktraces was changed in Erlang/OTP R15, adding location information. This had the effect that EUnit did not recognize stack traces as such and only printed the exception term. This patch makes Eunit recognize and print the new stacktrace format as well as the old.
-rw-r--r--lib/eunit/src/eunit_lib.erl43
1 files changed, 38 insertions, 5 deletions
diff --git a/lib/eunit/src/eunit_lib.erl b/lib/eunit/src/eunit_lib.erl
index 1c41e229c5..c700989bae 100644
--- a/lib/eunit/src/eunit_lib.erl
+++ b/lib/eunit/src/eunit_lib.erl
@@ -86,6 +86,12 @@ analyze_exit_term(Term) ->
is_stacktrace([]) ->
true;
+is_stacktrace([{M,F,A,L}|Fs])
+ when is_atom(M), is_atom(F), is_integer(A), is_list(L) ->
+ is_stacktrace(Fs);
+is_stacktrace([{M,F,As,L}|Fs])
+ when is_atom(M), is_atom(F), is_list(As), is_list(L) ->
+ is_stacktrace(Fs);
is_stacktrace([{M,F,A}|Fs]) when is_atom(M), is_atom(F), is_integer(A) ->
is_stacktrace(Fs);
is_stacktrace([{M,F,As}|Fs]) when is_atom(M), is_atom(F), is_list(As) ->
@@ -96,10 +102,11 @@ is_stacktrace(_) ->
format_stacktrace(Trace) ->
format_stacktrace(Trace, "in function", "in call from").
-format_stacktrace([{M,F,A}|Fs], Pre, Pre1) when is_integer(A) ->
- [io_lib:fwrite(" ~s ~w:~w/~w\n", [Pre, M, F, A])
+format_stacktrace([{M,F,A,L}|Fs], Pre, Pre1) when is_integer(A) ->
+ [io_lib:fwrite(" ~s ~w:~w/~w~s\n",
+ [Pre, M, F, A, format_stacktrace_location(L)])
| format_stacktrace(Fs, Pre1, Pre1)];
-format_stacktrace([{M,F,As}|Fs], Pre, Pre1) when is_list(As) ->
+format_stacktrace([{M,F,As,L}|Fs], Pre, Pre1) when is_list(As) ->
A = length(As),
C = case is_op(M,F,A) of
true when A =:= 1 ->
@@ -112,12 +119,23 @@ format_stacktrace([{M,F,As}|Fs], Pre, Pre1) when is_list(As) ->
false ->
io_lib:fwrite("~w(~s)", [F,format_arglist(As)])
end,
- [io_lib:fwrite(" ~s ~w:~w/~w\n called as ~s\n",
- [Pre,M,F,A,C])
+ [io_lib:fwrite(" ~s ~w:~w/~w~s\n called as ~s\n",
+ [Pre,M,F,A,format_stacktrace_location(L),C])
| format_stacktrace(Fs,Pre1,Pre1)];
+format_stacktrace([{M,F,As}|Fs], Pre, Pre1) ->
+ format_stacktrace([{M,F,As,[]}|Fs], Pre, Pre1);
format_stacktrace([],_Pre,_Pre1) ->
"".
+format_stacktrace_location(Location) ->
+ File = proplists:get_value(file, Location),
+ Line = proplists:get_value(line, Location),
+ if File =/= undefined, Line =/= undefined ->
+ io_lib:format(" (~s, line ~w)", [File, Line]);
+ true ->
+ ""
+ end.
+
format_arg(A) ->
io_lib:format("~P",[A,15]).
@@ -166,6 +184,21 @@ error_msg(Title, Fmt, Args) ->
Msg = io_lib:format("::"++Fmt, Args), % gets indentation right
io_lib:fwrite("*** ~s ***\n~s\n\n", [Title, Msg]).
+-ifdef(TEST).
+format_exception_test_() ->
+ [?_assertMatch(
+ "error:dummy"++_,
+ lists:flatten(
+ format_exception(try erlang:error(dummy)
+ catch C:R -> {C, R, erlang:get_stacktrace()}
+ end))),
+ ?_assertMatch(
+ "error:dummy"++_,
+ lists:flatten(
+ format_exception(try erlang:error(dummy, [a])
+ catch C:R -> {C, R, erlang:get_stacktrace()}
+ end)))].
+-endif.
%% ---------------------------------------------------------------------
%% Deep list iterator; accepts improper lists/sublists, and also accepts