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 t[0-9][0-9][0-9][0-9]/* -whitespace
/chainlint/*.expect eol=lf /chainlint/*.expect eol=lf -whitespace
/t0110/url-* binary /t0110/url-* binary
/t3206/* eol=lf /t3206/* eol=lf
/t3900/*.txt eol=lf /t3900/*.txt eol=lf

View File

@ -108,20 +108,8 @@ clean-chainlint:
check-chainlint: check-chainlint:
@mkdir -p '$(CHAINLINTTMP_SQ)' && \ @mkdir -p '$(CHAINLINTTMP_SQ)' && \
for i in $(CHAINLINTTESTS); do \ '$(PERL_PATH_SQ)' chainlint-cat.pl '$(CHAINLINTTMP_SQ)' $(CHAINLINTTESTS) && \
echo "test_expect_success '$$i' '" && \ { $(CHAINLINT) --emit-all '$(CHAINLINTTMP_SQ)'/tests >'$(CHAINLINTTMP_SQ)'/actual || true; } && \
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 && \
diff -u '$(CHAINLINTTMP_SQ)'/expect '$(CHAINLINTTMP_SQ)'/actual diff -u '$(CHAINLINTTMP_SQ)'/expect '$(CHAINLINTTMP_SQ)'/actual
test-lint: test-lint-duplicates test-lint-executable test-lint-shell-syntax \ 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.' \ 'git-write-tree should be able to write an empty tree.' \
'tree=$(git-write-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 If you supply three parameters the first will be taken to be a
prerequisite; see the test_set_prereq and test_have_prereq prerequisite; see the test_set_prereq and test_have_prereq
documentation below: 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; $$b =~ /(?:\G|\n)$indent\Q$$tag[0]\E(?:\n|\z)/gc;
if (pos($$b) > $start) { if (pos($$b) > $start) {
my $body = substr($$b, $start, 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; $self->{lineno} += () = $body =~ /\n/sg;
next; next;
} }
@ -232,7 +236,8 @@ sub new {
my $self = bless { my $self = bless {
buff => [], buff => [],
stop => [], stop => [],
output => [] output => [],
heredocs => {},
} => $class; } => $class;
$self->{lexer} = Lexer->new($self, $s); $self->{lexer} = Lexer->new($self, $s);
return $self; return $self;
@ -616,14 +621,21 @@ sub unwrap {
sub check_test { sub check_test {
my $self = shift @_; 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}++; $self->{ntests}++;
my $parser = TestParser->new(\$body); my $parser = TestParser->new(\$body);
my @tokens = $parser->parse(); my @tokens = $parser->parse();
my $problems = $parser->{problems}; my $problems = $parser->{problems};
return unless $emit_all || @$problems; return unless $emit_all || @$problems;
my $c = main::fd_colors(1); my $c = main::fd_colors(1);
my $lineno = $_[1]->[3];
my $start = 0; my $start = 0;
my $checked = ''; my $checked = '';
for (sort {$a->[1]->[2] <=> $b->[1]->[2]} @$problems) { 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)$/; return @tokens unless @tokens && $tokens[0]->[0] =~ /^test_expect_(?:success|failure)$/;
my $n = $#tokens; my $n = $#tokens;
$n-- while $n >= 0 && $tokens[$n]->[0] =~ /^(?:[;&\n|]|&&|\|\|)$/; $n-- while $n >= 0 && $tokens[$n]->[0] =~ /^(?:[;&\n|]|&&|\|\|)$/;
$self->check_test($tokens[1], $tokens[2]) if $n == 2; # title body my $herebody;
$self->check_test($tokens[2], $tokens[3]) if $n > 2; # prereq title body 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; return @tokens;
} }
@ -762,7 +779,7 @@ sub check_script {
while (my $path = $next_script->()) { while (my $path = $next_script->()) {
$nscripts++; $nscripts++;
my $fh; my $fh;
unless (open($fh, "<", $path)) { unless (open($fh, "<:unix:crlf", $path)) {
$emit->("?!ERR?! $path: $!\n"); $emit->("?!ERR?! $path: $!\n");
next; next;
} }
@ -806,8 +823,10 @@ unless (@scripts) {
show_stats($start_time, \@stats) if $show_stats; show_stats($start_time, \@stats) if $show_stats;
exit; exit;
} }
$jobs = @scripts if @scripts < $jobs;
unless ($Config{useithreads} && eval { unless ($jobs > 1 &&
$Config{useithreads} && eval {
require threads; threads->import(); require threads; threads->import();
require Thread::Queue; Thread::Queue->import(); require Thread::Queue; Thread::Queue->import();
1; 1;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,3 +1,4 @@
test_expect_success 'block-comment' '
( (
{ {
# show a # show a
@ -6,3 +7,4 @@
echo b echo b
} }
) )
'

View File

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

View File

@ -1,3 +1,4 @@
test_expect_success 'block' '
( (
# LINT: missing "&&" after first "echo" # LINT: missing "&&" after first "echo"
foo && foo &&
@ -25,3 +26,4 @@
echo "done" echo "done"
} && } &&
finis finis
'

View File

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

View File

@ -1,3 +1,4 @@
test_expect_success 'broken-chain' '
( (
foo && foo &&
# LINT: missing "&&" from "bar" # LINT: missing "&&" from "bar"
@ -6,3 +7,4 @@
# LINT: final statement before closing ")" legitimately lacks "&&" # LINT: final statement before closing ")" legitimately lacks "&&"
wop wop
) )
'

View File

@ -1,11 +1,11 @@
( 2 (
case "$x" in 3 case "$x" in
# found foo 4 # found foo
x) foo ;; 5 x) foo ;;
# found other 6 # found other
*) 7 *)
# treat it as bar 8 # treat it as bar
bar 9 bar
;; 10 ;;
esac 11 esac
) 12 )

View File

@ -1,3 +1,4 @@
test_expect_success 'case-comment' '
( (
case "$x" in case "$x" in
# found foo # found foo
@ -9,3 +10,4 @@
;; ;;
esac esac
) )
'

View File

@ -1,19 +1,19 @@
( 2 (
case "$x" in 3 case "$x" in
x) foo ;; 4 x) foo ;;
*) bar ;; 5 *) bar ;;
esac && 6 esac &&
foobar 7 foobar
) && 8 ) &&
( 9 (
case "$x" in 10 case "$x" in
x) foo ;; 11 x) foo ;;
*) bar ;; 12 *) bar ;;
esac ?!AMP?! 13 esac ?!AMP?!
foobar 14 foobar
) && 15 ) &&
( 16 (
case "$x" in 1) true;; esac && 17 case "$x" in 1) true;; esac &&
case "$y" in 2) false;; esac ?!AMP?! 18 case "$y" in 2) false;; esac ?!AMP?!
foobar 19 foobar
) 20 )

View File

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

View File

@ -1,9 +1,9 @@
JGIT_DAEMON_PID= && 2 JGIT_DAEMON_PID= &&
git init --bare empty.git && 3 git init --bare empty.git &&
>empty.git/git-daemon-export-ok && 4 >empty.git/git-daemon-export-ok &&
mkfifo jgit_daemon_output && 5 mkfifo jgit_daemon_output &&
{ 6 {
jgit daemon --port="$JGIT_DAEMON_PORT" . >jgit_daemon_output & 7 jgit daemon --port="$JGIT_DAEMON_PORT" . >jgit_daemon_output &
JGIT_DAEMON_PID=$! 8 JGIT_DAEMON_PID=$!
} && 9 } &&
test_expect_code 2 git ls-remote --exit-code git://localhost:$JGIT_DAEMON_PORT/empty.git 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= && JGIT_DAEMON_PID= &&
git init --bare empty.git && git init --bare empty.git &&
>empty.git/git-daemon-export-ok && >empty.git/git-daemon-export-ok &&
@ -8,3 +9,4 @@ mkfifo jgit_daemon_output &&
JGIT_DAEMON_PID=$! JGIT_DAEMON_PID=$!
} && } &&
test_expect_code 2 git ls-remote --exit-code git://localhost:$JGIT_DAEMON_PORT/empty.git 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 | 2 git ls-tree --name-only -r refs/notes/many_notes |
while read path 3 while read path
do 4 do
test "$path" = "foobar/non-note.txt" && continue 5 test "$path" = "foobar/non-note.txt" && continue
test "$path" = "deadbeef" && continue 6 test "$path" = "deadbeef" && continue
test "$path" = "de/adbeef" && continue 7 test "$path" = "de/adbeef" && continue
8
if test $(expr length "$path") -ne $hexsz 9 if test $(expr length "$path") -ne $hexsz
then 10 then
return 1 11 return 1
fi 12 fi
done 13 done

View File

@ -1,3 +1,4 @@
test_expect_success 'chain-break-continue' '
git ls-tree --name-only -r refs/notes/many_notes | git ls-tree --name-only -r refs/notes/many_notes |
while read path while read path
do do
@ -11,3 +12,4 @@ do
return 1 return 1
fi fi
done done
'

View File

@ -1,9 +1,9 @@
if condition not satisified 2 if condition not satisified
then 3 then
echo it did not work... 4 echo it did not work...
echo failed! 5 echo failed!
false 6 false
else 7 else
echo it went okay ?!AMP?! 8 echo it went okay ?!AMP?!
congratulate user 9 congratulate user
fi 10 fi

View File

@ -1,3 +1,4 @@
test_expect_success 'chain-break-false' '
# LINT: broken &&-chain okay if explicit "false" signals failure # LINT: broken &&-chain okay if explicit "false" signals failure
if condition not satisified if condition not satisified
then then
@ -8,3 +9,4 @@ else
echo it went okay echo it went okay
congratulate user congratulate user
fi fi
'

View File

@ -1,19 +1,19 @@
case "$(git ls-files)" in 2 case "$(git ls-files)" in
one) echo pass one ;; 3 one) echo pass one ;;
*) echo bad one; return 1 ;; 4 *) echo bad one; return 1 ;;
esac && 5 esac &&
( 6 (
case "$(git ls-files)" in 7 case "$(git ls-files)" in
two) echo pass two ;; 8 two) echo pass two ;;
*) echo bad two; exit 1 ;; 9 *) echo bad two; exit 1 ;;
esac 10 esac
) && 11 ) &&
case "$(git ls-files)" in 12 case "$(git ls-files)" in
dir/two"$LF"one) echo pass both ;; 13 dir/two"$LF"one) echo pass both ;;
*) echo bad; return 1 ;; 14 *) echo bad; return 1 ;;
esac && 15 esac &&
16
for i in 1 2 3 4 ; do 17 for i in 1 2 3 4 ; do
git checkout main -b $i || return $? 18 git checkout main -b $i || return $?
test_commit $i $i $i tag$i || return $? 19 test_commit $i $i $i tag$i || return $?
done 20 done

View File

@ -1,3 +1,4 @@
test_expect_success 'chain-break-return-exit' '
case "$(git ls-files)" in case "$(git ls-files)" in
one) echo pass one ;; one) echo pass one ;;
# LINT: broken &&-chain okay if explicit "return 1" signals failuire # 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 $? git checkout main -b $i || return $?
test_commit $i $i $i tag$i || return $? test_commit $i $i $i tag$i || return $?
done done
'

View File

@ -1,9 +1,9 @@
OUT=$( ((large_git; echo $? 1>&3) | :) 3>&1 ) && 2 OUT=$( ((large_git; echo $? 1>&3) | :) 3>&1 ) &&
test_match_signal 13 "$OUT" && 3 test_match_signal 13 "$OUT" &&
4
{ test-tool sigchain >actual; ret=$?; } && 5 { test-tool sigchain >actual; ret=$?; } &&
{ 6 {
test_match_signal 15 "$ret" || 7 test_match_signal 15 "$ret" ||
test "$ret" = 3 8 test "$ret" = 3
} && 9 } &&
test_cmp expect actual 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 # LINT: broken &&-chain okay if next command handles "$?" explicitly
OUT=$( ((large_git; echo $? 1>&3) | :) 3>&1 ) && OUT=$( ((large_git; echo $? 1>&3) | :) 3>&1 ) &&
test_match_signal 13 "$OUT" && test_match_signal 13 "$OUT" &&
@ -9,3 +10,4 @@ test_match_signal 13 "$OUT" &&
test "$ret" = 3 test "$ret" = 3
} && } &&
test_cmp expect actual test_cmp expect actual
'

View File

@ -1,9 +1,9 @@
echo nobody home && { 2 echo nobody home && {
test the doohicky ?!AMP?! 3 test the doohicky ?!AMP?!
right now 4 right now
} && 5 } &&
6
GIT_EXTERNAL_DIFF=echo git diff | { 7 GIT_EXTERNAL_DIFF=echo git diff | {
read path oldfile oldhex oldmode newfile newhex newmode && 8 read path oldfile oldhex oldmode newfile newhex newmode &&
test "z$oh" = "z$oldhex" 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 # LINT: start of block chained to preceding command
echo nobody home && { echo nobody home && {
test the doohicky test the doohicky
@ -9,3 +10,4 @@ GIT_EXTERNAL_DIFF=echo git diff | {
read path oldfile oldhex oldmode newfile newhex newmode && read path oldfile oldhex oldmode newfile newhex newmode &&
test "z$oh" = "z$oldhex" test "z$oh" = "z$oldhex"
} }
'

View File

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

View File

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

View File

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

View File

@ -1,3 +1,5 @@
test_expect_success 'close-nested-and-parent-together' '
(cd foo && (cd foo &&
(bar && (bar &&
baz)) baz))
'

View File

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

View File

@ -1,3 +1,4 @@
test_expect_success 'close-subshell' '
# LINT: closing ")" with various decorations ("&&", ">", "|", etc.) # LINT: closing ")" with various decorations ("&&", ">", "|", etc.)
( (
foo foo
@ -25,3 +26,4 @@ fuzzle &&
( (
yop yop
) )
'

View File

@ -1,2 +1,2 @@
OUT=$( ((large_git 1>&3) | :) 3>&1 ) && 2 OUT=$( ((large_git 1>&3) | :) 3>&1 ) &&
test_match_signal 13 "$OUT" 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 # LINT: subshell nested in subshell nested in command substitution
OUT=$( ((large_git 1>&3) | :) 3>&1 ) && OUT=$( ((large_git 1>&3) | :) 3>&1 ) &&
test_match_signal 13 "$OUT" test_match_signal 13 "$OUT"
'

View File

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

View File

@ -1,3 +1,4 @@
test_expect_success 'command-substitution' '
( (
foo && foo &&
# LINT: closing ")" of $(...) not misinterpreted as subshell-closing ")" # LINT: closing ")" of $(...) not misinterpreted as subshell-closing ")"
@ -9,3 +10,4 @@
bar=$(gobble blocks) bar=$(gobble blocks)
baz baz
) )
'

View File

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

View File

@ -1,3 +1,4 @@
test_expect_success 'comment' '
( (
# LINT: swallow comment lines # LINT: swallow comment lines
# comment 1 # comment 1
@ -9,3 +10,4 @@
# comment 3 # comment 3
# comment 4 # comment 4
) )
'

View File

@ -1,9 +1,9 @@
(for i in a b c; do 2 (for i in a b c; do
if test "$(echo $(waffle bat))" = "eleventeen" && 3 if test "$(echo $(waffle bat))" = "eleventeen" &&
test "$x" = "$y"; then 4 test "$x" = "$y"; then
: 5 :
else 6 else
echo >file 7 echo >file
fi ?!LOOP?! 8 fi ?!LOOP?!
done) && 9 done) &&
test ! -f file 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: "for" loop cuddled with "(" and ")" and nested "if" with complex
# LINT: multi-line condition; indented with spaces, not tabs # LINT: multi-line condition; indented with spaces, not tabs
(for i in a b c; do (for i in a b c; do
@ -9,3 +10,4 @@
fi fi
done) && done) &&
test ! -f file test ! -f file
'

View File

@ -1,6 +1,6 @@
(if test -z ""; then 2 (if test -z ""; then
echo empty 3 echo empty
else 4 else
echo bizzy 5 echo bizzy
fi) && 6 fi) &&
echo foobar 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 # LINT: "if" cuddled with "(" and ")"; indented with spaces, not tabs
(if test -z ""; then (if test -z ""; then
echo empty echo empty
@ -5,3 +6,4 @@
echo bizzy echo bizzy
fi) && fi) &&
echo foobar echo foobar
'

View File

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

View File

@ -1,3 +1,4 @@
test_expect_success 'cuddled-loop' '
# LINT: "while" loop cuddled with "(" and ")", with embedded (allowed) # LINT: "while" loop cuddled with "(" and ")", with embedded (allowed)
# LINT: "|| exit {n}" to exit loop early, and using redirection "<" to feed # LINT: "|| exit {n}" to exit loop early, and using redirection "<" to feed
# LINT: loop; indented with spaces, not tabs # LINT: loop; indented with spaces, not tabs
@ -5,3 +6,4 @@
do foobar bop || exit 1 do foobar bop || exit 1
done <file ) && done <file ) &&
outside subshell outside subshell
'

View File

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

View File

@ -1,3 +1,4 @@
test_expect_success 'cuddled' '
# LINT: first subshell statement cuddled with opening "(" # LINT: first subshell statement cuddled with opening "("
(cd foo && (cd foo &&
bar bar
@ -20,3 +21,4 @@
# LINT: same with missing "&&" # LINT: same with missing "&&"
(cd foo (cd foo
bar) bar)
'

View File

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

View File

@ -1,5 +1,5 @@
2
echo 'fatal: reword option of --fixup is mutually exclusive with' '--patch/--interactive/--all/--include/--only' >expect && 3 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 && 4 test_must_fail git commit --fixup=reword:HEAD~ $1 2>actual &&
test_cmp expect 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 # LINT: line-splice within DQ-string
'" '"
echo 'fatal: reword option of --fixup is mutually exclusive with'\ 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_must_fail git commit --fixup=reword:HEAD~ $1 2>actual &&
test_cmp expect actual test_cmp expect actual
"' "'
'

View File

@ -1,12 +1,12 @@
grep "^ ! [rejected][ ]*$BRANCH -> $BRANCH (non-fast-forward)$" out && 2 grep "^ ! [rejected][ ]*$BRANCH -> $BRANCH (non-fast-forward)$" out &&
3
grep "^\.git$" output.txt && 4 grep "^\.git$" output.txt &&
5
6
( 7 (
cd client$version && 8 cd client$version &&
GIT_TEST_PROTOCOL_VERSION=$version git fetch-pack --no-progress .. $(cat ../input) 9 GIT_TEST_PROTOCOL_VERSION=$version git fetch-pack --no-progress .. $(cat ../input)
) >output && 10 ) >output &&
cut -d ' ' -f 2 <output | sort >actual && 11 cut -d ' ' -f 2 <output | sort >actual &&
test_cmp expect 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 # LINT: regex dollar-sign eol anchor in double-quoted string not special
grep "^ ! \[rejected\][ ]*$BRANCH -> $BRANCH (non-fast-forward)$" out && grep "^ ! \[rejected\][ ]*$BRANCH -> $BRANCH (non-fast-forward)$" out &&
@ -13,3 +14,4 @@ grep "^\\.git\$" output.txt &&
cut -d ' ' -f 2 <output | sort >actual && cut -d ' ' -f 2 <output | sort >actual &&
test_cmp expect actual test_cmp expect actual
"' "'
'

View File

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

View File

@ -1,5 +1,7 @@
test_expect_success 'empty-here-doc' '
git ls-tree $tree path >current && git ls-tree $tree path >current &&
# LINT: empty here-doc # LINT: empty here-doc
cat >expected <<\EOF && cat >expected <<\EOF &&
EOF EOF
test_output test_output
'

View File

@ -1,4 +1,4 @@
if ! condition; then echo nope; else yep; fi && 2 if ! condition; then echo nope; else yep; fi &&
test_prerequisite !MINGW && 3 test_prerequisite !MINGW &&
mail uucp!address && 4 mail uucp!address &&
echo !whatever! 5 echo !whatever!

View File

@ -1,3 +1,4 @@
test_expect_success 'exclamation' '
# LINT: "! word" is two tokens # LINT: "! word" is two tokens
if ! condition; then echo nope; else yep; fi && if ! condition; then echo nope; else yep; fi &&
# LINT: "!word" is single token, not two tokens "!" and "word" # LINT: "!word" is single token, not two tokens "!" and "word"
@ -6,3 +7,4 @@ test_prerequisite !MINGW &&
mail uucp!address && mail uucp!address &&
# LINT: "!word!" is single token, not three tokens "!", "word", and "!" # LINT: "!word!" is single token, not three tokens "!", "word", and "!"
echo !whatever! echo !whatever!
'

View File

@ -1,24 +1,24 @@
( 2 (
for i in a b c 3 for i in a b c
do 4 do
foo || exit 1 5 foo || exit 1
bar && 6 bar &&
baz 7 baz
done 8 done
) && 9 ) &&
( 10 (
while true 11 while true
do 12 do
foo || exit 1 13 foo || exit 1
bar && 14 bar &&
baz 15 baz
done 16 done
) && 17 ) &&
( 18 (
i=0 && 19 i=0 &&
while test $i -lt 10 20 while test $i -lt 10
do 21 do
echo $i || exit 22 echo $i || exit
i=$(($i + 1)) 23 i=$(($i + 1))
done 24 done
) 25 )

View File

@ -1,3 +1,4 @@
test_expect_success 'exit-loop' '
( (
for i in a b c for i in a b c
do do
@ -25,3 +26,4 @@
i=$(($i + 1)) i=$(($i + 1))
done done
) )
'

View File

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

View File

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

View File

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

View File

@ -1,6 +1,8 @@
test_expect_success 'for-loop-abbreviated' '
# LINT: for-loop lacking optional "in [word...]" before "do" # LINT: for-loop lacking optional "in [word...]" before "do"
for it for it
do do
path=$(expr "$it" : '\([^:]*\)') && path=$(expr "$it" : '\([^:]*\)') &&
git update-index --add "$path" || exit git update-index --add "$path" || exit
done done
'

View File

@ -1,14 +1,14 @@
( 2 (
for i in a b c 3 for i in a b c
do 4 do
echo $i ?!AMP?! 5 echo $i ?!AMP?!
cat <<-\EOF ?!LOOP?! 6 cat <<-\EOF ?!LOOP?!
bar 7 bar
EOF 8 EOF
done ?!AMP?! 9 done ?!AMP?!
10
for i in a b c; do 11 for i in a b c; do
echo $i && 12 echo $i &&
cat $i ?!LOOP?! 13 cat $i ?!LOOP?!
done 14 done
) 15 )

View File

@ -1,3 +1,4 @@
test_expect_success 'for-loop' '
( (
# LINT: "for", "do", "done" do not need "&&" # LINT: "for", "do", "done" do not need "&&"
for i in a b c for i in a b c
@ -17,3 +18,4 @@
cat $i cat $i
done done
) )
'

View File

@ -1,11 +1,11 @@
sha1_file() { 2 sha1_file() {
echo "$*" | sed "s#..#.git/objects/&/#" 3 echo "$*" | sed "s#..#.git/objects/&/#"
} && 4 } &&
5
remove_object() { 6 remove_object() {
file=$(sha1_file "$*") && 7 file=$(sha1_file "$*") &&
test -e "$file" ?!AMP?! 8 test -e "$file" ?!AMP?!
rm -f "$file" 9 rm -f "$file"
} ?!AMP?! 10 } ?!AMP?!
11
sha1_file arg && remove_object arg 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 # LINT: "()" in function definition not mistaken for subshell
sha1_file() { sha1_file() {
echo "$*" | sed "s#..#.git/objects/&/#" echo "$*" | sed "s#..#.git/objects/&/#"
@ -11,3 +12,4 @@ remove_object() {
} }
sha1_file arg && remove_object arg 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 @@
( 2 (
cat <<-\INPUT) 3 cat <<-\INPUT)
fizz 4 fizz
INPUT 5 INPUT

View File

@ -1,5 +1,7 @@
test_expect_success 'here-doc-close-subshell' '
( (
# LINT: line contains here-doc and closes nested subshell # LINT: line contains here-doc and closes nested subshell
cat <<-\INPUT) cat <<-\INPUT)
fizz fizz
INPUT 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 && 2 cat >expect <<- EOF &&
header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0 3 header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0
num_commits: $1 4 num_commits: $1
chunks: oid_fanout oid_lookup commit_metadata generation_data bloom_indexes bloom_data 5 chunks: oid_fanout oid_lookup commit_metadata generation_data bloom_indexes bloom_data
EOF 6 EOF
7
cat >expect << -EOF ?!AMP?! 8 cat >expect << -EOF ?!AMP?!
this is not indented 9 this is not indented
-EOF 10 -EOF
11
cleanup 12 cleanup

View File

@ -1,3 +1,4 @@
test_expect_success 'here-doc-indent-operator' '
# LINT: whitespace between operator "<<-" and tag legal # LINT: whitespace between operator "<<-" and tag legal
cat >expect <<- EOF && cat >expect <<- EOF &&
header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0 header: 43475048 1 $(test_oid oid_version) $NUM_CHUNKS 0
@ -11,3 +12,4 @@ this is not indented
-EOF -EOF
cleanup cleanup
'

View File

@ -1,8 +1,8 @@
( 2 (
x=$(bobble <<-\END && 3 x=$(bobble <<-\END &&
fossil 4 fossil
vegetable 5 vegetable
END 6 END
wiffle) ?!AMP?! 7 wiffle) ?!AMP?!
echo $x 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 $(...) # LINT: line contains here-doc and opens multi-line $(...)
x=$(bobble <<-\END && x=$(bobble <<-\END &&
@ -7,3 +8,4 @@
wiffle) wiffle)
echo $x echo $x
) )
'

View File

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

View File

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

View File

@ -1,3 +1,4 @@
test_expect_success 'here-doc' '
# LINT: stitch together incomplete \-ending lines # LINT: stitch together incomplete \-ending lines
# LINT: swallow here-doc to avoid false positives in content # LINT: swallow here-doc to avoid false positives in content
boodle wobba \ boodle wobba \
@ -28,3 +29,4 @@ morticia
wednesday wednesday
pugsly pugsly
EOF EOF
'

View File

@ -1,7 +1,7 @@
if bob && 2 if bob &&
marcia || 3 marcia ||
kevin 4 kevin
then 5 then
echo "nomads" ?!AMP?! 6 echo "nomads" ?!AMP?!
echo "for sure" 7 echo "for sure"
fi 8 fi

View File

@ -1,3 +1,4 @@
test_expect_success 'if-condition-split' '
# LINT: "if" condition split across multiple lines at "&&" or "||" # LINT: "if" condition split across multiple lines at "&&" or "||"
if bob && if bob &&
marcia || marcia ||
@ -6,3 +7,4 @@ then
echo "nomads" echo "nomads"
echo "for sure" echo "for sure"
fi fi
'

View File

@ -1,12 +1,12 @@
( 2 (
for i in a b c 3 for i in a b c
do 4 do
if false 5 if false
then 6 then
echo "err" 7 echo "err"
exit 1 8 exit 1
fi ?!AMP?! 9 fi ?!AMP?!
foo 10 foo
done ?!AMP?! 11 done ?!AMP?!
bar 12 bar
) 13 )

View File

@ -1,3 +1,4 @@
test_expect_success 'if-in-loop' '
( (
for i in a b c for i in a b c
do do
@ -13,3 +14,4 @@
done done
bar bar
) )
'

View File

@ -1,22 +1,22 @@
( 2 (
if test -n "" 3 if test -n ""
then 4 then
echo very ?!AMP?! 5 echo very ?!AMP?!
echo empty 6 echo empty
elif test -z "" 7 elif test -z ""
then 8 then
echo foo 9 echo foo
else 10 else
echo foo && 11 echo foo &&
cat <<-\EOF 12 cat <<-\EOF
bar 13 bar
EOF 14 EOF
fi ?!AMP?! 15 fi ?!AMP?!
echo poodle 16 echo poodle
) && 17 ) &&
( 18 (
if test -n ""; then 19 if test -n ""; then
echo very && 20 echo very &&
echo empty 21 echo empty
fi 22 fi
) 23 )

View File

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

View File

@ -1,10 +1,10 @@
line 1 \ 2 line 1 \
line 2 \ 3 line 2 \
line 3 \ 4 line 3 \
line 4 && 5 line 4 &&
( 6 (
line 5 \ 7 line 5 \
line 6 \ 8 line 6 \
line 7 \ 9 line 7 \
line 8 10 line 8
) 11 )

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