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>
This commit is contained in:
Jeff King 2024-07-10 04:37:55 -04:00 committed by Junio C Hamano
parent 382f6edaee
commit 03763e68fb
74 changed files with 913 additions and 894 deletions

View file

@ -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 \

29
t/chainlint-cat.pl Normal file
View file

@ -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++;
}
}

View file

@ -1,9 +1,9 @@
(
foo &&
bar=$((42 + 1)) &&
baz
) &&
(
bar=$((42 + 1)) ?!AMP?!
baz
)
2 (
3 foo &&
4 bar=$((42 + 1)) &&
5 baz
6 ) &&
7 (
8 bar=$((42 + 1)) ?!AMP?!
9 baz
10 )

View file

@ -1,10 +1,10 @@
(
foo &&
bar=(gumbo stumbo wumbo) &&
baz
) &&
(
foo &&
bar=${#bar[@]} &&
baz
)
2 (
3 foo &&
4 bar=(gumbo stumbo wumbo) &&
5 baz
6 ) &&
7 (
8 foo &&
9 bar=${#bar[@]} &&
10 baz
11 )

View file

@ -1,18 +1,18 @@
test_done () {
case "$test_failure" in
0)
test_at_end_hook_
exit 0 ;;
*)
if test $test_external_has_tap -eq 0
then
say_color error "# failed $test_failure among $msg"
say "1..$test_count"
fi
exit 1 ;;
esac
}
2 test_done () {
3 case "$test_failure" in
4 0)
5 test_at_end_hook_
6
7 exit 0 ;;
8
9 *)
10 if test $test_external_has_tap -eq 0
11 then
12 say_color error "# failed $test_failure among $msg"
13 say "1..$test_count"
14 fi
15
16 exit 1 ;;
17
18 esac
19 }

View file

@ -1,8 +1,8 @@
(
nothing &&
something
)
2 (
3
4 nothing &&
5
6 something
7
8
9 )

View file

@ -1,8 +1,8 @@
(
{
# show a
echo a &&
# show b
echo b
}
)
2 (
3 {
4 # show a
5 echo a &&
6 # show b
7 echo b
8 }
9 )

View file

@ -1,23 +1,23 @@
(
foo &&
{
echo a ?!AMP?!
echo b
} &&
bar &&
{
echo c
} ?!AMP?!
baz
) &&
{
echo a; ?!AMP?! echo b
} &&
{ echo a; ?!AMP?! echo b; } &&
{
echo "${var}9" &&
echo "done"
} &&
finis
2 (
3 foo &&
4 {
5 echo a ?!AMP?!
6 echo b
7 } &&
8 bar &&
9 {
10 echo c
11 } ?!AMP?!
12 baz
13 ) &&
14
15 {
16 echo a; ?!AMP?! echo b
17 } &&
18 { echo a; ?!AMP?! echo b; } &&
19
20 {
21 echo "${var}9" &&
22 echo "done"
23 } &&
24 finis

View file

@ -1,6 +1,6 @@
(
foo &&
bar ?!AMP?!
baz &&
wop
)
2 (
3 foo &&
4 bar ?!AMP?!
5 baz &&
6 wop
7 )

View file

@ -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 )

View file

@ -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 )

View file

@ -1,9 +1,9 @@
JGIT_DAEMON_PID= &&
git init --bare empty.git &&
>empty.git/git-daemon-export-ok &&
mkfifo jgit_daemon_output &&
{
jgit daemon --port="$JGIT_DAEMON_PORT" . >jgit_daemon_output &
JGIT_DAEMON_PID=$!
} &&
test_expect_code 2 git ls-remote --exit-code git://localhost:$JGIT_DAEMON_PORT/empty.git
2 JGIT_DAEMON_PID= &&
3 git init --bare empty.git &&
4 >empty.git/git-daemon-export-ok &&
5 mkfifo jgit_daemon_output &&
6 {
7 jgit daemon --port="$JGIT_DAEMON_PORT" . >jgit_daemon_output &
8 JGIT_DAEMON_PID=$!
9 } &&
10 test_expect_code 2 git ls-remote --exit-code git://localhost:$JGIT_DAEMON_PORT/empty.git

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -1,9 +1,9 @@
OUT=$( ((large_git; echo $? 1>&3) | :) 3>&1 ) &&
test_match_signal 13 "$OUT" &&
{ test-tool sigchain >actual; ret=$?; } &&
{
test_match_signal 15 "$ret" ||
test "$ret" = 3
} &&
test_cmp expect actual
2 OUT=$( ((large_git; echo $? 1>&3) | :) 3>&1 ) &&
3 test_match_signal 13 "$OUT" &&
4
5 { test-tool sigchain >actual; ret=$?; } &&
6 {
7 test_match_signal 15 "$ret" ||
8 test "$ret" = 3
9 } &&
10 test_cmp expect actual

