"""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)