diff --git a/docs/index.md b/docs/index.md index 35ad02b5..766793ac 100644 --- a/docs/index.md +++ b/docs/index.md @@ -295,6 +295,19 @@ def test_good_datasets2(data): assert sqrt(data) > 0 ``` + - pytest-cases offers you an array of default filter for you to choose from in the `filters` module such as: `has_tag`, `has_prefix`, and etc. You can use logical operations on them like "and" (&) "or" (|) and "invert" (~) in order to create you own custom filters. + +```python +from pytest_cases import filters + + +@parametrize_with_cases("data", cases='.', + filter=filters.has_tag("success") & filters.id_has_prefix( + "case_b") +def test_good_datasets3(data): + assert sqrt(data) > 0 +``` + ### b- Case functions diff --git a/pytest_cases/filters.py b/pytest_cases/filters.py new file mode 100644 index 00000000..eb18e002 --- /dev/null +++ b/pytest_cases/filters.py @@ -0,0 +1,76 @@ +import re + +from .case_info import CaseInfo + + +class CaseFilter(object): + """ + This class represents a case filter. You can use it in order to filter cases + to be used by `parametrize_by_cases`. + + You can join filters with the "and" relation by using & operator and join them + by "or" relation using | operator. + Moreover, you can negate a filter by using ~. + """ + + def __init__(self, filter_function): + self.filter_function = filter_function + + def __call__(self, case): + return self.filter_function(case) + + def __and__(self, other): + return CaseFilter( + lambda case: self(case) and other(case) + ) + + def __rand__(self, other): + return self & other + + def __or__(self, other): + return CaseFilter( + lambda case: self(case) or other(case) + ) + + def __ror__(self, other): + return self | other + + def __invert__(self): + return CaseFilter( + lambda case: not self(case) + ) + + +def has_tag(tag_name): + """Select cases that have the tag `tag_name`. See `@case(tags=...)` to add tags to a case.""" + return CaseFilter(lambda case: tag_name in CaseInfo.get_from(case).tags) + + +def id_has_prefix(prefix): + """ + Select cases that have a case id prefix `prefix`. + + Note that this is not the prefix of the whole case function name, but the case id, + possibly overridden with `@case(id=)` + """ + return CaseFilter(lambda case: CaseInfo.get_from(case).id.startswith(prefix)) + + +def id_has_suffix(suffix): + """ + Select cases that have a case id suffix `suffix`. + + Note that this is not the suffix of the whole case function name, but the case id, + possibly overridden with `@case(id=)` + """ + return CaseFilter(lambda case: CaseInfo.get_from(case).id.endswith(suffix)) + + +def id_match_regex(regex): + """ + Select cases that have a case id matching `regex`. + + Note that this is not a match of the whole case function name, but the case id, + possibly overridden with `@case(id=)` + """ + return CaseFilter(lambda case: re.match(regex, CaseInfo.get_from(case).id)) diff --git a/pytest_cases/tests/pytest_extension/parametrize_plus/test_filter.py b/pytest_cases/tests/pytest_extension/parametrize_plus/test_filter.py new file mode 100644 index 00000000..20cd4f6b --- /dev/null +++ b/pytest_cases/tests/pytest_extension/parametrize_plus/test_filter.py @@ -0,0 +1,86 @@ +from pytest_cases import filters, case, parametrize_with_cases + +A = "a" +B = "b" +C = "c" + + +@case(tags=[A], id="tom") +def case_one(): + return 1 + + +@case(tags=[A, B], id="tim") +def case_two(): + return 2 + + +@case(tags=[B, C], id="toni") +def case_three(): + return 3 + + +@case(tags=[A, C], id="dom") +def case_four(): + return 4 + + +@parametrize_with_cases( + argnames="value", cases=".", filter=filters.has_tag(B) +) +def test_filter_with_tag(value): + pass + + +@parametrize_with_cases( + argnames="value", cases=".", filter=~filters.has_tag(B) +) +def test_filter_without_tag(value): + pass + + +@parametrize_with_cases( + argnames="value", cases=".", filter=filters.has_tag(B) & filters.has_tag(C) +) +def test_filter_with_and_relation(value): + pass + + +@parametrize_with_cases( + argnames="value", cases=".", filter=filters.has_tag(B) | filters.has_tag(C) +) +def test_filter_with_or_relation(value): + pass + + +@parametrize_with_cases( + argnames="value", cases=".", filter=filters.id_has_prefix("t") +) +def test_filter_with_prefix(value): + pass + + +@parametrize_with_cases( + argnames="value", cases=".", filter=filters.id_has_suffix("m") +) +def test_filter_with_suffix(value): + pass + + +def test_filter(module_results_dct): + assert list(module_results_dct) == [ + 'test_filter_with_tag[tim]', + 'test_filter_with_tag[toni]', + 'test_filter_without_tag[tom]', + 'test_filter_without_tag[dom]', + 'test_filter_with_and_relation[toni]', + 'test_filter_with_or_relation[tim]', + 'test_filter_with_or_relation[toni]', + 'test_filter_with_or_relation[dom]', + 'test_filter_with_prefix[tom]', + 'test_filter_with_prefix[tim]', + 'test_filter_with_prefix[toni]', + 'test_filter_with_suffix[tom]', + 'test_filter_with_suffix[tim]', + 'test_filter_with_suffix[dom]' + ]