View file

@ -1,9 +1,9 @@
echo nobody home && {
test the doohicky ?!AMP?!
right now
} &&
GIT_EXTERNAL_DIFF=echo git diff | {
read path oldfile oldhex oldmode newfile newhex newmode &&
test "z$oh" = "z$oldhex"
}
2 echo nobody home && {
3 test the doohicky ?!AMP?!
4 right now
5 } &&
6
7 GIT_EXTERNAL_DIFF=echo git diff | {
8 read path oldfile oldhex oldmode newfile newhex newmode &&
9 test "z$oh" = "z$oldhex"
10 }

View file

@ -1,10 +1,10 @@
mkdir sub && (
cd sub &&
foo the bar ?!AMP?!
nuff said
) &&
cut "-d " -f actual | (read s1 s2 s3 &&
test -f $s1 ?!AMP?!
test $(cat $s2) = tree2path1 &&
test $(cat $s3) = tree3path1)
2 mkdir sub && (
3 cd sub &&
4 foo the bar ?!AMP?!
5 nuff said
6 ) &&
7
8 cut "-d " -f actual | (read s1 s2 s3 &&
9 test -f $s1 ?!AMP?!
10 test $(cat $s2) = tree2path1 &&
11 test $(cat $s3) = tree3path1)

View file

@ -1,3 +1,3 @@
(cd foo &&
(bar &&
baz))
2 (cd foo &&
3 (bar &&
4 baz))

View file

@ -1,26 +1,26 @@
(
foo
) &&
(
bar
) >out &&
(
baz
) 2>err &&
(
boo
) <input &&
(
bip
) | wuzzle &&
(
bop
) | fazz \
fozz &&
(
bup
) |
fuzzle &&
(
yop
)
2 (
3 foo
4 ) &&
5 (
6 bar
7 ) >out &&
8 (
9 baz
10 ) 2>err &&
11 (
12 boo
13 ) <input &&
14 (
15 bip
16 ) | wuzzle &&
17 (
18 bop
19 ) | fazz \
20 fozz &&
21 (
22 bup
23 ) |
24 fuzzle &&
25 (
26 yop
27 )

View file

@ -1,2 +1,2 @@
OUT=$( ((large_git 1>&3) | :) 3>&1 ) &&
test_match_signal 13 "$OUT"
2 OUT=$( ((large_git 1>&3) | :) 3>&1 ) &&
3 test_match_signal 13 "$OUT"

View file

@ -1,9 +1,9 @@
(
foo &&
bar=$(gobble) &&
baz
) &&
(
bar=$(gobble blocks) ?!AMP?!
baz
)
2 (
3 foo &&
4 bar=$(gobble) &&
5 baz
6 ) &&
7 (
8 bar=$(gobble blocks) ?!AMP?!
9 baz
10 )

View file

@ -1,8 +1,8 @@
(
# comment 1
nothing &&
# comment 2
something
# comment 3
# comment 4
)
2 (
3 # comment 1
4 nothing &&
5 # comment 2
6 something
7 # comment 3
8 # comment 4
9 )

View file

@ -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

View file

@ -1,6 +1,6 @@
(if test -z ""; then
echo empty
else
echo bizzy
fi) &&
echo foobar
2 (if test -z ""; then
3 echo empty
4 else
5 echo bizzy
6 fi) &&
7 echo foobar

