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>
227 lines
7.5 KiB
Python
227 lines
7.5 KiB
Python
"""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 |