Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/fix string newlines #32

Merged
merged 2 commits into from
Apr 20, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ This `pytest`_ plugin was generated with `Cookiecutter`_ along with `@hackebrot`
Features
--------

* snapshot testing of strings ands bytes
* snapshot testing of strings and bytes
* snapshot testing of collections of strings and bytes
* the user has complete control over the snapshot file path and content

Expand Down
18 changes: 17 additions & 1 deletion pytest_snapshot/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@ def _assert_equal(value, expected_value) -> None:
assert expected_value == value


def _file_encode(string: str) -> bytes:
"""
Returns the bytes that would be in a file created using ``path.write_text(string)``.
See universal newlines documentation.
"""
return string.replace('\n', os.linesep).encode()


def _file_decode(data: bytes) -> str:
"""
Returns the string that would be read from a file using ``path.read_text(string)``.
See universal newlines documentation.
"""
return data.decode().replace('\r\n', '\n').replace('\r', '\n')


class Snapshot:
_snapshot_update = None # type: bool
_allow_snapshot_deletion = None # type: bool
Expand Down Expand Up @@ -120,7 +136,7 @@ def _get_compare_encode_decode(self, value: Union[str, bytes]):
* The decoding function should decode bytes from a snapshot file into a object.
"""
if isinstance(value, str):
return _assert_equal, str.encode, bytes.decode
return _assert_equal, _file_encode, _file_decode
elif isinstance(value, bytes):
return _assert_equal, lambda x: x, lambda x: x
else:
Expand Down
50 changes: 27 additions & 23 deletions tests/test_assert_match.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import os

import pytest

from tests.utils import assert_pytest_passes
Expand All @@ -6,17 +8,17 @@
@pytest.fixture
def basic_case_dir(testdir):
case_dir = testdir.mkdir('case_dir')
case_dir.join('snapshot1.txt').write_text('the valuÉ of snapshot1.txt', 'utf-8')
case_dir.join('snapshot1.txt').write_text('the valuÉ of snapshot1.txt\n', 'utf-8')
return case_dir


def test_assert_match_with_external_snapshot_path(testdir, basic_case_dir):
testdir.makepyfile("""
testdir.makepyfile(r"""
from pathlib import Path

def test_sth(snapshot):
snapshot.snapshot_dir = 'case_dir'
snapshot.assert_match('the value of snapshot1.txt', Path('not_case_dir/snapshot1.txt').absolute())
snapshot.assert_match('the value of snapshot1.txt\n', Path('not_case_dir/snapshot1.txt').absolute())
""")
result = testdir.runpytest('-v')
result.stdout.fnmatch_lines([
Expand All @@ -27,28 +29,29 @@ def test_sth(snapshot):


def test_assert_match_success_string(testdir, basic_case_dir):
testdir.makepyfile("""
testdir.makepyfile(r"""
def test_sth(snapshot):
snapshot.snapshot_dir = 'case_dir'
snapshot.assert_match('the valuÉ of snapshot1.txt', 'snapshot1.txt')
snapshot.assert_match('the valuÉ of snapshot1.txt\n', 'snapshot1.txt')
""")
assert_pytest_passes(testdir)


def test_assert_match_success_bytes(testdir, basic_case_dir):
testdir.makepyfile(r"""
import os
def test_sth(snapshot):
snapshot.snapshot_dir = 'case_dir'
snapshot.assert_match(b'the valu\xc3\x89 of snapshot1.txt', 'snapshot1.txt')
snapshot.assert_match(b'the valu\xc3\x89 of snapshot1.txt' + os.linesep.encode(), 'snapshot1.txt')
""")
assert_pytest_passes(testdir)


def test_assert_match_failure_string(testdir, basic_case_dir):
testdir.makepyfile("""
testdir.makepyfile(r"""
def test_sth(snapshot):
snapshot.snapshot_dir = 'case_dir'
snapshot.assert_match('the INCORRECT value of snapshot1.txt', 'snapshot1.txt')
snapshot.assert_match('the INCORRECT value of snapshot1.txt\n', 'snapshot1.txt')
""")
result = testdir.runpytest('-v')
result.stdout.fnmatch_lines([
Expand All @@ -65,10 +68,11 @@ def test_sth(snapshot):


def test_assert_match_failure_bytes(testdir, basic_case_dir):
testdir.makepyfile("""
testdir.makepyfile(r"""
import os
def test_sth(snapshot):
snapshot.snapshot_dir = 'case_dir'
snapshot.assert_match(b'the INCORRECT value of snapshot1.txt', 'snapshot1.txt')
snapshot.assert_match(b'the INCORRECT value of snapshot1.txt' + os.linesep.encode(), 'snapshot1.txt')
""")
result = testdir.runpytest('-v')
result.stdout.fnmatch_lines([
Expand All @@ -78,14 +82,14 @@ def test_sth(snapshot):
r"E* assert * == *",
r"E* At index 4 diff: * != *",
r"E* Full diff:",
r"E* - b'the valu\xc3\x89 of snapshot1.txt'",
r"E* + b'the INCORRECT value of snapshot1.txt'",
r"E* - b'the valu\xc3\x89 of snapshot1.txt{}'".format(repr(os.linesep)[1:-1]),
r"E* + b'the INCORRECT value of snapshot1.txt{}'".format(repr(os.linesep)[1:-1]),
])
assert result.ret == 1


def test_assert_match_invalid_type(testdir, basic_case_dir):
testdir.makepyfile("""
testdir.makepyfile(r"""
def test_sth(snapshot):
snapshot.snapshot_dir = 'case_dir'
snapshot.assert_match(123, 'snapshot1.txt')
Expand All @@ -99,7 +103,7 @@ def test_sth(snapshot):


def test_assert_match_missing_snapshot(testdir, basic_case_dir):
testdir.makepyfile("""
testdir.makepyfile(r"""
def test_sth(snapshot):
snapshot.snapshot_dir = 'case_dir'
snapshot.assert_match('something', 'snapshot_that_doesnt_exist.txt')
Expand All @@ -114,10 +118,10 @@ def test_sth(snapshot):


def test_assert_match_update_existing_snapshot_no_change(testdir, basic_case_dir):
testdir.makepyfile("""
testdir.makepyfile(r"""
def test_sth(snapshot):
snapshot.snapshot_dir = 'case_dir'
snapshot.assert_match('the valuÉ of snapshot1.txt', 'snapshot1.txt')
snapshot.assert_match('the valuÉ of snapshot1.txt\n', 'snapshot1.txt')
""")
result = testdir.runpytest('-v', '--snapshot-update')
result.stdout.fnmatch_lines([
Expand Down Expand Up @@ -152,12 +156,12 @@ def test_assert_match_update_existing_snapshot(testdir, basic_case_dir, case_dir

Also tests that `Snapshot` supports absolute/relative str/Path snapshot directories and snapshot paths.
"""
testdir.makepyfile("""
testdir.makepyfile(r"""
from pathlib import Path

def test_sth(snapshot):
snapshot.snapshot_dir = {case_dir_repr}
snapshot.assert_match('the NEW value of snapshot1.txt', {snapshot_name_repr})
snapshot.assert_match('the NEW value of snapshot1.txt\n', {snapshot_name_repr})
""".format(case_dir_repr=case_dir_repr, snapshot_name_repr=snapshot_name_repr))
result = testdir.runpytest('-v', '--snapshot-update')
result.stdout.fnmatch_lines([
Expand All @@ -177,12 +181,12 @@ def test_assert_match_update_existing_snapshot_and_exception_in_test(testdir, ba
Tests that `Snapshot.assert_match` works when updating an existing snapshot and then the test function fails.
In this case, both the snapshot update error and the test function error are printed out.
"""
testdir.makepyfile("""
testdir.makepyfile(r"""
from pathlib import Path

def test_sth(snapshot):
snapshot.snapshot_dir = 'case_dir'
snapshot.assert_match('the NEW value of snapshot1.txt', 'snapshot1.txt')
snapshot.assert_match('the NEW value of snapshot1.txt\n', 'snapshot1.txt')
assert False
""")
result = testdir.runpytest('-v', '--snapshot-update')
Expand All @@ -198,7 +202,7 @@ def test_sth(snapshot):


def test_assert_match_create_new_snapshot(testdir, basic_case_dir):
testdir.makepyfile("""
testdir.makepyfile(r"""
def test_sth(snapshot):
snapshot.snapshot_dir = 'case_dir'
snapshot.assert_match('the NEW value of new_snapshot1.txt', 'sub_dir/new_snapshot1.txt')
Expand All @@ -217,7 +221,7 @@ def test_sth(snapshot):


def test_assert_match_create_new_snapshot_in_default_dir(testdir):
testdir.makepyfile("""
testdir.makepyfile(r"""
def test_sth(snapshot):
snapshot.assert_match('the value of new_snapshot1.txt', 'sub_dir/new_snapshot1.txt')
""")
Expand All @@ -239,7 +243,7 @@ def test_sth(snapshot):

def test_assert_match_existing_snapshot_is_not_file(testdir, basic_case_dir):
basic_case_dir.mkdir('directory1')
testdir.makepyfile("""
testdir.makepyfile(r"""
def test_sth(snapshot):
snapshot.snapshot_dir = 'case_dir'
snapshot.assert_match('something', 'directory1')
Expand Down