View file

@ -1,4 +1,4 @@
( while read x
do foobar bop || exit 1
done <file ) &&
outside subshell
2 ( while read x
3 do foobar bop || exit 1
4 done <file ) &&
5 outside subshell

View file

@ -1,17 +1,17 @@
(cd foo &&
bar
) &&
(cd foo ?!AMP?!
bar
) &&
(
cd foo &&
bar) &&
(cd foo &&
bar) &&
(cd foo ?!AMP?!
bar)
2 (cd foo &&
3 bar
4 ) &&
5
6 (cd foo ?!AMP?!
7 bar
8 ) &&
9
10 (
11 cd foo &&
12 bar) &&
13
14 (cd foo &&
15 bar) &&
16
17 (cd foo ?!AMP?!
18 bar)

View file

@ -1,12 +1,12 @@
run_sub_test_lib_test_err run-inv-range-start \
"--run invalid range start" \
--run="a-5" <<-\EOF &&
test_expect_success "passing test #1" "true"
test_done
EOF
check_sub_test_lib_test_err run-inv-range-start \
<<-\EOF_OUT 3<<-EOF_ERR
> FATAL: Unexpected exit with code 1
EOF_OUT
> error: --run: invalid non-numeric in range start: ${SQ}a-5${SQ}
EOF_ERR
2 run_sub_test_lib_test_err run-inv-range-start \
3 "--run invalid range start" \
4 --run="a-5" <<-\EOF &&
5 test_expect_success "passing test #1" "true"
6 test_done
7 EOF
8 check_sub_test_lib_test_err run-inv-range-start \
9 <<-\EOF_OUT 3<<-EOF_ERR
10 > FATAL: Unexpected exit with code 1
11 EOF_OUT
12 > error: --run: invalid non-numeric in range start: ${SQ}a-5${SQ}
13 EOF_ERR

View file

@ -1,5 +1,5 @@
echo 'fatal: reword option of --fixup is mutually exclusive with' '--patch/--interactive/--all/--include/--only' >expect &&
test_must_fail git commit --fixup=reword:HEAD~ $1 2>actual &&
test_cmp expect actual
2
3 echo 'fatal: reword option of --fixup is mutually exclusive with' '--patch/--interactive/--all/--include/--only' >expect &&
4 test_must_fail git commit --fixup=reword:HEAD~ $1 2>actual &&
5 test_cmp expect actual
6

View file

@ -1,12 +1,12 @@
grep "^ ! [rejected][ ]*$BRANCH -> $BRANCH (non-fast-forward)$" out &&
grep "^\.git$" output.txt &&
(
cd client$version &&
GIT_TEST_PROTOCOL_VERSION=$version git fetch-pack --no-progress .. $(cat ../input)
) >output &&
cut -d ' ' -f 2 <output | sort >actual &&
test_cmp expect actual
2 grep "^ ! [rejected][ ]*$BRANCH -> $BRANCH (non-fast-forward)$" out &&
3
4 grep "^\.git$" output.txt &&
5
6
7 (
8 cd client$version &&
9 GIT_TEST_PROTOCOL_VERSION=$version git fetch-pack --no-progress .. $(cat ../input)
10 ) >output &&
11 cut -d ' ' -f 2 <output | sort >actual &&
12 test_cmp expect actual
13

View file

@ -1,4 +1,4 @@
git ls-tree $tree path >current &&
cat >expected <<\EOF &&
EOF
test_output
2 git ls-tree $tree path >current &&
3 cat >expected <<\EOF &&
4 EOF
5 test_output

View file

@ -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!

View file

@ -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 )

View file

@ -1,5 +1,5 @@
(
foo || exit 1
bar &&
baz
)
2 (
3 foo || exit 1
4 bar &&
5 baz
6 )

View file

@ -1,5 +1,5 @@
for it
do
path=$(expr "$it" : ([^:]*)) &&
git update-index --add "$path" || exit
done
2 for it
3 do
4 path=$(expr "$it" : ([^:]*)) &&
5 git update-index --add "$path" || exit
6 done

