aboutsummaryrefslogtreecommitdiff
path: root/internal/cond/eval_test.go
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-09-14 23:39:37 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-09-14 23:39:37 +0200
commitc09020c2fb01da24d5befbed78ce3b73b5efbe4c (patch)
tree8cd1086588988fafaf238aed8a38a7ec85b0afa3 /internal/cond/eval_test.go
parent3990586a85e91923c0a3ae1a1f0f61420db555ac (diff)
downloadkrino-c09020c2fb01da24d5befbed78ce3b73b5efbe4c.tar.gz
krino-c09020c2fb01da24d5befbed78ce3b73b5efbe4c.zip
content tests are three-valued: unknown when unreadable or read in part
Diffstat (limited to 'internal/cond/eval_test.go')
-rw-r--r--internal/cond/eval_test.go33
1 files changed, 30 insertions, 3 deletions
diff --git a/internal/cond/eval_test.go b/internal/cond/eval_test.go
index 2e8bcfd..7d796a1 100644
--- a/internal/cond/eval_test.go
+++ b/internal/cond/eval_test.go
@@ -167,11 +167,11 @@ func TestExplainFormat(t *testing.T) {
c, _ := Compile("d.conf", nodes(t, `(type pdf) (or (content "acme ltd") (name "\bacme\b"))`), Options{IgnoreCase: true})
var b strings.Builder
c.Explain(f).Format(&b)
- want := "no and\n" +
+ want := "? and\n" +
"yes type pdf\n" +
- "no or\n" +
+ "? or\n" +
"no name \"\\bacme\\b\"\n" +
- "no content \"acme ltd\" (content unreadable: needs pdftotext, not installed)\n"
+ "? content \"acme ltd\" (content unreadable: needs pdftotext, not installed)\n"
if b.String() != want {
t.Fatalf("got\n%s\nwant\n%s", b.String(), want)
}
@@ -257,3 +257,30 @@ func TestCapturesKeepDiacritics(t *testing.T) {
t.Errorf("captures with a group that did not take part = %q, want %q", r.Captures, want)
}
}
+
+// TestUnreadableContentIsUnknown: a content test that cannot read the file
+// is unknown, not false, and and/or/not combine unknowns the way Kleene's
+// three-valued logic does: a condition certainly false (or true) whatever
+// the text holds is decided, and only one that depends on the text is
+// unknown (plan 11, re-review cache F2). A rule matches only a true
+// condition; an exclude holds on true or unknown.
+func TestUnreadableContentIsUnknown(t *testing.T) {
+ f := &fake{name: "a.pdf", rawErr: errors.New("larger than max-read")}
+ cases := []struct {
+ src string
+ match, unreadable bool
+ }{
+ {`(and (content "x") (type txt))`, false, false},
+ {`(or (content "x") (type pdf))`, true, false},
+ {`(not (content "x"))`, false, true},
+ {`(and (type pdf) (content "x"))`, false, true},
+ {`(or (type txt) (content "x"))`, false, true},
+ {`(content "secret") (and (content "other") (type txt))`, false, false},
+ {`(not (and (content "x") (type txt)))`, true, false},
+ }
+ for _, c := range cases {
+ if r := eval(t, c.src, Options{}, f); r.Match != c.match || r.Unreadable != c.unreadable {
+ t.Errorf("%s: Match %v Unreadable %v; want %v, %v", c.src, r.Match, r.Unreadable, c.match, c.unreadable)
+ }
+ }
+}