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:
parent
803394459d
commit
5238710eb4
9
t/chainlint/arithmetic-expansion.expect
Normal file
9
t/chainlint/arithmetic-expansion.expect
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
(
|
||||||
|
foo &&
|
||||||
|
bar=$((42 + 1)) &&
|
||||||
|
baz
|
||||||
|
>) &&
|
||||||
|
(
|
||||||
|
?!AMP?! bar=$((42 + 1))
|
||||||
|
baz
|
||||||
|
>)
|
11
t/chainlint/arithmetic-expansion.test
Normal file
11
t/chainlint/arithmetic-expansion.test
Normal 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
|
||||||
|
)
|
6
t/chainlint/broken-chain.expect
Normal file
6
t/chainlint/broken-chain.expect
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
(
|
||||||
|
foo &&
|
||||||
|
?!AMP?! bar
|
||||||
|
baz &&
|
||||||
|
wop
|
||||||
|
>)
|
8
t/chainlint/broken-chain.test
Normal file
8
t/chainlint/broken-chain.test
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
(
|
||||||
|
foo &&
|
||||||
|
# LINT: missing "&&" from 'bar'
|
||||||
|
bar
|
||||||
|
baz &&
|
||||||
|
# LINT: final statement before closing ")" legitimately lacks "&&"
|
||||||
|
wop
|
||||||
|
)
|
25
t/chainlint/close-subshell.expect
Normal file
25
t/chainlint/close-subshell.expect
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
(
|
||||||
|
foo
|
||||||
|
>) &&
|
||||||
|
(
|
||||||
|
bar
|
||||||
|
>) >out &&
|
||||||
|
(
|
||||||
|
baz
|
||||||
|
>) 2>err &&
|
||||||
|
(
|
||||||
|
boo
|
||||||
|
>) <input &&
|
||||||
|
(
|
||||||
|
bip
|
||||||
|
>) | wuzzle &&
|
||||||
|
(
|
||||||
|
bop
|
||||||
|
>) | fazz fozz &&
|
||||||
|
(
|
||||||
|
bup
|
||||||
|
>) |
|
||||||
|
fuzzle &&
|
||||||
|
(
|
||||||
|
yop
|
||||||
|
>)
|
27
t/chainlint/close-subshell.test
Normal file
27
t/chainlint/close-subshell.test
Normal 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
|
||||||
|
)
|
9
t/chainlint/command-substitution.expect
Normal file
9
t/chainlint/command-substitution.expect
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
(
|
||||||
|
foo &&
|
||||||
|
bar=$(gobble) &&
|
||||||
|
baz
|
||||||
|
>) &&
|
||||||
|
(
|
||||||
|
?!AMP?! bar=$(gobble blocks)
|
||||||
|
baz
|
||||||
|
>)
|
11
t/chainlint/command-substitution.test
Normal file
11
t/chainlint/command-substitution.test
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
(
|
||||||
|
foo &&
|
||||||
|
# LINT: closing ")" of $(...) not misinterpreted as subshell-closing ")"
|
||||||
|
bar=$(gobble) &&
|
||||||
|
baz
|
||||||
|
) &&
|
||||||
|
(
|
||||||
|
# LINT: missing "&&" on $(...)
|
||||||
|
bar=$(gobble blocks)
|
||||||
|
baz
|
||||||
|
)
|
5
t/chainlint/exit-subshell.expect
Normal file
5
t/chainlint/exit-subshell.expect
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
(
|
||||||
|
foo || exit 1
|
||||||
|
bar &&
|
||||||
|
baz
|
||||||
|
>)
|
6
t/chainlint/exit-subshell.test
Normal file
6
t/chainlint/exit-subshell.test
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
(
|
||||||
|
# LINT: "|| exit {n}" valid subshell escape without hurting &&-chain
|
||||||
|
foo || exit 1
|
||||||
|
bar &&
|
||||||
|
baz
|
||||||
|
)
|
9
t/chainlint/multi-line-string.expect
Normal file
9
t/chainlint/multi-line-string.expect
Normal 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
|
||||||
|
>)
|
15
t/chainlint/multi-line-string.test
Normal file
15
t/chainlint/multi-line-string.test
Normal 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
8
t/chainlint/pipe.expect
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
(
|
||||||
|
foo |
|
||||||
|
bar |
|
||||||
|
baz &&
|
||||||
|
fish |
|
||||||
|
?!AMP?! cow
|
||||||
|
sunder
|
||||||
|
>)
|
12
t/chainlint/pipe.test
Normal file
12
t/chainlint/pipe.test
Normal 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
|
||||||
|
)
|
20
t/chainlint/semicolon.expect
Normal file
20
t/chainlint/semicolon.expect
Normal 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)
|
25
t/chainlint/semicolon.test
Normal file
25
t/chainlint/semicolon.test
Normal 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)
|
Loading…
Reference in New Issue
Block a user