Functional Weave
Code in Python

todo.next-occurrence@1.0.0

vectors.json

4,785 bytes · view raw

[
  {"name": "monthly from 31 January: February's due date is clamped to the 28th", "args": [{"frequency": "monthly", "interval": 1, "anchor": "2026-01-31"}, "2026-01-31", "2026-01-31"], "expect": "2026-02-28"},
  {"name": "monthly from 31 January, done on 28 February: back to the 31st, not the 28th", "args": [{"frequency": "monthly", "interval": 1, "anchor": "2026-01-31"}, "2026-02-28", "2026-02-28"], "expect": "2026-03-31"},
  {"name": "monthly from 31 January in a leap year: 29 February", "args": [{"frequency": "monthly", "interval": 1, "anchor": "2028-01-31"}, "2028-01-31", "2028-01-31"], "expect": "2028-02-29"},
  {"name": "quarterly from 31 January, done on 30 April: 31 July", "args": [{"frequency": "monthly", "interval": 3, "anchor": "2026-01-31"}, "2026-04-30", "2026-04-30"], "expect": "2026-07-31"},
  {"name": "yearly on 29 February falls on 28 February in an ordinary year", "args": [{"frequency": "yearly", "interval": 1, "anchor": "2024-02-29"}, "2024-02-29", "2024-02-29"], "expect": "2025-02-28"},
  {"name": "yearly on 29 February returns to the 29th in the next leap year", "args": [{"frequency": "yearly", "interval": 1, "anchor": "2024-02-29"}, "2027-02-28", "2027-02-28"], "expect": "2028-02-29"},
  {"name": "yearly on New Year's Eve crosses into the next year", "args": [{"frequency": "yearly", "interval": 1, "anchor": "2026-12-31"}, "2026-12-31", "2026-12-31"], "expect": "2027-12-31"},
  {"name": "daily, done on the day: tomorrow", "args": [{"frequency": "daily", "interval": 1, "anchor": "2026-09-28"}, "2026-09-28", "2026-09-28"], "expect": "2026-09-29"},
  {"name": "daily, done eight days late: tomorrow, the missed days are skipped", "args": [{"frequency": "daily", "interval": 1, "anchor": "2026-09-20"}, "2026-09-20", "2026-09-28"], "expect": "2026-09-29"},
  {"name": "every 3 days from the 20th, done on the 28th: the 29th (20, 23, 26, 29)", "args": [{"frequency": "daily", "interval": 3, "anchor": "2026-09-20"}, "2026-09-20", "2026-09-28"], "expect": "2026-09-29"},
  {"name": "every 3 days from the 20th, done on the 29th itself: 2 October", "args": [{"frequency": "daily", "interval": 3, "anchor": "2026-09-20"}, "2026-09-26", "2026-09-29"], "expect": "2026-10-02"},
  {"name": "monthly bill due 1 October paid early on 28 September: 1 November", "args": [{"frequency": "monthly", "interval": 1, "anchor": "2026-10-01"}, "2026-10-01", "2026-09-28"], "expect": "2026-11-01"},
  {"name": "every other week from Monday 7 September, done on 21 September: 5 October", "args": [{"frequency": "weekly", "interval": 2, "anchor": "2026-09-07"}, "2026-09-21", "2026-09-21"], "expect": "2026-10-05"},
  {"name": "weekly, done three days late: the next one after today, a week after the missed one", "args": [{"frequency": "weekly", "interval": 1, "anchor": "2026-09-21"}, "2026-09-21", "2026-09-24"], "expect": "2026-09-28"},
  {"name": "weekdays, done on Friday 2 October: Monday 5 October", "args": [{"frequency": "weekdays", "interval": 1, "anchor": "2026-09-28"}, "2026-10-02", "2026-10-02"], "expect": "2026-10-05"},
  {"name": "weekdays, due Saturday: Monday", "args": [{"frequency": "weekdays", "interval": 1, "anchor": "2026-09-28"}, "2026-10-03", "2026-10-03"], "expect": "2026-10-05"},
  {"name": "weekdays, due Monday done Wednesday: Thursday", "args": [{"frequency": "weekdays", "interval": 1, "anchor": "2026-09-28"}, "2026-09-28", "2026-09-30"], "expect": "2026-10-01"},
  {"name": "an interval of 0", "args": [{"frequency": "daily", "interval": 0, "anchor": "2026-09-28"}, "2026-09-28", "2026-09-28"], "expectError": "repeat interval must be 1 or more"},
  {"name": "a fractional interval", "args": [{"frequency": "daily", "interval": 1.5, "anchor": "2026-09-28"}, "2026-09-28", "2026-09-28"], "expectError": "repeat interval must be 1 or more"},
  {"name": "weekdays every other week", "args": [{"frequency": "weekdays", "interval": 2, "anchor": "2026-09-28"}, "2026-09-28", "2026-09-28"], "expectError": "weekday repeats cannot skip weeks"},
  {"name": "an unknown frequency", "args": [{"frequency": "hourly", "interval": 1, "anchor": "2026-09-28"}, "2026-09-28", "2026-09-28"], "expectError": "unknown repeat frequency \"hourly\""},
  {"name": "a due date that never existed", "args": [{"frequency": "daily", "interval": 1, "anchor": "2026-02-01"}, "2026-02-30", "2026-02-01"], "expectError": "is not a real calendar date"},
  {"name": "today in the wrong format", "args": [{"frequency": "daily", "interval": 1, "anchor": "2026-09-28"}, "2026-09-28", "28/09/2026"], "expectError": "is not an ISO date"},
  {"name": "an anchor after the due date", "args": [{"frequency": "monthly", "interval": 1, "anchor": "2026-10-01"}, "2026-09-01", "2026-09-01"], "expectError": "repeat anchor 2026-10-01 is after the due date 2026-09-01"}
]