Pin the prep-time guards, and say why an operand's set is the narrow one
The guards report an invariant break instead of computing around it, and no data reaches them, so they are called directly: coverage 97.4% -> 97.7%, which also covers the empty-cover skip through a literal operand. operandDraw's doc keeps why neither wider set works, since both were tried here — containment reaches a sibling the operand never renders, the render closure reaches a source two operands share — and drops the rest. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -103,6 +103,19 @@ func TestCalcTokenOperandsReadsOnlyACalc(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestCalcGuardsPanic pins the guards on calc's own invariants: checkCalc parsed
|
||||
// the expression before prep sees it, and indexVars places every name calcVars
|
||||
// read, so a break in either is reported rather than computed around.
|
||||
func TestCalcGuardsPanic(t *testing.T) {
|
||||
for name, call := range map[string]func(){
|
||||
"prep on an expression that does not parse": func() { calcPrep([]string{"1 +"}) },
|
||||
"an operand name never placed": func() { calcVar("n").eval(nil) },
|
||||
"indexVars on a name it did not read": func() { indexVars(calcVar("n"), map[string]int{}) },
|
||||
} {
|
||||
mustPanic(t, name, call)
|
||||
}
|
||||
}
|
||||
|
||||
// --- one draw, one value: a calc operand reads the expansion's draw ---
|
||||
|
||||
// TestCalcOperandReadsTheExpansionsDraw pins the one-draw rule for a calc operand.
|
||||
|
||||
Reference in New Issue
Block a user