Skip to content

Commit 1680d10

Browse files
authored
fix: compare snapshots without deserializing (#26)
* wip: remove deserialization * wip: use yaml safe full loader * wip: compare serialized data * wip: remove unneeded import * test: refactor grouping * refactor: test grouping * wip: do not rewrite matching snapshots * cr: collapse conditionals
1 parent c57b3ba commit 1680d10

File tree

5 files changed

+62
-18
lines changed

5 files changed

+62
-18
lines changed

src/syrupy/assertion.py

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,13 @@ def assert_match(self, data):
6666
assert self == data
6767

6868
def get_assert_diff(self, data) -> List[str]:
69-
deserialized = self._recall_data(index=self.num_executions - 1)
70-
if deserialized is None:
69+
serialized_data = self.serializer.encode(data)
70+
snapshot_data = self._recall_data(index=self.num_executions - 1)
71+
if snapshot_data is None:
7172
return ["Snapshot does not exist!"]
7273

73-
if data != deserialized:
74-
return [f"- {data}", f"+ {deserialized}"]
74+
if serialized_data != snapshot_data:
75+
return [f"- {serialized_data}", f"+ {snapshot_data}"]
7576

7677
return []
7778

@@ -90,23 +91,20 @@ def __eq__(self, other) -> bool:
9091
def _assert(self, data) -> bool:
9192
self._session.register_assertion(self)
9293
try:
93-
if self._update_snapshots:
94-
serialized_data = self.serializer.encode(data)
94+
serialized_data = self.serializer.encode(data)
95+
snapshot_data = self._recall_data(index=self.num_executions)
96+
matches = snapshot_data is not None and serialized_data == snapshot_data
97+
if not matches and self._update_snapshots:
9598
self.io.create_or_update_snapshot(
9699
serialized_data, index=self.num_executions
97100
)
98101
return True
99-
100-
deserialized = self._recall_data(index=self.num_executions)
101-
if deserialized is None or data != deserialized:
102-
return False
103-
return True
102+
return matches
104103
finally:
105104
self._executions += 1
106105

107106
def _recall_data(self, index: int) -> Optional[Any]:
108107
try:
109-
saved_data = self.io.read_snapshot(index=index)
110-
return self.serializer.decode(saved_data)
108+
return self.io.read_snapshot(index=index)
111109
except SnapshotDoesNotExist:
112110
return None

src/syrupy/io.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def _read_file(self, filepath: str) -> Any:
128128
"""
129129
try:
130130
with open(filepath, "r") as f:
131-
return yaml.safe_load(f) or {}
131+
return yaml.load(f, Loader=yaml.FullLoader) or {}
132132
except FileNotFoundError:
133133
pass
134134
return {}
@@ -158,7 +158,7 @@ def _write_file(self, filepath: str, data: Any):
158158
Writes the snapshot data into the snapshot file that be read later.
159159
"""
160160
with open(filepath, "w") as f:
161-
yaml.safe_dump(data, f)
161+
yaml.dump(data, f, allow_unicode=True)
162162

163163
def _snap_file_hook(self, index: int):
164164
"""

src/syrupy/serializer.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,3 @@ def __init__(self):
77

88
def encode(self, data):
99
return data
10-
11-
def decode(self, data):
12-
return data

tests/__snapshots__/test_snapshots.yaml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,36 @@ test_parametrized_with_special_char[Escaped \\n]:
2828
data: Escaped \n
2929
test_raw_string:
3030
data: Raw string
31+
test_set:
32+
data: !!set
33+
a: null
34+
is: null
35+
set: null
36+
this: null
37+
test_set.1:
38+
data: !!set
39+
this: null
40+
is: null
41+
a: null
42+
? !!python/object/apply:builtins.frozenset
43+
- - nested, set
44+
: null
3145
test_simple_string:
3246
data: Loreeeeeem ipsum.
47+
test_tuples:
48+
data: !!python/tuple
49+
- this
50+
- is
51+
- !!python/tuple
52+
- a
53+
- tuple
54+
test_tuples.1:
55+
data: !!python/object/new:tests.test_snapshots.ExampleTuple
56+
- this
57+
- is
58+
- a
59+
- !!set
60+
named: null
61+
tuple: null
62+
test_unicode_string:
63+
data: 🥞🐍🍯

tests/test_snapshots.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from collections import namedtuple
12
import pytest
23

34

@@ -9,6 +10,10 @@ def test_raw_string(snapshot):
910
assert r"Raw string" == snapshot
1011

1112

13+
def test_unicode_string(snapshot):
14+
assert "🥞🐍🍯" == snapshot
15+
16+
1217
def test_multiple_snapshots(snapshot):
1318
assert "First." == snapshot
1419
snapshot.assert_match("Second.")
@@ -29,3 +34,16 @@ def test_parametrized_with_special_char(snapshot, expected):
2934
)
3035
def test_dict(snapshot, actual):
3136
assert actual == snapshot
37+
38+
39+
def test_set(snapshot):
40+
assert snapshot == {"this", "is", "a", "set"}
41+
assert snapshot == {"this", "is", "a", frozenset({"nested, set"})}
42+
43+
44+
ExampleTuple = namedtuple("ExampleTuple", ["a", "b", "c", "d"])
45+
46+
47+
def test_tuples(snapshot):
48+
assert snapshot == ("this", "is", ("a", "tuple"))
49+
assert snapshot == ExampleTuple(a="this", b="is", c="a", d={"named", "tuple"})

0 commit comments

Comments
 (0)