Skip to content

Commit edfb650

Browse files
author
José Valim
committed
Properly format and indent test output
1 parent c012456 commit edfb650

File tree

7 files changed

+137
-94
lines changed

7 files changed

+137
-94
lines changed

lib/elixir/lib/kernel.ex

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1841,8 +1841,7 @@ defmodule Kernel do
18411841
18421842
* `:pretty` - if set to true enables pretty printing, defaults to false;
18431843
1844-
* `:width` - the width available for inspect to layout the data structure
1845-
representation. Defaults to the smaller of 80 or the terminal width;
1844+
* `:width` - defaults to the 80 characters;
18461845
18471846
## Examples
18481847

lib/ex_unit/lib/ex_unit/assertions.ex

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ defexception ExUnit.AssertionError,
22
left: :ex_unit_no_meaningful_value,
33
right: :ex_unit_no_meaningful_value,
44
message: :ex_unit_no_meaningful_value,
5-
expr: "missing failing expression" do
5+
expr: :ex_unit_no_meaningful_value do
66

77
@doc """
88
Indicates no meaningful value for a field.
@@ -62,7 +62,7 @@ defmodule ExUnit.Assertions do
6262
rhs: 15
6363
"""
6464
defmacro assert({ :=, _, [left, right] } = assertion) do
65-
code = Macro.to_string(assertion)
65+
code = Macro.escape(assertion)
6666
{ :case, meta, args } =
6767
quote do
6868
case right do
@@ -90,8 +90,8 @@ defmodule ExUnit.Assertions do
9090

9191
unless value do
9292
raise ExUnit.AssertionError,
93-
expr: unquote(Macro.to_string(assertion)),
94-
message: "#{inspect value} is not truthy"
93+
expr: unquote(Macro.escape(assertion)),
94+
message: "Expected truthy, got #{inspect value}"
9595
end
9696

9797
value
@@ -112,7 +112,7 @@ defmodule ExUnit.Assertions do
112112
113113
"""
114114
defmacro refute({ :=, _, [left, right] } = assertion) do
115-
code = Macro.to_string(assertion)
115+
code = Macro.escape(assertion)
116116
{ :case, meta, args } =
117117
quote do
118118
case right do
@@ -140,8 +140,8 @@ defmodule ExUnit.Assertions do
140140

141141
if value do
142142
raise ExUnit.AssertionError,
143-
expr: unquote(Macro.to_string(assertion)),
144-
message: "#{inspect value} should be false or nil"
143+
expr: unquote(Macro.escape(assertion)),
144+
message: "Expected false or nil, got #{inspect value}"
145145
end
146146

147147
value
@@ -157,7 +157,7 @@ defmodule ExUnit.Assertions do
157157
@operator [:==, :<, :>, :<=, :>=, :===, :=~, :!==, :!=, :in]
158158

159159
defp translate_assertion({ operator, _, [left, right] } = expr) when operator in @operator do
160-
expr = Macro.to_string(expr)
160+
expr = Macro.escape(expr)
161161
quote do
162162
left = unquote(left)
163163
right = unquote(right)
@@ -170,7 +170,7 @@ defmodule ExUnit.Assertions do
170170
end
171171

172172
defp translate_assertion({ :!, [], [{ operator, _, [left, right] } = expr] }) when operator in @operator do
173-
expr = Macro.to_string(expr)
173+
expr = Macro.escape(expr)
174174
quote do
175175
left = unquote(left)
176176
right = unquote(right)
@@ -197,7 +197,7 @@ defmodule ExUnit.Assertions do
197197
198198
"""
199199
def assert(value, message) when is_binary(message) do
200-
assert(value, message: message, expr: ExUnit.AssertionError.no_value)
200+
assert(value, message: message)
201201
end
202202

203203
def assert(value, opts) when is_list(opts) do
@@ -219,8 +219,7 @@ defmodule ExUnit.Assertions do
219219
220220
"""
221221
def assert(value, left, right, message) when is_binary(message) do
222-
assert(value, left: left, right: right,
223-
message: message, expr: ExUnit.AssertionError.no_value)
222+
assert(value, left: left, right: right, message: message)
224223
end
225224

226225
@doc """
@@ -307,7 +306,7 @@ defmodule ExUnit.Assertions do
307306
end
308307

309308
msg = "Wrong message for #{inspect exception}. Expected #{inspect message}, got #{inspect error.message}"
310-
assert is_match, message: msg, expr: ExUnit.AssertionError.no_value
309+
assert is_match, message: msg
311310

312311
error
313312
end
@@ -520,6 +519,6 @@ defmodule ExUnit.Assertions do
520519
@spec flunk :: no_return
521520
@spec flunk(String.t) :: no_return
522521
def flunk(message \\ "Flunked!") do
523-
assert false, message: message, expr: ExUnit.AssertionError.no_value
522+
assert false, message: message
524523
end
525524
end

lib/ex_unit/lib/ex_unit/cli_formatter.ex

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,18 @@ defmodule ExUnit.CLIFormatter do
33

