aboutsummaryrefslogtreecommitdiff
path: root/tests/library/algebra.test.py
blob: ee4005d93ae49a0b673422a425d80213c3789703 (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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
"""Chain <-> operator-algebra equivalence: ``+``, ``|`` and ``.use()`` emit the fluent-chain regex.

Every character-class module constant is driven through both surfaces and the two
emitted regex strings are asserted identical, so the operator algebra can never
drift from the fluent builder it stands in for.
"""

import pytest

from edify import (
    ALPHANUMERIC,
    ANY_CHAR,
    CARRIAGE_RETURN,
    DIGIT,
    LETTER,
    LOWERCASE,
    NEW_LINE,
    NON_DIGIT,
    NON_WHITESPACE,
    NON_WORD,
    NULL_BYTE,
    TAB,
    UPPERCASE,
    WHITESPACE,
    WORD,
    Pattern,
)

_CONSTANTS: dict[str, Pattern] = {
    "ANY_CHAR": ANY_CHAR,
    "WHITESPACE": WHITESPACE,
    "NON_WHITESPACE": NON_WHITESPACE,
    "DIGIT": DIGIT,
    "NON_DIGIT": NON_DIGIT,
    "WORD": WORD,
    "NON_WORD": NON_WORD,
    "NEW_LINE": NEW_LINE,
    "CARRIAGE_RETURN": CARRIAGE_RETURN,
    "TAB": TAB,
    "NULL_BYTE": NULL_BYTE,
    "LETTER": LETTER,
    "UPPERCASE": UPPERCASE,
    "LOWERCASE": LOWERCASE,
    "ALPHANUMERIC": ALPHANUMERIC,
}
_IDS = list(_CONSTANTS)
_VALUES = list(_CONSTANTS.values())


@pytest.mark.parametrize("constant", _VALUES, ids=_IDS)
def test_plus_matches_chain_subexpression(constant: Pattern):
    operator_form = (constant + DIGIT).to_regex_string()
    chain_form = Pattern().subexpression(constant).subexpression(DIGIT).to_regex_string()
    assert operator_form == chain_form


@pytest.mark.parametrize("constant", _VALUES, ids=_IDS)
def test_or_matches_chain_any_of(constant: Pattern):
    operator_form = (constant | DIGIT).to_regex_string()
    chain_form = (
        Pattern().any_of().subexpression(constant).subexpression(DIGIT).end().to_regex_string()
    )
    assert operator_form == chain_form


@pytest.mark.parametrize("constant", _VALUES, ids=_IDS)
def test_use_matches_chain_subexpression(constant: Pattern):
    use_form = Pattern().use(constant).to_regex_string()
    chain_form = Pattern().subexpression(constant).to_regex_string()
    assert use_form == chain_form


@pytest.mark.parametrize("constant", _VALUES, ids=_IDS)
def test_operator_and_chain_compile_to_the_same_matcher(constant: Pattern):
    operator_compiled = (constant + DIGIT).to_regex().source
    chain_compiled = Pattern().subexpression(constant).subexpression(DIGIT).to_regex().source
    assert operator_compiled == chain_compiled