2Tests for ``javascript_data_files.validate_type``.
8from pydantic import ValidationError
10from javascript_data_files.validate_type import validate_type
13Shape = typing.TypedDict("Shape", {"colour": str, "sides": int})
14Circle = typing.TypedDict("Circle", {"colour": str, "radius": int})
17@pytest.mark.parametrize(
22 {"colour": "red", "sides": "four"},
23 {"colour": (255, 0, 0), "sides": 4},
24 {"colour": "red", "sides": 4, "angle": 36},
27def test_validate_type_flags_incorrect_data(data: typing.Any) -> None:
29 If you pass data that doesn't match the model to ``validate_type``,
30 it throws a ``ValidationError``.
32 with pytest.raises(ValidationError):
33 validate_type(data, model=Shape)
36def test_validate_type_allows_valid_data() -> None:
38 If you pass data which matches the model to ``validate_type``,
39 it passes without exception.
41 validate_type({"colour": "red", "sides": 4}, model=Shape)
44def test_validate_type_supports_builtin_list() -> None:
46 You can validate a list with ``validate_type``.
48 validate_type([1, 2, 3], model=list[int])
51def test_validate_type_supports_builtin_type() -> None:
53 You can validate a list with ``validate_type``.
55 validate_type(1, model=int)
58@pytest.mark.parametrize(
59 "data", [{"colour": "red", "sides": 4}, {"colour": "blue", "radius": 3}]
61def test_validate_type_supports_union_type(data: typing.Any) -> None:
63 You can validate a type which is a union of two TypedDict's.
65 validate_type(data, model=Shape | Circle) # type: ignore
68@pytest.mark.parametrize(
71 {"colour": "red", "sides": 4, "name": "square"},
72 {"colour": "red", "sides": 4, "stroke": "black", "depth": 3},
75def test_validate_type_rejects_extra_fields(data: typing.Any) -> None:
77 Adding extra keys to a TypedDict is a validation error.
79 with pytest.raises(ValidationError):
80 validate_type(data, model=Shape)
83@pytest.mark.parametrize(
86 {"colour": "red", "sides": 4, "name": "square"},
87 {"colour": "red", "sides": 4, "stroke": "black", "depth": 3},
90def test_validate_type_of_union_rejects_extra_fields(data: typing.Any) -> None:
92 Adding extra keys to a Union of TypedDict's is a validation error.
94 with pytest.raises(ValidationError):
95 validate_type(data, model=Shape | Circle) # type: ignore
98def test_validate_type_does_not_change_data() -> None:
100 Check that ``validate_type`` does not change the value, merely make
101 assertions about the type.
103 This is a regression test for a bug I encountered in my bookmarks
104 project -- notice that `s` does not really conform to either type.
106 * If it's UncolouredShape, it shouldn't have a "type"
107 * If it's ColouredShape, it should have a "colour"
109 This appears to be caused by a bug in Pydantic, see
110 https://github.com/pydantic/pydantic/issues/11328
114 class UncolouredShape(typing.TypedDict):
117 class ColouredShape(typing.TypedDict):
120 type: typing.Literal["coloured_shape"]
122 Shape = UncolouredShape | ColouredShape
126 "type": "coloured_shape",
129 with pytest.raises(ValidationError):
130 assert validate_type(s, model=Shape) == s # type: ignore