aboutsummaryrefslogtreecommitdiff
path: root/tests/pattern/factories/quantifiers.test.py
blob: a0f558a0bde225d19b7a1b119a1a1f03ee727a5d (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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
"""Tests for the functional quantifier factories."""

import pytest

from edify import (
    DIGIT,
    WORD,
    Pattern,
    at_least,
    at_most,
    between,
    between_lazy,
    char,
    exactly,
    one_or_more,
    one_or_more_lazy,
    optional,
    string,
    zero_or_more,
    zero_or_more_lazy,
)
from edify.errors.input import (
    MustBeIntegerGreaterThanZeroError,
    MustBeLessThanError,
    MustBePositiveIntegerError,
)


def test_optional_wraps_a_single_element_operand_directly():
    assert optional(char("x")).to_regex_string() == "x?"


def test_zero_or_more_wraps_a_module_constant():
    assert zero_or_more(WORD).to_regex_string() == "\\w*"


def test_zero_or_more_lazy_emits_lazy_star():
    assert zero_or_more_lazy(WORD).to_regex_string() == "\\w*?"


def test_one_or_more_wraps_a_module_constant():
    assert one_or_more(DIGIT).to_regex_string() == "\\d+"


def test_one_or_more_lazy_emits_lazy_plus():
    assert one_or_more_lazy(DIGIT).to_regex_string() == "\\d+?"


def test_exactly_wraps_a_module_constant_without_extra_grouping():
    assert exactly(3, DIGIT).to_regex_string() == "\\d{3}"


def test_exactly_groups_a_multi_element_operand():
    combined = DIGIT + WORD
    assert exactly(3, combined).to_regex_string() == "(?:\\d\\w){3}"


def test_exactly_groups_a_multi_character_string_operand():
    assert exactly(3, string("ab")).to_regex_string() == "(?:ab){3}"


def test_at_least_produces_open_ended_quantifier():
    assert at_least(2, DIGIT).to_regex_string() == "\\d{2,}"


def test_at_most_produces_zero_lower_bound_quantifier():
    assert at_most(3, DIGIT).to_regex_string() == "\\d{0,3}"


def test_at_most_groups_a_multi_element_operand():
    assert at_most(3, DIGIT + WORD).to_regex_string() == "(?:\\d\\w){0,3}"


def test_between_produces_greedy_bounded_quantifier():
    assert between(2, 4, DIGIT).to_regex_string() == "\\d{2,4}"


def test_between_lazy_produces_lazy_bounded_quantifier():
    assert between_lazy(2, 4, DIGIT).to_regex_string() == "\\d{2,4}?"


def test_optional_returns_a_pattern_instance():
    assert isinstance(optional(DIGIT), Pattern)


def test_exactly_rejects_zero_count():
    with pytest.raises(MustBePositiveIntegerError):
        exactly(0, DIGIT)


def test_at_least_rejects_negative_count():
    with pytest.raises(MustBePositiveIntegerError):
        at_least(-1, DIGIT)


def test_at_most_rejects_zero_count():
    with pytest.raises(MustBePositiveIntegerError):
        at_most(0, DIGIT)


def test_between_rejects_negative_lower_bound():
    with pytest.raises(MustBeIntegerGreaterThanZeroError):
        between(-1, 5, DIGIT)


def test_between_rejects_upper_bound_less_than_or_equal_to_lower():
    with pytest.raises(MustBeLessThanError):
        between(3, 3, DIGIT)