feat/improvements #1

Merged
kenkeiras merged 10 commits from lyz/org-rw:feat/improvements into develop 2024-07-29 14:17:18 +00:00
2 changed files with 115 additions and 18 deletions
Showing only changes of commit be68d10d7a - Show all commits

View File

@ -1033,34 +1033,47 @@ class Timestamp:
def __init__( def __init__(
self, self,
active: bool, active: bool,
year: int, year: Optional[int] = None,
month: int, month: Optional[int] = None,
day: int, day: Optional[int] = None,
dow: Optional[str], dow: Optional[str] = None,
hour: Optional[int], hour: Optional[int] = None,
minute: Optional[int], minute: Optional[int] = None,
repetition: Optional[str] = None, repetition: Optional[str] = None,
datetime_: Optional[Union[date, datetime]] = None,
): ):
""" """
Initializes a Timestamp instance. Initializes a Timestamp instance.
Args: Args:
active (bool): Whether the timestamp is active. active (bool): Whether the timestamp is active.
year (int): The year of the timestamp. year (Optional[int]): The year of the timestamp.
month (int): The month of the timestamp. month (Optional[int]): The month of the timestamp.
day (int): The day of the timestamp. day (Optional[int]): The day of the timestamp.
dow (Optional[str]): The day of the week, if any. dow (Optional[str]): The day of the week, if any.
hour (Optional[int]): The hour of the timestamp, if any. hour (Optional[int]): The hour of the timestamp, if any.
minute (Optional[int]): The minute of the timestamp, if any. minute (Optional[int]): The minute of the timestamp, if any.
repetition (Optional[str]): The repetition pattern, 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.active = active
self._year = year
self._month = month if datetime_ is not None:
self._day = day self.from_datetime(datetime_)
self.dow = dow elif year is not None and month is not None and day is not None:
self.hour = hour self._year = year
self.minute = minute 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 self.repetition = repetition
def to_datetime(self) -> datetime: def to_datetime(self) -> datetime:
@ -1475,16 +1488,16 @@ class OrgTime:
""" """
self.time.active = False 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. Updates the timestamp to use the given datetime.
Args: Args:
dt (datetime): The datetime to update the timestamp with. dt (datetime): The datetime to update the timestamp with.
""" """
self.time = Timestamp.from_datetime(dt) self.time.from_datetime(dt)
if self.end_time: 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]: def time_from_str(s: str) -> Optional[OrgTime]:

84
tests/test_timestamp.py Normal file
View File

@ -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",
kenkeiras marked this conversation as resolved Outdated

In practice, the repetition patterns are the ones for Org-mode, which you can see as part of BASE_TIME_STAMP_RE.

They generally match the regexp: (?P<repetition> (?P<rep_mark>(\+|\+\+|\.\+|-|--))(?P<rep_value>\d+)(?P<rep_unit>[hdwmy]))

For example:
+1d, ++1w or +.1m

See: https://orgmode.org/manual/Repeated-tasks.html

In practice, the repetition patterns are the ones for Org-mode, which you can see as part of `BASE_TIME_STAMP_RE`. They generally match the regexp: `(?P<repetition> (?P<rep_mark>(\+|\+\+|\.\+|-|--))(?P<rep_value>\d+)(?P<rep_unit>[hdwmy]))` For example: `+1d`, `++1w` or `+.1m` See: https://orgmode.org/manual/Repeated-tasks.html
Outdated
Review

Fixed at 191bb75

Fixed at 191bb75
)
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