from datetime import date from app.engine.recurrence import occurrences def test_monthly_clamps_short_months(): got = occurrences("monthly", 31, date(2026, 1, 1), date(2026, 3, 31)) assert got == [date(2026, 1, 31), date(2026, 2, 28), date(2026, 3, 31)] def test_quarterly_respects_item_bounds(): got = occurrences("quarterly", 15, date(2026, 1, 1), date(2026, 12, 31), item_start=date(2026, 4, 1), item_end=date(2026, 10, 31)) assert got == [date(2026, 4, 15), date(2026, 7, 15), date(2026, 10, 15)] def test_yearly(): got = occurrences("yearly", 1, date(2026, 1, 1), date(2028, 12, 31)) assert got == [date(2026, 1, 1), date(2027, 1, 1), date(2028, 1, 1)] def test_monthly_leap_year_clamping(): got = occurrences("monthly", 31, date(2028, 1, 1), date(2028, 3, 31)) assert got == [date(2028, 1, 31), date(2028, 2, 29), date(2028, 3, 31)] def test_quarterly_clamping(): got = occurrences("quarterly", 31, date(2026, 1, 1), date(2026, 12, 31)) assert got == [date(2026, 1, 31), date(2026, 4, 30), date(2026, 7, 31), date(2026, 10, 31)]