229 lines
8.0 KiB
Python
229 lines
8.0 KiB
Python
"""Unit tests for CalendarParser."""
|
|
import pytest
|
|
from datetime import datetime, time
|
|
from src.parsers.calendar_parser import CalendarParser, Event
|
|
|
|
|
|
class TestCalendarParser:
|
|
"""Tests for CalendarParser class."""
|
|
|
|
def test_parse_event_with_time(self) -> None:
|
|
"""Test parsing an event with specific time."""
|
|
line = "2026-02-01 09:00 Team standup"
|
|
event = CalendarParser.parse_line(line)
|
|
|
|
assert event is not None
|
|
assert event.date == datetime(2026, 2, 1)
|
|
assert event.time == time(9, 0)
|
|
assert event.description == "Team standup"
|
|
assert event.all_day == False
|
|
|
|
def test_parse_all_day_event(self) -> None:
|
|
"""Test parsing an all-day event."""
|
|
line = "2026-02-15 Birthday party"
|
|
event = CalendarParser.parse_line(line)
|
|
|
|
assert event is not None
|
|
assert event.date == datetime(2026, 2, 15)
|
|
assert event.time is None
|
|
assert event.description == "Birthday party"
|
|
assert event.all_day == True
|
|
|
|
def test_parse_event_with_context(self) -> None:
|
|
"""Test parsing an event with context tags."""
|
|
line = "2026-02-01 14:30 Doctor appointment @personal"
|
|
event = CalendarParser.parse_line(line)
|
|
|
|
assert event is not None
|
|
assert "personal" in event.contexts
|
|
assert event.description == "Doctor appointment"
|
|
|
|
def test_parse_event_with_project(self) -> None:
|
|
"""Test parsing an event with project tags."""
|
|
line = "2026-02-05 10:00 Project kickoff +myorg-assistant"
|
|
event = CalendarParser.parse_line(line)
|
|
|
|
assert event is not None
|
|
assert "myorg-assistant" in event.projects
|
|
assert event.description == "Project kickoff"
|
|
|
|
def test_parse_event_with_multiple_tags(self) -> None:
|
|
"""Test parsing an event with multiple contexts and projects."""
|
|
line = "2026-02-10 15:00 Team meeting @telefon +work +team-sync"
|
|
event = CalendarParser.parse_line(line)
|
|
|
|
assert event is not None
|
|
assert "telefon" in event.contexts
|
|
assert "work" in event.projects
|
|
assert "team-sync" in event.projects
|
|
assert event.description == "Team meeting"
|
|
|
|
def test_parse_event_with_tags(self) -> None:
|
|
"""Test parsing an event with custom tags."""
|
|
line = "2026-02-20 18:00 Dinner location:restaurant duration:2h"
|
|
event = CalendarParser.parse_line(line)
|
|
|
|
assert event is not None
|
|
assert event.tags.get("location") == "restaurant"
|
|
assert event.tags.get("duration") == "2h"
|
|
|
|
def test_parse_empty_line(self) -> None:
|
|
"""Test parsing an empty line returns None."""
|
|
event = CalendarParser.parse_line("")
|
|
assert event is None
|
|
|
|
def test_parse_comment_line(self) -> None:
|
|
"""Test parsing a comment line returns None."""
|
|
event = CalendarParser.parse_line("# This is a comment")
|
|
assert event is None
|
|
|
|
def test_parse_invalid_format(self) -> None:
|
|
"""Test parsing invalid format returns None."""
|
|
event = CalendarParser.parse_line("Not a valid event format")
|
|
assert event is None
|
|
|
|
def test_format_event_with_time(self) -> None:
|
|
"""Test formatting an event with time."""
|
|
formatted = CalendarParser.format_event(
|
|
date=datetime(2026, 2, 1),
|
|
time=time(9, 0),
|
|
description="Team standup"
|
|
)
|
|
assert formatted == "2026-02-01 09:00 Team standup"
|
|
|
|
def test_format_all_day_event(self) -> None:
|
|
"""Test formatting an all-day event."""
|
|
formatted = CalendarParser.format_event(
|
|
date=datetime(2026, 2, 15),
|
|
description="Birthday party"
|
|
)
|
|
assert formatted == "2026-02-15 Birthday party"
|
|
|
|
def test_format_event_with_all_features(self) -> None:
|
|
"""Test formatting an event with all features."""
|
|
formatted = CalendarParser.format_event(
|
|
date=datetime(2026, 2, 10),
|
|
time=time(15, 0),
|
|
description="Team meeting",
|
|
contexts=["telefon"],
|
|
projects=["work"],
|
|
tags={"duration": "1h"}
|
|
)
|
|
assert "2026-02-10 15:00" in formatted
|
|
assert "Team meeting" in formatted
|
|
assert "@telefon" in formatted
|
|
assert "+work" in formatted
|
|
assert "duration:1h" in formatted
|
|
|
|
def test_parse_file(self) -> None:
|
|
"""Test parsing multiple events from file content."""
|
|
content = """# Calendar
|
|
2026-02-01 09:00 Morning meeting +work
|
|
2026-02-01 14:00 Afternoon appointment @personal
|
|
2026-02-15 Birthday party
|
|
|
|
2026-02-20 10:00 Project review +myorg-assistant"""
|
|
|
|
events = CalendarParser.parse_file(content)
|
|
assert len(events) == 4
|
|
# Events should be sorted by datetime
|
|
assert events[0].description == "Morning meeting"
|
|
assert events[1].description == "Afternoon appointment"
|
|
|
|
def test_filter_events_by_date_range(self) -> None:
|
|
"""Test filtering events by date range."""
|
|
events = [
|
|
Event(
|
|
raw_line="2026-02-01 Event 1",
|
|
line_number=1,
|
|
date=datetime(2026, 2, 1),
|
|
description="Event 1"
|
|
),
|
|
Event(
|
|
raw_line="2026-02-05 Event 2",
|
|
line_number=2,
|
|
date=datetime(2026, 2, 5),
|
|
description="Event 2"
|
|
),
|
|
Event(
|
|
raw_line="2026-02-10 Event 3",
|
|
line_number=3,
|
|
date=datetime(2026, 2, 10),
|
|
description="Event 3"
|
|
),
|
|
]
|
|
|
|
filtered = CalendarParser.filter_events(
|
|
events,
|
|
start_date=datetime(2026, 2, 3),
|
|
end_date=datetime(2026, 2, 8)
|
|
)
|
|
assert len(filtered) == 1
|
|
assert filtered[0].description == "Event 2"
|
|
|
|
def test_filter_events_by_context(self) -> None:
|
|
"""Test filtering events by context."""
|
|
events = [
|
|
Event(
|
|
raw_line="Event 1 @work",
|
|
line_number=1,
|
|
date=datetime(2026, 2, 1),
|
|
description="Event 1",
|
|
contexts=["work"]
|
|
),
|
|
Event(
|
|
raw_line="Event 2 @personal",
|
|
line_number=2,
|
|
date=datetime(2026, 2, 2),
|
|
description="Event 2",
|
|
contexts=["personal"]
|
|
),
|
|
]
|
|
|
|
work_events = CalendarParser.filter_events(events, context="work")
|
|
assert len(work_events) == 1
|
|
assert work_events[0].description == "Event 1"
|
|
|
|
def test_filter_events_by_project(self) -> None:
|
|
"""Test filtering events by project."""
|
|
events = [
|
|
Event(
|
|
raw_line="Event 1 +project1",
|
|
line_number=1,
|
|
date=datetime(2026, 2, 1),
|
|
description="Event 1",
|
|
projects=["project1"]
|
|
),
|
|
Event(
|
|
raw_line="Event 2 +project2",
|
|
line_number=2,
|
|
date=datetime(2026, 2, 2),
|
|
description="Event 2",
|
|
projects=["project2"]
|
|
),
|
|
]
|
|
|
|
project1_events = CalendarParser.filter_events(events, project="project1")
|
|
assert len(project1_events) == 1
|
|
assert project1_events[0].description == "Event 1"
|
|
|
|
def test_event_datetime_property(self) -> None:
|
|
"""Test the datetime property of Event."""
|
|
event = Event(
|
|
raw_line="2026-02-01 15:30 Meeting",
|
|
line_number=1,
|
|
date=datetime(2026, 2, 1),
|
|
time=time(15, 30),
|
|
description="Meeting"
|
|
)
|
|
assert event.datetime == datetime(2026, 2, 1, 15, 30)
|
|
|
|
all_day_event = Event(
|
|
raw_line="2026-02-01 Party",
|
|
line_number=1,
|
|
date=datetime(2026, 2, 1),
|
|
description="Party",
|
|
all_day=True
|
|
)
|
|
assert all_day_event.datetime == datetime(2026, 2, 1)
|