From f259dc1334020ad8c78ad2c3749b8f2166064dfb Mon Sep 17 00:00:00 2001 From: Dieter Weber Date: Tue, 3 Sep 2024 12:15:29 +0200 Subject: [PATCH] Test of full desired functionality, make sure errors don't pass --- src/libertem_schema/__init__.py | 7 +- tests/test_schemas.py | 115 +++++++++++++++++++++++++++++--- 2 files changed, 108 insertions(+), 14 deletions(-) diff --git a/src/libertem_schema/__init__.py b/src/libertem_schema/__init__.py index 5378407..16d0c62 100644 --- a/src/libertem_schema/__init__.py +++ b/src/libertem_schema/__init__.py @@ -7,9 +7,6 @@ BaseModel, GetCoreSchemaHandler, GetJsonSchemaHandler, - ValidationError, - AfterValidator, - BeforeValidator, WrapValidator, ValidationInfo, ValidatorFunctionWrapHandler, @@ -82,6 +79,7 @@ def _make_handler(dimensionality: str): def is_matching( q: Any, handler: ValidatorFunctionWrapHandler, info: ValidationInfo ) -> pint.Quantity: + # Ensure target type if isinstance(q, pint.Quantity): pass elif isinstance(q, Sequence): @@ -90,9 +88,10 @@ def is_matching( q = m * ureg(u) else: raise ValueError(f"Don't know how to interpret type {type(q)}.") - + # Check dimension if not q.check(dimensionality): raise DimensionError(f"Expected dimensionality {dimensionality}, got quantity {q}.") + # Return target type return q return is_matching diff --git a/tests/test_schemas.py b/tests/test_schemas.py index 892e06b..15c785b 100644 --- a/tests/test_schemas.py +++ b/tests/test_schemas.py @@ -2,11 +2,11 @@ import pytest -from pint import UnitRegistry +from pint import UnitRegistry, Quantity from pydantic_core import from_json from pydantic import ValidationError -from libertem_schema import Simple4DSTEMParams, DimensionError +from libertem_schema import Simple4DSTEMParams ureg = UnitRegistry() @@ -17,32 +17,127 @@ def test_smoke(): scan_pixel_pitch=0.000001 * ureg.meter, camera_length=0.15 * ureg.meter, detector_pixel_pitch=0.000050 * ureg.meter, - semiconv=0.020 * ureg.radian, # rad + semiconv=0.020 * ureg.radian, scan_rotation=330. * ureg.degree, flip_y=False, - # Offset to avoid subchip gap in butted detectors cy=(32 - 2) * ureg.pixel, cx=(32 - 2) * ureg.pixel, ) as_json = params.model_dump_json() - print(as_json) + pprint.pprint(("as json", as_json)) from_j = from_json(as_json) - assert Simple4DSTEMParams.model_validate(from_j) + pprint.pprint(("from json", from_j)) + res = Simple4DSTEMParams.model_validate(from_j) + pprint.pprint(("validated", res)) + assert isinstance(res.overfocus, Quantity) + assert isinstance(res.flip_y, bool) + assert res == params + + +def test_missing(): + with pytest.raises(ValidationError): + Simple4DSTEMParams( + # Missing! + # overfocus=0.0015 * ureg.meter, + scan_pixel_pitch=0.000001 * ureg.meter, + camera_length=0.15 * ureg.meter, + detector_pixel_pitch=0.000050 * ureg.meter, + semiconv=0.020 * ureg.radian, + scan_rotation=330. * ureg.degree, + flip_y=False, + cy=(32 - 2) * ureg.pixel, + cx=(32 - 2) * ureg.pixel, + ) + + +def test_carrots(): + with pytest.raises(ValidationError): + Simple4DSTEMParams( + overfocus=0.0015, # carrots + scan_pixel_pitch=0.000001 * ureg.meter, + camera_length=0.15 * ureg.meter, + detector_pixel_pitch=0.000050 * ureg.meter, + semiconv=0.020 * ureg.radian, + scan_rotation=330. * ureg.degree, + flip_y=False, + cy=(32 - 2) * ureg.pixel, + cx=(32 - 2) * ureg.pixel, + ) def test_dimensionality(): with pytest.raises(ValidationError): Simple4DSTEMParams( - ### - overfocus=0.0015 * ureg.degree, # mismatch + # dimensionality mismatch! + overfocus=0.0015 * ureg.degree, ### scan_pixel_pitch=0.000001 * ureg.meter, camera_length=0.15 * ureg.meter, detector_pixel_pitch=0.000050 * ureg.meter, - semiconv=0.020 * ureg.radian, # rad + semiconv=0.020 * ureg.radian, scan_rotation=330. * ureg.degree, flip_y=False, - # Offset to avoid subchip gap in butted detectors cy=(32 - 2) * ureg.pixel, cx=(32 - 2) * ureg.pixel, ) + + +def test_json_1(): + params = Simple4DSTEMParams( + overfocus=0.0015 * ureg.meter, + scan_pixel_pitch=0.000001 * ureg.meter, + camera_length=0.15 * ureg.meter, + detector_pixel_pitch=0.000050 * ureg.meter, + semiconv=0.020 * ureg.radian, + scan_rotation=330. * ureg.degree, + flip_y=False, + cy=(32 - 2) * ureg.pixel, + cx=(32 - 2) * ureg.pixel, + ) + as_json = params.model_dump_json() + from_j = from_json(as_json) + # Mess up dimensionality + from_j['overfocus'][1] = 'degree' + with pytest.raises(ValidationError): + Simple4DSTEMParams.model_validate(from_j) + + +def test_json_2(): + params = Simple4DSTEMParams( + overfocus=0.0015 * ureg.meter, + scan_pixel_pitch=0.000001 * ureg.meter, + camera_length=0.15 * ureg.meter, + detector_pixel_pitch=0.000050 * ureg.meter, + semiconv=0.020 * ureg.radian, + scan_rotation=330. * ureg.degree, + flip_y=False, + cy=(32 - 2) * ureg.pixel, + cx=(32 - 2) * ureg.pixel, + ) + as_json = params.model_dump_json() + from_j = from_json(as_json) + # Mess up plain type representation of Quantity as (float, str) + from_j['overfocus'].append('hurz') + with pytest.raises(ValidationError): + Simple4DSTEMParams.model_validate(from_j) + + +def test_json_3(): + params = Simple4DSTEMParams( + overfocus=0.0015 * ureg.meter, + scan_pixel_pitch=0.000001 * ureg.meter, + camera_length=0.15 * ureg.meter, + detector_pixel_pitch=0.000050 * ureg.meter, + semiconv=0.020 * ureg.radian, + scan_rotation=330. * ureg.degree, + flip_y=False, + # Offset to avoid subchip gap in butted detectors + cy=(32 - 2) * ureg.pixel, + cx=(32 - 2) * ureg.pixel, + ) + as_json = params.model_dump_json() + from_j = from_json(as_json) + # Missing key + del from_j['overfocus'] + with pytest.raises(ValidationError): + Simple4DSTEMParams.model_validate(from_j)