grant-radar / tests /utils /test_dates.py
Riley Coleman
feat: add PDF & supporting materials integration to context
bfcc872
Raw
History Blame Contribute Delete
5.93 kB
"""
Tests for src/analyzer/utils/dates.py
Tests cover:
- parse_date(): parsing common date formats
- format_date(): formatting dates for display
"""
import pytest
from datetime import datetime
from src.analyzer.utils.dates import parse_date, format_date
class TestParseDate:
"""Test parse_date() function for flexible date parsing."""
def test_parse_date_iso_with_time(self):
result = parse_date("2024-12-31T23:59:59")
assert result == datetime(2024, 12, 31, 23, 59, 59)
def test_parse_date_iso_date_only(self):
result = parse_date("2024-12-31")
assert result == datetime(2024, 12, 31)
def test_parse_date_uk_format(self):
result = parse_date("31/12/2024")
assert result == datetime(2024, 12, 31)
def test_parse_date_already_datetime(self):
dt = datetime(2024, 12, 31)
result = parse_date(dt)
assert result == dt
def test_parse_date_none(self):
assert parse_date(None) is None
def test_parse_date_empty_string(self):
assert parse_date("") is None
def test_parse_date_invalid(self):
assert parse_date("not a date") is None
def test_parse_date_partial_iso(self):
# Should handle truncated ISO format
result = parse_date("2024-12-31T23:59:59.123456")
assert result == datetime(2024, 12, 31, 23, 59, 59)
def test_parse_date_with_timezone(self):
# Should parse up to the format length
result = parse_date("2024-12-31T23:59:59Z")
assert result == datetime(2024, 12, 31, 23, 59, 59)
class TestFormatDate:
"""Test format_date() function for date formatting."""
def test_format_date_date_only(self):
result = format_date("2024-12-31")
assert result == "2024-12-31"
def test_format_date_with_time(self):
result = format_date("2024-12-31T14:30:00")
assert result == "2024-12-31 14:30:00"
def test_format_date_midnight(self):
# Midnight (00:00:00) should show date only
result = format_date("2024-12-31T00:00:00")
assert result == "2024-12-31"
def test_format_date_explicit_include_time(self):
result = format_date("2024-12-31", include_time=True)
assert result == "2024-12-31 00:00:00"
def test_format_date_none(self):
result = format_date(None)
assert result == "—"
def test_format_date_empty_string(self):
result = format_date("")
assert result == "—"
def test_format_date_invalid(self):
result = format_date("not a date")
assert result == "not a date"
def test_format_date_datetime_object(self):
dt = datetime(2024, 12, 31, 14, 30, 0)
result = format_date(dt)
assert result == "2024-12-31 14:30:00"
def test_format_date_uk_format_input(self):
result = format_date("31/12/2024")
assert result == "2024-12-31"
class TestDateRoundTrip:
"""Test parsing and formatting work together correctly."""
def test_roundtrip_date_only(self):
original = "2024-12-31"
parsed = parse_date(original)
formatted = format_date(parsed)
assert formatted == original
def test_roundtrip_with_time(self):
original = "2024-12-31T14:30:00"
parsed = parse_date(original)
formatted = format_date(parsed)
assert formatted == "2024-12-31 14:30:00"
def test_roundtrip_uk_format(self):
original = "31/12/2024"
parsed = parse_date(original)
formatted = format_date(parsed)
# UK format should convert to ISO format
assert formatted == "2024-12-31"
class TestEdgeCases:
"""Test edge cases and corner scenarios."""
def test_parse_date_leap_year(self):
result = parse_date("2024-02-29")
assert result == datetime(2024, 2, 29)
def test_parse_date_year_boundaries(self):
# Test year start and end
assert parse_date("2024-01-01") == datetime(2024, 1, 1)
assert parse_date("2024-12-31") == datetime(2024, 12, 31)
def test_format_date_preserves_seconds(self):
result = format_date("2024-12-31T23:59:59")
assert "59:59" in result
def test_parse_date_with_extra_text(self):
# Should handle ISO string with extra characters after
result = parse_date("2024-12-31 (deadline)")
# First 10 chars match date format
assert result == datetime(2024, 12, 31)
def test_format_date_with_microseconds(self):
# Datetime with microseconds should format cleanly
dt = datetime(2024, 12, 31, 14, 30, 0, 123456)
result = format_date(dt)
assert result == "2024-12-31 14:30:00"
class TestIntegrationWithChatTools:
"""Test compatibility with existing chat_tools.py usage."""
def test_deadline_sorting_compatible(self):
"""Ensure parse_date works for deadline sorting logic."""
dates = [
"2024-12-31",
"2024-01-15",
"2024-06-30",
None,
"",
]
# Should be able to parse all dates for sorting
parsed = [parse_date(d) for d in dates]
# None values should be handled
assert parsed[-2] is None
assert parsed[-1] is None
# Valid dates should be in order
valid_dates = [p for p in parsed if p is not None]
assert len(valid_dates) == 3
def test_format_date_for_display(self):
"""Ensure format_date produces user-friendly output."""
# Common patterns from grant data
test_cases = [
("2024-12-31", "2024-12-31"),
("2024-12-31T23:59:59", "2024-12-31 23:59:59"),
(None, "—"),
("", "—"),
]
for input_val, expected in test_cases:
result = format_date(input_val)
assert result == expected
if __name__ == "__main__":
pytest.main([__file__, "-v"])