== Daily fast-forward from decades earlier == PASS daily since 1980 matches reference walk PASS daily since 1980 includes 2026-02-15 PASS daily since 1980 is fast (< 50ms) == Daily INTERVAL > 1 == PASS daily interval=13 since 1985 matches reference PASS daily interval=13 produced some occurrences == COUNT ending before the range == PASS COUNT=100 from 2020 yields nothing in 2026 == COUNT spanning into the range == PASS COUNT=20 remaining occurrences match reference PASS COUNT=20 gives exactly Feb 1-8 == Weekly fast-forward from decades earlier == PASS weekly MO since 2000 → Feb 2026 Mondays == Weekly multiple BYDAY == PASS weekly MO,TH since 2000 → Feb 1-14 2026 == Monthly fast-forward from decades earlier == PASS monthly 15th since 2000 → 2026 Q1 == Monthly invalid-date skipping (no clamping) == PASS BYMONTHDAY=31 skips Feb/Apr/Jun/Sep/Nov (2026) PASS BYMONTHDAY=30 skips February PASS BYMONTHDAY=29 occurs in a leap February (2024) PASS BYMONTHDAY=29 skips a non-leap February (2026) PASS BYMONTHDAY=-1 is the actual final day of each month PASS BYMONTHDAY=-2 resolves to the second-last day PASS BYMONTHDAY=0 is unsupported (only DTSTART kept) PASS MONTHLY COUNT=3 from the 31st → Jan31, Mar31, May31 PASS MONTHLY INTERVAL=2 from the 31st (2026) == Yearly February 29 (leap-only) == PASS yearly Feb 29 across 2024-2029 → only 2024 and 2028 PASS yearly Feb 29 absent in non-leap 2026 PASS yearly Feb 29 COUNT=3 → 2024, 2028, 2032 == Monthly INTERVAL multiple of 12 on Feb 29 (leap counting) == PASS INTERVAL=12 Feb 29 lands only on leap Februaries (2024-2044) PASS INTERVAL=12 Feb 29 matches the reference walker PASS INTERVAL=12;COUNT=2 yields 2024-02-29 and 2028-02-29 PASS INTERVAL=12;COUNT=2 fast-forwarded into 2028 returns 2028-02-29 PASS INTERVAL=12;COUNT=2 fast-forward matches the reference walker PASS INTERVAL=24 Feb 29 → 2024, 2028, 2032, 2036, 2040 PASS INTERVAL=24 Feb 29 matches the reference walker PASS INTERVAL=36 Feb 29 → only 2024 and 2036 (leap) in 2024-2040 PASS INTERVAL=36 Feb 29 matches the reference walker PASS INTERVAL=12;BYMONTHDAY=-29 matches the reference walker PASS INTERVAL=12;COUNT=1 exhausted before 2028 → nothing PASS INTERVAL=12;COUNT=3 into 2032 → 2032-02-29 only == Century leap-year rules == PASS 2096 is a leap year PASS 2100 is NOT a leap year (divisible by 100, not 400) PASS 2400 is a leap year (divisible by 400) PASS 2000 is a leap year, 1900 is not PASS INTERVAL=12 Feb 29 skips non-leap 2100 → 2096, 2104 (not 2100) == UNTIL around invalid monthly positions == PASS UNTIL before the next valid position stops after Jan 31 PASS UNTIL after Mar 31 keeps Jan 31 and Mar 31 (Feb skipped) == Monthly EXDATE / RDATE == PASS EXDATE removes the Mar 31 occurrence PASS RDATE adds an explicit Feb 15 occurrence == Monthly fast-forward matches reference walker == PASS monthly 31 since 1985 matches reference PASS monthly 29 since 1984 matches reference (leap handling) PASS monthly 31 COUNT=200 since 1985 matches reference == Weekly fast-forward matches reference walker (sweep) == PASS weekly sweep matches the reference walker (1080 configurations) == UNTIL in UTC and local time == PASS daily UNTIL (UTC) stops at 2026-02-05 PASS daily UNTIL (local) stops at 2026-02-05 in Sydney == EXDATE after fast-forward == PASS EXDATE removes 2026-02-09 Monday == RDATE after fast-forward == PASS RDATE adds 2026-02-11 == Global work budget == PASS exhausted budget throws too_large (not partial data) PASS shared budget across many events throws too_large == Regression: origin far more than 10,000 days before range == PASS origin is > 10,000 days before range PASS far-origin daily still produces the full month (not truncated) == Work-budget accounting == PASS weekly 7-BYDAY consumes >= 7 units for one week PASS weekly 7-BYDAY costs ~6 more candidates than 1-BYDAY PASS many weekly events exhaust a small budget → too_large PASS RDATE candidates consume budget PASS per-event occurrence cap throws too_large PASS no partial occurrence array is returned on cap PASS ordinary month view stays well below the default budget PASS one unit per candidate and none on append (5 in-range days → spent 5) == Iteration guard fails closed == PASS DAILY guard exhaustion throws too_large PASS DAILY guard exhaustion returns no partial array PASS WEEKLY guard exhaustion throws too_large PASS WEEKLY guard exhaustion returns no partial array PASS MONTHLY guard exhaustion (via invalid positions) throws too_large PASS MONTHLY guard exhaustion returns no partial array PASS YEARLY guard exhaustion (via non-leap Feb 29) throws too_large PASS YEARLY guard exhaustion returns no partial array PASS guard exhaustion with all candidates EXDATE-excluded still throws too_large PASS EXDATE-excluded guard exhaustion returns no partial (empty) array PASS COUNT termination does not trip the guard PASS UNTIL termination does not trip the guard PASS range-end termination does not trip the guard PASS ordinary month rendering stays far below the iteration guard (limit 200) PASS env-lowered occurrence cap throws too_large PASS env-lowered occurrence cap returns no partial array == Single preview expansion == PASS preview flow expands recurrences exactly once PASS legacy separate calls expand twice (control) PASS bucket+select on one expansion still yields events == Exact-boundary recurrence termination == == Exact-boundary: DAILY == PASS DAILY COUNT=2 with limit/budget=2 succeeds PASS DAILY COUNT=2 exact-limit spends exactly 2 PASS DAILY COUNT=0 consumes zero iterations/work (limit 0 does not throw) PASS DAILY COUNT=0 produces no RRULE occurrence PASS DAILY UNTIL allowing exactly 2 candidates succeeds with limit/budget=2 PASS DAILY range containing exactly 2 candidates succeeds with limit/budget=2 PASS DAILY: a third required candidate with limit/budget=2 throws too_large == Exact-boundary: WEEKLY == PASS WEEKLY one emitted week with iteration limit=1 succeeds PASS WEEKLY two emitted weeks with limit=2 succeed PASS WEEKLY COUNT ending on the final BYDAY candidate succeeds with exactly 1 iteration (no wasted next-week probe) PASS WEEKLY COUNT-terminated series spends exactly 2 work units PASS WEEKLY UNTIL ending on the final candidate succeeds with exactly 1 iteration (no wasted next-week probe) PASS WEEKLY one additional required week (limit 1, needs 2) throws too_large == Exact-boundary: MONTHLY == PASS MONTHLY one valid position with iteration limit=1 succeeds PASS MONTHLY COUNT=1 does not enter or charge a second month PASS MONTHLY COUNT=1 spends exactly 1 PASS MONTHLY invalid February position is charged once (Jan valid + Feb invalid = 2) PASS MONTHLY invalid February position produces only the Jan occurrence PASS MONTHLY Jan(valid)+Feb(invalid) succeeds at exact limit 2 PASS MONTHLY Jan(valid)+Feb(invalid) throws too_large one below limit PASS MONTHLY one additional required inspected month throws too_large == Exact-boundary: YEARLY == PASS YEARLY one valid position with limit=1 succeeds PASS YEARLY COUNT=1 does not charge the following year PASS YEARLY non-leap Feb 29 position is charged once (2024 valid + 2025 invalid = 2) PASS YEARLY non-leap Feb 29 range yields only the 2024 occurrence PASS YEARLY natural range completion does not require an extra iteration PASS YEARLY one additional inspected year (2025, invalid but must be checked) throws too_large == Exact-boundary: work-budget assertions == PASS spent() equals the actual candidate count under exact COUNT termination PASS spent() does not increase for a COUNT termination check PASS spent() does not increase for an UNTIL termination check PASS spent() does not increase for a range-end termination check PASS exact work budget succeeds PASS one unit below the required budget throws too_large PASS no partial array is returned on actual budget exhaustion All recurrence self-tests passed.