diff --git a/tests/test_things.py b/tests/test_things.py index 3102689..01e8be2 100644 --- a/tests/test_things.py +++ b/tests/test_things.py @@ -93,7 +93,7 @@ def test_process_new(): assert todo._instance_creation_paused is False assert todo._projects == ["ABCd1ee0ykmXYZqT98huxa"] assert todo._areas == [] - assert todo._is_evening == 0 + assert todo._is_evening is False assert todo._tags == [] assert todo._type == Type.TASK assert todo._due_date_suppression_date is None diff --git a/tests/test_todo.py b/tests/test_todo.py index 3c6f849..7f43605 100644 --- a/tests/test_todo.py +++ b/tests/test_todo.py @@ -273,9 +273,14 @@ def test_cancel(): def test_today(): todo = TodoItem("test task") + assert todo.is_today is False + assert todo.is_evening is False todo.today() + assert todo.is_today is True + assert todo.is_evening is False assert todo.destination == Destination.ANYTIME assert todo.scheduled_date == Util.today() + assert todo._is_evening is False assert todo._today_index_reference_date == Util.today() assert todo.changes == { "_destination", @@ -287,11 +292,15 @@ def test_today(): def test_evening(): todo = TodoItem("test task") + assert todo.is_today is False + assert todo.is_evening is False todo.evening() + assert todo.is_today is True + assert todo.is_evening is True assert todo.destination == Destination.ANYTIME assert todo.scheduled_date == Util.today() assert todo._today_index_reference_date == Util.today() - assert todo._is_evening == 1 + assert todo._is_evening is True assert todo.changes == { "_destination", "_scheduled_date", @@ -353,7 +362,7 @@ def test_deserialize(): assert todo._instance_creation_paused is False assert todo._projects == ["ABCd1ee0ykmXYZqT98huxa"] assert todo._areas == [] - assert todo._is_evening == 0 + assert todo._is_evening is False assert todo._tags == [] assert todo._type == Type.TASK assert todo._due_date_suppression_date is None @@ -373,6 +382,7 @@ def test_deserialize(): assert todo._recurrence_rule is None assert todo._note == Note() assert not todo._changes + assert serialize_dict(todo) == api_object def test_update(): diff --git a/things_cloud/models/converters.py b/things_cloud/models/converters.py deleted file mode 100644 index aa4d338..0000000 --- a/things_cloud/models/converters.py +++ /dev/null @@ -1,20 +0,0 @@ -from typing import overload - - -@overload -def bool_int(bool_or_int: bool) -> int: # type: ignore[overload-overlap] - ... - - -@overload -def bool_int(bool_or_int: int) -> bool: - ... - - -def bool_int(bool_or_int: bool | int) -> int | bool: - if isinstance(bool_or_int, bool): - return int(bool_or_int) - else: - # bools are also ints in Python :'o - # so this has to be the else case - return bool(bool_or_int) diff --git a/things_cloud/models/serde.py b/things_cloud/models/serde.py index 70a07a1..27e3492 100644 --- a/things_cloud/models/serde.py +++ b/things_cloud/models/serde.py @@ -11,12 +11,10 @@ class Serde(ABC): type_serializers: dict[type, Callable] @abstractmethod - def serialize(self, v, *, default=None) -> str: - ... + def serialize(self, v, *, default=None) -> str: ... # noqa: E704 @abstractmethod - def deserialize(self, v) -> Any: - ... + def deserialize(self, v) -> Any: ... # noqa: E704 class JsonSerde(Serde): @@ -32,6 +30,7 @@ def dumps(v, *, default=None, indent: int | None = None) -> str: def prettydumps(v, *, default=None) -> str: return JsonSerde.dumps(v, default=default, indent=orjson.OPT_INDENT_2) + # @override # TODO def serialize(self, v, *, default=None) -> str: for key, value in v.items(): if serializer := self.field_serializers.get(key): @@ -41,8 +40,8 @@ def serialize(self, v, *, default=None) -> str: return JsonSerde.prettydumps(v, default=default) - @staticmethod - def deserialize(v: bytes | bytearray | str) -> Any: + # @override # TODO + def deserialize(self, v: bytes | bytearray | str) -> Any: return orjson.loads(v) diff --git a/things_cloud/models/todo.py b/things_cloud/models/todo.py index fd9e51c..7fa7284 100644 --- a/things_cloud/models/todo.py +++ b/things_cloud/models/todo.py @@ -1,16 +1,15 @@ from __future__ import annotations +from collections.abc import Callable from datetime import datetime, time, timezone from enum import Enum from typing import Any, Deque, ParamSpec, TypeVar -from collections.abc import Callable import cattrs from attrs import define, field from cattr.gen import make_dict_structure_fn from cattrs.gen import make_dict_unstructure_fn, override -from things_cloud.models.converters import bool_int from things_cloud.models.serde import TodoSerde from things_cloud.utils import Util @@ -81,7 +80,7 @@ class TodoItem: _instance_creation_paused: bool = field(default=False, kw_only=True) _projects: list[str] = field(factory=list, kw_only=True) _areas: list[str] = field(factory=list, kw_only=True) - _is_evening: bool = field(default=False, converter=bool_int, kw_only=True) + _is_evening: bool = field(default=False, kw_only=True) _tags: list[Any] = field(factory=list, kw_only=True) # TODO: set data type _type: Type = field(default=Type.TASK, kw_only=True) _due_date_suppression_date: datetime | None = field(default=None, kw_only=True) @@ -265,11 +264,20 @@ def reminder(self) -> time | None: def reminder(self, reminder: time | None) -> None: self._reminder = reminder + @property + def is_today(self) -> bool: + return ( + self.destination is Destination.ANYTIME + and self.scheduled_date == Util.today() + ) + + @property + def is_evening(self) -> bool: + return self.is_today and self._is_evening + @mod("_is_evening") def evening(self) -> None: - today = Util.today() - self.destination = Destination.ANYTIME - self.scheduled_date = today + self.today() self._is_evening = True @mod() @@ -309,7 +317,9 @@ def update(self, update: TodoItem, keys: set[str]) -> None: _instance_creation_paused=override(rename="icp"), _projects=override(rename="pr"), _areas=override(rename="ar"), - _is_evening=override(rename="sb"), + _is_evening=override( + rename="sb", struct_hook=lambda value, _: bool(value), unstruct_hook=int + ), _tags=override(rename="tg"), _type=override(rename="tp"), _due_date_suppression_date=override(rename="dds"),