Skip to content

Commit b80a779

Browse files
committed
feat: add assert_stderr_line
Add a new assert_stderr_line function for checking expected lines in the stderr output. This improves the clarity and functionality of the assertion process.
1 parent a214bc9 commit b80a779

File tree

3 files changed

+506
-0
lines changed

3 files changed

+506
-0
lines changed

README.md

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ This project provides the following functions:
4040
- [assert_line](#assert_line) / [refute_line](#refute_line) Assert a specific line of output does (or does not) contain given content.
4141
- [assert_regex](#assert_regex) / [refute_regex](#refute_regex) Assert a parameter does (or does not) match given pattern.
4242
- [assert_stderr](#assert_stderr) / [refute_stderr](#refute_stderr) Assert stderr does (or does not) contain given content.
43+
- [assert_stderr_line](#assert_stderr_line) Assert a specific line of stderr does contain given content.
4344

4445
These commands are described in more detail below.
4546

@@ -897,6 +898,115 @@ Similar to `refute_output`, this function verifies that a command or function do
897898
The stderr matching can be literal (the default), partial or by regular expression.
898899
The unexpected stderr can be specified either by positional argument or read from STDIN by passing the `-`/`--stdin` flag.
899900
901+
### `assert_stderr_line`
902+
903+
> _**Note**:
904+
> `run` has to be called with `--separate-stderr` to separate stdout and stderr into `$output` and `$stderr`.
905+
> If not, `$stderr` will be empty, causing `assert_stderr_line` to always fail.
906+
907+
Similarly to `assert_stderr`, this function verifies that a command or function produces the expected stderr.
908+
It checks that the expected line appears in the stderr (default) or at a specific line number.
909+
Matching can be literal (default), partial or regular expression.
910+
This function is the logical complement of `refute_stderr_line`.
911+
912+
#### Looking for a line in the stderr
913+
914+
By default, the entire stderr is searched for the expected line.
915+
The assertion fails if the expected line is not found in `${stderr_lines[@]}`.
916+
917+
```bash
918+
echo_err() {
919+
echo "$@" >&2
920+
}
921+
922+
@test 'assert_stderr_line() looking for line' {
923+
run --separate-stderr echo_err $'have-0\nhave-1\nhave-2'
924+
assert_stderr_line 'want'
925+
}
926+
```
927+
928+
On failure, the expected line and the stderr are displayed.
929+
930+
```
931+
-- stderr does not contain line --
932+
line : want
933+
stderr (3 lines):
934+
have-0
935+
have-1
936+
have-2
937+
--
938+
```
939+
940+
#### Matching a specific line
941+
942+
When the `--index <idx>` option is used (`-n <idx>` for short), the expected line is matched only against the line identified by the given index.
943+
The assertion fails if the expected line does not equal `${stderr_lines[<idx>]}`.
944+
945+
```bash
946+
@test 'assert_stderr_line() specific line' {
947+
run --separate-stderr echo_err $'have-0\nhave-1\nhave-2'
948+
assert_stderr_line --index 1 'want-1'
949+
}
950+
```
951+
952+
On failure, the index and the compared stderr_lines are displayed.
953+
954+
```
955+
-- line differs --
956+
index : 1
957+
expected : want-1
958+
actual : have-1
959+
--
960+
```
961+
962+
#### Partial matching
963+
964+
Partial matching can be enabled with the `--partial` option (`-p` for short).
965+
When used, a match fails if the expected *substring* is not found in the matched line.
966+
967+
```bash
968+
@test 'assert_stderr_line() partial matching' {
969+
run --separate-stderr echo_err $'have 1\nhave 2\nhave 3'
970+
assert_stderr_line --partial 'want'
971+
}
972+
```
973+
974+
On failure, the same details are displayed as for literal matching, except that the substring replaces the expected line.
975+
976+
```
977+
-- no stderr line contains substring --
978+
substring : want
979+
stderr (3 lines):
980+
have 1
981+
have 2
982+
have 3
983+
--
984+
```
985+
986+
#### Regular expression matching
987+
988+
Regular expression matching can be enabled with the `--regexp` option (`-e` for short).
989+
When used, a match fails if the *extended regular expression* does not match the line being tested.
990+
991+
*Note: As expected, the anchors `^` and `$` bind to the beginning and the end (respectively) of the matched line.*
992+
993+
```bash
994+
@test 'assert_stderr_line() regular expression matching' {
995+
run --separate-stderr echo_err $'have-0\nhave-1\nhave-2'
996+
assert_stderr_line --index 1 --regexp '^want-[0-9]$'
997+
}
998+
```
999+
1000+
On failure, the same details are displayed as for literal matching, except that the regular expression replaces the expected line.
1001+
1002+
```
1003+
-- regular expression does not match line --
1004+
index : 1
1005+
regexp : ^want-[0-9]$
1006+
line : have-1
1007+
--
1008+
```
1009+
9001010
<!-- REFERENCES -->
9011011
9021012
[bats]: https://github.com/bats-core/bats-core

src/assert_line.bash

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,38 @@ assert_line() {
131131
__assert_line "$@"
132132
}
133133

134+
# assert_stderr_line
135+
# ===========
136+
#
137+
# Summary: Fail if the expected line is not found in the stderr (default) or at a specific line number.
138+
#
139+
# Usage: assert_stderr_line [-n index] [-p | -e] [--] <expected>
140+
#
141+
# Options:
142+
# -n, --index <idx> Match the <idx>th line
143+
# -p, --partial Match if `expected` is a substring of `$stderr` or line <idx>
144+
# -e, --regexp Treat `expected` as an extended regular expression
145+
# <expected> The expected line string, substring, or regular expression
146+
#
147+
# IO:
148+
# STDERR - details, on failure
149+
# error message, on error
150+
# Globals:
151+
# stderr
152+
# stderr_lines
153+
# Returns:
154+
# 0 - if matching line found
155+
# 1 - otherwise
156+
#
157+
# Similarly to `assert_stderr`, this function verifies that a command or function produces the expected stderr.
158+
# (It is the logical complement of `refute_stderr_line`.)
159+
# It checks that the expected line appears in the stderr (default) or at a specific line number.
160+
# Matching can be literal (default), partial or regular expression.
161+
#
162+
assert_stderr_line() {
163+
__assert_line "$@"
164+
}
165+
134166
__assert_line() {
135167
local -r caller=${FUNCNAME[1]}
136168
local -i is_match_line=0

0 commit comments

Comments
 (0)