Skip to content

Commit

Permalink
Make global now/today/timeOfDay values json-serializable
Browse files Browse the repository at this point in the history
  • Loading branch information
m0rl committed Feb 10, 2024
1 parent 4540a65 commit 031583b
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 26 deletions.
6 changes: 3 additions & 3 deletions fhirpathpy/engine/invocations/datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,21 @@ 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


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


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
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
64 changes: 42 additions & 22 deletions tests/test_evaluators.py
Original file line number Diff line number Diff line change
@@ -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(
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -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(
Expand Down

0 comments on commit 031583b

Please sign in to comment.