Repository navigation
Expand file tree
/
Copy pathcoverage_test.go
More file actions
235 lines (220 loc) · 9.66 KB
/
Copy pathcoverage_test.go
File metadata and controls
235 lines (220 loc) · 9.66 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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
package resident
import (
"context"
"strings"
"testing"
"github.com/Agent-Field/codeaf/internal/plan"
"github.com/Agent-Field/codeaf/internal/store"
)
// alwaysCovered is the reading that refused three of ink v4-flash s14's rounds:
// a model told the plan's acceptance points are all mapped onto work that has
// landed, over a tree the world had a great deal to say about.
var alwaysCovered = SatisfierFunc(func(context.Context, plan.Done, []plan.Landed, []plan.Spec) (plan.Satisfaction, error) {
return plan.Satisfaction{Complete: true}, nil
})
// judgedJob is a job with a criterion to be covered against, and a repair round
// spliced beside it — the shape both stores end in.
func judgedJob(t *testing.T) *store.Store {
t.Helper()
graph := inkJob(t, t.TempDir())
if err := graph.Splice(store.RootID, store.Subtree{Nodes: []store.NodeSpec{
{ID: "task-2-x1", Brief: "finish the grid"},
{ID: "task-2-x1-n1", Parent: "task-2-x1", Brief: "a piece"},
}}, store.Provenance{Origin: store.OriginSelf, SessionID: "s1", Intent: "make the grid lay out"}); err != nil {
t.Fatal(err)
}
return graph
}
func coverageVerdict(t *testing.T, graph *store.Store, lineage, reason string, round int) GrowVerdict {
t.Helper()
node := jobNode(t, graph, "task-2-x1")
verdict, err := growJob(context.Background(), graph, alwaysCovered, GrowRequest{
JobRoot: "task-2-x1", Node: node, Lineage: lineage, Reason: reason, Round: round,
Criterion: plan.Done{Produces: []string{"a grid that lays out"}},
})
if err != nil {
t.Fatal(err)
}
return verdict
}
// COVERAGE IS A CLAIM ABOUT THE PLAN; A FINDING IS EVIDENCE FROM THE WORLD.
//
// ink v4-flash s14 refused an overrun round, a revision round and a gap round as
// goal-already-covered while its own readings ran 172 checks with 18 red. No
// round of any reason may be refused that way while the world has something
// standing.
func TestCoverageCannotRefuseWhileAReadingIsRed(t *testing.T) {
graph := judgedJob(t)
// With nothing standing, the coverage question is still the one that can
// say there is nothing left to do.
if verdict := coverageVerdict(t, graph, "task-2", GrowOverrun, 2); verdict.Allow ||
verdict.Cause != CauseCovered {
t.Fatalf("coverage may still refuse a job the world says nothing about: %+v", verdict)
}
// And then the world speaks: eighteen of the project's own checks are red.
if err := graph.RecordVerification("task-2-x1-n1", store.VerificationReading{
When: "on the finished tree", Command: "npm test", Read: true,
Named: 172, Red: 18, Sample: []string{"grid lays out box children"},
}); err != nil {
t.Fatal(err)
}
for _, reason := range []string{GrowOverrun, GrowRevision, GrowGap} {
for _, round := range []int{1, 2, 3} {
verdict := coverageVerdict(t, graph, "task-2", reason, round)
if !verdict.Allow {
t.Fatalf("%s round %d refused over red checks: %+v", reason, round, verdict)
}
if len(verdict.CoveredDespite) == 0 ||
verdict.CoveredDespite[0] != EvidenceFailing {
t.Fatalf("the disagreement was not recorded: %+v", verdict.CoveredDespite)
}
}
}
// And the admission carries it into the journal, where an autopsy reads it.
node := jobNode(t, graph, "task-2-x1")
request := GrowRequest{JobRoot: "task-2-x1", Node: node, Lineage: "task-2", Reason: GrowGap, Round: 2}
admitGrowth(graph, request, GrowVerdict{Allow: true, Round: 2,
CoveredDespite: []string{EvidenceFailing}}, 1)
rounds, err := graph.JobGrowthRounds("task-2")
if err != nil {
t.Fatal(err)
}
last := rounds[len(rounds)-1]
if len(last.CoveredDespite) != 1 || last.CoveredDespite[0] != EvidenceFailing {
t.Fatalf("covered_despite is not in the journal: %+v", last)
}
}
// igel v4-flash s13: a revision round weighed under `task-2-x1`, whose id
// namespace does not contain `task-2-x1-n1` — which is where the eight deleted
// public names had been journaled ninety seconds earlier. The job has one world.
func TestCoverageReadsTheJobsWorldAndNotTheAskingLineages(t *testing.T) {
graph := judgedJob(t)
if err := graph.RecordSurface("task-2-x1-n1", store.SurfaceReading{
Compared: 3, Lost: 8, Names: []string{"Igel.default_model_path", "Igel.results_path"},
}); err != nil {
t.Fatal(err)
}
verdict := coverageVerdict(t, graph, "task-2-x1", GrowRevision, 1)
if !verdict.Allow {
t.Fatalf("a revision round was refused over a world it could not see: %+v", verdict)
}
if len(verdict.CoveredDespite) != 1 || verdict.CoveredDespite[0] != EvidenceLost {
t.Fatalf("covered despite = %v, want the deleted public names", verdict.CoveredDespite)
}
}
// The other kinds the record holds, each on its own: a behaviour nothing
// exercises, a check that names one and asserts nothing, callers a reshaped
// definition left behind, and a file the plan promised that the disk does not
// hold.
func TestEveryKindOfStandingEvidenceStopsACoverageRefusal(t *testing.T) {
for _, probe := range []struct {
kind string
gate store.DeliveryGate
}{
{EvidenceUnexercised, store.DeliveryGate{Gap: "nothing exercises it",
Unexercised: []string{"the display style property accepts \"grid\""}}},
{EvidenceUnasserted, store.DeliveryGate{Gap: "nothing weighs it",
Unasserted: []string{"gridTemplateColumns accepts fr units"}}},
{EvidenceConsumers, store.DeliveryGate{Gap: "its callers were left behind",
Consumers: []string{"Igel.configs is now a class and six callers index it"}}},
{EvidenceMechanical, store.DeliveryGate{Gap: "src/grid.ts is not on disk",
Mechanical: true, Unclosed: true}},
} {
t.Run(probe.kind, func(t *testing.T) {
graph := judgedJob(t)
if err := graph.RecordDeliveryGate("task-2-x1", probe.gate); err != nil {
t.Fatal(err)
}
verdict := coverageVerdict(t, graph, "task-2", GrowOverrun, 3)
if !verdict.Allow {
t.Fatalf("a round was refused over %s: %+v", probe.kind, verdict)
}
if !strings.Contains(strings.Join(verdict.CoveredDespite, " "), probe.kind) {
t.Fatalf("covered despite = %v, want %s", verdict.CoveredDespite, probe.kind)
}
})
}
}
// A FINDING IN THE HAND IS STANDING EVIDENCE, WHATEVER THE JOURNAL HOLDS.
//
// This is the same table as the test above with one thing taken away: the gate
// row is NOT recorded. That is the production order — the delivery gate asks
// for its repair round and records its row one event later — and it is what
// made the package test pass while the run it covers acquitted a true finding.
// The finding rides the context the growth call already travels on, so the
// governor reads it out of the hand it is in.
func TestALiveFindingStopsACoverageRefusalWithNothingInTheJournal(t *testing.T) {
for _, probe := range []struct {
kind string
finding Finding
}{
{EvidenceUnexercised, Finding{Kind: FindingUnexercised,
Names: []string{"the display style property accepts \"grid\""}}},
{EvidenceUnasserted, Finding{Kind: FindingUnasserted,
Names: []string{"gridTemplateColumns accepts fr units"}}},
{EvidenceFailing, Finding{Kind: FindingOwnFailing, Names: []string{"grid lays out box children"}}},
{EvidenceMechanical, Finding{Kind: FindingMechanical, Names: []string{"src/grid.ts"}}},
{EvidenceFinding, Finding{Kind: FindingReview, Names: []string{"the blocker is discarded at construction"}}},
} {
t.Run(probe.kind, func(t *testing.T) {
graph := judgedJob(t)
gates, err := graph.DeliveryGateLineage("task-2")
if err != nil {
t.Fatal(err)
}
if len(gates) != 0 {
t.Fatalf("the journal already holds a gate row, so this proves nothing: %+v", gates)
}
node := jobNode(t, graph, "task-2-x1")
verdict, err := growJob(WithFinding(context.Background(), probe.finding), graph, alwaysCovered,
GrowRequest{JobRoot: "task-2-x1", Node: node, Lineage: "task-2",
Reason: GrowGap, Round: 2,
Criterion: plan.Done{Produces: []string{"a grid that lays out"}}})
if err != nil {
t.Fatal(err)
}
if !verdict.Allow {
t.Fatalf("a live %s finding was refused as already covered: %+v", probe.kind, verdict)
}
if !strings.Contains(strings.Join(verdict.CoveredDespite, " "), probe.kind) {
t.Fatalf("covered despite = %v, want %s", verdict.CoveredDespite, probe.kind)
}
})
}
}
// And a round nobody bought for a finding keeps exactly the governor it had:
// coverage may still refuse a job the world has nothing standing against, which
// is the question it was built for.
func TestCoverageStillRefusesWhenNoFindingIsInHand(t *testing.T) {
graph := judgedJob(t)
node := jobNode(t, graph, "task-2-x1")
verdict, err := growJob(WithFinding(context.Background(), Finding{}), graph, alwaysCovered,
GrowRequest{JobRoot: "task-2-x1", Node: node, Lineage: "task-2", Reason: GrowOverrun, Round: 2,
Criterion: plan.Done{Produces: []string{"a grid that lays out"}}})
if err != nil {
t.Fatal(err)
}
if verdict.Allow || verdict.Cause != CauseCovered {
t.Fatalf("coverage may still refuse a job nothing stands against: %+v", verdict)
}
}
// AND THE PERSON IS TOLD A GOVERNOR DECLINED TO FUND WHAT A REVIEW ASKED FOR.
// A coverage refusal used to say nothing at the end of the run: the closing line
// fell through to the gate's own words, so a run that stopped because one
// reading of its plan said there was nothing left read as a run that simply
// finished short.
func TestTheClosingLineNamesACoverageRefusal(t *testing.T) {
graph := judgedJob(t)
if err := graph.RecordJobGrowth("task-2", store.JobGrowth{Reason: GrowGap,
Lineage: "task-2", Round: 2, Allowed: false, Cause: CauseCovered,
Refused: RefusedCovered}); err != nil {
t.Fatal(err)
}
standing, ok := GovernorStanding(graph, "task-2")
if !ok {
t.Fatal("a governor refused the round a review asked for and the run said nothing")
}
if !strings.Contains(standing, "nothing left to add") {
t.Fatalf("the closing line does not say what was declined: %q", standing)
}
}