44
use GenEvent.Behaviour
55

6-
import ExUnit.Formatter, only: [format_time: 2, format_filters: 2, format_test_failure: 5, format_test_case_failure: 4]
6+
import ExUnit.Formatter, only: [format_time: 2, format_filters: 2, format_test_failure: 6,
7+
format_test_case_failure: 5]
78

89
defrecord Config, tests_counter: 0, invalids_counter: 0, failures_counter: 0,
9-
skips_counter: 0, trace: false, seed: nil, color: true
10+
skips_counter: 0, trace: false, seed: nil, color: true,
11+
width: :infinity
1012

1113
## Callbacks
1214

1315
def init(opts) do
1416
print_filters(Keyword.take(opts, [:include, :exclude]))
15-
{ :ok, Config.new(opts) }
17+
{ :ok, opts |> Config.new |> add_terminal_width }
1618
end
1719

1820
def handle_event({ :suite_finished, run_us, load_us }, config = Config[]) do
@@ -136,12 +138,14 @@ defmodule ExUnit.CLIFormatter do
136138
end
137139

138140
defp print_test_failure(ExUnit.Test[name: name, case: mod, state: { :failed, tuple }], config) do
139-
formatted = format_test_failure(mod, name, tuple, config.failures_counter + 1, &formatter(&1, &2, config))
141+
formatted = format_test_failure(mod, name, tuple, config.failures_counter + 1,
142+
config.width, &formatter(&1, &2, config))
140143
print_any_failure formatted, config
141144
end
142145

143146
defp print_test_case_failure(ExUnit.TestCase[name: name, state: { :failed, tuple }], config) do
144-
formatted = format_test_case_failure(name, tuple, config.failures_counter + 1, &formatter(&1, &2, config))
147+
formatted = format_test_case_failure(name, tuple, config.failures_counter + 1,
148+
config.width, &formatter(&1, &2, config))
145149
print_any_failure formatted, config
146150
end
147151

@@ -177,4 +181,13 @@ defmodule ExUnit.CLIFormatter do
177181
defp formatter(:error_info, msg, config), do: colorize("red", msg, config)
178182
defp formatter(:location_info, msg, config), do: colorize("cyan", msg, config)
179183
defp formatter(_, msg, _config), do: msg
184+
185+
defp add_terminal_width(config) do
186+
case :io.columns do
187+
{ :ok, width } ->
188+
config.width(max(40, width))
189+
_ ->
190+
config
191+
end
192+
end
180193
end

lib/ex_unit/lib/ex_unit/formatter.ex

Lines changed: 48 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ defmodule ExUnit.Formatter do
3232

3333
import Exception, only: [format_stacktrace_entry: 1]
3434

35-
# Width of error counter field
36-
@prefix_width 5
35+
@label_padding " "
36+
@counter_padding " "
37+
@inspect_padding @counter_padding <> @label_padding
3738

