Skip to content

Commit 7e9fd56

Browse files
committed
Support the 'format' option for 'traceback'
1 parent 87c36f7 commit 7e9fd56

3 files changed

Lines changed: 38 additions & 15 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ Possible [options](https://hexdocs.pm/erlang_doctor/0.3.1/tr.html#t:tb_options/0
350350
- `order` - `top_down` (default), `bottom_up` - call order in each tracaback; only for the `list` format.
351351
- `limit` - positive integer or `infinity` (default) - limits the number of matched traces. The actual number of tracebacks returned can be smaller unless `output => all`
352352

353-
There are also functions `tr:traceback/1` and `tr:traceback/2`. They set `limit` to one and return only one trace if it exists. The options for `tr:traceback/2` are the same as for `tr:traceback/2` except `limit` and `format` (which are not supported). Additionally, it is possible to pass a [`tr`](https://hexdocs.pm/erlang_doctor/0.3.1/tr.html#t:tr/0) record (or an index) as the first argument to `tr:traceback/1` or `tr:traceback/2` to obtain the traceback for the provided trace event.
353+
There are also functions `tr:traceback/1` and `tr:traceback/2`. They set `limit` to one and return only one trace if it exists. The options for `tr:traceback/2` are the same as for `tr:traceback/2` except `limit`. Additionally, it is possible to pass a [`tr`](https://hexdocs.pm/erlang_doctor/0.3.1/tr.html#t:tr/0) record (or an index) as the first argument to `tr:traceback/1` or `tr:traceback/2` to obtain the traceback for the provided trace event.
354354

355355
### Trace ranges for filtered traces: `ranges`
356356

src/tr.erl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -379,25 +379,25 @@ traceback(Pred) ->
379379
%% @doc Returns traceback of the first matching trace from {@link tr_source()}.
380380
%%
381381
%% Fails if no trace is matched.
382-
%% The options `limit' and `format' do not apply.
383-
-spec traceback(pred(tr()) | index() | tr(), tb_options()) -> [tr()].
382+
%% The `limit' option does not apply.
383+
-spec traceback(pred(tr()) | index() | tr(), tb_options()) -> [tr()] | tr() | tb_tree().
384384
traceback(Index, Options) when is_integer(Index) ->
385385
traceback(fun(#tr{index = I}) -> Index =:= I end, Options);
386386
traceback(T = #tr{}, Options) ->
387387
traceback(fun(Tr) -> Tr =:= T end, Options);
388388
traceback(PredF, Options) when is_function(PredF, 1) ->
389-
[TB] = tracebacks(PredF, Options#{limit => 1, format => list}),
390-
TB.
389+
[Result] = tracebacks(PredF, Options#{limit => 1}),
390+
Result.
391391

392392
%% @doc Returns tracebacks of all matching traces from `tab()'.
393393
%%
394394
%% @see tracebacks/2
395-
-spec tracebacks(pred(tr())) -> [[tr()]] | [tb_tree()].
395+
-spec tracebacks(pred(tr())) -> [[tr()]].
396396
tracebacks(PredF) ->
397397
tracebacks(PredF, #{}).
398398

399399
%% @doc Returns tracebacks of all matching traces from {@link tr_source()}.
400-
-spec tracebacks(pred(tr()), tb_options()) -> [[tr()]] | [tb_tree()].
400+
-spec tracebacks(pred(tr()), tb_options()) -> [[tr()]] | [tr()] | [tb_tree()].
401401
tracebacks(PredF, Options) when is_map(Options) ->
402402
Tab = maps:get(tab, Options, tab()),
403403
Output = maps:get(output, Options, shortest),

test/tr_SUITE.erl

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,11 @@ groups() ->
5555
tb_longest,
5656
tb_all,
5757
tb_all_limit,
58+
tb_trees,
5859
tb_tree,
5960
tb_tree_longest,
60-
tb_roots]},
61+
tb_roots,
62+
tb_root]},
6163
{util, [contains,
6264
match,
6365
do,
@@ -454,17 +456,28 @@ tb_all_limit(_Config) ->
454456
[#tr{data = [0]}, #tr{data = [2]}, #tr{data = [3]}, #tr{data = [4]}],
455457
[#tr{data = [2]}, #tr{data = [3]}, #tr{data = [4]}]], TBs).
456458

457-
tb_tree(_Config) ->
459+
tb_trees(_Config) ->
458460
tr:trace([{?MODULE, fib, 1}]),
459461
?MODULE:fib(4),
460462
wait_for_traces(18),
461463
tr:stop_tracing(),
462464
TBs = tr:tracebacks(fun(#tr{event = return, data = N}) when N < 2 -> true end,
463-
#{format => tree}),
465+
#{format => tree}),
464466
ct:pal("~p~n", [TBs]),
465467
?assertMatch([{#tr{data = [4]}, [{#tr{data = [3]}, [#tr{data = [2]},
466468
#tr{data = [1]}]},
467-
#tr{data = [2]}]}], TBs).
469+
#tr{data = [2]}]}], TBs).
470+
471+
tb_tree(_Config) ->
472+
tr:trace([{?MODULE, fib, 1}]),
473+
?MODULE:fib(4),
474+
wait_for_traces(18),
475+
tr:stop_tracing(),
476+
TB = tr:traceback(fun(#tr{event = return, data = N}) when N < 2 -> true end,
477+
#{format => tree}),
478+
ct:pal("~p~n", [TB]),
479+
?assertMatch({#tr{data = [4]}, [{#tr{data = [3]}, [{#tr{data = [2]},
480+
[#tr{data = [1]}]}]}]}, TB).
468481

469482
tb_tree_longest(_Config) ->
470483
tr:trace([{?MODULE, fib, 1}]),
@@ -488,17 +501,27 @@ tb_roots(_Config) ->
488501
wait_for_traces(18),
489502
tr:stop_tracing(),
490503

504+
Pred = fun(#tr{event = return, data = N}) when N < 2 -> true end,
505+
491506
%% Option 1: call root/1 or roots/1 on a tree
492-
TBs = tr:tracebacks(fun(#tr{event = return, data = N}) when N < 2 -> true end,
493-
#{format => tree}),
507+
TBs = tr:tracebacks(Pred, #{format => tree}),
494508
Roots = tr:roots(TBs),
495509
ct:pal("Roots: ~p~n", [Roots]),
496510
?assertMatch([#tr{data = [4]}], Roots),
497511
?assertEqual(hd(Roots), tr:root(hd(TBs))),
498512

499513
%% Option 2: directly use the root format
500-
?assertEqual(Roots, tr:tracebacks(fun(#tr{event = return, data = N}) when N < 2 -> true end,
501-
#{format => root})).
514+
?assertEqual(Roots, tr:tracebacks(Pred, #{format => root})).
515+
tb_root(_Config) ->
516+
tr:trace([{?MODULE, fib, 1}]),
517+
?MODULE:fib(4),
518+
wait_for_traces(18),
519+
tr:stop_tracing(),
520+
521+
Pred = fun(#tr{event = return, data = N}) when N < 2 -> true end,
522+
523+
Root = tr:traceback(Pred, #{format => root}),
524+
?assertMatch(#tr{data = [4]}, Root).
502525

503526
simple_total(_Config) ->
504527
tr:trace([{?MODULE, factorial, 1}]),

0 commit comments

Comments
 (0)