mirror of
https://github.com/zhayujie/chatgpt-on-wechat.git
synced 2026-07-17 11:07:11 +08:00
refactor(edit): unify fuzzy uniqueness check with the fuzzy matcher
The uniqueness guard counted occurrences via normalize_for_fuzzy_match, while fuzzy_find_text located matches with a whitespace-flexible regex, so the two could disagree. Extract the pattern builder as a single source of truth (_build_fuzzy_pattern) and add count_matches, which counts with the same exact-then-fuzzy strategy used to locate and replace. This is the optional follow-up suggested in the review of #2942. Adds regression tests for exact and fuzzy multi-match rejection.
This commit is contained in:
@@ -98,6 +98,41 @@ class TestEditFuzzyPreservesWhitespace(unittest.TestCase):
|
||||
"def foo():\n x = 100\n y = 2\n return x + y\n",
|
||||
)
|
||||
|
||||
def test_exact_match_rejects_multiple_occurrences(self):
|
||||
# Two byte-identical statements; the exact-match path applies and the
|
||||
# uniqueness guard counts exact occurrences, so the ambiguous edit is
|
||||
# rejected instead of silently editing only the first.
|
||||
with open(self.path, "w", encoding="utf-8") as f:
|
||||
f.write("a = 1\nb = 2\na = 1\n")
|
||||
result = self.tool.execute({
|
||||
"path": self.path,
|
||||
"oldText": "a = 1",
|
||||
"newText": "a = 9",
|
||||
})
|
||||
self.assertEqual(result.status, "error", result.result)
|
||||
self.assertIn("occurrences", result.result)
|
||||
# An ambiguous match must leave the file untouched.
|
||||
self.assertEqual(self._read(), "a = 1\nb = 2\na = 1\n")
|
||||
|
||||
def test_fuzzy_match_rejects_multiple_occurrences(self):
|
||||
# oldText uses loose spacing, so the exact match fails and the fuzzy
|
||||
# path runs. The uniqueness guard now counts with the SAME regex used
|
||||
# to match/replace, so an ambiguous fuzzy match (two hits) is rejected
|
||||
# rather than silently editing the first one.
|
||||
with open(self.path, "w", encoding="utf-8") as f:
|
||||
f.write("def foo():\n x = 1\n y = 2\n x = 1\n")
|
||||
result = self.tool.execute({
|
||||
"path": self.path,
|
||||
"oldText": "x = 1",
|
||||
"newText": "x = 99",
|
||||
})
|
||||
self.assertEqual(result.status, "error", result.result)
|
||||
self.assertIn("occurrences", result.result)
|
||||
self.assertEqual(
|
||||
self._read(),
|
||||
"def foo():\n x = 1\n y = 2\n x = 1\n",
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user