Skip to content
quarry Artifact [e3b6330eca]
Login

Artifact [e3b6330eca]

Artifact e3b6330eca116e440e3607072fa2e710a6d16ed16214506985f08f8ef83bb991:


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)
	})
}