Functional Weave
Code in TypeScript

fleet.service-due@1.0.0

vectors.json

5,011 bytes · view raw

[
  {"name": "an average driver: the 12 months come three days before the 10,000 miles", "args": ["2025-03-15", 30000, 12, 10000, "2025-09-15", 35000], "expect": {"dueDate": "2026-03-15", "dueMileage": 40000, "daysRemaining": 181, "milesRemaining": 5000, "projectedMileageDate": "2026-03-18", "nextDueDate": "2026-03-15", "dueBy": "date", "overdue": false}},
  {"name": "a high-mileage driver reaches 10,000 miles long before the year is up", "args": ["2025-01-10", 20000, 12, 10000, "2025-04-10", 26000], "expect": {"dueDate": "2026-01-10", "dueMileage": 30000, "daysRemaining": 275, "milesRemaining": 4000, "projectedMileageDate": "2025-06-09", "nextDueDate": "2025-06-09", "dueBy": "mileage", "overdue": false}},
  {"name": "overdue by date though the mileage is not reached", "args": ["2024-05-01", 10000, 12, 12000, "2025-05-20", 18000], "expect": {"dueDate": "2025-05-01", "dueMileage": 22000, "daysRemaining": -19, "milesRemaining": 4000, "projectedMileageDate": "2025-11-28", "nextDueDate": "2025-05-01", "dueBy": "date", "overdue": true}},
  {"name": "overdue by mileage: due from today, nothing to project", "args": ["2025-01-01", 50000, 24, 20000, "2025-06-01", 70500], "expect": {"dueDate": "2027-01-01", "dueMileage": 70000, "daysRemaining": 579, "milesRemaining": -500, "projectedMileageDate": null, "nextDueDate": "2025-06-01", "dueBy": "mileage", "overdue": true}},
  {"name": "exactly at the due mileage is due, not overdue", "args": ["2025-01-01", 0, 12, 10000, "2025-07-01", 10000], "expect": {"dueDate": "2026-01-01", "dueMileage": 10000, "daysRemaining": 184, "milesRemaining": 0, "projectedMileageDate": null, "nextDueDate": "2025-07-01", "dueBy": "mileage", "overdue": false}},
  {"name": "time only: a service on 29 February is next due on 28 February", "args": ["2024-02-29", 1000, 12, 0, "2024-06-01", 3000], "expect": {"dueDate": "2025-02-28", "dueMileage": null, "daysRemaining": 272, "milesRemaining": null, "projectedMileageDate": null, "nextDueDate": "2025-02-28", "dueBy": "date", "overdue": false}},
  {"name": "mileage only: projected from 100 miles a day", "args": ["2025-01-01", 0, 0, 5000, "2025-01-11", 1000], "expect": {"dueDate": null, "dueMileage": 5000, "daysRemaining": null, "milesRemaining": 4000, "projectedMileageDate": "2025-02-20", "nextDueDate": "2025-02-20", "dueBy": "mileage", "overdue": false}},
  {"name": "serviced today: no average yet, so no projection", "args": ["2025-03-01", 40000, 12, 10000, "2025-03-01", 40000], "expect": {"dueDate": "2026-03-01", "dueMileage": 50000, "daysRemaining": 365, "milesRemaining": 10000, "projectedMileageDate": null, "nextDueDate": "2026-03-01", "dueBy": "date", "overdue": false}},
  {"name": "a vehicle that has not moved has no projection", "args": ["2025-03-01", 40000, 12, 10000, "2025-06-01", 40000], "expect": {"dueDate": "2026-03-01", "dueMileage": 50000, "daysRemaining": 273, "milesRemaining": 10000, "projectedMileageDate": null, "nextDueDate": "2026-03-01", "dueBy": "date", "overdue": false}},
  {"name": "the projection lands on the due date: a tie is by date", "args": ["2025-01-01", 0, 1, 310, "2025-01-11", 100], "expect": {"dueDate": "2025-02-01", "dueMileage": 310, "daysRemaining": 21, "milesRemaining": 210, "projectedMileageDate": "2025-02-01", "nextDueDate": "2025-02-01", "dueBy": "date", "overdue": false}},
  {"name": "a fractional day of driving rounds the projection up: 56.6 days is 57", "args": ["2025-01-01", 0, 12, 10000, "2025-01-08", 1100], "expect": {"dueDate": "2026-01-01", "dueMileage": 10000, "daysRemaining": 358, "milesRemaining": 8900, "projectedMileageDate": "2025-03-06", "nextDueDate": "2025-03-06", "dueBy": "mileage", "overdue": false}},
  {"name": "mileage only and not moving: nothing is due yet", "args": ["2025-01-01", 0, 0, 5000, "2025-02-01", 0], "expect": {"dueDate": null, "dueMileage": 5000, "daysRemaining": null, "milesRemaining": 5000, "projectedMileageDate": null, "nextDueDate": null, "dueBy": null, "overdue": false}},
  {"name": "no interval at all is an error", "args": ["2025-01-01", 0, 0, 0, "2025-02-01", 100], "expectError": "at least one of intervalMonths and intervalMiles must be above zero"},
  {"name": "a negative interval is an error", "args": ["2025-01-01", 0, -12, 10000, "2025-02-01", 100], "expectError": "intervalMonths must be a whole number, 0 or more"},
  {"name": "a fractional mileage is an error", "args": ["2025-01-01", 0, 12, 10000, "2025-02-01", 100.5], "expectError": "currentMileage must be a whole number, 0 or more"},
  {"name": "a date before the last service is an error", "args": ["2025-01-01", 0, 12, 10000, "2024-12-31", 0], "expectError": "is before the last service"},
  {"name": "a mileage below the last service is an error (clocked, or the wrong vehicle)", "args": ["2025-01-01", 5000, 12, 10000, "2025-02-01", 4000], "expectError": "is below the mileage at the last service"},
  {"name": "a malformed date is an error", "args": ["2025-1-1", 0, 12, 10000, "2025-02-01", 100], "expectError": "is not an ISO date"}
]