diff options
| author | natsuoto <[email protected]> | 2026-07-01 14:10:45 +0530 |
|---|---|---|
| committer | natsuoto <[email protected]> | 2026-07-01 14:10:45 +0530 |
| commit | 391a4c2fd4afbaa5910aaf670a5e1c88c5e5aa84 (patch) | |
| tree | fa0232556e112b320c0bfde96e3ef5f279b3df2d /tests | |
| parent | bd3b12ff2f30c251c5fc52b43f81ec2f282d53ab (diff) | |
| download | edify-391a4c2fd4afbaa5910aaf670a5e1c88c5e5aa84.tar.xz edify-391a4c2fd4afbaa5910aaf670a5e1c88c5e5aa84.zip | |
feat: add Pattern class and .use() composition (closes #125, #126)
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/builder/use.test.py | 30 | ||||
| -rw-r--r-- | tests/pattern/composition.test.py | 40 |
2 files changed, 70 insertions, 0 deletions
diff --git a/tests/builder/use.test.py b/tests/builder/use.test.py new file mode 100644 index 0000000..10d7855 --- /dev/null +++ b/tests/builder/use.test.py @@ -0,0 +1,30 @@ +"""Tests for the ``.use(pattern)`` chain method on :class:`RegexBuilder`.""" + +from edify import Pattern, RegexBuilder + + +def test_use_embeds_a_pattern_at_the_current_position(): + username = Pattern().between(3, 20).word() + expression = RegexBuilder().string("User ").use(username) + assert expression.to_regex_string() == "User \\w{3,20}" + + +def test_use_composes_multiple_patterns_in_sequence(): + first_pattern = Pattern().exactly(3).digit() + second_pattern = Pattern().char("-") + third_pattern = Pattern().exactly(4).digit() + expression = RegexBuilder().use(first_pattern).use(second_pattern).use(third_pattern) + assert expression.to_regex_string() == "\\d{3}\\-\\d{4}" + + +def test_use_drops_the_pattern_flag_snapshot_by_default(): + case_insensitive_pattern = Pattern().ignore_case().string("hello") + expression = RegexBuilder().use(case_insensitive_pattern) + compiled = expression.to_regex() + assert compiled.flags & 2 == 0 + + +def test_use_accepts_another_regex_builder_as_the_source(): + fragment = RegexBuilder().one_or_more().digit() + expression = RegexBuilder().string("id=").use(fragment) + assert expression.to_regex_string() == "id=\\d+" diff --git a/tests/pattern/composition.test.py b/tests/pattern/composition.test.py new file mode 100644 index 0000000..9cf0003 --- /dev/null +++ b/tests/pattern/composition.test.py @@ -0,0 +1,40 @@ +"""Tests for the :class:`Pattern` composition surface.""" + +import pytest + +from edify import Pattern, RegexBuilder +from edify.errors.input import MustBeInstanceError + + +def test_pattern_builds_the_same_element_tree_as_a_builder(): + pattern = Pattern().between(3, 20).word() + builder = RegexBuilder().between(3, 20).word() + assert pattern._state == builder._state + + +def test_pattern_has_no_to_regex_terminal(): + pattern = Pattern().digit() + assert not hasattr(pattern, "to_regex") + + +def test_pattern_has_no_to_regex_string_terminal(): + pattern = Pattern().digit() + assert not hasattr(pattern, "to_regex_string") + + +def test_pattern_supports_nested_use_composition(): + inner = Pattern().one_or_more().digit() + outer = Pattern().string("v").use(inner) + embedded = RegexBuilder().use(outer) + assert embedded.to_regex_string() == "v\\d+" + + +def test_subexpression_still_accepts_a_pattern(): + pattern = Pattern().at_least(3).word() + embedded = RegexBuilder().subexpression(pattern) + assert embedded.to_regex_string() == "\\w{3,}" + + +def test_subexpression_rejects_non_builder_input(): + with pytest.raises(MustBeInstanceError): + RegexBuilder().subexpression("not a pattern") |
