aboutsummaryrefslogtreecommitdiff
path: root/tests/discipline/matcher.test.py
blob: 8d606ec21b95b0e392ec48e1e79fdd327b0fc2f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
"""Discipline test — the builder exposes exactly the five closed match verbs."""

import pytest

from edify import Pattern, RegexBuilder

_ALLOWED_MATCH_VERBS = frozenset({"test", "match", "search", "findall", "sub"})
_FORBIDDEN_MATCH_VERBS = frozenset({"fullmatch", "finditer", "subn", "split"})
_FORBIDDEN_RE_PATTERN_ATTRS = frozenset({"groups", "groupindex", "pattern", "flags"})


@pytest.mark.parametrize("factory", [RegexBuilder, Pattern])
def test_builder_exposes_every_allowed_match_verb(factory: type[RegexBuilder | Pattern]):
    builder = factory()
    for verb in _ALLOWED_MATCH_VERBS:
        assert callable(getattr(builder, verb)), f"missing verb: {verb}"


@pytest.mark.parametrize("factory", [RegexBuilder, Pattern])
def test_builder_does_not_expose_any_forbidden_match_verb(factory: type[RegexBuilder | Pattern]):
    builder = factory()
    for verb in _FORBIDDEN_MATCH_VERBS:
        assert not hasattr(builder, verb), (
            f"builder must not expose re.Pattern verb {verb!r}; "
            "use .to_regex() and call it on the Regex wrapper instead"
        )


@pytest.mark.parametrize("factory", [RegexBuilder, Pattern])
def test_builder_does_not_expose_re_pattern_metadata_attributes(
    factory: type[RegexBuilder | Pattern],
):
    builder = factory()
    for attribute in _FORBIDDEN_RE_PATTERN_ATTRS:
        assert not hasattr(builder, attribute), (
            f"builder must not expose re.Pattern attribute {attribute!r}"
        )


def test_regex_wrapper_exposes_every_re_pattern_verb():
    regex = RegexBuilder().string("a").to_regex()
    re_pattern_verbs = (_ALLOWED_MATCH_VERBS | _FORBIDDEN_MATCH_VERBS) - {"test"}
    for verb in re_pattern_verbs:
        assert callable(getattr(regex, verb)), f"Regex wrapper missing verb: {verb}"