from __future__ import annotations import json from dataclasses import dataclass from enum import Enum from typing import Optional, get_type_hints from megasniff import SchemaDeflatorGenerator from src.megasniff import SchemaInflatorGenerator def test_basic_constructor(): class A: def __init__(self, a: int): self.a = a infl = SchemaInflatorGenerator() fn = infl.schema_to_inflator(A) a = fn({'a': 42}) assert a.a == 42 def test_unions(): @dataclass class A: a: int | str infl = SchemaInflatorGenerator() fn = infl.schema_to_inflator(A) a = fn({'a': 42}) assert a.a == 42 a = fn({'a': '42'}) assert a.a == 42 a = fn({'a': '42a'}) assert a.a == '42a' @dataclass class CircA: b: CircB @dataclass class CircB: a: CircA | None def test_circular(): infl = SchemaInflatorGenerator() fn = infl.schema_to_inflator(CircA) a = fn({'b': {'a': None}}) assert isinstance(a.b, CircB) def test_optional(): @dataclass class C: a: Optional[int] = None infl = SchemaInflatorGenerator() fn = infl.schema_to_inflator(C) c = fn({}) assert c.a is None class AEnum(Enum): a = 'a' b = 'b' c = 42 e1 = {'a': 'b'} e2 = ['a', 'b'] @dataclass class Z: a: Optional[AEnum] = None def test_enum(): infl = SchemaInflatorGenerator() defl = SchemaDeflatorGenerator() infl_fn = infl.schema_to_inflator(Z) defl_fn = defl.schema_to_deflator(Z) for it in AEnum: ref = {'a': it.value} ref_str = json.dumps(ref) z = infl_fn(json.loads(ref_str)) assert z.a is not None assert z.a.value == it.value assert z.a.name == it.name zdict = defl_fn(z) assert len(zdict) == 1 assert zdict['a'] == it.value assert json.dumps(zdict) == ref_str assert infl_fn(zdict) == z