Skip to content

Commit 9e6627e

Browse files
AdamWillmartin-schulze-vireso
authored andcommitted
Add a --negative-filter option (bats-core#1114)
See https://pagure.io/fedora-qa/os-autoinst-distri-fedora/pull-request/389 . The FAQ claimed "So you could try to invert the regex", but as far as I can tell, there's no practical way to do this with bash regexes, if you want to express "run all tests except foo_in_a" or something like that. You can do it in some regex flavors using negative lookahead matches, but bash's regex flavor does not seem to support that, and you can't just stick a `!` on the front of the regex or anything like that. So, this adds --negative-filter which just does the opposite of --filter. The implementation is intentionally 'dumb' because handling 'what if one or both is not defined?' gets a bit awkward if you try to handle both in one function. Signed-off-by: Adam Williamson <[email protected]>
1 parent d06dac3 commit 9e6627e

6 files changed

Lines changed: 46 additions & 5 deletions

File tree

docs/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ The format is based on [Keep a Changelog][kac] and this project adheres to
1414
### Added
1515

1616
* use the [`syntax`](https://docs.docker.com/reference/dockerfile/#syntax) parser directive to declare the Dockerfile syntax version (#1127)
17+
* Negative test filtering via `--negative-filter` - tests matching the filter are *excluded* (#1114)
1718

1819
### Fixed
1920

docs/source/faq.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ If you want to see this output, you need to print it yourself, or use functions
1818
Can I use `--filter` to exclude files/tests?
1919
--------------------------------------------
2020

21-
No, not directly. `--filter` uses a regex to match against test names. So you could try to invert the regex.
22-
The filename won't be part of the strings that are tested, so you cannot filter against files.
21+
You can use `--negative-filter` to do this.
2322

2423
How can I exclude a single test from a test run?
2524
------------------------------------------------

libexec/bats-core/bats

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ HELP_TEXT_HEADER
4747
- custom: provide your own via defining bats_format_file_line_reference_custom
4848
with parameters <filename> <line>, store via `printf -v "$output"`
4949
-f, --filter <regex> Only run tests that match the regular expression
50+
--negative-filter <regex> Only run tests that do not match the regular expression
5051
--filter-status <status> Only run tests with the given status in the last completed (no CTRL+C/SIGINT) run.
5152
Valid <status> values are:
5253
failed - runs tests that failed or were not present in the last run
@@ -190,6 +191,10 @@ while [[ "$#" -ne 0 ]]; do
190191
shift
191192
flags+=('-f' "$1")
192193
;;
194+
--negative-filter)
195+
shift
196+
flags+=('--negative-filter' "$1")
197+
;;
193198
-F | --formatter)
194199
shift
195200
# allow cat formatter to see extended output but don't advertise to users

libexec/bats-core/bats-exec-suite

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ set -e
33

44
count_only_flag=''
55
filter=''
6+
nfilter=''
67
num_jobs=${BATS_NUMBER_OF_PARALLEL_JOBS:-1}
78
parallel_binary_name=${BATS_PARALLEL_BINARY_NAME:-"parallel"}
89
bats_no_parallelize_across_files=${BATS_NO_PARALLELIZE_ACROSS_FILES-}
@@ -61,6 +62,10 @@ while [[ "$#" -ne 0 ]]; do
6162
shift
6263
gather_tests_flags+=("--filter-tags" "$1")
6364
;;
65+
--negative-filter)
66+
shift
67+
nfilter="$1"
68+
;;
6469
--dummy-flag) ;;
6570

6671
--trace)
@@ -128,7 +133,7 @@ fi
128133

129134
# create file even if no tests are found so the `read` below won't fail
130135
touch "$TESTS_LIST_FILE"
131-
gather_tests_output=$(TESTS_LIST_FILE="$TESTS_LIST_FILE" filter="$filter" filter_status="$filter_status" bats-gather-tests "${gather_tests_flags[@]}" -- "$@")
136+
gather_tests_output=$(TESTS_LIST_FILE="$TESTS_LIST_FILE" filter="$filter" nfilter="$nfilter" filter_status="$filter_status" bats-gather-tests "${gather_tests_flags[@]}" -- "$@")
132137
test_count=$(grep -c ^ "$TESTS_LIST_FILE" || true) # don't fail here when there are no tests
133138
if [[ $gather_tests_output == focus_mode ]]; then
134139
focus_mode=1
@@ -313,4 +318,4 @@ fi
313318
set -eET
314319
bats_run_teardown_suite
315320

316-
bats_exit_suite
321+
bats_exit_suite

libexec/bats-core/bats-gather-tests

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ bats_test_function() {
8585
line+=$'\t'
8686
line+="$*"
8787
# always execute should_skip_because_of_status for its sideeffects
88-
if should_skip_because_of_status || should_skip_because_of_focus || should_skip_because_of_filter_tags || should_skip_because_of_filter; then
88+
if should_skip_because_of_status || should_skip_because_of_focus || should_skip_because_of_filter_tags || should_skip_because_of_filter || should_skip_because_of_negative_filter; then
8989
return 0
9090
fi
9191

@@ -164,6 +164,18 @@ function should_skip_because_of_filter() {
164164
}
165165
fi
166166

167+
if [[ -n "${nfilter-}" ]]; then
168+
function should_skip_because_of_negative_filter() {
169+
# shellcheck disable=SC2154 # nfilter should be inherited as env var
170+
[[ "$description" =~ $nfilter ]]
171+
}
172+
else
173+
function should_skip_because_of_negative_filter() {
174+
# skip this when there is no $nfilter
175+
return 1
176+
}
177+
fi
178+
167179
function should_skip_because_of_status() {
168180
# disable this filter if not activated by $filter_status
169181
return 1

test/suite.bats

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,25 @@ setup() {
219219
[ "${lines[2]}" = 'ok 2 bar_in_b' ]
220220
}
221221

222+
@test "use --negative-filter to exclude specific test cases" {
223+
reentrant_run bats --negative-filter 'ba[rz]' "${FIXTURE_ROOT}/filter"
224+
[ "$status" -eq 0 ]
225+
[ "${lines[0]}" = '1..5' ]
226+
[ "${lines[1]}" = 'ok 1 foo in a' ]
227+
[ "${lines[2]}" = 'ok 2 quux_in_b' ]
228+
[ "${lines[3]}" = 'ok 3 quux_in c' ]
229+
[ "${lines[4]}" = 'ok 4 xyzzy in c' ]
230+
[ "${lines[5]}" = 'ok 5 plugh_in c' ]
231+
}
232+
233+
@test "--negative-filter together with --filter" {
234+
reentrant_run bats -f 'in a' --negative-filter 'baz' "${FIXTURE_ROOT}/filter"
235+
[ "$status" -eq 0 ]
236+
[ "${lines[0]}" = '1..2' ]
237+
[ "${lines[1]}" = 'ok 1 foo in a' ]
238+
[ "${lines[2]}" = 'ok 2 --bar in a' ]
239+
}
240+
222241
@test "skip is handled correctly in setup, test, and teardown" {
223242
bats "${FIXTURE_ROOT}/skip"
224243
}

0 commit comments

Comments
 (0)