testmark-bash

check: compare a repeated check against the hunk too, so a mismatch can't pass the second time.

commit 19923c2a6a3d80e099ed50eeb3034da6a174f5af · parent 2063a16c56 · browse this tree
Ximianth, 2026-10-24 00:50:32 UTC

The duplicate rule returned 0 as soon as the output equalled the first
check's, skipping the comparison against the hunk.  So in normal mode,
the same wrong output checked twice failed once, then passed.  The test
for that case asserted the pass; it now asserts a failure in normal mode
(and still a pass in regen mode, which stages the same body again).
diff --git a/lib/testmark/check.bash b/lib/testmark/check.bash
index 64f4c2d..3d1dcae 100644
--- a/lib/testmark/check.bash
+++ b/lib/testmark/check.bash
@@ -17,15 +17,13 @@ _testmark_check() {
 		return 1
 	}
 
-	# Two checks claiming one hunk is a harness bug, whether or not the first one matched.
+	# Two checks claiming one hunk with different output is a harness bug, whether or not the first one matched.
+	# The same output again is compared like the first time, so a mismatch can't pass by repetition.
 	local -n checked=_testmark_checked_$1
-	if [[ -n ${checked[$2]+set} ]]; then
-		[[ ${checked[$2]} == "$input" ]] || {
-			_testmark_err "$1: hunk \"$2\": checked twice, with different output"
-			return 1
-		}
-		return 0
-	fi
+	[[ ${checked[$2]-$input} == "$input" ]] || {
+		_testmark_err "$1: hunk \"$2\": checked twice, with different output"
+		return 1
+	}
 	checked[$2]=$input
 
 	_testmark_get_body "$1" "$2"
diff --git a/tests/test-check.sh b/tests/test-check.sh
index 0f61e6f..9c709bf 100755
--- a/tests/test-check.sh
+++ b/tests/test-check.sh
@@ -84,11 +84,14 @@ for mode in normal regen; do
 	expect_ok "$mode: none of which staged anything" testmark_write c
 	expect_eq "$mode: so the file is unchanged" "$(bytes c.md)" "$(esc "$(printf -- "$DOC")"$'\n')"
 
-	# Checking a hunk twice: the same output is fine, other output is an error, whether or not the first check matched.
+	# Checking a hunk twice: the same output is checked again like the first time, other output is an error, whether or not the first check matched.
 	for first in alpha omega; do
 		testmark_parse c c.md
 		"${run[@]}" testmark_check c a <<<"$first" 2>/dev/null || :
-		expect_ok "$mode: first $first, then the same again" "${run[@]}" testmark_check c a <<<"$first"
+		rc=0 want=0
+		"${run[@]}" testmark_check c a <<<"$first" 2>/dev/null || rc=$?
+		[[ $mode == regen || $first == alpha ]] || want=1
+		expect_eq "$mode: first $first, then the same again" "$rc" "$want"
 		expect_fail "$mode: first $first, then other output" 'testmark: c: hunk "a": checked twice, with different output' "${run[@]}" testmark_check c a <<<'other'
 		expect_fail "$mode: first $first, then glob characters" 'testmark: c: hunk "a": checked twice, with different output' "${run[@]}" testmark_check c a <<<'*'
 	done