File: test_amber_matchers.py

package info (click to toggle)
python-syrupy 4.9.1-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 4,368 kB
  • sloc: python: 5,978; makefile: 3
file content (143 lines) | stat: -rw-r--r-- 4,299 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
import datetime
import uuid

import pytest

from syrupy.extensions.amber.serializer import (
    AmberDataSerializer,
    Repr,
)
from syrupy.matchers import (
    PathTypeError,
    compose_matchers,
    path_type,
    path_value,
)


def test_matcher_path_type_noop(snapshot):
    with pytest.raises(PathTypeError, match="argument cannot be empty"):
        path_type()


def test_matches_expected_type(snapshot):
    my_matcher = path_type(
        {"date_created": (datetime.datetime,), "nested.id": (int,)}, types=(uuid.UUID,)
    )
    actual = {
        "date_created": datetime.datetime.now(),
        "nested": {"id": 4},
        "nested_id": 5,
        "some_uuid": uuid.uuid4(),
    }
    assert actual == snapshot(matcher=my_matcher)


def test_raises_unexpected_type(snapshot):
    kwargs = {
        "mapping": {
            "date_created": (datetime.datetime,),
            "date_updated": (datetime.datetime,),
            "nested.id": (str,),
        },
        "types": (uuid.UUID, int),
    }
    actual = {
        "date_created": datetime.datetime.now(),
        "date_updated": datetime.date(2020, 6, 1),
        "nested": {"id": 4},
        "some_uuid": uuid.uuid4(),
    }
    assert actual == snapshot(matcher=path_type(**kwargs, strict=False))
    with pytest.raises(AssertionError, match="does not match any of the expected"):
        assert actual == snapshot(matcher=path_type(**kwargs))


def test_matches_non_deterministic_snapshots(snapshot):
    def matcher(data, path):
        if isinstance(data, uuid.UUID):
            return Repr("UUID(...)")
        if isinstance(data, datetime.datetime):
            return Repr("datetime.datetime(...)")
        if tuple(p for p, _ in path[-2:]) == ("c", 0):
            return "Your wish is my command"
        return data

    assert {
        "a": uuid.uuid4(),
        "b": {"b_1": "This is deterministic", "b_2": datetime.datetime.now()},
        "c": ["Replace this one", "Do not replace this one"],
    } == snapshot(matcher=matcher)
    assert {
        "a": uuid.UUID("06335e84-2872-4914-8c5d-3ed07d2a2f16"),
        "b": {
            "b_1": "This is deterministic",
            "b_2": datetime.datetime(year=2020, month=5, day=31),
        },
        "c": ["Replace this one", "Do not replace this one"],
    } == snapshot


def test_matches_regex_in_regex_mode(snapshot):
    my_matcher = path_type(
        {
            r"data\.list\..*\.date_created": (datetime.datetime,),
            r"any_number": (int,),
            "any_number.adjacent": (str,),
        },
        regex=True,
    )
    actual = {
        "data": {
            "list": [
                {"k": "1", "date_created": datetime.datetime.now()},
                {"k": "2", "date_created": datetime.datetime.now()},
            ],
        },
        "any_number": 3,
        "any_number_adjacent": "hi",
        "specific_number": 5,
    }
    assert actual == snapshot(matcher=my_matcher)


def test_regex_matcher_str_value(request, snapshot, tmp_path):
    def replacer(data, match):
        # check that the match is for the expected file path
        if match and request.node.name in match[0]:
            return match[0].replace(match[1], "<tmp-path>/")
        return Repr(AmberDataSerializer.object_type(data))

    my_matcher = path_value(
        {
            r"data\.list\..*\.id": "[a-z0-9]{8}-([a-z0-9]{4}-){3}[a-z0-9]{12}",
            "dir": rf"(.*){request.node.name}.*",
        },
        types=(str, uuid.UUID),
        replacer=replacer,
        regex=True,
    )
    actual = {
        "data": {
            "any_number": 3,
            "any_string": "hello",
            "list": [
                {"k": "1", "id": uuid.uuid4()},
                {"k": "2", "id": uuid.uuid4()},
            ],
        },
        "dir": str(tmp_path),
    }
    assert actual == snapshot(matcher=my_matcher)


def test_multiple_matchers(snapshot):
    data = {"number": 1, "datetime": datetime.datetime.now(), "float": 1.3}

    assert data == snapshot(
        matcher=compose_matchers(
            path_type(types=(list,), replacer=lambda *_: "DO_NOT_MATCH"),
            path_type(types=(int, float), replacer=lambda *_: "MATCHER_1"),
            path_type(types=(datetime.datetime,), replacer=lambda *_: "MATCHER_2"),
        ),
    )