View file

@ -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 )

View file

@ -1,11 +1,11 @@
sha1_file() {
echo "$*" | sed "s#..#.git/objects/&/#"
} &&
remove_object() {
file=$(sha1_file "$*") &&
test -e "$file" ?!AMP?!
rm -f "$file"
} ?!AMP?!
sha1_file arg && remove_object arg
2 sha1_file() {
3 echo "$*" | sed "s#..#.git/objects/&/#"
4 } &&
5
6 remove_object() {
7 file=$(sha1_file "$*") &&
8 test -e "$file" ?!AMP?!
9 rm -f "$file"
10 } ?!AMP?!
11
12 sha1_file arg && remove_object arg

View file

@ -1,4 +1,4 @@
(
cat <<-\INPUT)
fizz
INPUT
2 (
3 cat <<-\INPUT)
4 fizz
5 INPUT

View file

@ -1,11 +1,11 @@
cat >expect <<- EOF &&
header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0
num_commits: $1
chunks: oid_fanout oid_lookup commit_metadata generation_data bloom_indexes bloom_data
EOF
cat >expect << -EOF ?!AMP?!
this is not indented
-EOF
cleanup
2 cat >expect <<- EOF &&
3 header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0
4 num_commits: $1
5 chunks: oid_fanout oid_lookup commit_metadata generation_data bloom_indexes bloom_data
6 EOF
7
8 cat >expect << -EOF ?!AMP?!
9 this is not indented
10 -EOF
11
12 cleanup

View file

@ -1,8 +1,8 @@
(
x=$(bobble <<-\END &&
fossil
vegetable
END
wiffle) ?!AMP?!
echo $x
)
2 (
3 x=$(bobble <<-\END &&
4 fossil
5 vegetable
6 END
7 wiffle) ?!AMP?!
8 echo $x
9 )

View file

@ -1,7 +1,7 @@
(
cat <<-\TXT && echo "multi-line
string" ?!AMP?!
fizzle
TXT
bap
)
2 (
3 cat <<-\TXT && echo "multi-line
4 string" ?!AMP?!
5 fizzle
6 TXT
7 bap
8 )

View file

@ -1,25 +1,25 @@
boodle wobba \
gorgo snoot \
wafta snurb <<EOF &&
quoth the raven,
nevermore...
EOF
cat <<-Arbitrary_Tag_42 >foo &&
snoz
boz
woz
Arbitrary_Tag_42
cat <<"zump" >boo &&
snoz
boz
woz
zump
horticulture <<\EOF
gomez
morticia
wednesday
pugsly
EOF
2 boodle wobba \
3 gorgo snoot \
4 wafta snurb <<EOF &&
5 quoth the raven,
6 nevermore...
7 EOF
8
9 cat <<-Arbitrary_Tag_42 >foo &&
10 snoz
11 boz
12 woz
13 Arbitrary_Tag_42
14
15 cat <<"zump" >boo &&
16 snoz
17 boz
18 woz
19 zump
20
21 horticulture <<\EOF
22 gomez
23 morticia
24 wednesday
25 pugsly
26 EOF

View file

@ -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

View file

@ -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 )

View file

@ -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 )

View file

@ -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 )

View file

@ -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")

View file

@ -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

View file

