From f6972b53e15116d314cb9138004aa74e69ef4eb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20Matheson=20Wergeland?= Date: Wed, 10 Jul 2024 21:39:39 +0200 Subject: [PATCH] Parse datetime propeties - Add unit tests --- .github/workflows/python-publish.yaml | 2 ++ connectlife/appliance.py | 22 ++++++++++++++++++-- connectlife/tests/__init__.py | 0 connectlife/tests/test_appliance.py | 29 +++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 connectlife/tests/__init__.py create mode 100644 connectlife/tests/test_appliance.py diff --git a/.github/workflows/python-publish.yaml b/.github/workflows/python-publish.yaml index 194b1bf..201b3c8 100644 --- a/.github/workflows/python-publish.yaml +++ b/.github/workflows/python-publish.yaml @@ -13,6 +13,8 @@ jobs: uses: actions/setup-python@v5 with: python-version: "3.x" + - name: Run tests + run: python3 -m unittest - name: Install pypa/build run: >- python3 -m diff --git a/connectlife/appliance.py b/connectlife/appliance.py index 3be1af5..bef13d5 100644 --- a/connectlife/appliance.py +++ b/connectlife/appliance.py @@ -1,4 +1,5 @@ import datetime as dt +import re from enum import StrEnum from typing import Dict @@ -36,6 +37,10 @@ class DeviceType(StrEnum): } +RE_DATETIME = re.compile(r"^(\d{4,5})/(\d{2})/(\d{2})T(\d{2}):(\d{2}):(\d{2})$") +MAX_DATETIME = dt.datetime(dt.MAXYEAR, 12, 31, 23, 59, 59, tzinfo=dt.UTC) + + class ConnectLifeAppliance: """Class representing a single appliance.""" @@ -135,8 +140,21 @@ def device_type(self) -> DeviceType: return self._device_type -def convert(value: str) -> int | str: +def convert(value: str) -> int | str | dt.datetime: try: return int(value) except ValueError: - return value + pass + try: + # Unknown if timezone depends on property or appliance. Some properties include UTC in the name. + # Extreme values observed: + # "0002/11/30T00:00:00" (probably represents no value) + # "16679/02/18T23:47:45" (probably represents no value) + if match := RE_DATETIME.match(value): + (year, month, day, hour, minute, seconds) = map(int, match.groups()) + if year > dt.MAXYEAR: + return MAX_DATETIME + return dt.datetime(year, month, day, hour, minute, seconds, tzinfo=dt.UTC) + except ValueError: + pass + return value diff --git a/connectlife/tests/__init__.py b/connectlife/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/connectlife/tests/test_appliance.py b/connectlife/tests/test_appliance.py new file mode 100644 index 0000000..5511b04 --- /dev/null +++ b/connectlife/tests/test_appliance.py @@ -0,0 +1,29 @@ +import datetime as dt +import unittest + +from connectlife.appliance import convert + + +class TestAppliance(unittest.TestCase): + + def test_convert_int(self): + self.assertEqual(1, convert("1")) + self.assertEqual(0, convert("0")) + self.assertEqual(-1, convert("-1")) + + def test_convert_datetime(self): + self.assertEqual( + dt.datetime(2024, 9, 12, 21, 25, 33, tzinfo=dt.UTC), + convert("2024/09/12T21:25:33") + ) + self.assertEqual( + dt.datetime(2, 11, 30, 00, 00, 00, tzinfo=dt.UTC), + convert("0002/11/30T00:00:00") + ) + self.assertEqual( + dt.datetime(dt.MAXYEAR, 12, 31, 23, 59, 59, tzinfo=dt.UTC), + convert("16679/02/18T23:47:45") + ) + + def test_convert_str(self): + self.assertEqual("string", convert("string"))