1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
// SPDX-License-Identifier: GPL-3.0-or-later
package engine
import (
"context"
"os"
"path/filepath"
"testing"
"time"
"krino/internal/cond"
"krino/internal/extract"
"krino/internal/scan"
)
// contentFacts builds a *facts for a real text file, under a Dir whose
// ContentVariants is variants, for exercising B2's raw-release directly.
func contentFacts(t *testing.T, body string, variants []cond.Options) *facts {
t.Helper()
p := filepath.Join(t.TempDir(), "a.txt")
if err := os.WriteFile(p, []byte(body), 0o644); err != nil {
t.Fatal(err)
}
fi, err := os.Stat(p)
if err != nil {
t.Fatal(err)
}
e := &Engine{Extract: extract.New(), Now: time.Now}
d := &Dir{Name: "d", ContentVariants: variants}
file := scan.File{Path: p, Rel: "a.txt", Name: "a.txt", Size: fi.Size(), ModTime: fi.ModTime()}
run := newMatchRun(e, d, context.Background(), time.Now(), []scan.File{file})
return newFacts(run, file)
}
// TestContentReleasesRawWithOneVariant: B2. A directory whose rules use
// exactly one (ignoreCase, fold) variant releases the raw extracted text
// once that variant's normalised copy exists.
func TestContentReleasesRawWithOneVariant(t *testing.T) {
f := contentFacts(t, "Hello World", []cond.Options{{IgnoreCase: true, Fold: false}})
const want = "hello world"
got, err := f.Content(true, false)
if err != nil {
t.Fatal(err)
}
if got != want {
t.Fatalf("got %q, want %q", got, want)
}
if f.content != "" {
t.Errorf("raw text not released with a single content variant: %q", f.content)
}
// A second call for the same (already cached) variant must still work
// from normCache, without needing the released raw text.
if got, err := f.Content(true, false); err != nil || got != want {
t.Errorf("second call for the cached variant: got %q, %v, want %q", got, err, want)
}
}
// TestContentKeepsRawWithTwoVariants: B2. A directory whose rules use two
// distinct variants must not release the raw text after the first: the
// second variant still needs it, and normalising it correctly (not from an
// emptied string) is the proof the raw text was kept.
func TestContentKeepsRawWithTwoVariants(t *testing.T) {
f := contentFacts(t, "Hello World", []cond.Options{
{IgnoreCase: true, Fold: false},
{IgnoreCase: false, Fold: false},
})
if got, err := f.Content(true, false); err != nil || got != "hello world" {
t.Fatalf("first variant: got %q, %v", got, err)
}
if f.content == "" {
t.Fatal("raw text released after only the first of two variants")
}
if got, err := f.Content(false, false); err != nil || got != "Hello World" {
t.Fatalf("second variant: got %q, %v, want the unfolded original (raw text must still be available)", got, err)
}
}
|