def test_optional(self): actual1 = JsonModel(DataclassWithOptional).load('{"x": 1}') expected1 = DataclassWithOptional(1) assert actual1 == expected1 actual2 = JsonModel(DataclassWithOptional).load('{"x": null}') expected2 = DataclassWithOptional(None) assert actual2 == expected2
def test_mutable_default_dict(self): expected = DataclassMutableDefaultDict() actual1 = JsonModel(DataclassMutableDefaultDict).load('{"xs": {}}') assert actual1 == expected actual2 = JsonModel(DataclassMutableDefaultDict, allow_missing=True).load('{}') assert actual2 == expected
def fetch(name: str) -> PypiPackage: response = requests.get(f'https://pypi.org/pypi/{name}/json') try: response.raise_for_status() except requests.exceptions.HTTPError as e: raise PypiError(name) from e package_json = response.text model = JsonModel(PypiPackage, allow_any=True, camel_case=False) return model.load(package_json)
class TestTime: def setup_class(self): self.model = JsonModel(Alarm) self.json = f'{{"at": "07:00:00", "enabled": true}}' self.dataclass = Alarm(time(7, 0, 0), enabled=True) def test_load(self): assert self.model.load(self.json) == self.dataclass def test_dump(self): assert self.model.dump(self.dataclass) == self.json
class TestDate: def setup_class(self): self.model = JsonModel(Event) self.json = f'{{"what": "Nobel Prize", "when": "1922-09-09"}}' self.dataclass = Event("Nobel Prize", date(1922, 9, 9)) def test_load(self): assert self.model.load(self.json) == self.dataclass def test_dump(self): assert self.model.dump(self.dataclass) == self.json
def test_optional_str(self): actual1 = JsonModel(DataclassWithOptionalStr).load('{"x": "1"}') expected1 = DataclassWithOptionalStr("1") assert actual1 == expected1 actual2 = JsonModel(DataclassWithOptionalStr).load('{"x": null}') expected2 = DataclassWithOptionalStr(None) assert actual2 == expected2 actual3 = JsonModel(DataclassWithOptionalStr, allow_missing=True).load('{}') expected3 = DataclassWithOptionalStr() assert actual3 == expected3
class TestTypes: def setup_class(self): self.uuid_s = 'd1d61dd7-c036-47d3-a6ed-91cc2e885fc8' self.dc_uuid_json = f'{{"id": "{self.uuid_s}"}}' self.uuid_model = JsonModel(DataclassWithUuid) def test_uuid_decode(self): actual = self.uuid_model.load(self.dc_uuid_json) assert actual == DataclassWithUuid(UUID(self.uuid_s)) def test_uuid_encode(self): actual = self.uuid_model.dump(DataclassWithUuid(UUID(self.uuid_s))) assert actual == self.dc_uuid_json
class TestDefaultDatetime: def setup_class(self): self.model = JsonModel(Post) dt = datetime(2018, 11, 17, 16, 55, 28, 456753, tzinfo=timezone.utc) iso = dt.isoformat() self.json = f'{{"createdAt": "{iso}"}}' self.dataclass = Post(datetime.fromisoformat(iso)) def test_load(self): assert self.model.load(self.json) == self.dataclass def test_dump(self): assert self.model.dump(self.dataclass) == self.json
def fetch_package(name: str, warehouse='https://pypi.org/pypi') -> Package: """Fetch a package from pypi.org by name. Provide a URL for other warehouse to use it instead of PyPI. """ response = requests.get(f'{warehouse}/{name}/json') try: response.raise_for_status() except requests.exceptions.HTTPError as e: raise PackageIndexError(name) from e package_json = response.text model = JsonModel(Package, camel_case=False) return model.load(package_json)
class TestTimestamp: def setup_class(self): self.model = JsonModel(TimestampDatetime) dt = datetime(2018, 11, 17, 16, 55, 28, 456753, tzinfo=timezone.utc) ts = dt.timestamp() self.json = f'{{"value": {ts}}}' self.dataclass = TimestampDatetime(Timestamp(dt)) def test_load(self): assert self.model.load(self.json) == self.dataclass def test_dump(self): assert self.model.dump(self.dataclass) == self.json
class TestDecoder: def setup_class(self): self.dcwdc = JsonModel(DataclassWithDataclass) self.dcxs = JsonModel(DataclassXs) def test_nested_dataclass(self): actual = self.dcwdc.load(json.dumps({"dc_with_list": {"xs": [1]}})) expected = DataclassWithDataclass(DataclassWithList([1])) assert actual == expected def test_nested_list_of_dataclasses(self): actual = self.dcxs.load(json.dumps({"xs": [{"x": 0}, {"x": 1}]})) expected = DataclassXs([DataclassX(0), DataclassX(1)]) assert actual == expected
def test_students_missing(self): s1_anon = Student(1, 'student') s2_anon = Student(2, 'student') one = [s1_anon, s2_anon] two = [s2_anon, s1_anon] actual = JsonModel(Student, allow_missing=True).load_many('[{"id": 1}, {"id": 2}]') assert actual == one or actual == two
class TestSerializer: def setup_class(self): serializers = field_serializers([UserIdSerializer]) self.model = JsonModel(User, serializers=serializers) def test_dump(self): actual = self.model.dump( User(id=UserId(0), username='******', password='******', age=None)) expected = '{"id": 0, "username": "******", "password": "******", "age": null}' assert actual == expected def test_load(self): actual = self.model.load( '{"id": 0, "username": "******", "password": "******", "age": null}') expected = User(id=UserId(0), username='******', password='******', age=None) assert actual == expected
class TestDefaults: def setup_class(self): self.model = JsonModel(User) def test_invalid_class(self): with pytest.raises(AssertionError): JsonModel(dict, serializers=[]) def test_load(self): user = self.model.load( '{"id": {"value": 0}, "username": "******", "password": "******", "age": null}' ) assert user == User(id=UserId(0), username='******', password='******', age=None) def test_load_many(self): expected = [ User(id=UserId(0), username='******', password='******', age=None), User(id=UserId(1), username='******', password='******', age=23) ] data = '[{"id": {"value": 0}, "username": "******", "password": "******", "age": null},' \ '{"id": {"value": 1}, "username": "******", "password": "******", "age": 23}]' actual = self.model.load_many(data) assert actual == expected def test_dump(self): user = User(id=UserId(0), username='******', password='******', age=None) d = self.model.dump(user) assert d == '{"id": {"value": 0}, "username": "******", "password": "******", "age": null}' def test_dump_many(self): user1 = User(id=UserId(0), username='******', password='******', age=None) user2 = User(id=UserId(1), username='******', password='******', age=23) expected = '[{"id": {"value": 0}, "username": "******", "password": "******", "age": null}, ' \ '{"id": {"value": 1}, "username": "******", "password": "******", "age": 23}]' actual = self.model.dump_many([user1, user2]) assert actual == expected
def test_tree_decode(self): assert JsonModel(Tree).load(self.json) == self.o
def test_professor(self): model = JsonModel(Professor) assert model.dump(self.p) == '{"id": 1, "name": "professor"}'
def test_course(self): model = JsonModel(Course) assert model.dump(self.c) == '{"id": 1, ' \ '"name": "course", ' \ '"professor": {"id": 1, "name": "professor"}, ' \ '"students": [{"id": 1, "name": "student"}]}'
def test_tree_encode(self): assert JsonModel(Tree, indent=4).dump(self.o) == self.json
def test_student(self): model = JsonModel(Student) assert model.dump(self.s1) == '{"id": 1, "name": "student"}'
def test_explicit_with_any(self): assert JsonModel(Something, allow_any=True) with pytest.raises(ModelContainsAny): assert JsonModel(Something, allow_any=False)
def test_json_skips_transformation(): model = JsonModel(Snack, camel_case=False) actual = model.dump(Snack(1, 2, 3, 4)) expected = '{"butterbeer": 1, "dragon_tartare": 2, "hogwarts_steak_and_kidney_pie_": 3, "_pumpkin__fizz": 4}' assert actual == expected
def setup_class(self): self.dcwdc = JsonModel(DataclassWithDataclass) self.dcxs = JsonModel(DataclassXs)
def setup_class(self): self.model = JsonModel(TimestampDatetime) dt = datetime(2018, 11, 17, 16, 55, 28, 456753, tzinfo=timezone.utc) ts = dt.timestamp() self.json = f'{{"value": {ts}}}' self.dataclass = TimestampDatetime(Timestamp(dt))
def setup_class(self): self.model = JsonModel(Post) dt = datetime(2018, 11, 17, 16, 55, 28, 456753, tzinfo=timezone.utc) iso = dt.isoformat() self.json = f'{{"createdAt": "{iso}"}}' self.dataclass = Post(datetime.fromisoformat(iso))
def test_json_transforms_case(): model = JsonModel(Snack, camel_case=True) actual = model.dump(Snack(1, 2, 3, 4)) expected = '{"butterbeer": 1, "dragonTartare": 2, "hogwartsSteakAndKidneyPie": 3, "pumpkinFizz": 4}' assert actual == expected
def setup_class(self): self.model = JsonModel(Event) self.json = f'{{"what": "Nobel Prize", "when": "1922-09-09"}}' self.dataclass = Event("Nobel Prize", date(1922, 9, 9))
def test_default(self): assert JsonModel(Thing) with pytest.raises(ModelContainsAny): JsonModel(Something)
def setup_class(self): self.model = JsonModel(Alarm) self.json = f'{{"at": "07:00:00", "enabled": true}}' self.dataclass = Alarm(time(7, 0, 0), enabled=True)
def test_explicit_without_any(self): assert JsonModel(Thing, allow_any=True) assert JsonModel(Thing, allow_any=False)
def test_list(self): assert JsonModel(DataclassWithList).dump(DataclassWithList([1])) == '{"xs": [1]}'