test: sentinel rows across the shape predicate, the armed guard, and the assembler
Must-pass and must-fail rows from #182's test plan: the flip shape green under the sentinel, drift and malformed sentinels red with file named, the D3 fragment-list assertion, and D5 sentinel survival through consumption. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
7d29acdeb0
commit
2fd9cb7ded
3 changed files with 202 additions and 0 deletions
|
|
@ -362,6 +362,48 @@ check "fragment mode refuses a flat set over a grouped published section" 1 \
|
|||
"changelog.d/115.md' is flat but newest published section '1.2.3'" \
|
||||
in_tree fragments-dev-flat-over-grouped
|
||||
|
||||
# The declared anchor (#182): the flip tree — a grouped set under a
|
||||
# 'grouped' sentinel over a flat published section — is green, where the
|
||||
# same tree minus the sentinel is the all-grouped-over-flat red row above.
|
||||
fragment_tree fragments-dev-flip 1.2.4-dev <<'EOF'
|
||||
# Changelog
|
||||
|
||||
## 1.2.3 — 2026-07-20
|
||||
|
||||
- The shipped entry.
|
||||
EOF
|
||||
printf '%s\n' "grouped" >"$TMP/fragments-dev-flip/changelog.d/shape"
|
||||
cat >"$TMP/fragments-dev-flip/changelog.d/115.md" <<'EOF'
|
||||
### Fixed
|
||||
|
||||
- Grouped fragment.
|
||||
EOF
|
||||
check "fragment mode: 'grouped' sentinel admits the flip tree over a flat published section" 0 \
|
||||
"fragment mode" in_tree fragments-dev-flip
|
||||
|
||||
# Post-flip drift is refused on its own PR: a flat probe fragment atop the
|
||||
# flip tree goes red — beside grouped fragments the mix rule names it first.
|
||||
printf '%s\n' "- Flat probe." >"$TMP/fragments-dev-flip/changelog.d/116.md"
|
||||
check "fragment mode: a flat probe atop the flip tree is refused" 1 \
|
||||
"changelog.d/115.md' is grouped but fragment 'changelog.d/116.md' is not" \
|
||||
in_tree fragments-dev-flip
|
||||
rm "$TMP/fragments-dev-flip/changelog.d/116.md"
|
||||
|
||||
# And once the grouped fragments are consumed, the sentinel alone still
|
||||
# holds the shape: an all-flat set under 'grouped' is refused, sentinel
|
||||
# named — the published-section inference never gets a say.
|
||||
rm "$TMP/fragments-dev-flip/changelog.d/115.md"
|
||||
printf '%s\n' "- Flat probe." >"$TMP/fragments-dev-flip/changelog.d/116.md"
|
||||
check "fragment mode: a flat set under the 'grouped' sentinel refused, sentinel named" 1 \
|
||||
"changelog.d/116.md' is flat but 'changelog.d/shape' declares grouped" \
|
||||
in_tree fragments-dev-flip
|
||||
rm "$TMP/fragments-dev-flip/changelog.d/116.md"
|
||||
|
||||
printf '%s\n' "Grouped" >"$TMP/fragments-dev-flip/changelog.d/shape"
|
||||
check "fragment mode: a malformed sentinel is refused, file named" 1 \
|
||||
"'changelog.d/shape' declares neither shape" \
|
||||
in_tree fragments-dev-flip
|
||||
|
||||
fragment_tree fragments-dev-no-published 1.2.4-dev <<'EOF'
|
||||
# Changelog
|
||||
|
||||
|
|
|
|||
|
|
@ -143,6 +143,51 @@ check "grouped: the written file is exact" 0 "" \
|
|||
assert_file "$TMP/grouped/CHANGELOG.md" \
|
||||
$'# Changelog\n\nPreamble prose belongs to no section.\n\n## 0.2.0 — 2026-07-24\n\n'"$GROUPED_BODY"$'\n\n## 0.1.0 — 2026-07-01\n\n### Fixed\n\n- The shipped entry.'
|
||||
|
||||
# --- the declared anchor: the first grouped release over a flat history ------
|
||||
# The flip ceremony (#182): a 'grouped' sentinel admits grouped fragments
|
||||
# over a flat newest published section, the sentinel is never a stray file,
|
||||
# and it survives the consumption (D5) — the next -dev tree still declares
|
||||
# its shape.
|
||||
|
||||
tree flip <<EOF
|
||||
$BASE_CHANGELOG
|
||||
EOF
|
||||
printf 'grouped\n' >"$TMP/flip/changelog.d/shape"
|
||||
frag flip 40.md <<'EOF'
|
||||
### Added
|
||||
|
||||
- Forty landed.
|
||||
EOF
|
||||
check "sentinel: the flip release assembles grouped over a flat published section" 0 \
|
||||
"consumed 1 fragment" in_tree flip 0.2.0 2026-07-24
|
||||
check "sentinel: the written flip section is exact" 0 "" \
|
||||
assert_file "$TMP/flip/CHANGELOG.md" \
|
||||
$'# Changelog\n\nPreamble prose belongs to no section.\n\n## 0.2.0 — 2026-07-24\n\n### Added\n\n- Forty landed.\n\n## 0.1.0 — 2026-07-01\n\n- The shipped entry.'
|
||||
check "sentinel: changelog.d/shape survives consumption" 0 "" \
|
||||
test -e "$TMP/flip/changelog.d/shape"
|
||||
|
||||
tree flip-flat-frag <<EOF
|
||||
$BASE_CHANGELOG
|
||||
EOF
|
||||
printf 'grouped\n' >"$TMP/flip-flat-frag/changelog.d/shape"
|
||||
frag flip-flat-frag 41.md <<'EOF'
|
||||
- Flat forty-one.
|
||||
EOF
|
||||
check "sentinel: a flat fragment under 'grouped' refuses, sentinel named" 1 \
|
||||
"changelog.d/shape' declares grouped" in_tree flip-flat-frag 0.2.0 2026-07-24
|
||||
|
||||
tree flip-malformed <<EOF
|
||||
$BASE_CHANGELOG
|
||||
EOF
|
||||
printf 'Grouped\n' >"$TMP/flip-malformed/changelog.d/shape"
|
||||
frag flip-malformed 42.md <<'EOF'
|
||||
### Added
|
||||
|
||||
- Forty-two.
|
||||
EOF
|
||||
check "sentinel: a malformed sentinel refuses, file named" 1 \
|
||||
"changelog.d/shape' declares neither shape" in_tree flip-malformed 0.2.0 2026-07-24
|
||||
|
||||
# --- a changelog holding only its preamble -----------------------------------
|
||||
|
||||
tree preamble-only <<'EOF'
|
||||
|
|
|
|||
|
|
@ -469,4 +469,119 @@ rm "$SHAPE_DIR/1.md"
|
|||
check "shape: empty fragment set makes the anchor rule vacuous" 0 "" \
|
||||
changelog_shape_problem "$SHAPE_CHANGELOG" "$SHAPE_DIR"
|
||||
|
||||
# --- the declarable anchor: <dir>/shape (#182) -------------------------------
|
||||
# The sentinel pins the set's shape and outranks the newest-published-section
|
||||
# inference — the door a deliberate flip walks through, while the undeclared
|
||||
# drift rows above stay red, verbatim.
|
||||
|
||||
cat >"$SHAPE_CHANGELOG" <<'EOF'
|
||||
# Changelog
|
||||
|
||||
## 2.0.0 — 2026-07-24
|
||||
|
||||
- Newest section is flat.
|
||||
EOF
|
||||
cat >"$SHAPE_DIR/1.md" <<'EOF'
|
||||
### Fixed
|
||||
|
||||
- Grouped fragment.
|
||||
EOF
|
||||
printf 'grouped\n' >"$SHAPE_DIR/shape"
|
||||
check "shape: 'grouped' sentinel admits a grouped set over a flat published section" 0 "" \
|
||||
changelog_shape_problem "$SHAPE_CHANGELOG" "$SHAPE_DIR"
|
||||
check "shape: the sentinel binds with no changelog at all — the assembler's call" 0 "" \
|
||||
changelog_shape_problem "" "$SHAPE_DIR"
|
||||
|
||||
printf -- '- Flat fragment.\n' >"$SHAPE_DIR/1.md"
|
||||
check "shape: flat fragment under a 'grouped' sentinel refused, fragment and sentinel named" 1 \
|
||||
"fragment '$SHAPE_DIR/1.md' is flat but '$SHAPE_DIR/shape' declares grouped" \
|
||||
changelog_shape_problem "$SHAPE_CHANGELOG" "$SHAPE_DIR"
|
||||
|
||||
cat >"$SHAPE_CHANGELOG" <<'EOF'
|
||||
# Changelog
|
||||
|
||||
## 2.0.0 — 2026-07-24
|
||||
|
||||
### Fixed
|
||||
|
||||
- Newest section is grouped.
|
||||
EOF
|
||||
printf 'flat\n' >"$SHAPE_DIR/shape"
|
||||
check "shape: 'flat' sentinel admits a flat set over a grouped published section" 0 "" \
|
||||
changelog_shape_problem "$SHAPE_CHANGELOG" "$SHAPE_DIR"
|
||||
cat >"$SHAPE_DIR/1.md" <<'EOF'
|
||||
### Fixed
|
||||
|
||||
- Grouped fragment.
|
||||
EOF
|
||||
check "shape: grouped fragment under a 'flat' sentinel refused, fragment and sentinel named" 1 \
|
||||
"fragment '$SHAPE_DIR/1.md' is grouped but '$SHAPE_DIR/shape' declares flat" \
|
||||
changelog_shape_problem "$SHAPE_CHANGELOG" "$SHAPE_DIR"
|
||||
|
||||
printf 'grouped\n' >"$SHAPE_DIR/shape"
|
||||
printf -- '- Flat two.\n' >"$SHAPE_DIR/2.md"
|
||||
check "shape: a mixed set is refused regardless of the sentinel" 1 \
|
||||
"fragment '$SHAPE_DIR/1.md' is grouped but fragment '$SHAPE_DIR/2.md' is not" \
|
||||
changelog_shape_problem "$SHAPE_CHANGELOG" "$SHAPE_DIR"
|
||||
rm "$SHAPE_DIR/1.md" "$SHAPE_DIR/2.md"
|
||||
|
||||
check "shape: empty fragment set with a valid sentinel passes" 0 "" \
|
||||
changelog_shape_problem "$SHAPE_CHANGELOG" "$SHAPE_DIR"
|
||||
|
||||
printf 'Grouped\n' >"$SHAPE_DIR/shape"
|
||||
check "shape: a capitalized sentinel is refused, file named" 1 \
|
||||
"'$SHAPE_DIR/shape' declares neither shape" \
|
||||
changelog_shape_problem "$SHAPE_CHANGELOG" "$SHAPE_DIR"
|
||||
: >"$SHAPE_DIR/shape"
|
||||
check "shape: an empty sentinel is refused — never a silent fallback" 1 \
|
||||
"'$SHAPE_DIR/shape' declares neither shape" \
|
||||
changelog_shape_problem "$SHAPE_CHANGELOG" "$SHAPE_DIR"
|
||||
printf 'grouped\nflat\n' >"$SHAPE_DIR/shape"
|
||||
check "shape: a two-line sentinel is refused" 1 \
|
||||
"'$SHAPE_DIR/shape' declares neither shape" \
|
||||
changelog_shape_problem "$SHAPE_CHANGELOG" "$SHAPE_DIR"
|
||||
|
||||
# The sentinel is not a fragment (#182 D3): the *.md glob is the mechanism,
|
||||
# but the assertion is on the list itself, so a glob change cannot silently
|
||||
# start publishing the sentinel.
|
||||
printf 'grouped\n' >"$SHAPE_DIR/shape"
|
||||
cat >"$SHAPE_DIR/1.md" <<'EOF'
|
||||
### Fixed
|
||||
|
||||
- Grouped fragment.
|
||||
EOF
|
||||
assert_fragments_exclude_sentinel() {
|
||||
local out
|
||||
out="$(changelog_fragments "$SHAPE_DIR")"
|
||||
[ -n "$out" ] || { echo "wanted a non-empty fragment list"; return 1; }
|
||||
if printf '%s\n' "$out" | grep -q '/shape$'; then
|
||||
printf 'the sentinel leaked into the fragment list:\n%s\n' "$out"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
check "fragments: the shape sentinel never enters the fragment list" 0 "" \
|
||||
assert_fragments_exclude_sentinel
|
||||
rm "$SHAPE_DIR/1.md" "$SHAPE_DIR/shape"
|
||||
|
||||
AS="$TMP/assemble-sentinel"
|
||||
mkdir -p "$AS"
|
||||
printf 'grouped\n' >"$AS/shape"
|
||||
cat >"$AS/30.md" <<'EOF'
|
||||
### Fixed
|
||||
|
||||
- Fixed thirty.
|
||||
EOF
|
||||
cat >"$AS/31.md" <<'EOF'
|
||||
### Added
|
||||
|
||||
- Added thirty-one.
|
||||
EOF
|
||||
check "assemble: the sentinel never assembles, and canonical order holds under it" 0 "" \
|
||||
assert_assemble "$AS" $'### Added\n\n- Added thirty-one.\n\n### Fixed\n\n- Fixed thirty.'
|
||||
rm "$AS/30.md" "$AS/31.md"
|
||||
printf -- '- Flat probe.\n' >"$AS/29.md"
|
||||
check "assemble: a flat set under a 'grouped' sentinel refuses to assemble" 1 \
|
||||
"declares grouped" \
|
||||
changelog_assemble "$AS"
|
||||
|
||||
summary
|
||||
|
|
|
|||
Loading…
Reference in a new issue