gh-68968: Correcting message display issue with assertEqual (#103937)

This commit is contained in:
Michael Blahay 2023-05-04 18:37:17 -04:00 committed by GitHub
parent 7d35c3121a
commit 46361bb843
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 87 additions and 11 deletions

View file

@ -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),

View file

@ -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():

View file

@ -1217,19 +1217,34 @@ def assertCountEqual(self, first, second, msg=None):
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')
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 second and second[-1] != '\n':
second_presplit += '\n'
elif first and first[-1] != '\n':
first_presplit += '\n'
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)

View file

@ -0,0 +1 @@
Fixed garbled output of :meth:`~unittest.TestCase.assertEqual` when an input lacks final newline.