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"),
),
)
|