Skip to content

Commit a30dd52

Browse files
committed
add some more test for dataclass de/serialization
1 parent be16e05 commit a30dd52

File tree

2 files changed

+98
-2
lines changed

2 files changed

+98
-2
lines changed

robotcode/utils/dataclasses.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ def convert_value(value: Any, types: Union[Type[_T], Tuple[Type[_T], ...], None]
166166
match = t
167167
match_value = cased_value
168168
match_type_hints = type_hints
169+
elif match_same_keys is not None and len(match_same_keys) == len(same_keys):
170+
raise TypeError(
171+
f"Value {repr(value)} matches to more then one types of "
172+
f"{repr(types[0].__name__) if len(types)==1 else ' | '.join(repr(e.__name__) for e in types)}."
173+
)
169174

170175
if match is not None and match_value is not None and match_type_hints is not None:
171176
params: Dict[str, Any] = {k: convert_value(v, match_type_hints[k]) for k, v in match_value.items()}
@@ -184,8 +189,8 @@ def convert_value(value: Any, types: Union[Type[_T], Tuple[Type[_T], ...], None]
184189
return cast(_T, v)
185190

186191
raise TypeError(
187-
f"Cant convert value of type {repr(type(value).__name__)} to type "
188-
f"{repr(types[0].__name__) if len(types)==1 else ' | '.join(repr(e.__name__) for e in types) }."
192+
f"Cant convert value {repr(value)} to type "
193+
f"{repr(types[0].__name__) if len(types)==1 else ' | '.join(repr(e.__name__) for e in types)}."
189194
)
190195

191196

tests/robotcode/utils/test_dataclasses.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,3 +167,94 @@ def test_decode_optional_simple_class() -> None:
167167
)
168168
def test_decode_complex_class_with_encoding(expr: Any, type: Any, expected: str) -> None:
169169
assert from_json(expr, type) == expected
170+
171+
172+
@dataclass
173+
class SimpleItemWithOptionalFields:
174+
first: int
175+
second: bool = True
176+
third: Optional[str] = None
177+
forth: Optional[float] = None
178+
179+
180+
@pytest.mark.parametrize(
181+
("expr", "type", "expected"),
182+
[
183+
('{"first": 1}', SimpleItemWithOptionalFields, SimpleItemWithOptionalFields(first=1)),
184+
(
185+
'{"first": 1, "third": "Hello"}',
186+
SimpleItemWithOptionalFields,
187+
SimpleItemWithOptionalFields(first=1, third="Hello"),
188+
),
189+
('{"first": 1, "forth": 1.0}', SimpleItemWithOptionalFields, SimpleItemWithOptionalFields(first=1, forth=1.0)),
190+
],
191+
)
192+
def test_decode_simple_item_with_optional_field(expr: Any, type: Any, expected: str) -> None:
193+
assert from_json(expr, type) == expected
194+
195+
196+
@dataclass
197+
class SimpleItem1:
198+
d: int
199+
e: int
200+
f: int = 1
201+
202+
203+
@dataclass
204+
class ComplexItemWithUnionType:
205+
a_union_field: Union[SimpleItem, SimpleItem1]
206+
207+
208+
@pytest.mark.parametrize(
209+
("expr", "type", "expected"),
210+
[
211+
('{"a_union_field":{"a":1, "b":2}}', ComplexItemWithUnionType, ComplexItemWithUnionType(SimpleItem(1, 2))),
212+
('{"a_union_field":{"d":1, "e":2}}', ComplexItemWithUnionType, ComplexItemWithUnionType(SimpleItem1(1, 2))),
213+
(
214+
'{"a_union_field":{"d":1, "e":2, "f": 3}}',
215+
ComplexItemWithUnionType,
216+
ComplexItemWithUnionType(SimpleItem1(1, 2, 3)),
217+
),
218+
],
219+
)
220+
def test_decode_with_union_and_different_keys(expr: Any, type: Any, expected: str) -> None:
221+
assert from_json(expr, type) == expected
222+
223+
224+
@dataclass
225+
class SimpleItem2:
226+
a: int
227+
b: int
228+
c: int = 1
229+
230+
231+
@dataclass
232+
class ComplexItemWithUnionTypeWithSameProperties:
233+
a_union_field: Union[SimpleItem, SimpleItem2]
234+
235+
236+
def test_decode_with_union_and_some_same_keys() -> None:
237+
assert from_json(
238+
'{"a_union_field": {"a": 1, "b":2, "c":3}}', ComplexItemWithUnionTypeWithSameProperties
239+
) == ComplexItemWithUnionTypeWithSameProperties(SimpleItem2(1, 2, 3))
240+
241+
242+
def test_decode_with_union_and_same_keys_should_raise_typeerror() -> None:
243+
with pytest.raises(TypeError):
244+
from_json(
245+
'{"a_union_field": {"a": 1, "b":2}}', ComplexItemWithUnionTypeWithSameProperties
246+
) == ComplexItemWithUnionTypeWithSameProperties(SimpleItem2(1, 2, 3))
247+
248+
249+
def test_decode_with_union_and_no_keys_should_raise_typeerror() -> None:
250+
with pytest.raises(TypeError):
251+
from_json(
252+
'{"a_union_field": {}}', ComplexItemWithUnionTypeWithSameProperties
253+
) == ComplexItemWithUnionTypeWithSameProperties(SimpleItem2(1, 2, 3))
254+
255+
256+
def test_decode_with_union_and_no_match_should_raise_typeerror() -> None:
257+
with pytest.raises(TypeError):
258+
from_json(
259+
'{"a_union_field": {"x": 1, "y":2}}', ComplexItemWithUnionTypeWithSameProperties
260+
) == ComplexItemWithUnionTypeWithSameProperties(SimpleItem2(1, 2, 3))

0 commit comments

Comments
 (0)