Skip to content

Commit

Permalink
Escape whitespace only strings when diffing them on failed assertions
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoddemus committed May 3, 2018
1 parent 08aed1a commit dca77b2
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 2 deletions.
20 changes: 18 additions & 2 deletions _pytest/assertion/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,10 +171,22 @@ def _diff_text(left, right, verbose=False):
"""
from difflib import ndiff
explanation = []

def to_unicode_text(binary_text):
"""
This ensures that the internal string is always valid unicode, converting any bytes safely to valid unicode.
This is done using repr() which then needs post-processing to fix the encompassing quotes and un-escape
newlines and carriage returns (#429).
"""
r = six.text_type(repr(binary_text)[1:-1])
r = r.replace(r'\n', '\n')
r = r.replace(r'\r', '\r')
return r

if isinstance(left, six.binary_type):
left = u(repr(left)[1:-1]).replace(r'\n', '\n')
left = to_unicode_text(left)
if isinstance(right, six.binary_type):
right = u(repr(right)[1:-1]).replace(r'\n', '\n')
right = to_unicode_text(right)
if not verbose:
i = 0 # just in case left or right has zero length
for i in range(min(len(left), len(right))):
Expand All @@ -197,6 +209,10 @@ def _diff_text(left, right, verbose=False):
left = left[:-i]
right = right[:-i]
keepends = True
if left.isspace() or right.isspace():
left = repr(str(left))
right = repr(str(right))
explanation += [u'Strings contain only whitespace, escaping them using repr()']
explanation += [line.strip('\n')
for line in ndiff(left.splitlines(keepends),
right.splitlines(keepends))]
Expand Down
1 change: 1 addition & 0 deletions changelog/3443.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
When showing diffs of failed assertions where the contents contain only whitespace, escape them using ``repr()`` first to make it easy to spot the differences.
12 changes: 12 additions & 0 deletions testing/test_assertion.py
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,18 @@ def test_reprcompare_notin(mock_config):
assert detail == ["'foo' is contained here:", ' aaafoobbb', '? +++']


def test_reprcompare_whitespaces(mock_config):
detail = plugin.pytest_assertrepr_compare(
mock_config, '==', '\r\n', '\n')
assert detail == [
r"'\r\n' == '\n'",
r"Strings contain only whitespace, escaping them using repr()",
r"- '\r\n'",
r"? --",
r"+ '\n'",
]


def test_pytest_assertrepr_compare_integration(testdir):
testdir.makepyfile("""
def test_hello():
Expand Down

0 comments on commit dca77b2

Please sign in to comment.