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.*)", 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[^']+)'", 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.*)", fix="Fix 1: {msg}", description="Rule 1", priority=10, ), Rule( id='rule2', name='Rule 2', pattern=r"Error2: (?P.*)", 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.*)", fix="Fix: {msg}", description="Generic", priority=1, ), Rule( id='high-priority', name='High Priority', pattern=r"GenericError: (?P.*)", 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[^']+)' 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.*)" 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