summaryrefslogtreecommitdiff
path: root/internal/engine/engine_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/engine/engine_test.go')
-rw-r--r--internal/engine/engine_test.go49
1 files changed, 49 insertions, 0 deletions
diff --git a/internal/engine/engine_test.go b/internal/engine/engine_test.go
index 5c0536f..8dcfcb3 100644
--- a/internal/engine/engine_test.go
+++ b/internal/engine/engine_test.go
@@ -138,6 +138,55 @@ func TestCheck(t *testing.T) {
}
}
+// TestLoadRejectsUnsuppliedCaptures: a rule using {N} must be able to get it
+// from its own name tests (spec 7.3) — adapted from the brief to this
+// package's actual sandbox/writeConfig/Load helpers (writeConfig takes a
+// main file body and a dirs map; there is no separate engineLoad, Load is
+// called directly).
+func TestLoadRejectsUnsuppliedCaptures(t *testing.T) {
+ tests := []struct{ rule, want string }{
+ {`(rule "a" (when (type pdf)) (move "Work/{1}"))`,
+ `rule "a": {1} needs a name test to capture from`},
+ {`(rule "a" (when (name "inv-(\d+)")) (move "Work/{2}"))`,
+ `rule "a": {2} but a name test has only 1 capture group`},
+ {`(rule "a" (when (or (name "x-(\d+)-(\d+)") (name "y-(\d+)"))) (rename "{2}"))`,
+ `rule "a": {2} but a name test has only 1 capture group`},
+ }
+ for _, tt := range tests {
+ h := sandbox(t)
+ main := writeConfig(t, h, `(include "dl")`, map[string]string{"dl": `(path "/tmp")
+` + tt.rule})
+ _, errs := Load(main, "dl")
+ joined := ""
+ for _, d := range errs {
+ joined += d.Error() + "\n"
+ }
+ if len(errs) != 1 || !strings.Contains(joined, tt.want) {
+ t.Errorf("rule %s: errs %v, want %q", tt.rule, errs, tt.want)
+ }
+ }
+}
+
+// TestLoadAcceptsSuppliedCaptures: a rule whose name test has enough groups
+// for every {N} it uses loads clean.
+func TestLoadAcceptsSuppliedCaptures(t *testing.T) {
+ for _, rule := range []string{
+ `(rule "a" (when (name "inv-(\d+)-(\d+)")) (move "Work/{2}/{1}"))`,
+ // B1a: a name test reachable only under a (not ...) must not count
+ // toward this rule's own captures (B1), but it must also not make
+ // the rule itself invalid - the outer (name ...) alone already
+ // supplies the two groups {2} needs.
+ `(rule "a" (when (and (name "inv-(\d+)-(\d+)") (not (name "draft")))) (move "Work/{2}"))`,
+ } {
+ h := sandbox(t)
+ main := writeConfig(t, h, `(include "dl")`, map[string]string{"dl": `(path "/tmp")
+` + rule})
+ if _, errs := Load(main, "dl"); len(errs) != 0 {
+ t.Errorf("rule %s: unexpected diagnostics: %v", rule, errs)
+ }
+ }
+}
+
// TestContentVariantsComputedAtLoad: B2 plumbing. Load computes each
// directory's distinct (ignoreCase, fold) content-test variants from its
// rules' resolved settings: a rule with no content test contributes