Pin CLI error messages through their real call sites, not reconstructed format strings #87
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
Follow-up from the PR #59 re-review (non-blocking findings NB1 and NB2).
Two tests added during that PR's rework do not test what they are credited
with testing. Both were found by mutation testing — deliberately
reintroducing the bug and confirming the suite still passed.
NB1 —
internal/cli/errmsg_test.gocopy-pastes the production formatstrings into the test rather than driving the real call sites. It asserts
that a string literal in the test renders the way the same string literal in
the test says it should. A future reword of, for example,
check.go:141would leave this test passing while the user-visible message changed — which
is precisely the regression the test was added to prevent.
mfer/errmsg_test.goalready does this correctly by drivingValidatePathand asserting on what actually comes back. The CLI test should follow it.
NB2 —
TestFreshenRecordEntryMtimePresencecannot distinguish the bug itguards. The stub's mtime is
1_700_000_000. An absent mtime misread asthe epoch also compares unequal to that value, so it also lands in the
"changed" branch. Restoring
recordEntryto its exact pre-rework expression— the original B5 bug — passes the entire suite.
The underlying protection does exist: removing the guard from
entryMtimeitself fails two other tests. So the nil-mtime behaviour is covered. It is
just not covered by the test named for it, which is worse than an absent
test because it advertises a guarantee it does not provide.
Definition of done
internal/cli/errmsg_test.goasserts on error text produced by invokingthe real functions —
verifyRequiredSigner,generateManifestOperation,downloadFile, and the other affected call sites — not on format stringsrestated in the test file.
worth pinning, it is pinned by observing the function that emits it.
TestFreshenRecordEntryMtimePresence's stub mtime istime.Unix(0, 0)sothat an absent mtime and an epoch mtime are distinguishable, and the test
fails if
recordEntry's nil guard is removed.recordEntryto its pre-rework expression while leavingentryMtimeintact — the suite must fail.suite must fail.
make checkpasses anddocker build .succeeds.TODO.mdupdated inthe same commit.
Implementation requirements
in the PR body that you ran them and what failed. A test that has not been
seen to fail is not evidence of anything — that is the entire lesson of
this issue.
equality, not
strings.Contains, unless the message legitimately embeds avariable path or count — in which case assert on the full string with a
known fixed value substituted.
message looks wrong, file it; wording changes are #84's scope.
(closes #87).