-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathreceipt_test.go
More file actions
144 lines (128 loc) · 4.87 KB
/
Copy pathreceipt_test.go
File metadata and controls
144 lines (128 loc) · 4.87 KB
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package diff
import (
"encoding/json"
"strings"
"testing"
"github.com/enola-labs/enola/internal/facts"
)
func TestCompareMeta(t *testing.T) {
base := facts.SnapshotMeta{
RepoPath: "/repo", EnolaVersion: "1.0", IgnoreGlobHash: "h",
Extractors: []string{"go", "typescript"},
}
t.Run("equivalent inputs produce no warnings", func(t *testing.T) {
cur := base
if c := CompareMeta(base, cur); !c.Comparable {
t.Errorf("expected comparable, got warnings: %v", c.Warnings)
}
})
t.Run("comparable verdict is an explicit JSON field", func(t *testing.T) {
// The gap this fixes: a full-JSON consumer must read comparable:true
// directly, not infer it from an absent warnings list.
out, err := json.Marshal(CompareMeta(base, base))
if err != nil {
t.Fatal(err)
}
if !strings.Contains(string(out), `"comparable":true`) {
t.Errorf(`clean verdict must marshal an explicit "comparable":true; got %s`, out)
}
})
t.Run("extractor removed in current is flagged as REMOVED", func(t *testing.T) {
cur := base
cur.Extractors = []string{"go"} // typescript dropped from the current run
msg := strings.Join(CompareMeta(base, cur).Warnings, " ")
if !strings.Contains(msg, "typescript") {
t.Fatalf("warning should name the missing extractor, got: %s", msg)
}
// typescript was in the baseline, not current → its facts appear as REMOVED.
if !strings.Contains(msg, "baseline had extractor(s) not in the current run: typescript") ||
!strings.Contains(msg, "REMOVED") {
t.Errorf("expected a 'baseline had … REMOVED' direction, got: %s", msg)
}
})
t.Run("extractor added in current is flagged as ADDED", func(t *testing.T) {
cur := base
cur.Extractors = []string{"go", "typescript", "openapi"} // openapi gained
msg := strings.Join(CompareMeta(base, cur).Warnings, " ")
// openapi is in current, not baseline → its facts appear as ADDED.
if !strings.Contains(msg, "current run added extractor(s) not in the baseline: openapi") ||
!strings.Contains(msg, "ADDED") {
t.Errorf("expected a 'current added … ADDED' direction, got: %s", msg)
}
})
t.Run("different enola version is flagged", func(t *testing.T) {
cur := base
cur.EnolaVersion = "2.0"
if CompareMeta(base, cur).Comparable {
t.Error("expected a warning for differing enola versions")
}
})
t.Run("empty baseline meta is a soft not-verifiable note, not a hard mismatch", func(t *testing.T) {
// An auto-loaded baseline carries only RepoPath.
autoLoaded := facts.SnapshotMeta{RepoPath: "/repo"}
c := CompareMeta(autoLoaded, base)
if c.Comparable {
t.Error("expected a not-verifiable note for an empty baseline")
}
if !strings.Contains(strings.Join(c.Warnings, " "), "predates snapshot receipts") {
t.Errorf("expected the soft 'predates receipts' note, got: %v", c.Warnings)
}
})
}
func TestCompareReceipts(t *testing.T) {
base := facts.SnapshotMeta{
EnolaVersion: "1.0", SnapshotID: "aaa", Extractors: []string{"go"},
FilesSeen: 100, FilesParsed: 90, ParseErrors: 0,
}
t.Run("rising parse errors surface as a quality regression", func(t *testing.T) {
cur := base
cur.SnapshotID = "bbb"
cur.ParseErrors = 3
rc := CompareReceipts(base, cur)
if len(rc.QualityRegressions) == 0 {
t.Fatal("expected a quality regression for rising parse errors")
}
if !strings.Contains(strings.Join(rc.QualityRegressions, " "), "parse errors rose") {
t.Errorf("unexpected regressions: %v", rc.QualityRegressions)
}
})
t.Run("dropping parsed/seen ratio is a regression", func(t *testing.T) {
cur := base
cur.SnapshotID = "bbb"
cur.FilesParsed = 50 // 50% vs 90%
rc := CompareReceipts(base, cur)
if !strings.Contains(strings.Join(rc.QualityRegressions, " "), "parsed/seen ratio dropped") {
t.Errorf("expected a ratio-drop regression, got: %v", rc.QualityRegressions)
}
})
t.Run("identical snapshot ids short-circuit", func(t *testing.T) {
rc := CompareReceipts(base, base)
if !rc.Identical {
t.Error("expected Identical=true for matching snapshot_id")
}
})
// A newly-ignored directory prunes a whole subtree. It reports as a dirs_skipped
// delta and NOT as a quality regression: pruning vendor/ is usually the operator
// doing the right thing, and files_seen falling is the signal that costs something.
t.Run("a pruned directory surfaces as a dirs_skipped delta", func(t *testing.T) {
cur := base
cur.SnapshotID = "bbb"
cur.DirsSkipped = 2
rc := CompareReceipts(base, cur)
var found *MetricDelta
for i := range rc.Deltas {
if rc.Deltas[i].Name == "dirs_skipped" {
found = &rc.Deltas[i]
}
}
if found == nil {
t.Fatalf("no dirs_skipped delta; got %v", rc.Deltas)
}
if found.Before != 0 || found.After != 2 || found.Delta != 2 {
t.Errorf("dirs_skipped delta = %+v, want before=0 after=2 delta=2", *found)
}
if len(rc.QualityRegressions) != 0 {
t.Errorf("pruning a directory is not a regression, got: %v", rc.QualityRegressions)
}
})
}