package cronexpr
import (
"strings"
"testing"
"time"
)
// AN EMPTY COMMA ITEM IS AN ERROR, NEVER A PANIC: a cron line arrives
// in a pushed file, and a panic there took the forge down.
func TestEmptyCommaItemsAreErrors(t *testing.T) {
for _, line := range []string{"0,,30 3 * * *", ",5 * * * *", "5, * * * *", "0 3 * * 1,", strings.Repeat("1", 300) + " * * * *"} {
func() {
defer func() {
if r := recover(); r != nil {
t.Errorf("FAIL: %q panicked: %v", line, r)
}
}()
if _, err := ParseCron(line); err == nil {
t.Errorf("FAIL: %q parsed; want an error", line)
}
}()
}
t.Log("ok: empty comma items and over-long lines are errors")
}
// Whatever the input, ParseCron answers an error or an expression that
// Matches and NextN can use without panicking.
func FuzzParseCron(f *testing.F) {
for _, s := range []string{"0,,30 3 * * *", ",5 * * * *", "5, * * * *", "0 3 * * 1,", "*/5 * * * *",
"0 0 29 2 *", "1-5,7 */2 1 1-12 0-6", "* * * * *", "60 * * * *", "*/0 * * * *", "-1 * * * *", "1- * * * *"} {
f.Add(s)
}
f.Fuzz(func(t *testing.T, line string) {
c, err := ParseCron(line)
if err != nil {
return
}
c.Matches(time.Date(2028, 2, 29, 3, 15, 0, 0, time.UTC))
c.NextN(time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC), 2)
})
}