From be68d10d7a94f11b70050ee848f0342890bdf0e4 Mon Sep 17 00:00:00 2001 From: Lyz Date: Sat, 20 Jul 2024 11:38:19 +0200 Subject: [PATCH] feat: initialise a Timestamp from a datetime object --- org_rw/org_rw.py | 49 +++++++++++++++--------- tests/test_timestamp.py | 84 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+), 18 deletions(-) create mode 100644 tests/test_timestamp.py diff --git a/org_rw/org_rw.py b/org_rw/org_rw.py index ff6d2b3..39fbef7 100644 --- a/org_rw/org_rw.py +++ b/org_rw/org_rw.py @@ -1033,34 +1033,47 @@ class Timestamp: def __init__( self, active: bool, - year: int, - month: int, - day: int, - dow: Optional[str], - hour: Optional[int], - minute: Optional[int], + year: Optional[int] = None, + month: Optional[int] = None, + day: Optional[int] = None, + dow: Optional[str] = None, + hour: Optional[int] = None, + minute: Optional[int] = None, repetition: Optional[str] = None, + datetime_: Optional[Union[date, datetime]] = None, ): """ Initializes a Timestamp instance. Args: active (bool): Whether the timestamp is active. - year (int): The year of the timestamp. - month (int): The month of the timestamp. - day (int): The day of the timestamp. + year (Optional[int]): The year of the timestamp. + month (Optional[int]): The month of the timestamp. + day (Optional[int]): The day of the timestamp. dow (Optional[str]): The day of the week, if any. hour (Optional[int]): The hour of the timestamp, if any. minute (Optional[int]): The minute of the timestamp, if any. repetition (Optional[str]): The repetition pattern, if any. + datetime_ (Optional[Union[date, datetime]]): A date or datetime object. + + Raises: + ValueError: If neither datetime_ nor the combination of year, month, and day are provided. """ self.active = active - self._year = year - self._month = month - self._day = day - self.dow = dow - self.hour = hour - self.minute = minute + + if datetime_ is not None: + self.from_datetime(datetime_) + elif year is not None and month is not None and day is not None: + self._year = year + self._month = month + self._day = day + self.dow = dow + self.hour = hour + self.minute = minute + else: + raise ValueError( + "Either datetime_ or year, month, and day must be provided." + ) self.repetition = repetition def to_datetime(self) -> datetime: @@ -1475,16 +1488,16 @@ class OrgTime: """ self.time.active = False - def set_datetime(self, dt: datetime) -> None: + def from_datetime(self, dt: datetime) -> None: """ Updates the timestamp to use the given datetime. Args: dt (datetime): The datetime to update the timestamp with. """ - self.time = Timestamp.from_datetime(dt) + self.time.from_datetime(dt) if self.end_time: - self.end_time = Timestamp.from_datetime(dt) + self.end_time.from_datetime(dt) def time_from_str(s: str) -> Optional[OrgTime]: diff --git a/tests/test_timestamp.py b/tests/test_timestamp.py new file mode 100644 index 0000000..14ceeac --- /dev/null +++ b/tests/test_timestamp.py @@ -0,0 +1,84 @@ +"""Test the Timestamp object.""" + +import pytest +from datetime import date, datetime +from org_rw import Timestamp + + +def test_init_with_datetime() -> None: + datetime_obj: datetime = datetime(2024, 7, 20, 15, 45) + + ts: Timestamp = Timestamp(active=True, datetime_=datetime_obj) + + assert ts.active is True + assert ts._year == 2024 + assert ts._month == 7 + assert ts._day == 20 + assert ts.hour == 15 + assert ts.minute == 45 + assert ts.dow is None + assert ts.repetition is None + + +def test_init_with_date() -> None: + date_obj: date = date(2024, 7, 20) + + ts: Timestamp = Timestamp(active=True, datetime_=date_obj) + + assert ts.active is True + assert ts._year == 2024 + assert ts._month == 7 + assert ts._day == 20 + assert ts.hour is None + assert ts.minute is None + assert ts.dow is None + assert ts.repetition is None + + +def test_init_with_year_month_day() -> None: + ts: Timestamp = Timestamp( + active=True, + year=2024, + month=7, + day=20, + hour=15, + minute=45, + dow="Saturday", + repetition="Weekly", + ) + + assert ts.active is True + assert ts._year == 2024 + assert ts._month == 7 + assert ts._day == 20 + assert ts.hour == 15 + assert ts.minute == 45 + assert ts.dow == "Saturday" + assert ts.repetition == "Weekly" + + +def test_init_without_required_arguments() -> None: + with pytest.raises(ValueError): + Timestamp(active=True) + + +def test_init_with_partial_date_info() -> None: + with pytest.raises(ValueError): + Timestamp(active=True, year=2024, month=7) + + +def test_init_with_datetime_overrides_date_info() -> None: + datetime_obj: datetime = datetime(2024, 7, 20, 15, 45) + + ts: Timestamp = Timestamp( + active=True, year=2020, month=1, day=1, datetime_=datetime_obj + ) + + assert ts.active is True + assert ts._year == 2024 + assert ts._month == 7 + assert ts._day == 20 + assert ts.hour == 15 + assert ts.minute == 45 + assert ts.dow is None + assert ts.repetition is None