From 8e74823ebde9deebfbd711ba106e2650bde5058e Mon Sep 17 00:00:00 2001 From: Luke Carr Date: Mon, 16 Dec 2024 17:48:47 +0000 Subject: [PATCH 1/6] feat: validation for number of datetimes in `Temporal.interval` --- src/edr_pydantic/extent.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/edr_pydantic/extent.py b/src/edr_pydantic/extent.py index cb5dfd6..0ba9275 100644 --- a/src/edr_pydantic/extent.py +++ b/src/edr_pydantic/extent.py @@ -1,7 +1,9 @@ +from typing import Annotated from typing import List from typing import Optional from typing import Union +from annotated_types import Len from pydantic import AwareDatetime from .base_model import EdrBaseModel @@ -13,8 +15,7 @@ class Spatial(EdrBaseModel): class Temporal(EdrBaseModel): - # TODO: Validate this list has two items (C.7. Temporal Object) - interval: List[List[AwareDatetime]] + interval: List[Annotated[List[AwareDatetime], Len(min_length=2, max_length=2)]] # TODO: Validate this is a list of ISO 8601 single time, ISO 8601 time duration or ISO 8601 interval values: List[str] trs: str From 89a07252c5b8f8ee20fdb077a6a286b8a60c34fe Mon Sep 17 00:00:00 2001 From: Luke Carr Date: Wed, 18 Dec 2024 08:48:44 +0000 Subject: [PATCH 2/6] fix: py3.8 compatibility with import from `typing_extensions` --- src/edr_pydantic/extent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/edr_pydantic/extent.py b/src/edr_pydantic/extent.py index 0ba9275..c08d2f6 100644 --- a/src/edr_pydantic/extent.py +++ b/src/edr_pydantic/extent.py @@ -1,10 +1,10 @@ -from typing import Annotated from typing import List from typing import Optional from typing import Union from annotated_types import Len from pydantic import AwareDatetime +from typing_extensions import Annotated from .base_model import EdrBaseModel From df32b500d8773e1181d4f346dcbc43c8860b5c99 Mon Sep 17 00:00:00 2001 From: Luke Carr Date: Thu, 16 Jan 2025 11:57:28 +0000 Subject: [PATCH 3/6] test: added test case for invalid temporal interval --- tests/test_data/temporal-interval.json | 11 +++++++++++ tests/test_edr.py | 7 +++++-- 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 tests/test_data/temporal-interval.json diff --git a/tests/test_data/temporal-interval.json b/tests/test_data/temporal-interval.json new file mode 100644 index 0000000..ad26e8d --- /dev/null +++ b/tests/test_data/temporal-interval.json @@ -0,0 +1,11 @@ +{ + "interval": [ + [ + "2020-04-19T11:00:00Z" + ] + ], + "values": [ + "2020-04-19T11:00:00Z/2020-06-30T09:00:00Z" + ], + "trs": "TIMECRS[\"DateTime\",TDATUM[\"Gregorian Calendar\"],CS[TemporalDateTime,1],AXIS[\"Time (T)\",future]]" +} \ No newline at end of file diff --git a/tests/test_edr.py b/tests/test_edr.py index 7064a10..52c3ca0 100644 --- a/tests/test_edr.py +++ b/tests/test_edr.py @@ -6,7 +6,7 @@ from edr_pydantic.capabilities import LandingPageModel from edr_pydantic.collections import Collections from edr_pydantic.collections import Instance -from edr_pydantic.extent import Extent +from edr_pydantic.extent import Extent, Temporal from edr_pydantic.parameter import Parameter from edr_pydantic.unit import Unit from pydantic import RootModel @@ -35,7 +35,10 @@ def test_happy_cases(file_name, object_type): assert object_type.model_validate_json(json_string).model_dump_json(exclude_none=True) == json_string -error_cases = [("label-or-symbol-unit.json", Unit, r"Either 'label' or 'symbol' should be set")] +error_cases = [ + ("label-or-symbol-unit.json", Unit, r"Either 'label' or 'symbol' should be set"), + ("temporal-interval.json", Temporal, r"List should have at least 2 items after validation"), +] @pytest.mark.parametrize("file_name, object_type, error_message", error_cases) From 0c258fa9a981e940b7a740af56b5d97107bad885 Mon Sep 17 00:00:00 2001 From: Luke Carr Date: Thu, 16 Jan 2025 12:06:16 +0000 Subject: [PATCH 4/6] fix: reordered imports to satisfy pre-commit --- tests/test_edr.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_edr.py b/tests/test_edr.py index 52c3ca0..254a281 100644 --- a/tests/test_edr.py +++ b/tests/test_edr.py @@ -6,7 +6,8 @@ from edr_pydantic.capabilities import LandingPageModel from edr_pydantic.collections import Collections from edr_pydantic.collections import Instance -from edr_pydantic.extent import Extent, Temporal +from edr_pydantic.extent import Extent +from edr_pydantic.extent import Temporal from edr_pydantic.parameter import Parameter from edr_pydantic.unit import Unit from pydantic import RootModel From df71de4a37b478715372c6651bc31685f790aa05 Mon Sep 17 00:00:00 2001 From: Luke Carr Date: Thu, 16 Jan 2025 12:07:59 +0000 Subject: [PATCH 5/6] chore: added newline to end of test data file --- tests/test_data/temporal-interval.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_data/temporal-interval.json b/tests/test_data/temporal-interval.json index ad26e8d..9e823f6 100644 --- a/tests/test_data/temporal-interval.json +++ b/tests/test_data/temporal-interval.json @@ -8,4 +8,4 @@ "2020-04-19T11:00:00Z/2020-06-30T09:00:00Z" ], "trs": "TIMECRS[\"DateTime\",TDATUM[\"Gregorian Calendar\"],CS[TemporalDateTime,1],AXIS[\"Time (T)\",future]]" -} \ No newline at end of file +} From 60bd8081231627207c9abdbb7e414551784b952c Mon Sep 17 00:00:00 2001 From: Luke Carr Date: Thu, 16 Jan 2025 12:20:03 +0000 Subject: [PATCH 6/6] test: refactored temporal interval length for more precise unit testing --- src/edr_pydantic/extent.py | 5 ++++- tests/test_extent.py | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 tests/test_extent.py diff --git a/src/edr_pydantic/extent.py b/src/edr_pydantic/extent.py index c08d2f6..3381e7c 100644 --- a/src/edr_pydantic/extent.py +++ b/src/edr_pydantic/extent.py @@ -14,8 +14,11 @@ class Spatial(EdrBaseModel): crs: str +IntervalLen = Len(min_length=2, max_length=2) + + class Temporal(EdrBaseModel): - interval: List[Annotated[List[AwareDatetime], Len(min_length=2, max_length=2)]] + interval: List[Annotated[List[AwareDatetime], IntervalLen]] # TODO: Validate this is a list of ISO 8601 single time, ISO 8601 time duration or ISO 8601 interval values: List[str] trs: str diff --git a/tests/test_extent.py b/tests/test_extent.py new file mode 100644 index 0000000..c0663ea --- /dev/null +++ b/tests/test_extent.py @@ -0,0 +1,6 @@ +from edr_pydantic.extent import IntervalLen + + +def test_interval_len(): + assert IntervalLen.min_length == 2, "Temporal intervals must have at least 2 items" + assert IntervalLen.max_length == 2, "Temporal intervals must have at most 2 items"