Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Correcting message display issue causing output of assertMultiLineEqu…
…al to be garbled.
  • Loading branch information
mblahay committed May 4, 2023
commit fb274f11e22534164e55415db712ceeff1d44116
6 changes: 3 additions & 3 deletions Lib/test/test_unittest/test_assertions.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,9 +273,9 @@ def testAssertDictEqual(self):

def testAssertMultiLineEqual(self):
self.assertMessages('assertMultiLineEqual', ("", "foo"),
[r"\+ foo$", "^oops$",
r"\+ foo$",
r"\+ foo : oops$"])
[r"\+ foo\n$", "^oops$",
r"\+ foo\n$",
r"\+ foo\n : oops$"])

def testAssertLess(self):
self.assertMessages('assertLess', (2, 1),
Expand Down
60 changes: 60 additions & 0 deletions Lib/test/test_unittest/test_case.py
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,66 @@ def testAssertEqualSingleLine(self):
error = str(e).split('\n', 1)[1]
self.assertEqual(sample_text_error, error)

def testAssertEqualwithEmptyString(self):
'''Verify when there is an empty string involved, the diff output
does not treat the empty string as a single empty line. It should
instead be handled as a non-line.
'''
sample_text = ''
revised_sample_text = 'unladen swallows fly quickly'
sample_text_error = '''\
+ unladen swallows fly quickly
'''
try:
self.assertEqual(sample_text, revised_sample_text)
except self.failureException as e:
# need to remove the first line of the error message
error = str(e).split('\n', 1)[1]
self.assertEqual(sample_text_error, error)

def testAssertEqualMultipleLinesMissingNewlineTerminator(self):
'''Verifying format of diff output from assertEqual involving strings
with multiple lines, but missing the terminating newline on both.
'''
sample_text = 'laden swallows\nfly sloely'
revised_sample_text = 'laden swallows\nfly slowly'
sample_text_error = '''\
laden swallows
- fly sloely
? ^
+ fly slowly
? ^
'''
try:
self.assertEqual(sample_text, revised_sample_text)
except self.failureException as e:
# need to remove the first line of the error message
error = str(e).split('\n', 1)[1]
self.assertEqual(sample_text_error, error)

def testAssertEqualMultipleLinesMismatchedNewlinesTerminators(self):
'''Verifying format of diff output from assertEqual involving strings
with multiple lines and mismatched newlines. The output should
include a - on it's own line to indicate the newline difference
between the two strings
'''
sample_text = 'laden swallows\nfly sloely\n'
revised_sample_text = 'laden swallows\nfly slowly'
sample_text_error = '''\
laden swallows
- fly sloely
? ^
+ fly slowly
? ^
-\x20
'''
try:
self.assertEqual(sample_text, revised_sample_text)
except self.failureException as e:
# need to remove the first line of the error message
error = str(e).split('\n', 1)[1]
self.assertEqual(sample_text_error, error)

def testEqualityBytesWarning(self):
if sys.flags.bytes_warning:
def bytes_warning():
Expand Down
36 changes: 27 additions & 9 deletions Lib/unittest/case.py
Original file line number Diff line number Diff line change
Expand Up @@ -1216,20 +1216,38 @@ def assertCountEqual(self, first, second, msg=None):
self.fail(msg)

def assertMultiLineEqual(self, first, second, msg=None):
"""Assert that two multi-line strings are equal."""
self.assertIsInstance(first, str, 'First argument is not a string')
self.assertIsInstance(second, str, 'Second argument is not a string')
"""Assert that two multi-line strings are equal.
If the assertion fails, then provide an error message with a detailed
diff output
Comment thread
mblahay marked this conversation as resolved.
Outdated
"""
self.assertIsInstance(first, str, "First argument is not a string")
self.assertIsInstance(second, str, "Second argument is not a string")

if first != second:
# don't use difflib if the strings are too long
# Don't use difflib if the strings are too long
if (len(first) > self._diffThreshold or
len(second) > self._diffThreshold):
self._baseAssertEqual(first, second, msg)
firstlines = first.splitlines(keepends=True)
secondlines = second.splitlines(keepends=True)
if len(firstlines) == 1 and first.strip('\r\n') == first:
firstlines = [first + '\n']
secondlines = [second + '\n']

# Append \n to both strings if either is missing the \n.
# This allows the final ndiff to show the \n difference. The
# exception here is if the string is empty, in which case no
# \n should be added
first_presplit = first
second_presplit = second
if first != '' and second != '':
if first[-1] != '\n' or second[-1] != '\n':
first_presplit += '\n'
second_presplit += '\n'
elif first == '' and second != '' and second[-1] != '\n':
second_presplit += '\n'
elif second == '' and first != '' and first[-1] != '\n':
first_presplit += '\n'
Comment thread
mblahay marked this conversation as resolved.
Outdated

firstlines = first_presplit.splitlines(keepends=True)
secondlines = second_presplit.splitlines(keepends=True)

# Generate the message and diff, then raise the exception
standardMsg = '%s != %s' % _common_shorten_repr(first, second)
diff = '\n' + ''.join(difflib.ndiff(firstlines, secondlines))
standardMsg = self._truncateMessage(standardMsg, diff)
Expand Down