File: test_union.py

package info (click to toggle)
python-mashumaro 3.16-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,400 kB
  • sloc: python: 19,890; sh: 16; makefile: 5
file content (141 lines) | stat: -rw-r--r-- 5,641 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
from dataclasses import dataclass
from datetime import date
from itertools import permutations
from typing import Any, Dict, List, Union

import pytest

from mashumaro import DataClassDictMixin
from mashumaro.codecs.basic import encode
from tests.utils import same_types


@dataclass
class UnionTestCase:
    type: Any
    dumped: Any
    loaded: Any


@pytest.mark.parametrize(
    "test_case",
    [
        # int | str
        UnionTestCase(Union[int, str], 1, 1),
        UnionTestCase(Union[int, str], "1", "1"),
        UnionTestCase(Union[int, str], 1.0, 1),
        UnionTestCase(Union[int, str], 1.2, 1),
        UnionTestCase(Union[int, str], "a", "a"),
        UnionTestCase(Union[int, str], [1, 2], "[1, 2]"),
        # str | int
        UnionTestCase(Union[str, int], 1, 1),
        UnionTestCase(Union[str, int], "1", "1"),
        UnionTestCase(Union[str, int], 1.0, "1.0"),
        UnionTestCase(Union[str, int], 1.2, "1.2"),
        UnionTestCase(Union[str, int], "a", "a"),
        UnionTestCase(Union[str, int], [1, 2], "[1, 2]"),
        # str | date
        UnionTestCase(Union[str, date], "2024-11-12", "2024-11-12"),
        UnionTestCase(Union[str, date], "a", "a"),
        # date | str
        UnionTestCase(Union[date, str], "2024-11-12", date(2024, 11, 12)),
        UnionTestCase(Union[date, str], "a", "a"),
        # int | float
        UnionTestCase(Union[int, float], 1, 1),
        UnionTestCase(Union[int, float], 1.0, 1.0),
        UnionTestCase(Union[int, float], "1", 1),
        UnionTestCase(Union[int, float], "1.0", 1.0),
        # float | int
        UnionTestCase(Union[float, int], 1, 1),
        UnionTestCase(Union[float, int], 1.0, 1.0),
        UnionTestCase(Union[float, int], "1", 1.0),
        UnionTestCase(Union[float, int], "1.0", 1.0),
        # bool | int
        UnionTestCase(Union[bool, int], 1, 1),
        UnionTestCase(Union[bool, int], 1.0, True),
        UnionTestCase(Union[bool, int], True, True),
        UnionTestCase(Union[bool, int], "1", True),
        UnionTestCase(Union[bool, int], "1.2", True),
        UnionTestCase(Union[bool, int], [1, 2], True),
        UnionTestCase(Union[bool, int], "a", True),
        # int | bool
        UnionTestCase(Union[int, bool], 1, 1),
        UnionTestCase(Union[int, bool], 1.0, 1),
        UnionTestCase(Union[int, bool], True, True),
        UnionTestCase(Union[int, bool], "1", 1),
        UnionTestCase(Union[int, bool], "1.2", True),
        UnionTestCase(Union[int, bool], [1, 2], True),
        UnionTestCase(Union[int, bool], "a", True),
        # dict[int, int] | list[int]
        UnionTestCase(Union[Dict[int, int], List[int]], {1: 2}, {1: 2}),
        UnionTestCase(Union[Dict[int, int], List[int]], {"1": "2"}, {1: 2}),
        UnionTestCase(Union[Dict[int, int], List[int]], [1], [1]),
        UnionTestCase(Union[Dict[int, int], List[int]], ["1"], [1]),
        # str | list[str]
        UnionTestCase(Union[str, List[str]], ["a"], ["a"]),
        UnionTestCase(Union[str, List[str]], "abc", "abc"),
        UnionTestCase(Union[str, List[str]], 1, "1"),
        UnionTestCase(Union[str, List[str]], [1, 2], ["1", "2"]),
        # int | float | None
        UnionTestCase(Union[int, float, None], None, None),
        UnionTestCase(Union[int, float, None], 1, 1),
        UnionTestCase(Union[int, float, None], 1.2, 1.2),
        UnionTestCase(Union[int, float, None], "1", 1),
        UnionTestCase(Union[int, float, None], "1.2", 1.2),
        UnionTestCase(Union[int, float, None], "a", None),
        # None | int | float
        UnionTestCase(Union[None, int, float], None, None),
        UnionTestCase(Union[None, int, float], 1, 1),
        UnionTestCase(Union[None, int, float], 1.2, 1.2),
        UnionTestCase(Union[None, int, float], "1", None),
        UnionTestCase(Union[None, int, float], "1.2", None),
        UnionTestCase(Union[None, int, float], "a", None),
        # int | None | float
        UnionTestCase(Union[int, None, float], None, None),
        UnionTestCase(Union[int, None, float], 1, 1),
        UnionTestCase(Union[int, None, float], 1.2, 1.2),
        UnionTestCase(Union[int, None, float], "1", 1),
        UnionTestCase(Union[int, None, float], "1.2", None),
        UnionTestCase(Union[int, None, float], "a", None),
    ],
)
def test_union_deserialization(test_case):
    @dataclass
    class DataClass(DataClassDictMixin):
        x: test_case.type

    instance = DataClass(x=test_case.loaded)
    loaded = DataClass.from_dict({"x": test_case.dumped})
    assert loaded == instance
    assert same_types(loaded.x, instance.x)


@pytest.mark.parametrize(
    "test_case",
    [
        UnionTestCase(Union[int, str], 1, 1),
        UnionTestCase(Union[int, str], "1", "1"),
        UnionTestCase(Union[int, str], "a", "a"),
        UnionTestCase(Union[Dict[int, int], List[int]], {1: 2}, {1: 2}),
        UnionTestCase(Union[Dict[int, int], List[int]], [1], [1]),
        UnionTestCase(Union[str, List[str]], ["a"], ["a"]),
        UnionTestCase(Union[str, List[str]], "abc", "abc"),
    ],
)
def test_union_serialization(test_case):
    @dataclass
    class DataClass(DataClassDictMixin):
        x: test_case.type

    instance = DataClass(x=test_case.loaded)
    dumped = instance.to_dict()
    assert dumped == {"x": test_case.dumped}
    assert same_types(dumped["x"], test_case.dumped)


def test_union_encoding():
    for variants in permutations((int, float, str, bool)):
        for value in (1, 2.0, 3.1, "4", "5.0", True, False):
            encoded = encode(value, Union[variants])
            assert value == encoded
            assert same_types(value, encoded)