chainlint.pl: check line numbers in expected output
While working on chainlint.pl recently, we introduced some bugs that
showed incorrect line numbers in the output. But it was hard to notice,
since we sanitize the output by removing all of the line numbers! It
would be nice to retain these so we can catch any regressions.
The main reason we sanitize is for maintainability: we concatenate all
of the test snippets into a single file, so it's hard for each ".expect"
file to know at which offset its test input will be found. We can handle
that by storing the per-test line numbers in the ".expect" files, and
then dynamically offsetting them as we build the concatenated test and
expect files together.
The changes to the ".expect" files look like tedious boilerplate, but it
actually makes adding new tests easier. You can now just run:
perl chainlint.pl chainlint/foo.test |
tail -n +2 >chainlint/foo.expect
to save the output of the script minus the comment headers (after
checking that it is correct, of course). Whereas before you had to strip
the line numbers. The conversions here were done mechanically using
something like the script above, and then spot-checked manually.
It would be possible to do all of this in shell via the Makefile, but it
gets a bit complicated (and requires a lot of extra processes). Instead,
I've written a short perl script that generates the concatenated files
(we already depend on perl, since chainlint.pl uses it). Incidentally,
this improves a few other things:
- we incorrectly used $(CHAINLINTTMP_SQ) inside a double-quoted
string. So if your test directory required quoting, like:
make "TEST_OUTPUT_DIRECTORY=/tmp/h'orrible"
we'd fail the chainlint tests.
- the shell in the Makefile didn't handle &&-chaining correctly in its
loops (though in practice the "sed" and "cat" invocations are not
likely to fail).
- likewise, the sed invocation to strip numbers was hiding the exit
code of chainlint.pl itself. In practice this isn't a big deal;
since there are linter violations in the test files, we expect it to
exit non-zero. But we could later use exit codes to distinguish
serious errors from expected ones.
- we now use a constant number of processes, instead of scaling with
the number of test scripts. So it should be a little faster (on my
machine, "make check-chainlint" goes from 133ms to 73ms).
There are some alternatives to this approach, but I think this is still
a good intermediate step:
1. We could invoke chainlint.pl individually on each test file, and
compare it to the expected output (and possibly using "make" to
avoid repeating already-done checks). This is a much bigger change
(and we'd have to figure out what to do with the "# LINT" lines in
the inputs). But in this case we'd still want the "expect" files to
be annotated with line numbers. So most of what's in this patch
would be needed anyway.
2. Likewise, we could run a single chainlint.pl and feed it all of the
scripts (with "--jobs=1" to get deterministic output). But we'd
still need to annotate the scripts as we did here, and we'd still
need to either assemble the "expect" file, or break apart the
script output to compare to each individual ".expect" file.
So we may pursue those in the long run, but this patch gives us more
robust tests without too much extra work or moving in a useless
direction.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff King committedJul 10, 2024 at 04:37 UTC03763e68fb7fc4b37dd2d184dde501618e6c171d
74 files changed+913-894
t/Makefile
+2-12
index e7a476966e..4c30e7c06f 100644--- a/t/Makefile+++ b/t/Makefile@@ -108,18 +108,8 @@ clean-chainlint: check-chainlint: @mkdir -p '$(CHAINLINTTMP_SQ)' && \- for i in $(CHAINLINTTESTS); do \- sed -e '/^# LINT: /d' chainlint/$$i.test; \- done >'$(CHAINLINTTMP_SQ)'/tests && \- { \- echo "# chainlint: $(CHAINLINTTMP_SQ)/tests" && \- for i in $(CHAINLINTTESTS); do \- echo "# chainlint: $$i" && \- cat chainlint/$$i.expect; \- done \- } >'$(CHAINLINTTMP_SQ)'/expect && \- $(CHAINLINT) --emit-all '$(CHAINLINTTMP_SQ)'/tests | \- sed -e 's/^[1-9][0-9]* //' >'$(CHAINLINTTMP_SQ)'/actual && \+ '$(PERL_PATH_SQ)' chainlint-cat.pl '$(CHAINLINTTMP_SQ)' $(CHAINLINTTESTS) && \+ { $(CHAINLINT) --emit-all '$(CHAINLINTTMP_SQ)'/tests >'$(CHAINLINTTMP_SQ)'/actual || true; } && \ diff -u '$(CHAINLINTTMP_SQ)'/expect '$(CHAINLINTTMP_SQ)'/actual test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax \
t/chainlint-cat.pl
+29
new file mode 100644index 0000000000..388f6e1e41--- /dev/null+++ b/t/chainlint-cat.pl@@ -0,0 +1,29 @@+#!/usr/bin/env perl++my $outdir = shift;+open(my $tests, '>', "$outdir/tests")+ or die "unable to open $outdir/tests: $!";+open(my $expect, '>', "$outdir/expect")+ or die "unable to open $outdir/expect: $!";++print $expect "# chainlint: $outdir/tests\n";++my $offset = 0;+for my $script (@ARGV) {+ print $expect "# chainlint: $script\n";++ open(my $expect_in, '<', "chainlint/$script.expect")+ or die "unable to open chainlint/$script.expect: $!";+ while (<$expect_in>) {+ s/^\d+/$& + $offset/e;+ print $expect $_;+ }++ open(my $test_in, '<', "chainlint/$script.test")+ or die "unable to open chainlint/$script.test: $!";+ while (<$test_in>) {+ /^# LINT: / and next;+ print $tests $_;+ $offset++;+ }+}
index cfb58fb6b9..9a1838736f 100644--- a/t/chainlint/broken-chain.expect+++ b/t/chainlint/broken-chain.expect@@ -1,6 +1,6 @@-(- foo &&- bar ?!AMP?!- baz &&- wop-)+2 (+3 foo &&+4 bar ?!AMP?!+5 baz &&+6 wop+7 )
t/chainlint/case-comment.expect
+11-11
index 641c157b98..2442dd5f25 100644--- a/t/chainlint/case-comment.expect+++ b/t/chainlint/case-comment.expect@@ -1,11 +1,11 @@-(- case "$x" in- # found foo- x) foo ;;- # found other- *)- # treat it as bar- bar- ;;- esac-)+2 (+3 case "$x" in+4 # found foo+5 x) foo ;;+6 # found other+7 *)+8 # treat it as bar+9 bar+10 ;;+11 esac+12 )
t/chainlint/case.expect
+19-19
index 31f280d8ce..c04c61ff36 100644--- a/t/chainlint/case.expect+++ b/t/chainlint/case.expect@@ -1,19 +1,19 @@-(- case "$x" in- x) foo ;;- *) bar ;;- esac &&- foobar-) &&-(- case "$x" in- x) foo ;;- *) bar ;;- esac ?!AMP?!- foobar-) &&-(- case "$x" in 1) true;; esac &&- case "$y" in 2) false;; esac ?!AMP?!- foobar-)+2 (+3 case "$x" in+4 x) foo ;;+5 *) bar ;;+6 esac &&+7 foobar+8 ) &&+9 (+10 case "$x" in+11 x) foo ;;+12 *) bar ;;+13 esac ?!AMP?!+14 foobar+15 ) &&+16 (+17 case "$x" in 1) true;; esac &&+18 case "$y" in 2) false;; esac ?!AMP?!+19 foobar+20 )
index 47a3457710..4bb60aae25 100644--- a/t/chainlint/chain-break-continue.expect+++ b/t/chainlint/chain-break-continue.expect@@ -1,12 +1,12 @@-git ls-tree --name-only -r refs/notes/many_notes |-while read path-do- test "$path" = "foobar/non-note.txt" && continue- test "$path" = "deadbeef" && continue- test "$path" = "de/adbeef" && continue-- if test $(expr length "$path") -ne $hexsz- then- return 1- fi-done+2 git ls-tree --name-only -r refs/notes/many_notes |+3 while read path+4 do+5 test "$path" = "foobar/non-note.txt" && continue+6 test "$path" = "deadbeef" && continue+7 test "$path" = "de/adbeef" && continue+8 +9 if test $(expr length "$path") -ne $hexsz+10 then+11 return 1+12 fi+13 done
t/chainlint/chain-break-false.expect
+9-9
index 989766fb85..4f815f8e14 100644--- a/t/chainlint/chain-break-false.expect+++ b/t/chainlint/chain-break-false.expect@@ -1,9 +1,9 @@-if condition not satisified-then- echo it did not work...- echo failed!- false-else- echo it went okay ?!AMP?!- congratulate user-fi+2 if condition not satisified+3 then+4 echo it did not work...+5 echo failed!+6 false+7 else+8 echo it went okay ?!AMP?!+9 congratulate user+10 fi
t/chainlint/chain-break-return-exit.expect
+19-19
index 4cd18e2edf..ba0ec51aa0 100644--- a/t/chainlint/chain-break-return-exit.expect+++ b/t/chainlint/chain-break-return-exit.expect@@ -1,19 +1,19 @@-case "$(git ls-files)" in-one) echo pass one ;;-*) echo bad one; return 1 ;;-esac &&-(- case "$(git ls-files)" in- two) echo pass two ;;- *) echo bad two; exit 1 ;;- esac-) &&-case "$(git ls-files)" in-dir/two"$LF"one) echo pass both ;;-*) echo bad; return 1 ;;-esac &&--for i in 1 2 3 4 ; do- git checkout main -b $i || return $?- test_commit $i $i $i tag$i || return $?-done+2 case "$(git ls-files)" in+3 one) echo pass one ;;+4 *) echo bad one; return 1 ;;+5 esac &&+6 (+7 case "$(git ls-files)" in+8 two) echo pass two ;;+9 *) echo bad two; exit 1 ;;+10 esac+11 ) &&+12 case "$(git ls-files)" in+13 dir/two"$LF"one) echo pass both ;;+14 *) echo bad; return 1 ;;+15 esac &&+16 +17 for i in 1 2 3 4 ; do+18 git checkout main -b $i || return $?+19 test_commit $i $i $i tag$i || return $?+20 done
index dac2d0fd1d..3a740103db 100644--- a/t/chainlint/complex-if-in-cuddled-loop.expect+++ b/t/chainlint/complex-if-in-cuddled-loop.expect@@ -1,9 +1,9 @@-(for i in a b c; do- if test "$(echo $(waffle bat))" = "eleventeen" &&- test "$x" = "$y"; then- :- else- echo >file- fi ?!LOOP?!- done) &&-test ! -f file+2 (for i in a b c; do+3 if test "$(echo $(waffle bat))" = "eleventeen" &&+4 test "$x" = "$y"; then+5 :+6 else+7 echo >file+8 fi ?!LOOP?!+9 done) &&+10 test ! -f file
index 765a35bb4c..078744b61b 100644--- a/t/chainlint/exclamation.expect+++ b/t/chainlint/exclamation.expect@@ -1,4 +1,4 @@-if ! condition; then echo nope; else yep; fi &&-test_prerequisite !MINGW &&-mail uucp!address &&-echo !whatever!+2 if ! condition; then echo nope; else yep; fi &&+3 test_prerequisite !MINGW &&+4 mail uucp!address &&+5 echo !whatever!
t/chainlint/exit-loop.expect
+24-24
index f76aa60466..407278094c 100644--- a/t/chainlint/exit-loop.expect+++ b/t/chainlint/exit-loop.expect@@ -1,24 +1,24 @@-(- for i in a b c- do- foo || exit 1- bar &&- baz- done-) &&-(- while true- do- foo || exit 1- bar &&- baz- done-) &&-(- i=0 &&- while test $i -lt 10- do- echo $i || exit- i=$(($i + 1))- done-)+2 (+3 for i in a b c+4 do+5 foo || exit 1+6 bar &&+7 baz+8 done+9 ) &&+10 (+11 while true+12 do+13 foo || exit 1+14 bar &&+15 baz+16 done+17 ) &&+18 (+19 i=0 &&+20 while test $i -lt 10+21 do+22 echo $i || exit+23 i=$(($i + 1))+24 done+25 )
t/chainlint/exit-subshell.expect
+5-5
index da80339f78..793db12453 100644--- a/t/chainlint/exit-subshell.expect+++ b/t/chainlint/exit-subshell.expect@@ -1,5 +1,5 @@-(- foo || exit 1- bar &&- baz-)+2 (+3 foo || exit 1+4 bar &&+5 baz+6 )
index d2237f1e38..908aeedf96 100644--- a/t/chainlint/for-loop.expect+++ b/t/chainlint/for-loop.expect@@ -1,14 +1,14 @@-(- for i in a b c- do- echo $i ?!AMP?!- cat <<-\EOF ?!LOOP?!- bar- EOF- done ?!AMP?!-- for i in a b c; do- echo $i &&- cat $i ?!LOOP?!- done-)+2 (+3 for i in a b c+4 do+5 echo $i ?!AMP?!+6 cat <<-\EOF ?!LOOP?!+7 bar+8 EOF+9 done ?!AMP?!+10 +11 for i in a b c; do+12 echo $i &&+13 cat $i ?!LOOP?!+14 done+15 )
index ee745ef8d7..9daf3d294a 100644--- a/t/chainlint/if-condition-split.expect+++ b/t/chainlint/if-condition-split.expect@@ -1,7 +1,7 @@-if bob &&- marcia ||- kevin-then- echo "nomads" ?!AMP?!- echo "for sure"-fi+2 if bob &&+3 marcia ||+4 kevin+5 then+6 echo "nomads" ?!AMP?!+7 echo "for sure"+8 fi
t/chainlint/if-in-loop.expect
+12-12
index d6514ae749..ff8c60dbdb 100644--- a/t/chainlint/if-in-loop.expect+++ b/t/chainlint/if-in-loop.expect@@ -1,12 +1,12 @@-(- for i in a b c- do- if false- then- echo "err"- exit 1- fi ?!AMP?!- foo- done ?!AMP?!- bar-)+2 (+3 for i in a b c+4 do+5 if false+6 then+7 echo "err"+8 exit 1+9 fi ?!AMP?!+10 foo+11 done ?!AMP?!+12 bar+13 )
t/chainlint/if-then-else.expect
+22-22
index cbaaf857d4..965d7e41a2 100644--- a/t/chainlint/if-then-else.expect+++ b/t/chainlint/if-then-else.expect@@ -1,22 +1,22 @@-(- if test -n ""- then- echo very ?!AMP?!- echo empty- elif test -z ""- then- echo foo- else- echo foo &&- cat <<-\EOF- bar- EOF- fi ?!AMP?!- echo poodle-) &&-(- if test -n ""; then- echo very &&- echo empty- fi-)+2 (+3 if test -n ""+4 then+5 echo very ?!AMP?!+6 echo empty+7 elif test -z ""+8 then+9 echo foo+10 else+11 echo foo &&+12 cat <<-\EOF+13 bar+14 EOF+15 fi ?!AMP?!+16 echo poodle+17 ) &&+18 (+19 if test -n ""; then+20 echo very &&+21 echo empty+22 fi+23 )
t/chainlint/incomplete-line.expect
+10-10
index 134d3a14f5..b15e00b901 100644--- a/t/chainlint/incomplete-line.expect+++ b/t/chainlint/incomplete-line.expect@@ -1,10 +1,10 @@-line 1 \-line 2 \-line 3 \-line 4 &&-(- line 5 \- line 6 \- line 7 \- line 8-)+2 line 1 \+3 line 2 \+4 line 3 \+5 line 4 &&+6 (+7 line 5 \+8 line 6 \+9 line 7 \+10 line 8+11 )
t/chainlint/inline-comment.expect
+8-8
index 6bad218530..0285c0b22c 100644--- a/t/chainlint/inline-comment.expect+++ b/t/chainlint/inline-comment.expect@@ -1,8 +1,8 @@-(- foobar && # comment 1- barfoo ?!AMP?! # wrong position for &&- flibble "not a # comment"-) &&--(cd foo &&- flibble "not a # comment")+2 (+3 foobar && # comment 1+4 barfoo ?!AMP?! # wrong position for &&+5 flibble "not a # comment"+6 ) &&+7 +8 (cd foo &&+9 flibble "not a # comment")
t/chainlint/loop-detect-failure.expect
+15-15
index a66025c39d..40c06f0d53 100644--- a/t/chainlint/loop-detect-failure.expect+++ b/t/chainlint/loop-detect-failure.expect@@ -1,15 +1,15 @@-git init r1 &&-for n in 1 2 3 4 5-do- echo "This is file: $n" > r1/file.$n &&- git -C r1 add file.$n &&- git -C r1 commit -m "$n" || return 1-done &&--git init r2 &&-for n in 1000 10000-do- printf "%"$n"s" X > r2/large.$n &&- git -C r2 add large.$n &&- git -C r2 commit -m "$n" ?!LOOP?!-done+2 git init r1 &&+3 for n in 1 2 3 4 5+4 do+5 echo "This is file: $n" > r1/file.$n &&+6 git -C r1 add file.$n &&+7 git -C r1 commit -m "$n" || return 1+8 done &&+9 +10 git init r2 &&+11 for n in 1000 10000+12 do+13 printf "%"$n"s" X > r2/large.$n &&+14 git -C r2 add large.$n &&+15 git -C r2 commit -m "$n" ?!LOOP?!+16 done
index 29b3832a98..70d9b68dc9 100644--- a/t/chainlint/nested-here-doc.expect+++ b/t/chainlint/nested-here-doc.expect@@ -1,30 +1,30 @@-cat <<ARBITRARY >foop &&-naddle-fub <<EOF- nozzle- noodle-EOF-formp-ARBITRARY--(- cat <<-\INPUT_END &&- fish are mice- but geese go slow- data <<EOF- perl is lerp- and nothing else- EOF- toink- INPUT_END-- cat <<-\EOT ?!AMP?!- text goes here- data <<EOF- data goes here- EOF- more test here- EOT-- foobar-)+2 cat <<ARBITRARY >foop &&+3 naddle+4 fub <<EOF+5 nozzle+6 noodle+7 EOF+8 formp+9 ARBITRARY+10 +11 (+12 cat <<-\INPUT_END &&+13 fish are mice+14 but geese go slow+15 data <<EOF+16 perl is lerp+17 and nothing else+18 EOF+19 toink+20 INPUT_END+21 +22 cat <<-\EOT ?!AMP?!+23 text goes here+24 data <<EOF+25 data goes here+26 EOF+27 more test here+28 EOT+29 +30 foobar+31 )
t/chainlint/nested-loop-detect-failure.expect
+31-31
index 3461df40e5..c13c4d2f90 100644--- a/t/chainlint/nested-loop-detect-failure.expect+++ b/t/chainlint/nested-loop-detect-failure.expect@@ -1,31 +1,31 @@-for i in 0 1 2 3 4 5 6 7 8 9;-do- for j in 0 1 2 3 4 5 6 7 8 9;- do- echo "$i$j" >"path$i$j" ?!LOOP?!- done ?!LOOP?!-done &&--for i in 0 1 2 3 4 5 6 7 8 9;-do- for j in 0 1 2 3 4 5 6 7 8 9;- do- echo "$i$j" >"path$i$j" || return 1- done-done &&--for i in 0 1 2 3 4 5 6 7 8 9;-do- for j in 0 1 2 3 4 5 6 7 8 9;- do- echo "$i$j" >"path$i$j" ?!LOOP?!- done || return 1-done &&--for i in 0 1 2 3 4 5 6 7 8 9;-do- for j in 0 1 2 3 4 5 6 7 8 9;- do- echo "$i$j" >"path$i$j" || return 1- done || return 1-done+2 for i in 0 1 2 3 4 5 6 7 8 9;+3 do+4 for j in 0 1 2 3 4 5 6 7 8 9;+5 do+6 echo "$i$j" >"path$i$j" ?!LOOP?!+7 done ?!LOOP?!+8 done &&+9 +10 for i in 0 1 2 3 4 5 6 7 8 9;+11 do+12 for j in 0 1 2 3 4 5 6 7 8 9;+13 do+14 echo "$i$j" >"path$i$j" || return 1+15 done+16 done &&+17 +18 for i in 0 1 2 3 4 5 6 7 8 9;+19 do+20 for j in 0 1 2 3 4 5 6 7 8 9;+21 do+22 echo "$i$j" >"path$i$j" ?!LOOP?!+23 done || return 1+24 done &&+25 +26 for i in 0 1 2 3 4 5 6 7 8 9;+27 do+28 for j in 0 1 2 3 4 5 6 7 8 9;+29 do+30 echo "$i$j" >"path$i$j" || return 1+31 done || return 1+32 done
t/chainlint/nested-subshell-comment.expect
+11-11
index 9138cf386d..f89a8d03a8 100644--- a/t/chainlint/nested-subshell-comment.expect+++ b/t/chainlint/nested-subshell-comment.expect@@ -1,11 +1,11 @@-(- foo &&- (- bar &&- # bottles wobble while fiddles gobble- # minor numbers of cows (or do they?)- baz &&- snaff- ) ?!AMP?!- fuzzy-)+2 (+3 foo &&+4 (+5 bar &&+6 # bottles wobble while fiddles gobble+7 # minor numbers of cows (or do they?)+8 baz &&+9 snaff+10 ) ?!AMP?!+11 fuzzy+12 )
t/chainlint/nested-subshell.expect
+13-13
index 73ff28546a..811e8a7912 100644--- a/t/chainlint/nested-subshell.expect+++ b/t/chainlint/nested-subshell.expect@@ -1,13 +1,13 @@-(- cd foo &&- (- echo a &&- echo b- ) >file &&-- cd foo &&- (- echo a ?!AMP?!- echo b- ) >file-)+2 (+3 cd foo &&+4 (+5 echo a &&+6 echo b+7 ) >file &&+8 +9 cd foo &&+10 (+11 echo a ?!AMP?!+12 echo b+13 ) >file+14 )
index 6a387917a7..64f3235d26 100644--- a/t/chainlint/token-pasting.expect+++ b/t/chainlint/token-pasting.expect@@ -1,27 +1,27 @@-git config filter.rot13.smudge ./rot13.sh &&-git config filter.rot13.clean ./rot13.sh &&--{- echo "*.t filter=rot13" ?!AMP?!- echo "*.i ident"-} >.gitattributes &&--{- echo a b c d e f g h i j k l m ?!AMP?!- echo n o p q r s t u v w x y z ?!AMP?!- echo '$Id$'-} >test &&-cat test >test.t &&-cat test >test.o &&-cat test >test.i &&-git add test test.t test.i &&-rm -f test test.t test.i &&-git checkout -- test test.t test.i &&--echo "content-test2" >test2.o &&-echo "content-test3 - filename with special characters" >"test3 'sq',$x=.o" ?!AMP?!--downstream_url_for_sed=$(- printf "%sn" "$downstream_url" |- sed -e 's/\/\\/g' -e 's/[[/.*^$]/\&/g'-)+2 git config filter.rot13.smudge ./rot13.sh &&+3 git config filter.rot13.clean ./rot13.sh &&+4 +5 {+6 echo "*.t filter=rot13" ?!AMP?!+7 echo "*.i ident"+8 } >.gitattributes &&+9 +10 {+11 echo a b c d e f g h i j k l m ?!AMP?!+12 echo n o p q r s t u v w x y z ?!AMP?!+13 echo '$Id$'+14 } >test &&+15 cat test >test.t &&+16 cat test >test.o &&+17 cat test >test.i &&+18 git add test test.t test.i &&+19 rm -f test test.t test.i &&+20 git checkout -- test test.t test.i &&+21 +22 echo "content-test2" >test2.o &&+23 echo "content-test3 - filename with special characters" >"test3 'sq',$x=.o" ?!AMP?!+24 +25 downstream_url_for_sed=$(+26 printf "%sn" "$downstream_url" |+27 sed -e 's/\/\\/g' -e 's/[[/.*^$]/\&/g'+28 )
t/chainlint/unclosed-here-doc-indent.expect
+4-4
index 7c30a1a024..f78e23cb63 100644--- a/t/chainlint/unclosed-here-doc-indent.expect+++ b/t/chainlint/unclosed-here-doc-indent.expect@@ -1,4 +1,4 @@-command_which_is_run &&-cat >expect <<-\EOF ?!UNCLOSED-HEREDOC?! &&-we forget to end the here-doc-command_which_is_gobbled+2 command_which_is_run &&+3 cat >expect <<-\EOF ?!UNCLOSED-HEREDOC?! &&+4 we forget to end the here-doc+5 command_which_is_gobbled
t/chainlint/unclosed-here-doc.expect
+7-7
index d65e50f78d..51304672cf 100644--- a/t/chainlint/unclosed-here-doc.expect+++ b/t/chainlint/unclosed-here-doc.expect@@ -1,7 +1,7 @@-command_which_is_run &&-cat >expect <<\EOF ?!UNCLOSED-HEREDOC?! &&- we try to end the here-doc below,- but the indentation throws us off- since the operator is not "<<-".- EOF-command_which_is_gobbled+2 command_which_is_run &&+3 cat >expect <<\EOF ?!UNCLOSED-HEREDOC?! &&+4 we try to end the here-doc below,+5 but the indentation throws us off+6 since the operator is not "<<-".+7 EOF+8 command_which_is_gobbled
t/chainlint/while-loop.expect
+14-14
index 06c1567f48..5ffabd5a93 100644--- a/t/chainlint/while-loop.expect+++ b/t/chainlint/while-loop.expect@@ -1,14 +1,14 @@-(- while true- do- echo foo ?!AMP?!- cat <<-\EOF ?!LOOP?!- bar- EOF- done ?!AMP?!-- while true; do- echo foo &&- cat bar ?!LOOP?!- done-)+2 (+3 while true+4 do+5 echo foo ?!AMP?!+6 cat <<-\EOF ?!LOOP?!+7 bar+8 EOF+9 done ?!AMP?!+10 +11 while true; do+12 echo foo &&+13 cat bar ?!LOOP?!+14 done+15 )