t/chainlint: add chainlint "basic" test cases

The --chain-lint option uses heuristics and knowledge of shell syntax to
detect broken &&-chains in subshells by pure textual inspection. The
heuristics handle a range of stylistic variations in existing tests
(evolved over the years), however, they are still best-guesses. As such,
it is possible for future changes to accidentally break assumptions upon
which the heuristics are based. Protect against this possibility by
adding tests which check the linter itself for correctness.

In addition to protecting against regressions, these tests help document
(for humans) expected behavior, which is important since the linter's
implementation language ('sed') does not necessarily lend itself to easy
comprehension.

Signed-off-by: Eric Sunshine <sunshine@sunshineco.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Eric Sunshine 2018-07-11 02:46:35 -04:00 committed by Junio C Hamano
parent 803394459d
commit 5238710eb4
16 changed files with 206 additions and 0 deletions

View File

@ -0,0 +1,9 @@
(
foo &&
bar=$((42 + 1)) &&
baz
>) &&
(
?!AMP?! bar=$((42 + 1))
baz
>)

View File

@ -0,0 +1,11 @@
(
foo &&
# LINT: closing ")" of $((...)) not misinterpreted as subshell-closing ")"
bar=$((42 + 1)) &&
baz
) &&
(
# LINT: missing "&&" on $((...))
bar=$((42 + 1))
baz
)

View File

@ -0,0 +1,6 @@
(
foo &&
?!AMP?! bar
baz &&
wop
>)

View File

@ -0,0 +1,8 @@
(
foo &&
# LINT: missing "&&" from 'bar'
bar
baz &&
# LINT: final statement before closing ")" legitimately lacks "&&"
wop
)

View File

@ -0,0 +1,25 @@
(
foo
>) &&
(
bar
>) >out &&
(
baz
>) 2>err &&
(
boo
>) <input &&
(
bip
>) | wuzzle &&
(
bop
>) | fazz fozz &&
(
bup
>) |
fuzzle &&
(
yop
>)

View File

@ -0,0 +1,27 @@
# LINT: closing ")" with various decorations ("&&", ">", "|", etc.)
(
foo
) &&
(
bar
) >out &&
(
baz
) 2>err &&
(
boo
) <input &&
(
bip
) | wuzzle &&
(
bop
) | fazz \
fozz &&
(
bup
) |
fuzzle &&
(
yop
)

View File

@ -0,0 +1,9 @@
(
foo &&
bar=$(gobble) &&
baz
>) &&
(
?!AMP?! bar=$(gobble blocks)
baz
>)

View File

@ -0,0 +1,11 @@
(
foo &&
# LINT: closing ")" of $(...) not misinterpreted as subshell-closing ")"
bar=$(gobble) &&
baz
) &&
(
# LINT: missing "&&" on $(...)
bar=$(gobble blocks)
baz
)

View File

@ -0,0 +1,5 @@
(
foo || exit 1
bar &&
baz
>)

View File

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

View File

@ -0,0 +1,9 @@
(
x=line 1 line 2 line 3" &&
?!AMP?! y=line 1 line2'
foobar
>) &&
(
echo "there's nothing to see here" &&
exit
>)

View File

@ -0,0 +1,15 @@
(
x="line 1
line 2
line 3" &&
# LINT: missing "&&" on assignment
y='line 1
line2'
foobar
) &&
(
# LINT: apostrophe (in a contraction) within string not misinterpreted as
# LINT: starting multi-line single-quoted string
echo "there's nothing to see here" &&
exit
)

8
t/chainlint/pipe.expect Normal file
View File

@ -0,0 +1,8 @@
(
foo |
bar |
baz &&
fish |
?!AMP?! cow
sunder
>)

12
t/chainlint/pipe.test Normal file
View File

@ -0,0 +1,12 @@
(
# LINT: no "&&" needed on line ending with "|"
foo |
bar |
baz &&
# LINT: final line of pipe sequence ('cow') lacking "&&"
fish |
cow
sunder
)

View File

@ -0,0 +1,20 @@
(
?!AMP?!?!SEMI?! cat foo ; echo bar
?!SEMI?! cat foo ; echo bar
>) &&
(
?!SEMI?! cat foo ; echo bar &&
?!SEMI?! cat foo ; echo bar
>) &&
(
echo "foo; bar" &&
?!SEMI?! cat foo; echo bar
>) &&
(
?!SEMI?! foo;
>) &&
(
cd foo &&
for i in a b c; do
?!SEMI?! echo;
> done)

View File

@ -0,0 +1,25 @@
(
# LINT: missing internal "&&" and ending "&&"
cat foo ; echo bar
# LINT: final statement before ")" only missing internal "&&"
cat foo ; echo bar
) &&
(
# LINT: missing internal "&&"
cat foo ; echo bar &&
cat foo ; echo bar
) &&
(
# LINT: not fooled by semicolon in string
echo "foo; bar" &&
cat foo; echo bar
) &&
(
# LINT: unnecessary terminating semicolon
foo;
) &&
(cd foo &&
for i in a b c; do
# LINT: unnecessary terminating semicolon
echo;
done)