Skip to content

Commit 1c12486

Browse files
author
Sylvain MARIE
committed
Improved description for the glob argument in @parametrize_with_cases. Also made the implementation escape all regex special characters so that they can't be used. Finally a pattern should now match the entire case id (previously, a partial match would work if it was at the beginning of the string). Added tests. One simple step towards #147
1 parent 0470686 commit 1c12486

File tree

4 files changed

+42
-5
lines changed

4 files changed

+42
-5
lines changed

docs/api_reference.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ argvalues = get_parametrize_args(host_class_or_module_of_f, cases_funs)
7272

7373
- `prefix`: the prefix for case functions. Default is 'case_' but you might wish to use different prefixes to denote different kind of cases, for example 'data_', 'algo_', 'user_', etc.
7474

75-
- `glob`: an optional glob-like pattern for case ids, for example "*_success" or "*_failure". Note that this is applied on the case id, and therefore if it is customized through [`@case(id=...)`](#case) it should be taken into account.
75+
- `glob`: a matching pattern for case ids, for example `*_success` or `*_failure`. The only special character that can be used for now in this pattern is `*`, it can not be escaped, and it can be used several times in the same expression. The pattern should match the entire case id for the case to be selected. Note that this is applied on the case id, and therefore if it is customized through [`@case(id=...)`](#case) it will be taken into account.
7676

7777
- `has_tag`: a single tag or a tuple, set, list of tags that should be matched by the ones set with the [`@case`](#case) decorator on the case function(s) to be selected.
7878

pytest_cases/case_parametrizer_new.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,16 @@ def create_glob_name_filter(glob_str # type: str
126126
):
127127
"""
128128
Creates a glob-like matcher for the name of case functions
129+
The only special character that is supported is `*` and it can not be
130+
escaped. However it can be used multiple times in an expression.
129131
130-
:param case_fun:
132+
:param glob_str: for example `*_success` or `*_*`
131133
:return:
132134
"""
133-
name_matcher = re.compile(glob_str.replace("*", ".*"))
135+
# escape all special regex characters, then find the (escaped) stars and turn them into the regex star .*
136+
re_str = re.escape(glob_str).replace("\\*", ".*")
137+
# add "end" special regex char
138+
name_matcher = re.compile(re_str + "$")
134139

135140
def _glob_name_filter(case_fun):
136141
case_fun_id = case_fun._pytestcase.id
@@ -162,8 +167,10 @@ def get_all_cases(parametrization_target, # type: Callable
162167
explicitly provided in the list, they can have any name and do not need to follow this `*Case*` pattern.
163168
:param prefix: the prefix for case functions. Default is 'case_' but you might wish to use different prefixes to
164169
denote different kind of cases, for example 'data_', 'algo_', 'user_', etc.
165-
:param glob: an optional glob-like pattern for case ids, for example "*_success" or "*_failure". Note that this
166-
is applied on the case id, and therefore if it is customized through `@case(id=...)` it should be taken into
170+
:param glob: a matching pattern for case ids, for example `*_success` or `*_failure`. The only special character
171+
that can be used for now in this pattern is `*`, it can not be escaped, and it can be used several times in the
172+
same expression. The pattern should match the entire case id for the case to be selected. Note that this is
173+
applied on the case id, and therefore if it is customized through `@case(id=...)` it will be taken into
167174
account.
168175
:param has_tag: a single tag or a tuple, set, list of tags that should be matched by the ones set with the `@case`
169176
decorator on the case function(s) to be selected.

pytest_cases/tests/cases/others/__init__.py

Whitespace-only changes.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from pytest_cases import case
2+
3+
from pytest_cases.case_parametrizer_new import create_glob_name_filter
4+
5+
6+
def test_glob_low_level():
7+
"""Tests that the glob-like filtering mechanism for case ids works"""
8+
9+
def case_fun_with_id(id):
10+
@case(id=id)
11+
def _f():
12+
pass
13+
# CaseInfo(id=id).attach_to(_f)
14+
return _f
15+
16+
filtr = create_glob_name_filter("o*_success")
17+
assert filtr(case_fun_with_id("oooh_success"))
18+
assert not filtr(case_fun_with_id("oh_no"))
19+
# beginning and end: no match
20+
assert not filtr(case_fun_with_id("oh_success2"))
21+
assert not filtr(case_fun_with_id("yoh_success"))
22+
23+
filtr = create_glob_name_filter("*_*")
24+
assert filtr(case_fun_with_id("oh_success"))
25+
assert filtr(case_fun_with_id("oh_no"))
26+
assert not filtr(case_fun_with_id("ohno"))
27+
28+
filtr = create_glob_name_filter("*_$[ab]+")
29+
assert filtr(case_fun_with_id("oh_$[ab]+"))
30+
assert not filtr(case_fun_with_id("oh_$"))

0 commit comments

Comments
 (0)