Skip to content

Commit 6bd08cc

Browse files
author
Sylvain MARIE
committed
Cases generators can now support explicit name lists, and name generator callables, in addition to the name template strings. Fixed #24
1 parent d4beef5 commit 6bd08cc

File tree

3 files changed

+44
-8
lines changed

3 files changed

+44
-8
lines changed

pytest_cases/case_funcs.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ def test_target(target # type: Any
108108
test_target.__test__ = False # disable this function in pytest (otherwise name starts with 'test' > it will appear)
109109

110110

111-
def cases_generator(name_template, # type: str
111+
def cases_generator(names=None, # type: Union[str, Callable[[Any], str], Iterable[str]]
112112
lru_cache=False, # type: bool
113113
**param_ranges # type: Iterable[Any]
114114
):
@@ -127,9 +127,11 @@ def cases_generator(name_template, # type: str
127127
>>> outs = i+1, i+2
128128
>>> return ins, outs, None
129129
130-
:param name_template: a name template, that will be transformed into the case name using
131-
`name_template.format(**params)` for each case, where params is the dictionary of parameter values for this
132-
generated case.
130+
:param names: a name template, that will be transformed into the case name using
131+
`names.format(**params)` for each case, where `params` is the dictionary of parameter values for this
132+
generated case. Alternately a callable returning a string can be provided, in which case
133+
`names(**params)` will be used. Finally an explicit list of names can be provided, in which case it should have
134+
the correct length (an error will be raised otherwise).
133135
:param lru_cache: a boolean (default False) indicating if the generated cases should be cached. This is identical
134136
to decorating the function with an additional `@lru_cache(maxsize=n)` where n is the total number of generated
135137
cases.
@@ -141,7 +143,7 @@ def cases_generator(name_template, # type: str
141143

142144
def cases_generator_decorator(test_func):
143145
kwarg_values = list(product(*param_ranges.values()))
144-
setattr(test_func, _GENERATOR_FIELD, (name_template, param_ranges.keys(), kwarg_values))
146+
setattr(test_func, _GENERATOR_FIELD, (names, param_ranges.keys(), kwarg_values))
145147
if lru_cache:
146148
nb_cases = len(kwarg_values)
147149
# decorate the function with the appropriate lru cache size

pytest_cases/main.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -727,15 +727,30 @@ def _get_case_getter_s(f,
727727
if gen:
728728
already_used_names = []
729729

730-
name_template, param_ids, all_param_values_combinations = gen
730+
names, param_ids, all_param_values_combinations = gen
731+
732+
if isinstance(names, str):
733+
# then this is a string formatter
734+
_formatter = names
735+
names = lambda **params: _formatter.format(**params)
736+
731737
nb_cases_generated = len(all_param_values_combinations)
738+
if not callable(names):
739+
if len(names) != nb_cases_generated:
740+
raise ValueError("An explicit list of names has been provided but it has not the same length (%s) than"
741+
" the number of cases to be generated (%s)" % (len(names), nb_cases_generated))
732742

733743
for gen_case_id, case_params_values in enumerate(all_param_values_combinations):
734744
# build the dictionary of parameters for the case functions
735745
gen_case_params_dct = dict(zip(param_ids, case_params_values))
736746

737747
# generate the case name by applying the name template
738-
gen_case_name = name_template.format(**gen_case_params_dct)
748+
if callable(names):
749+
gen_case_name = names(**gen_case_params_dct)
750+
else:
751+
# an explicit list is provided
752+
gen_case_name = names[gen_case_id]
753+
739754
if gen_case_name in already_used_names:
740755
raise ValueError("Generated function names for generator case function {} are not "
741756
"unique. Please use all parameter names in the string format variables"

pytest_cases/tests/simple/test_generators.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,33 @@ def case_simple():
2323
# yield ins, outs, None
2424

2525

26-
@cases_generator("test with i={i}, j={j}", i=range(2), j=range(3))
26+
@cases_generator("test with i={i}, j={j} and name template", i=range(2), j=range(3))
2727
def case_simple_generator(i, j):
2828
# type: (...) -> CaseData
2929
ins = dict(a=i, b=j)
3030
outs = i+1, j+1
3131
return ins, outs, None
3232

3333

34+
@cases_generator("test with i={i}, j={j} and names callable provider", i=range(2), j=range(3))
35+
def case_simple_generator_callable_name(i, j):
36+
# type: (...) -> CaseData
37+
ins = dict(a=i, b=j)
38+
outs = i+1, j+1
39+
return ins, outs, None
40+
41+
42+
names_list = ["test with i={i}, j={j} and explicit names list".format(i=i, j=j) for i in range(2) for j in range(3)]
43+
44+
45+
@cases_generator(names_list, i=range(2), j=range(3))
46+
def case_simple_generator_explicit_name_list(i, j):
47+
# type: (...) -> CaseData
48+
ins = dict(a=i, b=j)
49+
outs = i+1, j+1
50+
return ins, outs, None
51+
52+
3453
@cases_data(module=THIS_MODULE)
3554
def test_with_cases_decorated(case_data # type: CaseDataGetter
3655
):

0 commit comments

Comments
 (0)