aboutsummaryrefslogtreecommitdiff
path: root/tests/errors/frames.test.py
diff options
context:
space:
mode:
authornatsuoto <[email protected]>2026-07-15 15:15:21 +0530
committernatsuoto <[email protected]>2026-07-15 15:15:21 +0530
commit91942559f53003d2ef7a524456aef84f93b7f319 (patch)
treed4064676c1188ff23541a1c50072af448ae74068 /tests/errors/frames.test.py
parentc343f05467045bd369aa8ecd6273924fe7c89f95 (diff)
downloadedify-91942559f53003d2ef7a524456aef84f93b7f319.tar.xz
edify-91942559f53003d2ef7a524456aef84f93b7f319.zip
feat(errors): structured open-frame stack with per-frame call sites; DanglingQuantifierError names the pending quantifier
Diffstat (limited to 'tests/errors/frames.test.py')
-rw-r--r--tests/errors/frames.test.py69
1 files changed, 69 insertions, 0 deletions
diff --git a/tests/errors/frames.test.py b/tests/errors/frames.test.py
new file mode 100644
index 0000000..b4077ba
--- /dev/null
+++ b/tests/errors/frames.test.py
@@ -0,0 +1,69 @@
+"""Tests for the structured open-frame stack surfaced by CannotCallSubexpressionError."""
+
+import pytest
+
+from edify import RegexBuilder
+from edify.errors.structure import CannotCallSubexpressionError
+
+
+def test_single_open_capture_frame_is_named_in_the_error_message():
+ unfinished = RegexBuilder().capture().digit()
+ with pytest.raises(CannotCallSubexpressionError) as excinfo:
+ unfinished.to_regex_string()
+ text = str(excinfo.value)
+ assert "1 open frame" in text
+ assert "1. .capture()" in text
+
+
+def test_nested_open_frames_are_listed_innermost_first():
+ unfinished = RegexBuilder().capture().group().assert_ahead().digit()
+ with pytest.raises(CannotCallSubexpressionError) as excinfo:
+ unfinished.to_regex_string()
+ text = str(excinfo.value)
+ assert "3 open frame" in text
+ innermost_index = text.index("1. .assert_ahead()")
+ middle_index = text.index("2. .group()")
+ outermost_index = text.index("3. .capture()")
+ assert innermost_index < middle_index < outermost_index
+
+
+def test_named_capture_frame_reports_the_declared_group_name():
+ unfinished = RegexBuilder().named_capture("username").letter()
+ with pytest.raises(CannotCallSubexpressionError) as excinfo:
+ unfinished.to_regex_string()
+ text = str(excinfo.value)
+ assert '.named_capture("username")' in text
+
+
+def test_open_frames_carry_a_file_line_column_pointer_when_the_context_is_captured():
+ unfinished = RegexBuilder().assert_behind().digit()
+ with pytest.raises(CannotCallSubexpressionError) as excinfo:
+ unfinished.to_regex_string()
+ text = str(excinfo.value)
+ assert "opened at" in text
+ assert __file__ in text or "frames.test.py" in text
+
+
+def test_subexpression_lists_open_frames_from_the_argument_not_the_receiver():
+ unfinished = RegexBuilder().named_capture("group").digit()
+ parent = RegexBuilder()
+ with pytest.raises(CannotCallSubexpressionError) as excinfo:
+ parent.subexpression(unfinished)
+ assert 'named_capture("group")' in str(excinfo.value)
+
+
+def test_dangling_quantifier_reports_the_specific_pending_quantifier_name():
+ from edify.errors.quantifier import DanglingQuantifierError
+
+ with pytest.raises(DanglingQuantifierError) as excinfo:
+ RegexBuilder().exactly(3).to_regex_string()
+ text = str(excinfo.value)
+ assert ".exactly(3)" in text
+
+
+def test_dangling_quantifier_falls_back_to_generic_summary_when_name_unknown():
+ from edify.errors.quantifier import DanglingQuantifierError
+
+ error = DanglingQuantifierError()
+ text = str(error)
+ assert "dangling quantifier" in text