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>
183 lines
6.1 KiB
Python
183 lines
6.1 KiB
Python
"""Tests for sun functionality."""
|
|
|
|
from datetime import datetime
|
|
from unittest.mock import Mock, patch
|
|
|
|
import pytest
|
|
|
|
from agenda.sun import bristol, sunrise, sunset
|
|
|
|
|
|
class TestBristol:
|
|
"""Test the bristol function."""
|
|
|
|
def test_bristol_returns_observer(self) -> None:
|
|
"""Test that bristol returns an ephem.Observer with correct coordinates."""
|
|
observer = bristol()
|
|
|
|
# Check that it's an observer object with the right attributes
|
|
assert hasattr(observer, 'lat')
|
|
assert hasattr(observer, 'lon')
|
|
|
|
# Check coordinates are set to Bristol
|
|
assert str(observer.lat) == "51:27:16.2" # 51.4545 degrees
|
|
assert str(observer.lon) == "-2:35:16.4" # -2.5879 degrees
|
|
|
|
def test_bristol_observer_type(self) -> None:
|
|
"""Test that bristol returns the correct type."""
|
|
observer = bristol()
|
|
|
|
# Should have methods needed for sun calculations
|
|
assert hasattr(observer, 'next_rising')
|
|
assert hasattr(observer, 'next_setting')
|
|
|
|
|
|
class TestSunrise:
|
|
"""Test the sunrise function."""
|
|
|
|
@patch('agenda.sun.ephem')
|
|
def test_sunrise_returns_datetime(self, mock_ephem: Mock) -> None:
|
|
"""Test that sunrise returns a datetime object."""
|
|
# Mock the observer and sun
|
|
mock_observer = Mock()
|
|
mock_sun = Mock()
|
|
mock_ephem.Sun.return_value = mock_sun
|
|
|
|
# Mock the rising calculation
|
|
mock_rising = Mock()
|
|
mock_rising.datetime.return_value = datetime(2024, 6, 15, 5, 30, 0)
|
|
mock_observer.next_rising.return_value = mock_rising
|
|
|
|
result = sunrise(mock_observer)
|
|
|
|
assert isinstance(result, datetime)
|
|
assert result == datetime(2024, 6, 15, 5, 30, 0)
|
|
|
|
# Verify ephem calls
|
|
mock_ephem.Sun.assert_called_once_with(mock_observer)
|
|
mock_observer.next_rising.assert_called_once_with(mock_sun)
|
|
|
|
def test_sunrise_with_real_observer(self) -> None:
|
|
"""Test sunrise with a real observer (integration test)."""
|
|
observer = bristol()
|
|
|
|
# Set a specific date for the observer
|
|
observer.date = "2024/6/21" # Summer solstice
|
|
|
|
result = sunrise(observer)
|
|
|
|
# Should return a datetime object
|
|
assert isinstance(result, datetime)
|
|
|
|
# On summer solstice in Bristol, sunrise should be early morning
|
|
assert 3 <= result.hour <= 6 # Roughly between 3-6 AM
|
|
|
|
# Should be in 2024
|
|
assert result.year == 2024
|
|
|
|
def test_sunrise_different_dates(self) -> None:
|
|
"""Test sunrise for different dates."""
|
|
observer = bristol()
|
|
|
|
# Summer solstice (longest day)
|
|
observer.date = "2024/6/21"
|
|
summer_sunrise = sunrise(observer)
|
|
|
|
# Winter solstice (shortest day)
|
|
observer.date = "2024/12/21"
|
|
winter_sunrise = sunrise(observer)
|
|
|
|
# Summer sunrise should be earlier than winter sunrise
|
|
assert summer_sunrise.hour < winter_sunrise.hour
|
|
|
|
|
|
class TestSunset:
|
|
"""Test the sunset function."""
|
|
|
|
@patch('agenda.sun.ephem')
|
|
def test_sunset_returns_datetime(self, mock_ephem: Mock) -> None:
|
|
"""Test that sunset returns a datetime object."""
|
|
# Mock the observer and sun
|
|
mock_observer = Mock()
|
|
mock_sun = Mock()
|
|
mock_ephem.Sun.return_value = mock_sun
|
|
|
|
# Mock the setting calculation
|
|
mock_setting = Mock()
|
|
mock_setting.datetime.return_value = datetime(2024, 6, 15, 20, 30, 0)
|
|
mock_observer.next_setting.return_value = mock_setting
|
|
|
|
result = sunset(mock_observer)
|
|
|
|
assert isinstance(result, datetime)
|
|
assert result == datetime(2024, 6, 15, 20, 30, 0)
|
|
|
|
# Verify ephem calls
|
|
mock_ephem.Sun.assert_called_once_with(mock_observer)
|
|
mock_observer.next_setting.assert_called_once_with(mock_sun)
|
|
|
|
def test_sunset_with_real_observer(self) -> None:
|
|
"""Test sunset with a real observer (integration test)."""
|
|
observer = bristol()
|
|
|
|
# Set a specific date for the observer
|
|
observer.date = "2024/6/21" # Summer solstice
|
|
|
|
result = sunset(observer)
|
|
|
|
# Should return a datetime object
|
|
assert isinstance(result, datetime)
|
|
|
|
# On summer solstice in Bristol, sunset should be in evening
|
|
assert 19 <= result.hour <= 22 # Roughly between 7-10 PM
|
|
|
|
# Should be in 2024
|
|
assert result.year == 2024
|
|
|
|
def test_sunset_different_dates(self) -> None:
|
|
"""Test sunset for different dates."""
|
|
observer = bristol()
|
|
|
|
# Summer solstice (longest day)
|
|
observer.date = "2024/6/21"
|
|
summer_sunset = sunset(observer)
|
|
|
|
# Winter solstice (shortest day)
|
|
observer.date = "2024/12/21"
|
|
winter_sunset = sunset(observer)
|
|
|
|
# Summer sunset should be later than winter sunset
|
|
assert summer_sunset.hour > winter_sunset.hour
|
|
|
|
|
|
class TestSunIntegration:
|
|
"""Integration tests for sun calculations."""
|
|
|
|
def test_day_length_summer_vs_winter(self) -> None:
|
|
"""Test that summer days are longer than winter days."""
|
|
observer = bristol()
|
|
|
|
# Summer solstice
|
|
observer.date = "2024/6/21"
|
|
summer_sunrise = sunrise(observer)
|
|
summer_sunset = sunset(observer)
|
|
summer_day_length = summer_sunset - summer_sunrise
|
|
|
|
# Winter solstice
|
|
observer.date = "2024/12/21"
|
|
winter_sunrise = sunrise(observer)
|
|
winter_sunset = sunset(observer)
|
|
winter_day_length = winter_sunset - winter_sunrise
|
|
|
|
# Summer day should be longer than winter day
|
|
assert summer_day_length > winter_day_length
|
|
|
|
def test_sunrise_before_sunset(self) -> None:
|
|
"""Test that sunrise is always before sunset."""
|
|
observer = bristol()
|
|
observer.date = "2024/6/15" # Arbitrary date
|
|
|
|
sunrise_time = sunrise(observer)
|
|
sunset_time = sunset(observer)
|
|
|
|
assert sunrise_time < sunset_time |