aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authornatsuoto <[email protected]>2026-07-01 14:10:45 +0530
committernatsuoto <[email protected]>2026-07-01 14:10:45 +0530
commit391a4c2fd4afbaa5910aaf670a5e1c88c5e5aa84 (patch)
treefa0232556e112b320c0bfde96e3ef5f279b3df2d /tests
parentbd3b12ff2f30c251c5fc52b43f81ec2f282d53ab (diff)
downloadedify-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.py30
-rw-r--r--tests/pattern/composition.test.py40
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")