@ -1,18 +1,18 @@
(while test $i -le $blobcount
do
printf "Generating blob $i/$blobcount\r" >&2 &&
printf "blob\nmark :$i\ndata $blobsize\n" &&
#test-tool genrandom $i $blobsize &&
printf "%-${blobsize}s" $i &&
echo "M 100644 :$i $i" >> commit &&
i=$(($i+1)) ||
echo $? > exit-status
done &&
echo "commit refs/heads/main" &&
echo "author A U Thor <author@email.com> 123456789 +0000" &&
echo "committer C O Mitter <committer@email.com> 123456789 +0000" &&
echo "data 5" &&
echo ">2gb" &&
cat commit) |
git fast-import --big-file-threshold=2 &&
test ! -f exit-status
2 (while test $i -le $blobcount
3 do
4 printf "Generating blob $i/$blobcount\r" >&2 &&
5 printf "blob\nmark :$i\ndata $blobsize\n" &&
6 #test-tool genrandom $i $blobsize &&
7 printf "%-${blobsize}s" $i &&
8 echo "M 100644 :$i $i" >> commit &&
9 i=$(($i+1)) ||
10 echo $? > exit-status
11 done &&
12 echo "commit refs/heads/main" &&
13 echo "author A U Thor <author@email.com> 123456789 +0000" &&
14 echo "committer C O Mitter <committer@email.com> 123456789 +0000" &&
15 echo "data 5" &&
16 echo ">2gb" &&
17 cat commit) |
18 git fast-import --big-file-threshold=2 &&
19 test ! -f exit-status

View file

@ -1,12 +1,12 @@
(
if true
then
while true
do
echo "pop" ?!AMP?!
echo "glup" ?!LOOP?!
done ?!AMP?!
foo
fi ?!AMP?!
bar
)
2 (
3 if true
4 then
5 while true
6 do
7 echo "pop" ?!AMP?!
8 echo "glup" ?!LOOP?!
9 done ?!AMP?!
10 foo
11 fi ?!AMP?!
12 bar
13 )

View file

@ -1,10 +1,10 @@
(
git rev-list --objects --no-object-names base..loose |
while read oid
do
path="$objdir/$(test_oid_to_path "$oid")" &&
printf "%s %d\n" "$oid" "$(test-tool chmtime --get "$path")" ||
echo "object list generation failed for $oid"
done |
sort -k1
) >expect &&
2 (
3 git rev-list --objects --no-object-names base..loose |
4 while read oid
5 do
6 path="$objdir/$(test_oid_to_path "$oid")" &&
7 printf "%s %d\n" "$oid" "$(test-tool chmtime --get "$path")" ||
8 echo "object list generation failed for $oid"
9 done |
10 sort -k1
11 ) >expect &&

View file

@ -1,18 +1,18 @@
(
foo &&
x=$(
echo bar |
cat
) &&
echo ok
) |
sort &&
(
bar &&
x=$(echo bar |
cat
) &&
y=$(echo baz |
fip) &&
echo fail
)
2 (
3 foo &&
4 x=$(
5 echo bar |
6 cat
7 ) &&
8 echo ok
9 ) |
10 sort &&
11 (
12 bar &&
13 x=$(echo bar |
14 cat
15 ) &&
16 y=$(echo baz |
17 fip) &&
18 echo fail
19 )

View file

@ -1,14 +1,14 @@
(
x="line 1
line 2
line 3" &&
y="line 1
line2" ?!AMP?!
foobar
) &&
(
echo "xyz" "abc
def
ghi" &&
barfoo
)
2 (
3 x="line 1
4 line 2
5 line 3" &&
6 y="line 1
7 line2" ?!AMP?!
8 foobar
9 ) &&
10 (
11 echo "xyz" "abc
12 def
13 ghi" &&
14 barfoo
15 )

View file

@ -1,5 +1,5 @@
! (foo && bar) &&
! (foo && bar) >baz &&
! (foo; ?!AMP?! bar) &&
! (foo; ?!AMP?! bar) >baz
2 ! (foo && bar) &&
3 ! (foo && bar) >baz &&
4
5 ! (foo; ?!AMP?! bar) &&
6 ! (foo; ?!AMP?! bar) >baz

View file

@ -1,25 +1,25 @@
(
(cd foo &&
bar
) &&
(cd foo &&
bar
) ?!AMP?!
(
cd foo &&
bar) &&
(
cd foo &&
bar) ?!AMP?!
(cd foo &&
bar) &&
(cd foo &&
bar) ?!AMP?!
foobar
)
2 (
3 (cd foo &&
4 bar
5 ) &&
6
7 (cd foo &&
8 bar
9 ) ?!AMP?!
10
11 (
12 cd foo &&
13 bar) &&
14
15 (
16 cd foo &&
17 bar) ?!AMP?!
18
19 (cd foo &&
20 bar) &&
21
22 (cd foo &&
23 bar) ?!AMP?!
24
25 foobar
26 )

