AtlatestRepositorysigil-later

sigil-later / tree / testtest-later.sgl

1(import (sigil test)
2 (sigil time)
3 (sigil later))
4
5;; ============================================================
6;; parse-cron-string
7;; ============================================================
8
9(test-group "parse-cron-string"
10 (test "parses wildcard expression"
11 (let ((sched (parse-cron-string "* * * * *")))
12 (assert-true (later-schedule? sched))
13 (assert-equal 60 (length (later-schedule-minutes sched)))
14 (assert-equal 24 (length (later-schedule-hours sched)))
15 (assert-equal 31 (length (later-schedule-days-of-month sched)))
16 (assert-equal 12 (length (later-schedule-months sched)))
17 (assert-equal 7 (length (later-schedule-days-of-week sched)))))
19 (test "parses step expression"
20 (let ((sched (parse-cron-string "*/5 * * * *")))
21 (assert-equal '(0 5 10 15 20 25 30 35 40 45 50 55)
22 (later-schedule-minutes sched))))
24 (test "parses specific values"
25 (let ((sched (parse-cron-string "30 9 * * *")))
26 (assert-equal '(30) (later-schedule-minutes sched))
27 (assert-equal '(9) (later-schedule-hours sched))))
29 (test "parses ranges"
30 (let ((sched (parse-cron-string "0 9-17 * * *")))
31 (assert-equal '(9 10 11 12 13 14 15 16 17)
32 (later-schedule-hours sched))))
34 (test "parses lists"
35 (let ((sched (parse-cron-string "0,15,30,45 * * * *")))
36 (assert-equal '(0 15 30 45)
37 (later-schedule-minutes sched))))
39 (test "parses named days"
40 (let ((sched (parse-cron-string "0 9 * * MON-FRI")))
41 (assert-equal '(1 2 3 4 5)
42 (later-schedule-days-of-week sched))))
44 (test "parses named months"
45 (let ((sched (parse-cron-string "0 0 1 JAN,JUL *")))
46 (assert-equal '(1 7)
47 (later-schedule-months sched))))
49 (test "parses range with step"
50 (let ((sched (parse-cron-string "0 8-18/2 * * *")))
51 (assert-equal '(8 10 12 14 16 18)
52 (later-schedule-hours sched))))
54 (test "rejects invalid field count"
55 (assert-error (parse-cron-string "* * *"))))
57;; ============================================================
58;; later-matches?
59;; ============================================================
61(test-group "later-matches?"
62 (test "every-minute matches any timestamp"
63 (let ((sched (parse-cron-string "* * * * *")))
64 (assert-true (later-matches? sched (current-second)))))
66 (test "specific minute matches"
67 (let* ((sched (parse-cron-string "30 * * * *"))
68 (now (current-second))
69 (min (time-minute now)))
70 ;; If current minute is 30, it should match; otherwise not
71 (if (= min 30)
72 (assert-true (later-matches? sched now))
73 (assert-false (later-matches? sched now)))))
75 (test "non-matching minute returns false"
76 (let ((sched (parse-cron-string "0 * * * *")))
77 ;; Pick a time at minute 30
78 ;; 2026-01-01 00:30:00 = 1735689600 + 1800 = 1735691400
79 (assert-false (later-matches? sched 1735691400)))))
81;; ============================================================
82;; later-next
83;; ============================================================
85(test-group "later-next"
86 (test "finds next minute for every-minute schedule"
87 (let* ((sched (parse-cron-string "* * * * *"))
88 (now (current-second))
89 (next (later-next sched now)))
90 (assert-true (number? next))
91 (assert-true (> next now))
92 ;; Should be within 60 seconds
93 (assert-true (<= (- next now) 120))))
95 (test "finds next occurrence for specific time"
96 (let* ((sched (parse-cron-string "0 * * * *"))
97 ;; Start at 2026-01-01 00:30:00 (minute 30)
98 (start 1735691400)
99 (next (later-next sched start)))
100 (assert-true (number? next))
101 ;; Next :00 should be within an hour
102 (assert-true (<= (- next start) 3600))))
104 (test "returns #f for impossible schedule"
105 ;; Feb 31 never exists
106 (let* ((sched (parse-cron-string "0 0 31 2 *"))
107 (next (later-next sched (current-second))))
108 (assert-false next))))