Skip to content

Commit

Permalink
feat: numerically sort snapshots if possible, close #657
Browse files Browse the repository at this point in the history
  • Loading branch information
noahnu authored Jan 26, 2023
1 parent 3d296e1 commit 4ca0716
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 6 deletions.
24 changes: 23 additions & 1 deletion src/syrupy/extensions/amber/serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
Dict,
Generator,
Iterable,
List,
NamedTuple,
Optional,
Set,
Expand Down Expand Up @@ -87,6 +88,25 @@ class Marker:
Name = "name"
Divider = "---"

@classmethod
def __maybe_int(cls, part: str) -> Tuple[int, Union[str, int]]:
try:
# cast to int only if the string is the exact representation of the int
# for example, '012' != str(int('012'))
i = int(part)
if str(i) == part:
return (1, i)
return (0, part)
except ValueError:
# the nested tuple is to prevent comparing a str to an int
return (0, part)

@classmethod
def __snapshot_sort_key(
cls, snapshot: "Snapshot"
) -> List[Tuple[int, Union[str, int]]]:
return [cls.__maybe_int(part) for part in snapshot.name.split(".")]

@classmethod
def write_file(
cls, snapshot_collection: "SnapshotCollection", merge: bool = False
Expand All @@ -102,7 +122,9 @@ def write_file(

with open(filepath, "w", encoding=TEXT_ENCODING, newline=None) as f:
f.write(f"{cls._marker_prefix}{cls.Marker.Version}: {cls.VERSION}\n")
for snapshot in sorted(snapshot_collection, key=lambda s: s.name):
for snapshot in sorted(
snapshot_collection, key=lambda s: cls.__snapshot_sort_key(s)
):
snapshot_data = str(snapshot.data)
if snapshot_data is not None:
f.write(f"{cls._marker_prefix}{cls.Marker.Name}: {snapshot.name}\n")
Expand Down
10 changes: 5 additions & 5 deletions tests/syrupy/__snapshots__/test_doctest.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@
obj_attr='test class attr',
)
# ---
# name: DocTestClass.1
DocTestClass(
obj_attr='test class attr',
)
# ---
# name: DocTestClass.NestedDocTestClass
NestedDocTestClass(
nested_obj_attr='nested doc test class attr',
Expand All @@ -20,6 +15,11 @@
# name: DocTestClass.doctest_method
'doc test method return value'
# ---
# name: DocTestClass.1
DocTestClass(
obj_attr='test class attr',
)
# ---
# name: doctest_fn
'doc test fn return value'
# ---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,81 @@
}),
])
# ---
# name: test_many_sorted
0
# ---
# name: test_many_sorted.1
1
# ---
# name: test_many_sorted.2
2
# ---
# name: test_many_sorted.3
3
# ---
# name: test_many_sorted.4
4
# ---
# name: test_many_sorted.5
5
# ---
# name: test_many_sorted.6
6
# ---
# name: test_many_sorted.7
7
# ---
# name: test_many_sorted.8
8
# ---
# name: test_many_sorted.9
9
# ---
# name: test_many_sorted.10
10
# ---
# name: test_many_sorted.11
11
# ---
# name: test_many_sorted.12
12
# ---
# name: test_many_sorted.13
13
# ---
# name: test_many_sorted.14
14
# ---
# name: test_many_sorted.15
15
# ---
# name: test_many_sorted.16
16
# ---
# name: test_many_sorted.17
17
# ---
# name: test_many_sorted.18
18
# ---
# name: test_many_sorted.19
19
# ---
# name: test_many_sorted.20
20
# ---
# name: test_many_sorted.21
21
# ---
# name: test_many_sorted.22
22
# ---
# name: test_many_sorted.23
23
# ---
# name: test_many_sorted.24
24
# ---
# name: test_multiline_string_in_dict
dict({
'value': '''
Expand Down
5 changes: 5 additions & 0 deletions tests/syrupy/extensions/amber/test_amber_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,3 +228,8 @@ def test_ordered_dict(snapshot):
d["b"] = 0
d["a"] = 1
assert snapshot == d


def test_many_sorted(snapshot):
for i in range(25):
assert i == snapshot

4 comments on commit 4ca0716

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 4ca0716 Previous: 02abef5 Ratio
benchmarks/test_1000x.py::test_1000x_reads 0.6504332306731985 iter/sec (stddev: 0.05191258064344871) 0.8381195242511715 iter/sec (stddev: 0.04240394140227035) 1.29
benchmarks/test_1000x.py::test_1000x_writes 0.6261240564911069 iter/sec (stddev: 0.10312953811549232) 0.8626650008455868 iter/sec (stddev: 0.05153168408309042) 1.38
benchmarks/test_standard.py::test_standard 0.614240671022241 iter/sec (stddev: 0.09005798071493859) 0.7465173870618954 iter/sec (stddev: 0.1502009356924296) 1.22

This comment was automatically generated by workflow using github-action-benchmark.

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 4ca0716 Previous: 02abef5 Ratio
benchmarks/test_1000x.py::test_1000x_reads 0.6568448257877567 iter/sec (stddev: 0.07302106006938174) 0.8381195242511715 iter/sec (stddev: 0.04240394140227035) 1.28
benchmarks/test_1000x.py::test_1000x_writes 0.6461605240459128 iter/sec (stddev: 0.06661873960228565) 0.8626650008455868 iter/sec (stddev: 0.05153168408309042) 1.34
benchmarks/test_standard.py::test_standard 0.6168099212273088 iter/sec (stddev: 0.06670394338400236) 0.7465173870618954 iter/sec (stddev: 0.1502009356924296) 1.21

This comment was automatically generated by workflow using github-action-benchmark.

@noahnu
Copy link
Collaborator Author

@noahnu noahnu commented on 4ca0716 Jan 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Performance degradation 😢

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 4ca0716 Previous: 02abef5 Ratio
benchmarks/test_1000x.py::test_1000x_reads 0.6207178432624816 iter/sec (stddev: 0.06956937819502504) 0.8381195242511715 iter/sec (stddev: 0.04240394140227035) 1.35
benchmarks/test_1000x.py::test_1000x_writes 0.603983318764947 iter/sec (stddev: 0.06808163816493823) 0.8626650008455868 iter/sec (stddev: 0.05153168408309042) 1.43
benchmarks/test_standard.py::test_standard 0.5707622889069596 iter/sec (stddev: 0.030989220257344203) 0.7465173870618954 iter/sec (stddev: 0.1502009356924296) 1.31

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.