View file

@ -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 )

View file

@ -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

View file

@ -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 )

View file

@ -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 )

View file

@ -1,14 +1,14 @@
echo "<<<<<<< ours" &&
echo ourside &&
echo "=======" &&
echo theirside &&
echo ">>>>>>> theirs" &&
(
echo "<<<<<<< ours" &&
echo ourside &&
echo "=======" &&
echo theirside &&
echo ">>>>>>> theirs" ?!AMP?!
poodle
) >merged
2 echo "<<<<<<< ours" &&
3 echo ourside &&
4 echo "=======" &&
5 echo theirside &&
6 echo ">>>>>>> theirs" &&
7
8 (
9 echo "<<<<<<< ours" &&
10 echo ourside &&
11 echo "=======" &&
12 echo theirside &&
13 echo ">>>>>>> theirs" ?!AMP?!
14 poodle
15 ) >merged

View file

@ -1,9 +1,9 @@
git init dir-rename-and-content &&
(
cd dir-rename-and-content &&
test_write_lines 1 2 3 4 5 >foo &&
mkdir olddir &&
for i in a b c; do echo $i >olddir/$i; ?!LOOP?! done ?!AMP?!
git add foo olddir &&
git commit -m "original" &&
)
2 git init dir-rename-and-content &&
3 (
4 cd dir-rename-and-content &&
5 test_write_lines 1 2 3 4 5 >foo &&
6 mkdir olddir &&
7 for i in a b c; do echo $i >olddir/$i; ?!LOOP?! done ?!AMP?!
8 git add foo olddir &&
9 git commit -m "original" &&
10 )

View file

@ -1,9 +1,9 @@
(foo && bar) &&
(foo && bar) |
(foo && bar) >baz &&
(foo; ?!AMP?! bar) &&
(foo; ?!AMP?! bar) |
(foo; ?!AMP?! bar) >baz &&
(foo "bar; baz")
2 (foo && bar) &&
3 (foo && bar) |
4 (foo && bar) >baz &&
5
6 (foo; ?!AMP?! bar) &&
7 (foo; ?!AMP?! bar) |
8 (foo; ?!AMP?! bar) >baz &&
9
10 (foo "bar; baz")

View file

@ -1,4 +1,4 @@
(
p4 print -1 //depot/fiddle#42 >file &&
foobar
)
2 (
3 p4 print -1 //depot/fiddle#42 >file &&
4 foobar
5 )

View file

@ -1,10 +1,10 @@
(
foo |
bar |
baz &&
fish |
cow ?!AMP?!
sunder
)
2 (
3 foo |
4 bar |
5 baz &&
6
7 fish |
8 cow ?!AMP?!
9
10 sunder
11 )

View file

@ -1,5 +1,5 @@
while test $i -lt $((num - 5))
do
git notes add -m "notes for commit$i" HEAD~$i || return 1
i=$((i + 1))
done
2 while test $i -lt $((num - 5))
3 do
4 git notes add -m "notes for commit$i" HEAD~$i || return 1
5 i=$((i + 1))
6 done

View file

@ -1,19 +1,19 @@
(
cat foo ; ?!AMP?! echo bar ?!AMP?!
cat foo ; ?!AMP?! echo bar
) &&
(
cat foo ; ?!AMP?! echo bar &&
cat foo ; ?!AMP?! echo bar
) &&
(
echo "foo; bar" &&
cat foo; ?!AMP?! echo bar
) &&
(
foo;
) &&
(cd foo &&
for i in a b c; do
echo; ?!LOOP?!
done)
2 (
3 cat foo ; ?!AMP?! echo bar ?!AMP?!
4 cat foo ; ?!AMP?! echo bar
5 ) &&
6 (
7 cat foo ; ?!AMP?! echo bar &&
8 cat foo ; ?!AMP?! echo bar
9 ) &&
10 (
11 echo "foo; bar" &&
12 cat foo; ?!AMP?! echo bar
13 ) &&
14 (
15 foo;
16 ) &&
17 (cd foo &&
18 for i in a b c; do
19 echo; ?!LOOP?!
20 done)

