Skip to content

Commit 6ad25d9

Browse files
Merge pull request #43 from rico-chet/assert-equal-regexp
Add `assert_regex`
2 parents 397c735 + d950f28 commit 6ad25d9

4 files changed

Lines changed: 174 additions & 0 deletions

File tree

README.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,41 @@ An error is displayed if the specified extended regular expression is invalid.
693693
This option and partial matching (`--partial` or `-p`) are mutually exclusive.
694694
An error is displayed when used simultaneously.
695695

696+
### `assert_regex`
697+
698+
This function is similar to `assert_equal` but uses pattern matching instead of
699+
equality, by wrapping `[[ value =~ pattern ]]`.
700+
701+
Fail if the value (first parameter) does not match the pattern (second
702+
parameter).
703+
704+
```bash
705+
@test 'assert_regex()' {
706+
assert_regex 'what' 'x$'
707+
}
708+
```
709+
710+
On failure, the value and the pattern are displayed.
711+
712+
```
713+
-- values does not match regular expression --
714+
value : what
715+
pattern : x$
716+
--
717+
```
718+
719+
If the value is longer than one line then it is displayed in *multi-line*
720+
format.
721+
722+
An error is displayed if the specified extended regular expression is invalid.
723+
724+
For description of the matching behavior, refer to the documentation of the
725+
`=~` operator in the
726+
[Bash manual]: https://www.gnu.org/software/bash/manual/html_node/Conditional-Constructs.html.
727+
Note that the `BASH_REMATCH` array is available immediately after the
728+
assertion succeeds but is fragile, i.e. prone to being overwritten as a side
729+
effect of other actions.
730+
696731
<!-- REFERENCES -->
697732

698733
[bats]: https://github.com/bats-core/bats-core

load.bash

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,4 @@ source "$(dirname "${BASH_SOURCE[0]}")/src/assert_output.bash"
2929
source "$(dirname "${BASH_SOURCE[0]}")/src/refute_output.bash"
3030
source "$(dirname "${BASH_SOURCE[0]}")/src/assert_line.bash"
3131
source "$(dirname "${BASH_SOURCE[0]}")/src/refute_line.bash"
32+
source "$(dirname "${BASH_SOURCE[0]}")/src/assert_regex.bash"

src/assert_regex.bash

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# `assert_regex`
2+
#
3+
# This function is similar to `assert_equal` but uses pattern matching instead
4+
# of equality, by wrapping `[[ value =~ pattern ]]`.
5+
#
6+
# Fail if the value (first parameter) does not match the pattern (second
7+
# parameter).
8+
#
9+
# ```bash
10+
# @test 'assert_regex()' {
11+
# assert_regex 'what' 'x$'
12+
# }
13+
# ```
14+
#
15+
# On failure, the value and the pattern are displayed.
16+
#
17+
# ```
18+
# -- values does not match regular expression --
19+
# value : what
20+
# pattern : x$
21+
# --
22+
# ```
23+
#
24+
# If the value is longer than one line then it is displayed in *multi-line*
25+
# format.
26+
#
27+
# An error is displayed if the specified extended regular expression is invalid.
28+
#
29+
# For description of the matching behavior, refer to the documentation of the
30+
# `=~` operator in the
31+
# [Bash manual]: https://www.gnu.org/software/bash/manual/html_node/Conditional-Constructs.html.
32+
# Note that the `BASH_REMATCH` array is available immediately after the
33+
# assertion succeeds but is fragile, i.e. prone to being overwritten as a side
34+
# effect of other actions.
35+
assert_regex() {
36+
local -r value="${1}"
37+
local -r pattern="${2}"
38+
39+
if [[ '' =~ ${pattern} ]] || (( ${?} == 2 )); then
40+
echo "Invalid extended regular expression: \`${pattern}'" \
41+
| batslib_decorate 'ERROR: assert_regex' \
42+
| fail
43+
elif ! [[ "${value}" =~ ${pattern} ]]; then
44+
if shopt -p nocasematch &>/dev/null; then
45+
local case_sensitive=insensitive
46+
else
47+
local case_sensitive=sensitive
48+
fi
49+
batslib_print_kv_single_or_multi 8 \
50+
'value' "${value}" \
51+
'pattern' "${pattern}" \
52+
'case' "${case_sensitive}" \
53+
| batslib_decorate 'value does not match regular expression' \
54+
| fail
55+
fi
56+
}

test/assert_regex.bats

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#!/usr/bin/env bats
2+
3+
load test_helper
4+
5+
#
6+
# Literal matching
7+
#
8+
9+
# Correctness
10+
@test "assert_regex() <value> <pattern>: succeeds if a <value> substring matches extended regular expression <pattern>" {
11+
run assert_regex 'abc' '^[a-z]b[c-z]+'
12+
assert_test_pass
13+
}
14+
15+
@test "assert_regex() <value> <pattern>: fails if no <value> substring matches extended regular expression <pattern>" {
16+
run assert_regex 'bcd' '^[a-z]b[c-z]+'
17+
assert_test_fail <<'ERR_MSG'
18+
19+
-- value does not match regular expression --
20+
value : bcd
21+
pattern : ^[a-z]b[c-z]+
22+
case : sensitive
23+
--
24+
ERR_MSG
25+
}
26+
27+
@test "assert_regex() <value> <pattern>: provides results in BASH_REMATCH" {
28+
unset -v BASH_REMATCH
29+
30+
assert_regex 'abcd' 'b.d'
31+
declare -p BASH_REMATCH
32+
[ "${BASH_REMATCH[0]}" = 'bcd' ]
33+
}
34+
35+
@test "assert_regex() <value> <pattern>: matches case-insensitively when 'nocasematch' is set" {
36+
shopt -s nocasematch
37+
38+
assert_regex 'aBc' 'ABC'
39+
}
40+
41+
@test "assert_regex() <value> <pattern>: outputs multi-line <value> nicely when it fails" {
42+
run assert_regex $'bcd\n123' '^[a-z]b[c-z]+'
43+
assert_test_fail <<'ERR_MSG'
44+
45+
-- value does not match regular expression --
46+
value (2 lines):
47+
bcd
48+
123
49+
pattern (1 lines):
50+
^[a-z]b[c-z]+
51+
case (1 lines):
52+
sensitive
53+
--
54+
ERR_MSG
55+
56+
shopt -s nocasematch
57+
run assert_regex $'bcd\n123' '^[a-z]b[c-z]+'
58+
assert_test_fail <<'ERR_MSG'
59+
60+
-- value does not match regular expression --
61+
value (2 lines):
62+
bcd
63+
123
64+
pattern (1 lines):
65+
^[a-z]b[c-z]+
66+
case (1 lines):
67+
insensitive
68+
--
69+
ERR_MSG
70+
}
71+
72+
# Error handling
73+
@test "assert_regex() <value> <pattern>: returns 1 and displays an error message if <pattern> is not a valid extended regular expression" {
74+
run assert_regex value '[.*'
75+
76+
assert_test_fail <<'ERR_MSG'
77+
78+
-- ERROR: assert_regex --
79+
Invalid extended regular expression: `[.*'
80+
--
81+
ERR_MSG
82+
}

0 commit comments

Comments
 (0)