Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add assert_stderr and assert_stderr_line #52

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
215 changes: 215 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ This project provides the following functions:
- [assert_output](#assert_output) / [refute_output](#refute_output) Assert output does (or does not) contain given content.
- [assert_line](#assert_line) / [refute_line](#refute_line) Assert a specific line of output does (or does not) contain given content.
- [assert_regex](#assert_regex) / [refute_regex](#refute_regex) Assert a parameter does (or does not) match given pattern.
- [assert_stderr](#assert_stderr) Assert stderr does contain given content.
- [assert_stderr_line](#assert_stderr_line) Assert a specific line of stderr does contain given content.

These commands are described in more detail below.

Expand Down Expand Up @@ -773,6 +775,219 @@ actions like calling `run`. Thus, it's good practice to avoid using
the array contains is the matching part of the value which is printed in the
failing test log, as mentioned above.

### `assert_stderr`

Similarly to `assert_output`, this function verifies that a command or function produces the expected stderr.
The stderr matching can be literal (the default), partial or by regular expression.
The expected stderr can be specified either by positional argument or read from STDIN by passing the `-`/`--stdin` flag.

#### Literal matching

By default, literal matching is performed.
The assertion fails if `$stderr` does not equal the expected stderr.

```bash
echo_err() {
echo "$@" >&2
}

@test 'assert_stderr()' {
run echo_err 'have'
assert_stderr 'want'
}

@test 'assert_stderr() with pipe' {
run echo_err 'hello'
echo_err 'hello' | assert_stderr -
}

@test 'assert_stderr() with herestring' {
run echo_err 'hello'
assert_stderr - <<< hello
}
```

On failure, the expected and actual stderr are displayed.

```
-- stderr differs --
expected : want
actual : have
--
```

#### Existence

To assert that any stderr exists at all, omit the `expected` argument.

```bash
@test 'assert_stderr()' {
run echo_err 'have'
assert_stderr
}
```

On failure, an error message is displayed.

```
-- no stderr --
expected non-empty stderr, but stderr was empty
--
```

#### Partial matching

Partial matching can be enabled with the `--partial` option (`-p` for short).
When used, the assertion fails if the expected _substring_ is not found in `$stderr`.

```bash
@test 'assert_stderr() partial matching' {
run echo_err 'ERROR: no such file or directory'
assert_stderr --partial 'SUCCESS'
}
```

On failure, the substring and the stderr are displayed.

```
-- stderr does not contain substring --
substring : SUCCESS
stderr : ERROR: no such file or directory
--
```

#### Regular expression matching

Regular expression matching can be enabled with the `--regexp` option (`-e` for short).
When used, the assertion fails if the *extended regular expression* does not match `$stderr`.

*Note: The anchors `^` and `$` bind to the beginning and the end (respectively) of the entire stderr; not individual lines.*

```bash
@test 'assert_stderr() regular expression matching' {
run echo_err 'Foobar 0.1.0'
assert_stderr --regexp '^Foobar v[0-9]+\.[0-9]+\.[0-9]$'
}
```

On failure, the regular expression and the stderr are displayed.

```
-- regular expression does not match stderr --
regexp : ^Foobar v[0-9]+\.[0-9]+\.[0-9]$
stderr : Foobar 0.1.0
--
```

### `assert_stderr_line`

Similarly to `assert_stderr`, this function verifies that a command or function produces the expected stderr.
It checks that the expected line appears in the stderr (default) or at a specific line number.
Matching can be literal (default), partial or regular expression.

***Warning:***
*Due to a [bug in Bats][bats-93], empty stderr_lines are discarded from `${stderr_lines[@]}`, causing line indices to change and preventing testing for empty stderr_lines.*

[bats-93]: https://github.com/sstephenson/bats/pull/93

#### Looking for a line in the stderr

By default, the entire stderr is searched for the expected line.
The assertion fails if the expected line is not found in `${stderr_lines[@]}`.

```bash
echo_err() {
echo "$@" >&2
}

@test 'assert_stderr_line() looking for line' {
run echo_err $'have-0\nhave-1\nhave-2'
assert_stderr_line 'want'
}
```

On failure, the expected line and the stderr are displayed.

```
-- stderr does not contain line --
line : want
stderr (3 lines):
have-0
have-1
have-2
--
```

#### Matching a specific line

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.
The assertion fails if the expected line does not equal `${stderr_lines[<idx>]}`.

```bash
@test 'assert_stderr_line() specific line' {
run echo_err $'have-0\nhave-1\nhave-2'
assert_stderr_line --index 1 'want-1'
}
```

On failure, the index and the compared stderr_lines are displayed.

```
-- line differs --
index : 1
expected : want-1
actual : have-1
--
```

#### Partial matching

Partial matching can be enabled with the `--partial` option (`-p` for short).
When used, a match fails if the expected *substring* is not found in the matched line.

```bash
@test 'assert_stderr_line() partial matching' {
run echo_err $'have 1\nhave 2\nhave 3'
assert_stderr_line --partial 'want'
}
```

On failure, the same details are displayed as for literal matching, except that the substring replaces the expected line.

```
-- no stderr line contains substring --
substring : want
stderr (3 lines):
have 1
have 2
have 3
--
```

#### Regular expression matching

Regular expression matching can be enabled with the `--regexp` option (`-e` for short).
When used, a match fails if the *extended regular expression* does not match the line being tested.

*Note: As expected, the anchors `^` and `$` bind to the beginning and the end (respectively) of the matched line.*

```bash
@test 'assert_stderr_line() regular expression matching' {
run echo_err $'have-0\nhave-1\nhave-2'
assert_stderr_line --index 1 --regexp '^want-[0-9]$'
}
```

On failure, the same details are displayed as for literal matching, except that the regular expression replaces the expected line.

```
-- regular expression does not match line --
index : 1
regexp : ^want-[0-9]$
line : have-1
--
```

<!-- REFERENCES -->

[bats]: https://github.com/bats-core/bats-core
Expand Down
2 changes: 2 additions & 0 deletions load.bash
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,5 @@ source "$(dirname "${BASH_SOURCE[0]}")/src/assert_line.bash"
source "$(dirname "${BASH_SOURCE[0]}")/src/refute_line.bash"
source "$(dirname "${BASH_SOURCE[0]}")/src/assert_regex.bash"
source "$(dirname "${BASH_SOURCE[0]}")/src/refute_regex.bash"
source "$(dirname "${BASH_SOURCE[0]}")/src/assert_stderr.bash"
source "$(dirname "${BASH_SOURCE[0]}")/src/assert_stderr_line.bash"
Loading