Merge branch 'jk/test-body-in-here-doc'

The test framework learned to take the test body not as a single
string but as a here-document.

* jk/test-body-in-here-doc:
  t/.gitattributes: ignore whitespace in chainlint expect files
  t: convert some here-doc test bodies
  test-lib: allow test snippets as here-docs
  chainlint.pl: add tests for test body in heredoc
  chainlint.pl: recognize test bodies defined via heredoc
  chainlint.pl: check line numbers in expected output
  chainlint.pl: force CRLF conversion when opening input files
  chainlint.pl: do not spawn more threads than we have scripts
  chainlint.pl: only start threads if jobs > 1
  chainlint.pl: add test_expect_success call to test snippets
This commit is contained in:
Junio C Hamano
2024-07-17 10:47:24 -07:00
160 changed files with 1286 additions and 1026 deletions

2
t/.gitattributes vendored
View File

@ -1,5 +1,5 @@
t[0-9][0-9][0-9][0-9]/* -whitespace
/chainlint/*.expect eol=lf
/chainlint/*.expect eol=lf -whitespace
/t0110/url-* binary
/t3206/* eol=lf
/t3900/*.txt eol=lf

View File

@ -108,20 +108,8 @@ clean-chainlint:
check-chainlint:
@mkdir -p '$(CHAINLINTTMP_SQ)' && \
for i in $(CHAINLINTTESTS); do \
echo "test_expect_success '$$i' '" && \
sed -e '/^# LINT: /d' chainlint/$$i.test && \
echo "'"; \
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 \

View File

@ -882,6 +882,14 @@ see test-lib-functions.sh for the full list and their options.
'git-write-tree should be able to write an empty tree.' \
'tree=$(git-write-tree)'
If <script> is `-` (a single dash), then the script to run is read
from stdin. This lets you more easily use single quotes within the
script by using a here-doc. For example:
test_expect_success 'output contains expected string' - <<\EOT
grep "this string has 'quotes' in it" output
EOT
If you supply three parameters the first will be taken to be a
prerequisite; see the test_set_prereq and test_have_prereq
documentation below:

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

@ -174,6 +174,10 @@ sub swallow_heredocs {
$$b =~ /(?:\G|\n)$indent\Q$$tag[0]\E(?:\n|\z)/gc;
if (pos($$b) > $start) {
my $body = substr($$b, $start, pos($$b) - $start);
$self->{parser}->{heredocs}->{$$tag[0]} = {
content => substr($body, 0, length($body) - length($&)),
start_line => $self->{lineno},
};
$self->{lineno} += () = $body =~ /\n/sg;
next;
}
@ -232,7 +236,8 @@ sub new {
my $self = bless {
buff => [],
stop => [],
output => []
output => [],
heredocs => {},
} => $class;
$self->{lexer} = Lexer->new($self, $s);
return $self;
@ -616,14 +621,21 @@ sub unwrap {
sub check_test {
my $self = shift @_;
my ($title, $body) = map(unwrap, @_);
my $title = unwrap(shift @_);
my $body = shift @_;
my $lineno = $body->[3];
$body = unwrap($body);
if ($body eq '-') {
my $herebody = shift @_;
$body = $herebody->{content};
$lineno = $herebody->{start_line};
}
$self->{ntests}++;
my $parser = TestParser->new(\$body);
my @tokens = $parser->parse();
my $problems = $parser->{problems};
return unless $emit_all || @$problems;
my $c = main::fd_colors(1);
my $lineno = $_[1]->[3];
my $start = 0;
my $checked = '';
for (sort {$a->[1]->[2] <=> $b->[1]->[2]} @$problems) {
@ -649,8 +661,13 @@ sub parse_cmd {
return @tokens unless @tokens && $tokens[0]->[0] =~ /^test_expect_(?:success|failure)$/;
my $n = $#tokens;
$n-- while $n >= 0 && $tokens[$n]->[0] =~ /^(?:[;&\n|]|&&|\|\|)$/;
$self->check_test($tokens[1], $tokens[2]) if $n == 2; # title body
$self->check_test($tokens[2], $tokens[3]) if $n > 2; # prereq title body
my $herebody;
if ($n >= 2 && $tokens[$n-1]->[0] eq '-' && $tokens[$n]->[0] =~ /^<<-?(.+)$/) {
$herebody = $self->{heredocs}->{$1};
$n--;
}
$self->check_test($tokens[1], $tokens[2], $herebody) if $n == 2; # title body
$self->check_test($tokens[2], $tokens[3], $herebody) if $n > 2; # prereq title body
return @tokens;
}
@ -762,7 +779,7 @@ sub check_script {
while (my $path = $next_script->()) {
$nscripts++;
my $fh;
unless (open($fh, "<", $path)) {
unless (open($fh, "<:unix:crlf", $path)) {
$emit->("?!ERR?! $path: $!\n");
next;
}
@ -806,8 +823,10 @@ unless (@scripts) {
show_stats($start_time, \@stats) if $show_stats;
exit;
}
$jobs = @scripts if @scripts < $jobs;
unless ($Config{useithreads} && eval {
unless ($jobs > 1 &&
$Config{useithreads} && eval {
require threads; threads->import();
require Thread::Queue; Thread::Queue->import();
1;

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,3 +1,4 @@
test_expect_success 'arithmetic-expansion' '
(
foo &&
# LINT: closing ")" of $((...)) not misinterpreted as subshell-closing ")"
@ -9,3 +10,4 @@
bar=$((42 + 1))
baz
)
'

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,3 +1,4 @@
test_expect_success 'bash-array' '
(
foo &&
# LINT: ")" in Bash array assignment not misinterpreted as subshell-closing ")"
@ -10,3 +11,4 @@
bar=${#bar[@]} &&
baz
)
'

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,3 +1,4 @@
test_expect_success 'blank-line-before-esac' '
# LINT: blank line before "esac"
test_done () {
case "$test_failure" in
@ -17,3 +18,4 @@ test_done () {
esac
}
'

View File

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

View File

@ -1,3 +1,4 @@
test_expect_success 'blank-line' '
(
nothing &&
@ -8,3 +9,4 @@
)
'

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,3 +1,4 @@
test_expect_success 'block-comment' '
(
{
# show a
@ -6,3 +7,4 @@
echo b
}
)
'

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,3 +1,4 @@
test_expect_success 'block' '
(
# LINT: missing "&&" after first "echo"
foo &&
@ -25,3 +26,4 @@
echo "done"
} &&
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,3 +1,4 @@
test_expect_success 'broken-chain' '
(
foo &&
# LINT: missing "&&" from "bar"
@ -6,3 +7,4 @@
# LINT: final statement before closing ")" legitimately lacks "&&"
wop
)
'

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,3 +1,4 @@
test_expect_success 'case-comment' '
(
case "$x" in
# found foo
@ -9,3 +10,4 @@
;;
esac
)
'

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,3 +1,4 @@
test_expect_success 'case' '
(
# LINT: "...)" arms in "case" not misinterpreted as subshell-closing ")"
case "$x" in
@ -21,3 +22,4 @@
case "$y" in 2) false;; esac
foobar
)
'

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,3 +1,4 @@
test_expect_success 'chain-break-background' '
JGIT_DAEMON_PID= &&
git init --bare empty.git &&
>empty.git/git-daemon-export-ok &&
@ -8,3 +9,4 @@ mkfifo jgit_daemon_output &&
JGIT_DAEMON_PID=$!
} &&
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,3 +1,4 @@
test_expect_success 'chain-break-continue' '
git ls-tree --name-only -r refs/notes/many_notes |
while read path
do
@ -11,3 +12,4 @@ do
return 1
fi
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,3 +1,4 @@
test_expect_success 'chain-break-false' '
# LINT: broken &&-chain okay if explicit "false" signals failure
if condition not satisified
then
@ -8,3 +9,4 @@ else
echo it went okay
congratulate user
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,3 +1,4 @@
test_expect_success 'chain-break-return-exit' '
case "$(git ls-files)" in
one) echo pass one ;;
# LINT: broken &&-chain okay if explicit "return 1" signals failuire
@ -21,3 +22,4 @@ for i in 1 2 3 4 ; do
git checkout main -b $i || return $?
test_commit $i $i $i tag$i || return $?
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,3 +1,4 @@
test_expect_success 'chain-break-status' '
# LINT: broken &&-chain okay if next command handles "$?" explicitly
OUT=$( ((large_git; echo $? 1>&3) | :) 3>&1 ) &&
test_match_signal 13 "$OUT" &&
@ -9,3 +10,4 @@ test_match_signal 13 "$OUT" &&
test "$ret" = 3
} &&
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,3 +1,4 @@
test_expect_success 'chained-block' '
# LINT: start of block chained to preceding command
echo nobody home && {
test the doohicky
@ -9,3 +10,4 @@ GIT_EXTERNAL_DIFF=echo git diff | {
read path oldfile oldhex oldmode newfile newhex newmode &&
test "z$oh" = "z$oldhex"
}
'

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,4 @@
test_expect_success 'chained-subshell' '
# LINT: start of subshell chained to preceding command
mkdir sub && (
cd sub &&
@ -11,3 +12,4 @@ test -f $s1
test $(cat $s2) = tree2path1 &&
# LINT: closing subshell ")" correctly detected on same line as "$(...)"
test $(cat $s3) = tree3path1)
'

View File

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

View File

@ -1,3 +1,5 @@
test_expect_success 'close-nested-and-parent-together' '
(cd foo &&
(bar &&
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,3 +1,4 @@
test_expect_success 'close-subshell' '
# LINT: closing ")" with various decorations ("&&", ">", "|", etc.)
(
foo
@ -25,3 +26,4 @@ fuzzle &&
(
yop
)
'

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,3 +1,5 @@
test_expect_success 'command-substitution-subsubshell' '
# LINT: subshell nested in subshell nested in command substitution
OUT=$( ((large_git 1>&3) | :) 3>&1 ) &&
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,3 +1,4 @@
test_expect_success 'command-substitution' '
(
foo &&
# LINT: closing ")" of $(...) not misinterpreted as subshell-closing ")"
@ -9,3 +10,4 @@
bar=$(gobble blocks)
baz
)
'

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,3 +1,4 @@
test_expect_success 'comment' '
(
# LINT: swallow comment lines
# comment 1
@ -9,3 +10,4 @@
# comment 3
# comment 4
)
'

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,3 +1,4 @@
test_expect_success 'complex-if-in-cuddled-loop' '
# LINT: "for" loop cuddled with "(" and ")" and nested "if" with complex
# LINT: multi-line condition; indented with spaces, not tabs
(for i in a b c; do
@ -9,3 +10,4 @@
fi
done) &&
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,3 +1,4 @@
test_expect_success 'cuddled-if-then-else' '
# LINT: "if" cuddled with "(" and ")"; indented with spaces, not tabs
(if test -z ""; then
echo empty
@ -5,3 +6,4 @@
echo bizzy
fi) &&
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,3 +1,4 @@
test_expect_success 'cuddled-loop' '
# LINT: "while" loop cuddled with "(" and ")", with embedded (allowed)
# LINT: "|| exit {n}" to exit loop early, and using redirection "<" to feed
# LINT: loop; indented with spaces, not tabs
@ -5,3 +6,4 @@
do foobar bop || exit 1
done <file ) &&
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,3 +1,4 @@
test_expect_success 'cuddled' '
# LINT: first subshell statement cuddled with opening "("
(cd foo &&
bar
@ -20,3 +21,4 @@
# LINT: same with missing "&&"
(cd foo
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,3 +1,4 @@
test_expect_success 'double-here-doc' '
run_sub_test_lib_test_err run-inv-range-start \
"--run invalid range start" \
--run="a-5" <<-\EOF &&
@ -10,3 +11,4 @@ check_sub_test_lib_test_err run-inv-range-start \
EOF_OUT
> error: --run: invalid non-numeric in range start: ${SQ}a-5${SQ}
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,3 +1,4 @@
test_expect_success 'dqstring-line-splice' '
# LINT: line-splice within DQ-string
'"
echo 'fatal: reword option of --fixup is mutually exclusive with'\
@ -5,3 +6,4 @@ echo 'fatal: reword option of --fixup is mutually exclusive with'\
test_must_fail git commit --fixup=reword:HEAD~ $1 2>actual &&
test_cmp expect actual
"'
'

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,3 +1,4 @@
test_expect_success 'dqstring-no-interpolate' '
# LINT: regex dollar-sign eol anchor in double-quoted string not special
grep "^ ! \[rejected\][ ]*$BRANCH -> $BRANCH (non-fast-forward)$" out &&
@ -13,3 +14,4 @@ grep "^\\.git\$" output.txt &&
cut -d ' ' -f 2 <output | sort >actual &&
test_cmp expect actual
"'
'

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,5 +1,7 @@
test_expect_success 'empty-here-doc' '
git ls-tree $tree path >current &&
# LINT: empty here-doc
cat >expected <<\EOF &&
EOF
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,3 +1,4 @@
test_expect_success 'exclamation' '
# LINT: "! word" is two tokens
if ! condition; then echo nope; else yep; fi &&
# LINT: "!word" is single token, not two tokens "!" and "word"
@ -6,3 +7,4 @@ test_prerequisite !MINGW &&
mail uucp!address &&
# LINT: "!word!" is single token, not three tokens "!", "word", and "!"
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,3 +1,4 @@
test_expect_success 'exit-loop' '
(
for i in a b c
do
@ -25,3 +26,4 @@
i=$(($i + 1))
done
)
'

View File

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

View File

@ -1,6 +1,8 @@
test_expect_success 'exit-subshell' '
(
# LINT: "|| exit {n}" valid subshell escape without hurting &&-chain
foo || exit 1
bar &&
baz
)
'

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,6 +1,8 @@
test_expect_success 'for-loop-abbreviated' '
# LINT: for-loop lacking optional "in [word...]" before "do"
for it
do
path=$(expr "$it" : '\([^:]*\)') &&
git update-index --add "$path" || exit
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,3 +1,4 @@
test_expect_success 'for-loop' '
(
# LINT: "for", "do", "done" do not need "&&"
for i in a b c
@ -17,3 +18,4 @@
cat $i
done
)
'

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,3 +1,4 @@
test_expect_success 'function' '
# LINT: "()" in function definition not mistaken for subshell
sha1_file() {
echo "$*" | sed "s#..#.git/objects/&/#"
@ -11,3 +12,4 @@ remove_object() {
}
sha1_file arg && remove_object arg
'

View File

@ -0,0 +1,2 @@
2 echo "we should find this" ?!AMP?!
3 echo "even though our heredoc has its indent stripped"

View File

@ -0,0 +1,4 @@
test_expect_success 'here-doc-body-indent' - <<-\EOT
echo "we should find this"
echo "even though our heredoc has its indent stripped"
EOT

View File

@ -0,0 +1,7 @@
2 echo "outer here-doc does not allow indented end-tag" ?!AMP?!
3 cat >file <<-\EOF &&
4 but this inner here-doc
5 does allow indented EOF
6 EOF
7 echo "missing chain after" ?!AMP?!
8 echo "but this line is OK because it's the end"

View File

@ -0,0 +1,9 @@
test_expect_success 'here-doc-body-pathological' - <<\EOF
echo "outer here-doc does not allow indented end-tag"
cat >file <<-\EOF &&
but this inner here-doc
does allow indented EOF
EOF
echo "missing chain after"
echo "but this line is OK because it's the end"
EOF

View File

@ -0,0 +1,7 @@
2 echo "missing chain before" ?!AMP?!
3 cat >file <<-\EOF &&
4 inside inner here-doc
5 these are not shell commands
6 EOF
7 echo "missing chain after" ?!AMP?!
8 echo "but this line is OK because it's the end"

View File

@ -0,0 +1,9 @@
test_expect_success 'here-doc-body' - <<\EOT
echo "missing chain before"
cat >file <<-\EOF &&
inside inner here-doc
these are not shell commands
EOF
echo "missing chain after"
echo "but this line is OK because it's the end"
EOT

View File

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

View File

@ -1,5 +1,7 @@
test_expect_success 'here-doc-close-subshell' '
(
# LINT: line contains here-doc and closes nested subshell
cat <<-\INPUT)
fizz
INPUT
'

View File

@ -0,0 +1,2 @@
8 echo "actual test commands" ?!AMP?!
9 echo "that should be checked"

View File

@ -0,0 +1,10 @@
# This is obviously a ridiculous thing to do, but we should be able
# to handle two here-docs on the same line, and attribute them
# correctly.
test_expect_success "$(cat <<END_OF_PREREQS)" 'here-doc-double' - <<\EOT
SOME
PREREQS
END_OF_PREREQS
echo "actual test commands"
echo "that should be checked"
EOT

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,3 +1,4 @@
test_expect_success 'here-doc-indent-operator' '
# LINT: whitespace between operator "<<-" and tag legal
cat >expect <<- EOF &&
header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0
@ -11,3 +12,4 @@ this is not indented
-EOF
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,3 +1,4 @@
test_expect_success 'here-doc-multi-line-command-subst' '
(
# LINT: line contains here-doc and opens multi-line $(...)
x=$(bobble <<-\END &&
@ -7,3 +8,4 @@
wiffle)
echo $x
)
'

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,3 +1,4 @@
test_expect_success 'here-doc-multi-line-string' '
(
# LINT: line contains here-doc and opens multi-line string
cat <<-\TXT && echo "multi-line
@ -6,3 +7,4 @@
TXT
bap
)
'

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,3 +1,4 @@
test_expect_success 'here-doc' '
# LINT: stitch together incomplete \-ending lines
# LINT: swallow here-doc to avoid false positives in content
boodle wobba \
@ -28,3 +29,4 @@ morticia
wednesday
pugsly
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,3 +1,4 @@
test_expect_success 'if-condition-split' '
# LINT: "if" condition split across multiple lines at "&&" or "||"
if bob &&
marcia ||
@ -6,3 +7,4 @@ then
echo "nomads"
echo "for sure"
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,3 +1,4 @@
test_expect_success 'if-in-loop' '
(
for i in a b c
do
@ -13,3 +14,4 @@
done
bar
)
'

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,3 +1,4 @@
test_expect_success 'if-then-else' '
(
# LINT: "if", "then", "elif", "else", "fi" do not need "&&"
if test -n ""
@ -27,3 +28,4 @@
echo empty
fi
)
'

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 )

Some files were not shown because too many files have changed in this diff Show More