View file

@ -1,4 +1,4 @@
perl -e '
defined($_ = -s $_) or die for @ARGV;
exit 1 if $ARGV[0] <= $ARGV[1];
' test-2-$packname_2.pack test-3-$packname_3.pack
2 perl -e '
3 defined($_ = -s $_) or die for @ARGV;
4 exit 1 if $ARGV[0] <= $ARGV[1];
5 ' test-2-$packname_2.pack test-3-$packname_3.pack

View file

@ -1,30 +1,30 @@
(
echo wobba \
gorgo snoot \
wafta snurb <<-EOF &&
quoth the raven,
nevermore...
EOF
cat <<EOF >bip ?!AMP?!
fish fly high
EOF
echo <<-\EOF >bop
gomez
morticia
wednesday
pugsly
EOF
) &&
(
cat <<-\ARBITRARY >bup &&
glink
FIZZ
ARBITRARY
cat <<-"ARBITRARY3" >bup3 &&
glink
FIZZ
ARBITRARY3
meep
)
2 (
3 echo wobba \
4 gorgo snoot \
5 wafta snurb <<-EOF &&
6 quoth the raven,
7 nevermore...
8 EOF
9
10 cat <<EOF >bip ?!AMP?!
11 fish fly high
12 EOF
13
14 echo <<-\EOF >bop
15 gomez
16 morticia
17 wednesday
18 pugsly
19 EOF
20 ) &&
21 (
22 cat <<-\ARBITRARY >bup &&
23 glink
24 FIZZ
25 ARBITRARY
26 cat <<-"ARBITRARY3" >bup3 &&
27 glink
28 FIZZ
29 ARBITRARY3
30 meep
31 )

View file

@ -1,19 +1,19 @@
(
(foo && bar) &&
(foo && bar) |
(foo && bar) >baz &&
(foo; ?!AMP?! bar) &&
(foo; ?!AMP?! bar) |
(foo; ?!AMP?! bar) >baz &&
(foo || exit 1) &&
(foo || exit 1) |
(foo || exit 1) >baz &&
(foo && bar) ?!AMP?!
(foo && bar; ?!AMP?! baz) ?!AMP?!
foobar
)
2 (
3 (foo && bar) &&
4 (foo && bar) |
5 (foo && bar) >baz &&
6
7 (foo; ?!AMP?! bar) &&
8 (foo; ?!AMP?! bar) |
9 (foo; ?!AMP?! bar) >baz &&
10
11 (foo || exit 1) &&
12 (foo || exit 1) |
13 (foo || exit 1) >baz &&
14
15 (foo && bar) ?!AMP?!
16
17 (foo && bar; ?!AMP?! baz) ?!AMP?!
18
19 foobar
20 )

View file

@ -1,22 +1,22 @@
(
chks="sub1
sub2
sub3
sub4" &&
chks_sub=$(cat <<TXT | sed "s,^,sub dir/,"
$chks
TXT
) &&
chkms="main-sub1
main-sub2
main-sub3
main-sub4" &&
chkms_sub=$(cat <<TXT | sed "s,^,sub dir/,"
$chkms
TXT
) &&
subfiles=$(git ls-files) &&
check_equal "$subfiles" "$chkms
$chks"
)
2 (
3 chks="sub1
4 sub2
5 sub3
6 sub4" &&
7 chks_sub=$(cat <<TXT | sed "s,^,sub dir/,"
8 $chks
9 TXT
10 ) &&
11 chkms="main-sub1
12 main-sub2
13 main-sub3
14 main-sub4" &&
15 chkms_sub=$(cat <<TXT | sed "s,^,sub dir/,"
16 $chkms
17 TXT
18 ) &&
19
20 subfiles=$(git ls-files) &&
21 check_equal "$subfiles" "$chkms
22 $chks"
23 )

View file

@ -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 )

View file

@ -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

View file

@ -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

View file

@ -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 )