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

Commit 4cf346c

Browse files
committed
When truncating an object using ObjectFormatter.format that exceeds the max_formatted_output_length remove any partial ANSI color codes.
This fixes an edge case where partial ANSI color codes eg \e[3 is printed to the terminal which corrupts the output. eg calling object.inspect = "#<\e[33mClass\e[0m \e[36mname: \e[0m\"foobars\" \e[36mcount: \e[0m42>" If this was truncated at the 19th char then the result would be: "#<\e[33mClass\e[0m \e[3" This commit will remove the partial ANSI code so the result is now: "#<\e[33mClass\e[0m " This fixes an edge case where
1 parent abd792d commit 4cf346c

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

lib/rspec/support/object_formatter.rb

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ def format(object)
3737
if formatted_object.length < max_formatted_output_length
3838
return formatted_object
3939
else
40-
beginning = formatted_object[0 .. max_formatted_output_length / 2]
41-
ending = formatted_object[-max_formatted_output_length / 2 ..-1]
40+
beginning = cut_string_stripping_partial_color_ansi_codes formatted_object, 0, max_formatted_output_length / 2
41+
ending = cut_string_stripping_partial_color_ansi_codes formatted_object, -max_formatted_output_length / 2, -1
4242
return beginning + ELLIPSIS + ending
4343
end
4444
end
@@ -244,6 +244,18 @@ def inspect
244244
DelegatorInspector,
245245
InspectableObjectInspector
246246
]
247+
248+
private
249+
250+
# Returns the substring defined by the start_index and end_index
251+
# If the string ends with a partial ANSI code code then that will be removed as printing partial ANSI
252+
# codes to the terminal can lead to corruption
253+
def cut_string_stripping_partial_color_ansi_codes(str, start_index, end_index)
254+
cut_str = str[start_index..end_index]
255+
256+
# ANSI color codes are like: \e[33m so anything with \e[ and a number without a 'm' is an incomplete color code
257+
cut_str.sub(/\e\[\d+$/, '')
258+
end
247259
end
248260
end
249261
end

spec/rspec/support/object_formatter_spec.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,18 @@ def self.to_s
310310
formatter = ObjectFormatter.new(10)
311311
expect(formatter.format('Testing')).to eq('"Testing"')
312312
end
313+
314+
context 'with ANSI escape codes that fall on the truncate split' do
315+
it 'removes that escape code so terminals do not get corrupted print a partial escape code' do
316+
formatter = ObjectFormatter.new(38)
317+
object = Class.new do
318+
def inspect
319+
"#<\e[33mClass\e[0m \e[36mname: \e[0m\"foobars\" \e[36mcount: \e[0m42>"
320+
end
321+
end.new
322+
expect(formatter.format(object)).to eq("#<\e[33mClass\e[0m ...\e[36mcount: \e[0m42>")
323+
end
324+
end
313325
end
314326

315327
context 'with truncation disabled' do

0 commit comments

Comments
 (0)