aboutsummaryrefslogtreecommitdiff
path: root/internal/engine/cache_test.go
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-09-14 21:39:00 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-09-14 21:39:00 +0200
commite0dddff176a01d410904b6750b3395de4f7e54db (patch)
treea0490057abfb75e89f7bd4559472717297cad823 /internal/engine/cache_test.go
parentd53c83e2fe6f1ecef006f116095fa8d1d18f3a7d (diff)
downloadkrino-e0dddff176a01d410904b6750b3395de4f7e54db.tar.gz
krino-e0dddff176a01d410904b6750b3395de4f7e54db.zip
plan 9: keyword cache keys on extension, max-read and Unicode tables, trims removed keywords
Diffstat (limited to 'internal/engine/cache_test.go')
-rw-r--r--internal/engine/cache_test.go57
1 files changed, 57 insertions, 0 deletions
diff --git a/internal/engine/cache_test.go b/internal/engine/cache_test.go
index eee2860..8c52d48 100644
--- a/internal/engine/cache_test.go
+++ b/internal/engine/cache_test.go
@@ -6,9 +6,14 @@ import (
"context"
"os"
"path/filepath"
+ "runtime"
"strings"
"testing"
"time"
+ "unicode"
+
+ "krino/internal/config"
+ "krino/internal/extract"
)
// countingPDFTree makes ~/dl holding the given .pdf files, and a fake
@@ -222,3 +227,55 @@ func TestExplainUsesCacheWithoutWriting(t *testing.T) {
t.Errorf("explain extracted although the run cached a.pdf")
}
}
+
+// TestCacheRereadsARenamedExtension: the extension picks the extractor, so
+// a file renamed from .html to .txt - same inode, size and mtime - is read
+// again, not answered from what the markup reader found (review M6).
+func TestCacheRereadsARenamedExtension(t *testing.T) {
+ home, dl := excludeTree(t, map[string]string{"page.html": "<p>ACME</p>&nbsp;Ltd"})
+ main := writeConfig(t, home, `(include "dl")`, map[string]string{"dl": "(path \"~/dl\")\n(rule \"acme\" (when (content \"acme ltd\")) (move \"Acme\"))\n"})
+ if r := cachedMatch(t, home, main); matchedNames(r) != "page.html" {
+ t.Fatalf("as html: matched %q", matchedNames(r))
+ }
+ if err := os.Rename(filepath.Join(dl, "page.html"), filepath.Join(dl, "page.txt")); err != nil {
+ t.Fatal(err)
+ }
+ if r := cachedMatch(t, home, main); matchedNames(r) != "" {
+ t.Errorf("as txt, answered from the html read: matched %q", matchedNames(r))
+ }
+}
+
+// TestCacheFingerprintCoversMaxReadAndTables: answers depend on max-read
+// (it caps what is read), on the Go release and on the Unicode tables, so
+// all are in the fingerprint (review cache F2, F4).
+func TestCacheFingerprintCoversMaxReadAndTables(t *testing.T) {
+ e := &Engine{Extract: extract.New()}
+ small := e.cacheFingerprint(&Dir{Settings: config.Resolved{MaxRead: 1 << 10}})
+ large := e.cacheFingerprint(&Dir{Settings: config.Resolved{MaxRead: 1 << 20}})
+ if small == large {
+ t.Error("max-read does not change the fingerprint")
+ }
+ for _, want := range []string{runtime.Version(), unicode.Version} {
+ if !strings.Contains(small, want) {
+ t.Errorf("fingerprint %q lacks %q", small, want)
+ }
+ }
+}
+
+// TestCacheRemovedWhenNoContentTestsRemain: once a directory has no content
+// test, its cache - holding keywords it no longer uses - is removed (review
+// cache F6).
+func TestCacheRemovedWhenNoContentTestsRemain(t *testing.T) {
+ home, _, _ := countingPDFTree(t, map[string]string{"a.pdf": "Invoice ACME"})
+ main := writeConfig(t, home, `(include "dl")`, map[string]string{"dl": acmeRules})
+ cachedMatch(t, home, main)
+ file := filepath.Join(home, ".cache", "krino", "dl.cache")
+ if _, err := os.Stat(file); err != nil {
+ t.Fatal(err)
+ }
+ writeConfig(t, home, `(include "dl")`, map[string]string{"dl": "(path \"~/dl\")\n(rule \"all\" (move \"Out\"))\n"})
+ cachedMatch(t, home, main)
+ if _, err := os.Stat(file); !os.IsNotExist(err) {
+ t.Errorf("the cache of a directory without content tests is still there: %v", err)
+ }
+}