You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A multi-line array assignment inside a function that a test executes is reported as uncovered on
every line it spans. #722 fixed this for statements split with a backslash, but a statement that
spans lines because its parentheses are still open is not covered by that propagation, so an array
literal costs one uncovered line per element.
Current behavior
Bash's DEBUG trap reports the array assignment on the line of its closing), not on the line
where the statement starts:
#!/usr/bin/env bashset -T
trap'printf "DEBUG trap fired with LINENO=%s\n" "$LINENO"' DEBUG
demo() { # line 5local commands=( # line 6"start"# line 7"stop"# line 8
) # line 9printf'after array\n'# line 10
}
demo # line 13
DEBUG trap fired with LINENO=13
DEBUG trap fired with LINENO=5
DEBUG trap fired with LINENO=9
DEBUG trap fired with LINENO=10
after array
The only hit for the assignment is on line 9, a )-only line, which is classified as non-executable
and so is discarded when hits are matched against executable lines. The result is that the hit
disappears completely: the opening line and every element line are reported as uncovered, even
though the statement ran.
A multi-line quoted string is affected by the same gap but degrades differently — the hit does land
on the first line, so the first line is reported as covered and only the interior lines are
reported as uncovered.
Lines 22-24, the interior of the multi-line string, are reported uncovered while its first line
(21) is covered.
Expected behavior
A statement that ran should count as covered on every physical line it spans, however it happens to
span them — the same guarantee #722 established for a backslash chain. Alternatively the lines that
carry no statement of their own (array elements, the interior of a multi-line string) could be
treated as non-executable so they leave the denominator. Either way the array in the repro should
not contribute four uncovered lines after its function has run.
The scale of this in real code: in a repository of 13 shell scripts with 548 executable lines,
83 of the 188 lines reported as uncovered are array elements or interior lines of a multi-line
string, so roughly 15% of the denominator can never be covered by any test. Command allowlists such
as available_commands=("start" "stop" ...) written one entry per line make it worse the more
commands a script grows.
Summary
A multi-line array assignment inside a function that a test executes is reported as uncovered on
every line it spans. #722 fixed this for statements split with a backslash, but a statement that
spans lines because its parentheses are still open is not covered by that propagation, so an array
literal costs one uncovered line per element.
Current behavior
Bash's
DEBUGtrap reports the array assignment on the line of its closing), not on the linewhere the statement starts:
The only hit for the assignment is on line 9, a
)-only line, which is classified as non-executableand so is discarded when hits are matched against executable lines. The result is that the hit
disappears completely: the opening line and every element line are reported as uncovered, even
though the statement ran.
A multi-line quoted string is affected by the same gap but degrades differently — the hit does land
on the first line, so the first line is reported as covered and only the interior lines are
reported as uncovered.
How to reproduce
src/example.sh:tests/example_test.sh:All three tests pass, so all three functions ran, and the report is:
local commands=(...)statement, are reported uncovered.working as intended.
(21) is covered.
Expected behavior
A statement that ran should count as covered on every physical line it spans, however it happens to
span them — the same guarantee #722 established for a backslash chain. Alternatively the lines that
carry no statement of their own (array elements, the interior of a multi-line string) could be
treated as non-executable so they leave the denominator. Either way the array in the repro should
not contribute four uncovered lines after its function has run.
The scale of this in real code: in a repository of 13 shell scripts with 548 executable lines,
83 of the 188 lines reported as uncovered are array elements or interior lines of a multi-line
string, so roughly 15% of the denominator can never be covered by any test. Command allowlists such
as
available_commands=("start" "stop" ...)written one entry per line make it worse the morecommands a script grows.