From 017750f1468846a8391e4f8095278f57023379d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Collonval?= Date: Wed, 13 Apr 2022 16:59:23 +0200 Subject: [PATCH] Fix JSON Encoder --- .github/workflows/python-package.yml | 5 +++++ beakerx_base/tests/__init__.py | 0 beakerx_base/tests/test_utils.py | 16 ++++++++++++++ beakerx_base/utils.py | 32 ++++++++++++++-------------- configuration.yml | 1 + 5 files changed, 38 insertions(+), 16 deletions(-) create mode 100644 beakerx_base/tests/__init__.py create mode 100644 beakerx_base/tests/test_utils.py diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index bce778c..f6793a1 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -31,6 +31,11 @@ jobs: shell: bash -l {0} run: | conda env create -n beakerx -f configuration.yml + - name: Test BeakerX Base + shell: bash -l {0} + run: | + conda activate beakerx + pytest - name: Build BeakerX Base shell: bash -l {0} run: | diff --git a/beakerx_base/tests/__init__.py b/beakerx_base/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/beakerx_base/tests/test_utils.py b/beakerx_base/tests/test_utils.py new file mode 100644 index 0000000..2740d2d --- /dev/null +++ b/beakerx_base/tests/test_utils.py @@ -0,0 +1,16 @@ +from email import utils +import json +from datetime import date, datetime + +import pytest +from pandas import Timestamp + +from ..utils import ObjectEncoder, date_to_int + +@pytest.mark.parametrize("obj,expected", ( + (date(2021, 10, 22), '{"type": "Date", "timestamp": 1634860800000}'), + (datetime(2021, 10, 22, 5, 38, 42), '{"type": "Date", "timestamp": 1634881122000}'), + (Timestamp(datetime(2021, 10, 22, 5, 38, 42)), '{"type": "Date", "timestamp": 1634881122000}'), +)) +def test_ObjectEncoder(obj, expected): + assert json.dumps(obj, cls=ObjectEncoder) == expected diff --git a/beakerx_base/utils.py b/beakerx_base/utils.py index 7f0e11c..8481611 100644 --- a/beakerx_base/utils.py +++ b/beakerx_base/utils.py @@ -15,7 +15,7 @@ import inspect import json import time -from datetime import datetime +from datetime import date, datetime from enum import Enum import numpy as np @@ -54,13 +54,13 @@ def datetime_to_number(value): def unix_time(dt): if isinstance(dt, Timestamp): - j_object = { - 'type': 'Date', - 'timestamp': pandas_timestamp_to_int(dt) - } - return j_object + timestamp = pandas_timestamp_to_int(dt) else: - return date_to_int(dt) + timestamp = date_to_int(str(dt)) + return { + 'type': 'Date', + 'timestamp': timestamp + } def date_time_2_millis(dt): @@ -187,18 +187,18 @@ def padYs(g, gMax): class ObjectEncoder(json.JSONEncoder): def default(self, obj): - if isinstance(obj, datetime): - return self.default(date_time_2_millis(obj)) + if isinstance(obj, (date, datetime)): + return date_time_2_millis(obj) elif isinstance(obj, Enum): - return self.default(obj.value) + return obj.value elif isinstance(obj, Color): - return self.default(obj.hex()) + return obj.hex() elif isinstance(obj, pd.Series): - return self.default(obj.tolist()) + return obj.tolist() elif isinstance(obj, np.ndarray): - return self.default(obj.tolist()) + return obj.tolist() elif isinstance(obj, (np.int64, np.bool_)): - return self.default(obj.item()) + return obj.item() elif hasattr(obj, "__dict__"): d = dict( (key, value) @@ -218,9 +218,9 @@ def default(self, obj): and not inspect.ismethoddescriptor(value) and not inspect.isroutine(value) ) - return self.default(d) - return obj + return d + return json.JSONEncoder.default(self, obj) class ColorUtils: @staticmethod diff --git a/configuration.yml b/configuration.yml index 26dfe6e..aef6e12 100644 --- a/configuration.yml +++ b/configuration.yml @@ -6,3 +6,4 @@ dependencies: - pandas - python=3.7.5 - pytz + - pytest