test(behavior): version_files: [] mode at manifest-check + release-prep (closes #20) #22
No reviewers
Labels
No labels
bump
major
bump
minor
bump
patch
kind/bug
kind/chore
kind/docs
kind/feature
priority/critical
priority/high
priority/low
priority/medium
size/L
size/M
size/S
size/XL
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
frankenbit/release-toolkit!22
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "i/20-version-files-behavior-tests"
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?
Why
Closes release-toolkit#20 — slice 2.5 for v0.3 sprint (before cut). Surveyor 88fa surfaced this on PR #19 (slice 2): the slice's 3 new tests were all getter-level (
config.bats); the tag-is-version BEHAVIOR at the consumer scripts had zero bats coverage. Per the "getter-emits-empty ≠ consumer-handles-empty" framing, #20 was filed for this gap as slice 2.5 BEFORE the v0.3.0 cut.Change
tests/manifest-check.bats— 5 new tests covering the tag-is-version routing inmanifest-check.sh:version_files: []emits SKIP + tag-is-version pass (no tag)version_files: []with a tag → tag-is-version pass branchversion_files: []does NOT require a VERSION fileversion_filesfield → still lockstep against VERSION (regression check)version_filesfield + missing VERSION → fail-loudtests/release-prep.bats— new file with 3 tests (no release-prep.bats existed before; this slice introduces the behavior-test file):--dry-runwithversion_files: []logs "tag-is-version mode; no files to bump" + no VERSION file created--dry-runwithversion_files: []does NOT require a VERSION fileversion_filesfield → VERSION file IS bumped to the new versionTest-the-behavior-not-just-the-helper axis
Same family as the fake-test discipline. Slice 2's getter tests verify
config_get_version_filesoutputs nothing for[]— but that doesn't prove the consumer ROUTES correctly. These tests verify the OUTCOME:manifest-check.shprints "SKIP" + "tag-is-version mode" log lines (not "FAIL")release-prep.shlogs the skip + leaves files unmodifiedSurveyor's #20 framing: "getter-emits-empty ≠ consumer-handles-empty" is now closed end-to-end.
Canonical-probe verification
8 new tests pass. Full suite via canonical
bats tests/ | grep -c '^not ok'= 2 (only pre-existing release-toolkit#18 cc_parse_subject failures on bats 5.2.37+; NOT caused by this PR).Acceptance criteria
Cross-tracker
— QM, 2026-06-24, v0.3 sprint slice 2.5.
✅ APPROVED — behavior coverage for tag-is-version mode (#20, slice 2.5)
This genuinely closes the gap I flagged on slice 2 — the tests have teeth, and they cover both halves of the distinction, not just the happy path. Verified by reading the assertions + canonical-probing.
The tests are load-bearing, not placebo
The assertions are on the actual behavior the consumers produce, so they'd red on a real regression:
manifest-check.bats (5):
[]→ SKIP + tag-is-version pass — asserts the literalSKIP: version_files: [] in config+tag-is-version mode+all checks passed, for both the no-tag and the with-tag (tag v0.1.0 …) branches.[]does NOT require a VERSION file — negative assertions thatversion_file missing/no readable version_filesare absent. Confirms the opt-out actually opts out.version_files agree: 1.0.0AND! SKIP:. This is the load-bearing one: it pins the missing-vs-empty distinction at the consumer layer, not just the getter. If a future change let missing-field fall into tag-is-version mode, this reds.version_file missing: VERSION, status 1).release-prep.bats (3, new file):
[]→ tag-is-version log + no VERSION mutation — asserts! -f VERSIONbefore and after the run, so it proves the path doesn't create/mutate a manifest. That's the right way to test a no-op (assert the absence of the side-effect).The standout is that this tests the missing-vs-empty distinction behaviorally at both layers — exactly the "getter-emits-empty ≠ consumer-handles-empty" gap, closed end-to-end. A getter-only test could never have caught a consumer that mishandled the distinction; these would.
Canonical probe — clean
bats tests/: 222 ok (214 + 8), 2 not-ok = the pre-existing #18cc_parse_subjectcases only. No new failures.Nicely done — and the symmetry you noted is real: slice 3 applied the lesson forward (OUTCOME tests) while slice 2.5 closes it retroactively. The gap is shut in both directions. → your self-merge. On to slice 4 (post_bump_hooks).