Initial upload: ErrorFix CLI with rule engine and pattern matching
Some checks failed
CI / test (push) Has been cancelled
Some checks failed
CI / test (push) Has been cancelled
This commit is contained in:
109
tests/unit/test_patterns.py
Normal file
109
tests/unit/test_patterns.py
Normal file
@@ -0,0 +1,109 @@
|
||||
import pytest
|
||||
from errorfix.patterns import PatternMatcher, MatchResult
|
||||
from errorfix.rules import Rule
|
||||
|
||||
|
||||
class TestPatternMatcher:
|
||||
def setup_method(self):
|
||||
self.matcher = PatternMatcher()
|
||||
self.rule = Rule(
|
||||
id='test-rule',
|
||||
name='Test Rule',
|
||||
pattern=r"Error: (?P<message>.*)",
|
||||
fix="Fix: {message}",
|
||||
description="Test pattern",
|
||||
)
|
||||
|
||||
def test_simple_match(self):
|
||||
text = "Error: something went wrong"
|
||||
result = self.matcher.match(text, self.rule)
|
||||
assert result is not None
|
||||
assert result.matched_text == "Error: something went wrong"
|
||||
assert result.groups['message'] == "something went wrong"
|
||||
|
||||
def test_no_match(self):
|
||||
text = "This is not an error"
|
||||
result = self.matcher.match(text, self.rule)
|
||||
assert result is None
|
||||
|
||||
def test_match_with_special_chars(self):
|
||||
rule = Rule(
|
||||
id='special-rule',
|
||||
name='Special Rule',
|
||||
pattern=r"ValueError: invalid value '(?P<value>[^']+)'",
|
||||
fix="Correct value: {value}",
|
||||
description="Special pattern",
|
||||
)
|
||||
text = "ValueError: invalid value 'test@example.com'"
|
||||
result = self.matcher.match(text, rule)
|
||||
assert result is not None
|
||||
assert result.groups['value'] == 'test@example.com'
|
||||
|
||||
def test_match_all(self):
|
||||
rules = [
|
||||
Rule(
|
||||
id='rule1',
|
||||
name='Rule 1',
|
||||
pattern=r"Error1: (?P<msg>.*)",
|
||||
fix="Fix 1: {msg}",
|
||||
description="Rule 1",
|
||||
priority=10,
|
||||
),
|
||||
Rule(
|
||||
id='rule2',
|
||||
name='Rule 2',
|
||||
pattern=r"Error2: (?P<msg>.*)",
|
||||
fix="Fix 2: {msg}",
|
||||
description="Rule 2",
|
||||
priority=5,
|
||||
),
|
||||
]
|
||||
text = "Error1: test1\nError2: test2"
|
||||
results = self.matcher.match_all(text, rules)
|
||||
assert len(results) == 2
|
||||
|
||||
def test_match_with_priority(self):
|
||||
rules = [
|
||||
Rule(
|
||||
id='low-priority',
|
||||
name='Low Priority',
|
||||
pattern=r"GenericError: (?P<msg>.*)",
|
||||
fix="Fix: {msg}",
|
||||
description="Generic",
|
||||
priority=1,
|
||||
),
|
||||
Rule(
|
||||
id='high-priority',
|
||||
name='High Priority',
|
||||
pattern=r"GenericError: (?P<msg>.*)",
|
||||
fix="Fix: {msg}",
|
||||
description="Specific",
|
||||
priority=10,
|
||||
),
|
||||
]
|
||||
text = "GenericError: test"
|
||||
result = self.matcher.find_best_match(text, rules)
|
||||
assert result is not None
|
||||
assert result.rule.id == 'high-priority'
|
||||
|
||||
def test_apply_fix_with_variables(self):
|
||||
rule = Rule(
|
||||
id='fix-rule',
|
||||
name='Fix Rule',
|
||||
pattern=r"NameError: name '(?P<name>[^']+)' is not defined",
|
||||
fix="Define {name} before using it",
|
||||
description="Name error',
|
||||
)
|
||||
text = "NameError: name 'foo' is not defined"
|
||||
result = self.matcher.match(text, rule)
|
||||
assert result is not None
|
||||
fix = result.apply_fix()
|
||||
assert "foo" in fix
|
||||
|
||||
def test_caching(self):
|
||||
self.matcher._compile_pattern.cache_clear()
|
||||
pattern = r"Test: (?P<val>.*)"
|
||||
self.matcher._compile_pattern(pattern)
|
||||
assert self.matcher._compile_pattern.cache_info().currsize == 1
|
||||
self.matcher._compile_pattern(pattern)
|
||||
assert self.matcher._compile_pattern.cache_info().currsize == 1
|
||||
Reference in New Issue
Block a user