Add methods to access examples faster

pull/623/head
Nicco Kunzmann 2024-06-07 17:10:35 +01:00
rodzic 2457f3646c
commit c9f425b25b
2 zmienionych plików z 54 dodań i 1 usunięć

Wyświetl plik

@ -3,6 +3,7 @@ files according to rfc2445.
These are the defined components.
"""
from __future__ import annotations
from datetime import datetime, timedelta
from icalendar.caselessdict import CaselessDict
from icalendar.parser import Contentline
@ -16,8 +17,21 @@ from icalendar.prop import vText, vDDDLists
from icalendar.timezone import tzp
from typing import Tuple, List
import dateutil.rrule, dateutil.tz
import os
def get_example(component_directory: str, example_name: str) -> bytes:
"""Return an example and raise an error if it is absent."""
here = os.path.dirname(__file__)
examples = os.path.join(here, "tests", component_directory)
if not example_name.endswith(".ics"):
example_name = example_name + ".ics"
example_file = os.path.join(examples, example_name)
if not os.path.isfile(example_file):
raise ValueError(f"Example {example_name} for {component_directory} not found. You can use one of {', '.join(os.listdir(examples))}")
with open(example_file, "rb") as f:
return f.read()
######################################
# The component factory
@ -492,6 +506,12 @@ class Event(Component):
)
ignore_exceptions = True
@classmethod
def example(cls, name) -> Event:
"""Return the calendar example with the given name."""
return cls.from_ical(get_example("events", name))
class Todo(Component):
@ -544,6 +564,11 @@ class Timezone(Component):
required = ('TZID',) # it also requires one of components DAYLIGHT and STANDARD
singletons = ('TZID', 'LAST-MODIFIED', 'TZURL',)
@classmethod
def example(cls, name) -> Calendar:
"""Return the calendar example with the given name."""
return cls.from_ical(get_example("timezones", name))
@staticmethod
def _extract_offsets(component, tzname):
"""extract offsets and transition times from a VTIMEZONE component
@ -728,6 +753,11 @@ class Calendar(Component):
required = ('PRODID', 'VERSION', )
singletons = ('PRODID', 'VERSION', 'CALSCALE', 'METHOD')
@classmethod
def example(cls, name) -> Calendar:
"""Return the calendar example with the given name."""
return cls.from_ical(get_example("calendars", name))
# These are read only singleton, so one instance is enough for the module
types_factory = TypesFactory()
component_factory = ComponentFactory()

Wyświetl plik

@ -1,7 +1,7 @@
'''tests ensuring that *the* way of doing things works'''
import datetime
from icalendar import Calendar, Event
from icalendar import Calendar, Event, Timezone
import pytest
@ -37,3 +37,26 @@ def test_creating_calendar_with_unicode_fields(calendars, utc):
cal.add_component(event2)
assert cal.to_ical() == calendars.created_calendar_with_unicode_fields.raw_ics
@pytest.mark.parametrize("component,example",
[
(Calendar, "example"),
(Calendar, "example.ics"),
(Event, "event_with_rsvp"),
(Timezone, "pacific_fiji"),
]
)
def test_component_has_examples(tzp, calendars, timezones, events, component, example):
"""Check that the examples function works."""
mapping = {Calendar: calendars, Event: events, Timezone: timezones}
example_component = component.example(example)
expected_component = mapping[component][example]
assert example_component == expected_component
def test_invalid_examples_lists_the_others():
"""We need a bit of guidance here."""
with pytest.raises(ValueError) as e:
Calendar.example("does not exist")
assert "example.ics" in str(e.value)