Skip to content
This repository was archived by the owner on Nov 30, 2024. It is now read-only.

Commit 13959f0

Browse files
committed
Simplify handling of linefeed and indentation in ExceptionPresenter
... by using Array for lines until final rendering.
1 parent 28eed7d commit 13959f0

File tree

2 files changed

+48
-32
lines changed

2 files changed

+48
-32
lines changed

lib/rspec/core/formatters/exception_presenter.rb

Lines changed: 44 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,21 @@ def colorized_formatted_backtrace(colorizer=::RSpec::Core::Formatters::ConsoleCo
7171
end
7272

7373
def fully_formatted(failure_number, colorizer=::RSpec::Core::Formatters::ConsoleCodes)
74-
alignment_basis = "#{' ' * @indentation}#{failure_number}) "
75-
indentation = ' ' * alignment_basis.length
74+
lines = fully_formatted_lines(failure_number, colorizer)
75+
lines.join("\n") << "\n"
76+
end
7677

77-
"\n#{alignment_basis}#{description_and_detail(colorizer, indentation)}" \
78-
"\n#{formatted_message_and_backtrace(colorizer, indentation)}" \
79-
"#{extra_detail_formatter.call(failure_number, colorizer, indentation)}"
78+
def fully_formatted_lines(failure_number, colorizer)
79+
lines = [
80+
description,
81+
detail_formatter.call(example, colorizer),
82+
formatted_message_and_backtrace(colorizer),
83+
extra_detail_formatter.call(failure_number, colorizer),
84+
].compact.flatten
85+
86+
lines = indent_lines(lines, failure_number)
87+
lines.unshift("")
88+
lines
8089
end
8190

8291
def failure_slash_error_line
@@ -93,12 +102,6 @@ def final_exception(exception)
93102
end
94103
end
95104

96-
def description_and_detail(colorizer, indentation)
97-
detail = detail_formatter.call(example, colorizer, indentation)
98-
return (description || detail) unless description && detail
99-
"#{description}\n#{indentation}#{detail}"
100-
end
101-
102105
if String.method_defined?(:encoding)
103106
def encoding_of(string)
104107
string.encoding
@@ -118,6 +121,21 @@ def encoded_string(string)
118121
# :nocov:
119122
end
120123

124+
def indent_lines(lines, failure_number)
125+
alignment_basis = "#{' ' * @indentation}#{failure_number}) "
126+
indentation = ' ' * alignment_basis.length
127+
128+
lines.each_with_index.map do |line, index|
129+
if index == 0
130+
"#{alignment_basis}#{line}"
131+
elsif line.empty?
132+
line
133+
else
134+
"#{indentation}#{line}"
135+
end
136+
end
137+
end
138+
121139
def exception_class_name(exception=@exception)
122140
name = exception.class.name.to_s
123141
name = "(anonymous error class)" if name == ''
@@ -130,7 +148,7 @@ def failure_lines
130148
lines << failure_slash_error_line unless (description == failure_slash_error_line)
131149
lines << "#{exception_class_name}:" unless exception_class_name =~ /RSpec/
132150
encoded_string(exception.message.to_s).split("\n").each do |line|
133-
lines << " #{line}"
151+
lines << (line.empty? ? line : " #{line}")
134152
end
135153
unless @extra_failure_lines.empty?
136154
lines << ''
@@ -180,16 +198,12 @@ def find_failed_line
180198
end || exception_backtrace.first
181199
end
182200

183-
def formatted_message_and_backtrace(colorizer, indentation)
201+
def formatted_message_and_backtrace(colorizer)
184202
lines = colorized_message_lines(colorizer) + colorized_formatted_backtrace(colorizer)
185-
186-
formatted = ""
187-
188-
lines.each do |line|
189-
formatted << RSpec::Support::EncodedString.new("#{indentation}#{line}\n", encoding_of(formatted))
203+
encoding = encoding_of("")
204+
lines.map do |line|
205+
RSpec::Support::EncodedString.new(line, encoding)
190206
end
191-
192-
formatted
193207
end
194208

195209
def exception_backtrace
@@ -262,7 +276,7 @@ def multiple_exceptions_error?(exception)
262276
end
263277

264278
def multiple_exception_summarizer(exception, prior_detail_formatter, color)
265-
lambda do |example, colorizer, indentation|
279+
lambda do |example, colorizer|
266280
summary = if exception.aggregation_metadata[:hide_backtrace]
267281
# Since the backtrace is hidden, the subfailures will come
268282
# immediately after this, and using `:` will read well.
@@ -275,27 +289,30 @@ def multiple_exception_summarizer(exception, prior_detail_formatter, color)
275289

276290
summary = colorizer.wrap(summary, color || RSpec.configuration.failure_color)
277291
return summary unless prior_detail_formatter
278-
"#{prior_detail_formatter.call(example, colorizer, indentation)}\n#{indentation}#{summary}"
292+
[
293+
prior_detail_formatter.call(example, colorizer),
294+
summary
295+
]
279296
end
280297
end
281298

282299
def sub_failure_list_formatter(exception, message_color)
283300
common_backtrace_truncater = CommonBacktraceTruncater.new(exception)
284301

285-
lambda do |failure_number, colorizer, indentation|
286-
exception.all_exceptions.each_with_index.map do |failure, index|
302+
lambda do |failure_number, colorizer|
303+
FlatMap.flat_map(exception.all_exceptions.each_with_index) do |failure, index|
287304
options = with_multiple_error_options_as_needed(
288305
failure,
289306
:description_formatter => :failure_slash_error_line.to_proc,
290-
:indentation => indentation.length,
307+
:indentation => 0,
291308
:message_color => message_color || RSpec.configuration.failure_color,
292309
:skip_shared_group_trace => true
293310
)
294311

295312
failure = common_backtrace_truncater.with_truncated_backtrace(failure)
296313
presenter = ExceptionPresenter.new(failure, @example, options)
297-
presenter.fully_formatted("#{failure_number}.#{index + 1}", colorizer)
298-
end.join
314+
presenter.fully_formatted_lines("#{failure_number}.#{index + 1}", colorizer)
315+
end
299316
end
300317
end
301318

spec/rspec/core/formatters/exception_presenter_spec.rb

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ module RSpec::Core
107107

108108
it 'allows a caller to specify extra details that are added to the bottom' do
109109
the_presenter = Formatters::ExceptionPresenter.new(
110-
exception, example, :extra_detail_formatter => lambda do |failure_number, colorizer, indentation|
111-
"#{indentation}extra detail for failure: #{failure_number}\n"
110+
exception, example, :extra_detail_formatter => lambda do |failure_number, colorizer|
111+
"extra detail for failure: #{failure_number}"
112112
end
113113
)
114114

@@ -156,16 +156,15 @@ module RSpec::Core
156156
failure_line = 'http://www.example.com/job_details/123'
157157
extra_example.metadata[:extra_failure_lines] = [failure_line]
158158
the_presenter = Formatters::ExceptionPresenter.new(exception, extra_example, :indentation => 4)
159-
indent = ' ' * 7 # work around: RSpec behaves like library wide checks has no malformed whitespace
160159
expect(the_presenter.fully_formatted(1)).to eq(<<-EOS.gsub(/^ +\|/, ''))
161160
|
162161
| 1) Example
163162
| Failure/Error: # The failure happened here!#{ encoding_check }
164163
| Boom
165164
| Bam
166-
|#{indent}
165+
|
167166
| #{failure_line}
168-
|#{indent}
167+
|
169168
| # ./spec/rspec/core/formatters/exception_presenter_spec.rb:#{line_num}
170169
EOS
171170
end

0 commit comments

Comments
 (0)