]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-68968: Correcting message display issue with assertEqual (#103937)
authorMichael Blahay <mblahay@users.noreply.github.com>
Thu, 4 May 2023 22:37:17 +0000 (18:37 -0400)
committerGitHub <noreply@github.com>
Thu, 4 May 2023 22:37:17 +0000 (16:37 -0600)
Lib/test/test_unittest/test_assertions.py
Lib/test/test_unittest/test_case.py
Lib/unittest/case.py
Misc/NEWS.d/next/Library/2023-04-27-18-46-31.gh-issue-68968.E3tnhy.rst [new file with mode: 0644]

index 6557104b81fc0f8451f1058d3bbdf910f5de9bbc..5c1a28ecda5b49ec459e6c877088fb853e250242 100644 (file)
@@ -273,9 +273,9 @@ class TestLongMessage(unittest.TestCase):
 
     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),
index dd5ff6d553e61deb441e8e3aff63258da0c4cb86..ed5eb5609a5dd10ff26ba42b82f38102c9df561e 100644 (file)
@@ -1149,6 +1149,66 @@ test case
             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():
index 018f22e7ce0c73d75ebb6ca16cc8774108bd0dd1..001b640dc43ad69aa4ea7d304c5a667424d031f8 100644 (file)
@@ -1217,19 +1217,34 @@ class TestCase(object):
 
     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)
diff --git a/Misc/NEWS.d/next/Library/2023-04-27-18-46-31.gh-issue-68968.E3tnhy.rst b/Misc/NEWS.d/next/Library/2023-04-27-18-46-31.gh-issue-68968.E3tnhy.rst
new file mode 100644 (file)
index 0000000..bf29b64
--- /dev/null
@@ -0,0 +1 @@
+Fixed garbled output of :meth:`~unittest.TestCase.assertEqual` when an input lacks final newline.