3839
@doc """
3940
Formats time taken running the test suite.
@@ -99,40 +100,42 @@ defmodule ExUnit.Formatter do
99100
@doc """
100101
Receives a test and formats its failure.
101102
"""
102-
def format_test_failure(test_case, test, { kind, reason, stack }, counter, terminal) do
103-
test_info(with_counter(counter, "#{test} (#{inspect test_case})"), terminal)
104-
<> format_kind_reason(kind, reason, terminal)
105-
<> format_stacktrace(stack, test_case, test, terminal)
103+
def format_test_failure(test_case, test, { kind, reason, stack }, counter, width, formatter) do
104+
test_info(with_counter(counter, "#{test} (#{inspect test_case})"), formatter)
105+
<> format_kind_reason(kind, reason, width, formatter)
106+
<> format_stacktrace(stack, test_case, test, formatter)
106107
end
107108

108109
@doc """
109110
Receives a test case and formats its failure.
110111
"""
111-
def format_test_case_failure(test_case, { kind, reason, stacktrace }, counter, terminal) do
112-
test_case_info(with_counter(counter, "#{inspect test_case}: "), terminal)
113-
<> format_kind_reason(kind, reason, terminal)
114-
<> format_stacktrace(stacktrace, test_case, nil, terminal)
112+
def format_test_case_failure(test_case, { kind, reason, stacktrace }, counter, width, formatter) do
113+
test_case_info(with_counter(counter, "#{inspect test_case}: "), formatter)
114+
<> format_kind_reason(kind, reason, width, formatter)
115+
<> format_stacktrace(stacktrace, test_case, nil, formatter)
115116
end
116117

117-
defp format_kind_reason(:error, ExUnit.AssertionError[] = record, terminal) do
118+
defp format_kind_reason(:error, ExUnit.AssertionError[] = record, width, formatter) do
119+
width = if width == :infinity, do: width, else: width - byte_size(@inspect_padding)
120+
118121
fields =
119-
[note: if_value(record.message, &format_message(&1, terminal)),
120-
code: record.expr,
121-
lhs: if_value(record.left, &inspect/1),
122-
rhs: if_value(record.right, &inspect/1)]
122+
[note: if_value(record.message, &format_message(&1, formatter)),
123+
code: if_value(record.expr, &macro_multiline(&1, width)),
124+
lhs: if_value(record.left, &inspect_multiline(&1, width)),
125+
rhs: if_value(record.right, &inspect_multiline(&1, width))]
123126

124127
fields
125128
|> filter_interesting_fields
126-
|> format_each_reason(terminal)
127-
|> make_into_lines
129+
|> format_each_reason(formatter)
130+
|> make_into_lines(@counter_padding)
128131
end
129132

130-
defp format_kind_reason(:error, exception, terminal) do
131-
error_info "** (#{inspect exception.__record__(:name)}) #{exception.message}", terminal
133+
defp format_kind_reason(:error, exception, _width, formatter) do
134+
error_info "** (#{inspect exception.__record__(:name)}) #{exception.message}", formatter
132135
end
133136

134-
defp format_kind_reason(kind, reason, terminal) do
135-
error_info "** (#{kind}) #{inspect(reason)}", terminal
137+
defp format_kind_reason(kind, reason, _width, formatter) do
138+
error_info "** (#{kind}) #{inspect(reason)}", formatter
136139
end
137140

138141
defp filter_interesting_fields(fields) do
@@ -141,15 +144,9 @@ defmodule ExUnit.Formatter do
141144
end)
142145
end
143146

144-
defp format_each_reason(reasons, terminal) do
145-
label_length =
146-
reasons
147-
|> Enum.map(fn {label,_} -> String.length(atom_to_binary(label)) end)
148-
|> Enum.max
149-
|> Kernel.+(2)
150-
147+
defp format_each_reason(reasons, formatter) do
151148
Enum.map(reasons, fn {label, value} ->
152-
format_label(label, label_length, terminal) <> value
149+
format_label(label, formatter) <> value
153150
end)
154151
end
155152

@@ -161,20 +158,30 @@ defmodule ExUnit.Formatter do
161158
end
162159
end
163160

164-
defp format_label(:note, _length, _terminal) do
161+
defp format_label(:note, _formatter) do
165162
""
166163
end
167164

168-
defp format_label(label, length, terminal) do
169-
terminal.(:error_info, String.ljust("#{label}:", length))
165+
defp format_label(label, formatter) do
166+
formatter.(:error_info, String.ljust("#{label}:", byte_size(@label_padding)))
167+
end
168+
169+
defp format_message(value, formatter) do
170+
formatter.(:error_info, value)
171+
end
172+
173+
defp macro_multiline(expr, _width) do
174+
expr |> Macro.to_string
170175
end
171176

172-
defp format_message(value, terminal) do
173-
terminal.(:error_info, value)
177+
defp inspect_multiline(expr, width) do
178+
expr
179+
|> inspect(pretty: true, width: width)
180+
|> String.replace("\n", "\n" <> @inspect_padding)
174181
end
175182

176-
defp make_into_lines(reasons) do
177-
" " <> Enum.join(reasons, "\n ") <> "\n"
183+
defp make_into_lines(reasons, padding) do
184+
padding <> Enum.join(reasons, "\n" <> padding) <> "\n"
178185
end
179186

180187
defp format_stacktrace([{ test_case, test, _, location }|_], test_case, test, color) do
@@ -195,17 +202,17 @@ defmodule ExUnit.Formatter do
195202
defp with_counter(counter, msg) do "#{counter}) #{msg}" end
196203

197204
defp test_case_info(msg, nil), do: msg <> "failure on setup_all/teardown_all callback, tests invalidated\n"
198-
defp test_case_info(msg, terminal), do: test_case_info(terminal.(:test_case_info, msg), nil)
205+
defp test_case_info(msg, formatter), do: test_case_info(formatter.(:test_case_info, msg), nil)
199206

200207
defp test_info(msg, nil), do: msg <> "\n"
201-
defp test_info(msg, terminal), do: test_info(terminal.(:test_info, msg), nil)
208+
defp test_info(msg, formatter), do: test_info(formatter.(:test_info, msg), nil)
202209

203210
defp error_info(msg, nil), do: " " <> msg <> "\n"
204-
defp error_info(msg, terminal), do: error_info(terminal.(:error_info, msg), nil)
211+
defp error_info(msg, formatter), do: error_info(formatter.(:error_info, msg), nil)
205212

206213
defp location_info(msg, nil), do: " " <> msg <> "\n"
207-
defp location_info(msg, terminal), do: location_info(terminal.(:location_info, msg), nil)
214+
defp location_info(msg, formatter), do: location_info(formatter.(:location_info, msg), nil)
208215

209216
defp stacktrace_info(msg, nil), do: " " <> msg <> "\n"
210-
defp stacktrace_info(msg, terminal), do: stacktrace_info(terminal.(:stacktrace_info, msg), nil)
217+
defp stacktrace_info(msg, formatter), do: stacktrace_info(formatter.(:stacktrace_info, msg), nil)
211218
end

0 commit comments

Comments
 (0)