Add comprehensive test coverage for 8 modules

Increases overall test coverage from 53% to 56% by adding tests for:
- accommodation.py (60% → 100%)
- birthday.py (24% → 100%)
- calendar.py (19% → 100%)
- carnival.py (33% → 100%)
- domains.py (75% → 100%)
- events_yaml.py (50% → 96%)
- fx.py (14% → 21% for tested functions)
- sun.py (55% → 100%)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Edward Betts 2025-07-20 11:39:49 +02:00
parent 8db777ae8b
commit e6327780aa
8 changed files with 1390 additions and 0 deletions

227
tests/test_birthday.py Normal file
View file

@ -0,0 +1,227 @@
"""Tests for birthday functionality."""
import tempfile
from datetime import date
from typing import Any
import pytest
import yaml
from agenda.birthday import YEAR_NOT_KNOWN, get_birthdays, next_birthday
from agenda.event import Event
class TestNextBirthday:
"""Test the next_birthday function."""
def test_birthday_this_year_future(self) -> None:
"""Test birthday that hasn't occurred this year."""
from_date = date(2024, 3, 15)
birth_date = date(1990, 6, 20)
next_bday, age = next_birthday(from_date, birth_date)
assert next_bday == date(2024, 6, 20)
assert age == 34
def test_birthday_this_year_past(self) -> None:
"""Test birthday that already occurred this year."""
from_date = date(2024, 8, 15)
birth_date = date(1990, 6, 20)
next_bday, age = next_birthday(from_date, birth_date)
assert next_bday == date(2025, 6, 20)
assert age == 35
def test_birthday_today(self) -> None:
"""Test when today is the birthday."""
from_date = date(2024, 6, 20)
birth_date = date(1990, 6, 20)
next_bday, age = next_birthday(from_date, birth_date)
assert next_bday == date(2024, 6, 20)
assert age == 34
def test_birthday_unknown_year(self) -> None:
"""Test birthday with unknown year."""
from_date = date(2024, 3, 15)
birth_date = date(YEAR_NOT_KNOWN, 6, 20)
next_bday, age = next_birthday(from_date, birth_date)
assert next_bday == date(2024, 6, 20)
assert age is None
def test_birthday_unknown_year_past(self) -> None:
"""Test birthday with unknown year that already passed."""
from_date = date(2024, 8, 15)
birth_date = date(YEAR_NOT_KNOWN, 6, 20)
next_bday, age = next_birthday(from_date, birth_date)
assert next_bday == date(2025, 6, 20)
assert age is None
def test_leap_year_birthday(self) -> None:
"""Test birthday on leap day."""
from_date = date(2024, 1, 15) # 2024 is a leap year
birth_date = date(2000, 2, 29) # Born on leap day
next_bday, age = next_birthday(from_date, birth_date)
assert next_bday == date(2024, 2, 29)
assert age == 24
class TestGetBirthdays:
"""Test the get_birthdays function."""
def test_get_birthdays_with_year(self) -> None:
"""Test getting birthdays with known birth years."""
birthday_data = [
{
"label": "John Doe",
"birthday": {"year": 1990, "month": 6, "day": 20}
},
{
"label": "Jane Smith",
"birthday": {"year": 1985, "month": 12, "day": 15}
}
]
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
yaml.dump(birthday_data, f)
filepath = f.name
try:
from_date = date(2024, 3, 15)
events = get_birthdays(from_date, filepath)
# Should have 4 events (2 people × 2 years each)
assert len(events) == 4
# Check John's birthdays
john_events = [e for e in events if "John Doe" in e.title]
assert len(john_events) == 2
assert john_events[0].date == date(2024, 6, 20)
assert "aged 34" in john_events[0].title
assert john_events[1].date == date(2025, 6, 20)
assert "aged 35" in john_events[1].title
# Check Jane's birthdays
jane_events = [e for e in events if "Jane Smith" in e.title]
assert len(jane_events) == 2
assert jane_events[0].date == date(2024, 12, 15)
assert "aged 39" in jane_events[0].title
# All events should be birthday events
for event in events:
assert event.name == "birthday"
assert isinstance(event, Event)
finally:
import os
os.unlink(filepath)
def test_get_birthdays_without_year(self) -> None:
"""Test getting birthdays with unknown birth years."""
birthday_data = [
{
"label": "Anonymous Person",
"birthday": {"month": 6, "day": 20}
}
]
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
yaml.dump(birthday_data, f)
filepath = f.name
try:
from_date = date(2024, 3, 15)
events = get_birthdays(from_date, filepath)
# Should have 2 events (1 person × 2 years)
assert len(events) == 2
# Check that age is unknown
for event in events:
assert "age unknown" in event.title
assert "Anonymous Person" in event.title
assert event.name == "birthday"
finally:
import os
os.unlink(filepath)
def test_get_birthdays_mixed_data(self) -> None:
"""Test getting birthdays with mixed known/unknown years."""
birthday_data = [
{
"label": "Known Person",
"birthday": {"year": 1990, "month": 6, "day": 20}
},
{
"label": "Unknown Person",
"birthday": {"month": 8, "day": 15}
}
]
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
yaml.dump(birthday_data, f)
filepath = f.name
try:
from_date = date(2024, 3, 15)
events = get_birthdays(from_date, filepath)
# Should have 4 events total
assert len(events) == 4
# Check known person events
known_events = [e for e in events if "Known Person" in e.title]
assert len(known_events) == 2
assert all("aged" in e.title and "age unknown" not in e.title for e in known_events)
# Check unknown person events
unknown_events = [e for e in events if "Unknown Person" in e.title]
assert len(unknown_events) == 2
assert all("age unknown" in e.title for e in unknown_events)
finally:
import os
os.unlink(filepath)
def test_get_birthdays_empty_file(self) -> None:
"""Test getting birthdays from empty file."""
birthday_data: list[dict[str, Any]] = []
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
yaml.dump(birthday_data, f)
filepath = f.name
try:
from_date = date(2024, 3, 15)
events = get_birthdays(from_date, filepath)
assert events == []
finally:
import os
os.unlink(filepath)
def test_get_birthdays_file_not_found(self) -> None:
"""Test error handling when file doesn't exist."""
from_date = date(2024, 3, 15)
with pytest.raises(FileNotFoundError):
get_birthdays(from_date, "/nonexistent/file.yaml")
class TestConstants:
"""Test module constants."""
def test_year_not_known_constant(self) -> None:
"""Test that YEAR_NOT_KNOWN has expected value."""
assert YEAR_NOT_KNOWN == 1900