Skip to content

Commit

Permalink
Increase code coverage for journal by sharing as_rrule implementation (
Browse files Browse the repository at this point in the history
…#436)

* Increase code coverage for journal by sharing as_rrule implementation

* Update typing
  • Loading branch information
allenporter authored Sep 12, 2024
1 parent 8ead01a commit 00815f5
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 31 deletions.
13 changes: 2 additions & 11 deletions ical/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

from .alarm import Alarm
from .component import ComponentModel, validate_until_dtstart, validate_recurrence_dates
from .iter import RulesetIterable
from .iter import RulesetIterable, as_rrule
from .exceptions import CalendarParseError
from .parsing.property import ParsedProperty
from .timespan import Timespan
Expand Down Expand Up @@ -362,16 +362,7 @@ def as_rrule(self) -> Iterable[datetime.datetime | datetime.date] | None:
This is only valid for events where `recurring` is True.
"""
if not self.rrule and not self.rdate:
return None
if not self.start:
raise CalendarParseError("Event must have a start date to be recurring")
return RulesetIterable(
self.start,
[self.rrule.as_rrule(self.start)] if self.rrule else [],
self.rdate,
self.exdate,
)
return as_rrule(self.rrule, self.rdate, self.exdate, self.dtstart)

@root_validator(pre=True, allow_reuse=True)
def _inspect_date_types(cls, values: dict[str, Any]) -> dict[str, Any]:
Expand Down
28 changes: 28 additions & 0 deletions ical/iter.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@

from .timespan import Timespan
from .util import normalize_datetime
from .types.recur import Recur
from .exceptions import CalendarParseError

__all__ = [
"RecurrenceError",
Expand Down Expand Up @@ -401,3 +403,29 @@ def today(self) -> Iterator[T]:
def now(self, tz: datetime.tzinfo | None = None) -> Iterator[T]:
"""Return an iterator containing all events active on the specified day."""
return self.at_instant(datetime.datetime.now(tz=tz))


def as_rrule(
rrule: Recur | None,
rdate: list[datetime.datetime | datetime.date],
exdate: list[datetime.datetime | datetime.date],
start: datetime.datetime | datetime.date | None,
) -> Iterable[datetime.datetime | datetime.date] | None:
"""Return an iterable containing the occurrences of a recurring event.
A recurring event is typically evaluated specially on the timeline. The
data model has a single event, but the timeline evaluates the recurrence
to expand and copy the the event to multiple places on the timeline.
This is only valid for events where `recurring` is True.
"""
if not rrule and not rdate:
return None
if not start:
raise CalendarParseError("Event must have a start date to be recurring")
return RulesetIterable(
start,
[rrule.as_rrule(start)] if rrule else [],
rdate,
exdate,
)
13 changes: 2 additions & 11 deletions ical/journal.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
)
from .exceptions import CalendarParseError
from .util import dtstamp_factory, normalize_datetime, uid_factory, local_timezone
from .iter import RulesetIterable
from .iter import RulesetIterable, as_rrule
from .timespan import Timespan


Expand Down Expand Up @@ -156,16 +156,7 @@ def as_rrule(self) -> Iterable[datetime.datetime | datetime.date] | None:
This is only valid for events where `recurring` is True.
"""
if not self.rrule and not self.rdate:
return None
if not self.start:
raise CalendarParseError("Event must have a start date to be recurring")
return RulesetIterable(
self.start,
[self.rrule.as_rrule(self.start)] if self.rrule else [],
self.rdate,
[],
)
return as_rrule(self.rrule, self.rdate, self.exdate, self.dtstart)

_validate_until_dtstart = root_validator(allow_reuse=True)(validate_until_dtstart)
_validate_recurrence_dates = root_validator(allow_reuse=True)(
Expand Down
11 changes: 2 additions & 9 deletions ical/todo.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from .alarm import Alarm
from .component import ComponentModel, validate_until_dtstart, validate_recurrence_dates
from .exceptions import CalendarParseError
from .iter import RulesetIterable
from .iter import RulesetIterable, as_rrule
from .parsing.property import ParsedProperty
from .timespan import Timespan
from .types import (
Expand Down Expand Up @@ -279,16 +279,9 @@ def as_rrule(self) -> Iterable[datetime.datetime | datetime.date] | None:
"""
if not self.rrule and not self.rdate:
return None
if not self.start:
raise CalendarParseError("Event must have a start date to be recurring")
if not self.due:
raise CalendarParseError("Event must have a due date to be recurring")
return RulesetIterable(
self.start,
[self.rrule.as_rrule(self.start)] if self.rrule else [],
self.rdate,
self.exdate,
)
return as_rrule(self.rrule, self.rdate, self.exdate, self.dtstart)

@root_validator
def _validate_one_due_or_duration(cls, values: dict[str, Any]) -> dict[str, Any]:
Expand Down

0 comments on commit 00815f5

Please sign in to comment.