import assert from "node:assert/strict" import { describe, it } from "node:test" import { describeRRule, expandOccurrences, parseRRule } from "./agenda-recurrence.ts" const d = (iso: string) => new Date(iso) describe("parseRRule", () => { it("parse une règle hebdomadaire avec BYDAY", () => { const rule = parseRRule("FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,TH") assert.deepEqual(rule, { freq: "WEEKLY", interval: 2, count: undefined, until: undefined, byday: [1, 4], }) }) it("rejette une fréquence inconnue", () => { assert.equal(parseRRule("FREQ=HOURLY"), null) }) }) describe("expandOccurrences", () => { it("développe une règle quotidienne dans la fenêtre", () => { const rule = parseRRule("FREQ=DAILY")! const out = expandOccurrences( d("2026-06-01T10:00:00"), rule, new Set(), d("2026-06-10T00:00:00"), d("2026-06-12T23:59:59"), ) assert.deepEqual(out.map((x) => x.getDate()), [10, 11, 12]) }) it("respecte COUNT depuis la première occurrence", () => { const rule = parseRRule("FREQ=DAILY;COUNT=5")! const out = expandOccurrences( d("2026-06-01T10:00:00"), rule, new Set(), d("2026-06-04T00:00:00"), d("2026-06-30T23:59:59"), ) // Occurrences 1–5 = 1er au 5 juin ; fenêtre depuis le 4 → 4 et 5 juin. assert.deepEqual(out.map((x) => x.getDate()), [4, 5]) }) it("respecte UNTIL", () => { const rule = parseRRule("FREQ=WEEKLY;UNTIL=20260615T000000Z")! const out = expandOccurrences( d("2026-06-01T10:00:00"), rule, new Set(), d("2026-06-01T00:00:00"), d("2026-07-31T23:59:59"), ) assert.equal(out.length, 2) // 1er et 8 juin (15 juin 10:00 > UNTIL) }) it("développe BYDAY hebdomadaire en gardant l'heure", () => { const rule = parseRRule("FREQ=WEEKLY;BYDAY=MO,WE")! // Lundi 1er juin 2026 à 09:30. const out = expandOccurrences( d("2026-06-01T09:30:00"), rule, new Set(), d("2026-06-01T00:00:00"), d("2026-06-07T23:59:59"), ) assert.deepEqual( out.map((x) => [x.getDate(), x.getHours(), x.getMinutes()]), [ [1, 9, 30], [3, 9, 30], ], ) }) it("exclut les EXDATE", () => { const rule = parseRRule("FREQ=DAILY")! const out = expandOccurrences( d("2026-06-01T10:00:00"), rule, new Set([d("2026-06-02T10:00:00").getTime()]), d("2026-06-01T00:00:00"), d("2026-06-03T23:59:59"), ) assert.deepEqual(out.map((x) => x.getDate()), [1, 3]) }) it("ne produit aucune occurrence avant le début du master", () => { const rule = parseRRule("FREQ=WEEKLY;BYDAY=MO,FR")! // Master mercredi 3 juin 2026 → seul le vendredi 5 reste cette semaine-là. const out = expandOccurrences( d("2026-06-03T10:00:00"), rule, new Set(), d("2026-06-01T00:00:00"), d("2026-06-07T23:59:59"), ) assert.deepEqual(out.map((x) => x.getDate()), [5]) }) }) describe("describeRRule", () => { it("décrit les règles courantes", () => { assert.equal(describeRRule("FREQ=DAILY"), "Tous les jours") assert.equal( describeRRule("FREQ=WEEKLY;BYDAY=MO,TU,WE,TH,FR"), "Tous les jours ouvrés (lun.–ven.)", ) assert.equal(describeRRule("FREQ=MONTHLY;INTERVAL=3"), "Tous les 3 mois") }) })