diff --git a/fhirpathpy/engine/invocations/datetime.py b/fhirpathpy/engine/invocations/datetime.py index 592ea7d..758d587 100644 --- a/fhirpathpy/engine/invocations/datetime.py +++ b/fhirpathpy/engine/invocations/datetime.py @@ -10,7 +10,7 @@ def now(ctx, data): if not now.tzinfo: now = now.astimezone() isoStr = now.isoformat() # YYYY-MM-DDThh:mm:ss.ffffff+zz:zz - constants.now = FP_DateTime(isoStr) + constants.now = str(FP_DateTime(isoStr)) return constants.now @@ -18,7 +18,7 @@ def today(ctx, data): if not constants.today: now = datetime.now() isoStr = now.date().isoformat() # YYYY-MM-DD - constants.today = FP_DateTime(isoStr).getDateTimeMatchStr() + constants.today = str(FP_DateTime(isoStr)) return constants.today @@ -26,5 +26,5 @@ def timeOfDay(ctx, data): if not constants.timeOfDay: now = datetime.now() isoStr = now.time().isoformat() # hh:mm:ss.ffffff - constants.timeOfDay = FP_Time(isoStr) + constants.timeOfDay = str(FP_Time(isoStr)) return constants.timeOfDay diff --git a/pyproject.toml b/pyproject.toml index ee610bb..b7851fc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,7 +55,7 @@ classifiers = [ requires-python = ">=3.8" [project.optional-dependencies] -test = ["pytest==7.1.1", "freezegun==1.2.2", "pyyaml==5.4"] +test = ["pytest==7.1.1", "pyyaml==5.4"] [project.urls] Homepage = "https://github.com/beda-software/fhirpath-py" diff --git a/tests/test_evaluators.py b/tests/test_evaluators.py index 4b53090..37a60dc 100644 --- a/tests/test_evaluators.py +++ b/tests/test_evaluators.py @@ -1,10 +1,10 @@ -import datetime +import json +from datetime import datetime, UTC +from unittest import mock from decimal import Decimal import pytest -from freezegun import freeze_time from fhirpathpy import evaluate -from fhirpathpy.engine.invocations.constants import constants @pytest.mark.parametrize( @@ -62,7 +62,11 @@ def simple_logic_expressions_test(resource, path, expected): ({"a": 3}, "a.exp()", [Decimal(3).exp()]), ({"a": 3}, "a.ln()", [Decimal(3).ln()]), ({"a": 3}, "a.log(3)", [Decimal(3).ln() / Decimal(3).ln()]), - ({"a": 3}, "a.truncate()", [Decimal(3).to_integral_value(rounding="ROUND_DOWN")]), + ( + {"a": 3}, + "a.truncate()", + [Decimal(3).to_integral_value(rounding="ROUND_DOWN")], + ), ], ) def math_functions_test(resource, path, expected): @@ -199,28 +203,44 @@ def misc_functions_test(resource, path, expected): assert evaluate(resource, path) == expected -def time_functions_test(): - local_tz = datetime.datetime.now(datetime.timezone.utc).astimezone().tzinfo - - # tz_offset = datetime.timezone(datetime.timedelta(hours=2)) - with freeze_time( - lambda: datetime.datetime(year=2020, month=8, day=20, hour=17, minute=52, second=15) - ): - assert ( - datetime.datetime.fromisoformat(str(evaluate({}, "now()")[0])).timestamp() - == datetime.datetime.now().replace(tzinfo=local_tz).timestamp() - ) - assert evaluate({}, "today()") == ["2020-08-20"] - assert evaluate({}, "timeOfDay()") == ["17:52:15"] +@mock.patch("fhirpathpy.engine.invocations.datetime.datetime") +@pytest.mark.parametrize( + ("expression", "expected_json"), + [ + ("now()", '["2020-08-20T17:52:15.123+00:00"]'), + ("now() + 1 year", '["2021-08-20T17:52:15.123+00:00"]'), + ("now() + 1 month", '["2020-09-20T17:52:15.123+00:00"]'), + ("now() + 1 day", '["2020-08-21T17:52:15.123+00:00"]'), + ("now() + 1 hour", '["2020-08-20T18:52:15.123+00:00"]'), + ("now() + 1 minute", '["2020-08-20T17:53:15.123+00:00"]'), + ("now() + 1 second", '["2020-08-20T17:52:16.123+00:00"]'), + ("now().toString()", '["2020-08-20T17:52:15.123+00:00"]'), + ("timeOfDay()", '["17:52:15.123"]'), + ("today()", '["2020-08-20"]'), + ("today() + 1 day", '["2020-08-21"]'), + ], +) +def datetime_json_serialization_test( + datetime_mock: mock.MagicMock, expression: str, expected_json: str +): + datetime_mock.now.return_value = datetime( + 2020, 8, 20, 17, 52, 15, 123000, tzinfo=UTC + ) + assert json.dumps(evaluate({}, expression)) == expected_json -def now_function_test(): - with freeze_time(lambda: datetime.datetime(2020, 8, 20)) as frozen_datetime: - old_now_value = evaluate({}, "now()") - frozen_datetime.tick(1.0) - new_now_value = evaluate({}, "now()") +@mock.patch("fhirpathpy.engine.invocations.datetime.datetime") +def now_function_test(datetime_mock: mock.MagicMock): + datetime_mock.now.side_effect = [ + datetime(2020, 8, 20, 17, 52, 15, 123000, tzinfo=UTC), + datetime(2020, 8, 20, 17, 52, 16, 123000, tzinfo=UTC), + ] + old_now_value = evaluate({}, "now()") + new_now_value = evaluate({}, "now()") assert old_now_value != new_now_value + assert old_now_value == ["2020-08-20T17:52:15.123+00:00"] + assert new_now_value == ["2020-08-20T17:52:16.123+00:00"] @pytest.mark.parametrize(