diff --git a/tests/basic/test_coder.py b/tests/basic/test_coder.py index f970f3cd6..2859283fa 100644 --- a/tests/basic/test_coder.py +++ b/tests/basic/test_coder.py @@ -284,6 +284,80 @@ class TestCoder(unittest.TestCase): coder.check_for_file_mentions(f"Please check `{fname}`") self.assertEqual(coder.abs_fnames, set([str(fname.resolve())])) + + def test_get_file_mentions_various_formats(self): + with GitTemporaryDirectory(): + io = InputOutput(pretty=False, yes=True) + coder = Coder.create(self.GPT35, None, io) + + # Create test files + test_files = [ + "file1.txt", + "file2.py", + "dir/nested_file.js", + "dir/subdir/deep_file.html", + "file with spaces.txt", + "special_chars!@#.md", + ] + + for fname in test_files: + fpath = Path(fname) + fpath.parent.mkdir(parents=True, exist_ok=True) + fpath.touch() + + # Mock get_addable_relative_files to return our test files + coder.get_addable_relative_files = MagicMock(return_value=set(test_files)) + + # Test different mention formats + test_cases = [ + # Simple plain text mentions + (f"You should edit {test_files[0]} first", {test_files[0]}), + + # Multiple files in plain text + (f"Edit both {test_files[0]} and {test_files[1]}", {test_files[0], test_files[1]}), + + # Files in backticks + (f"Check the file `{test_files[2]}`", {test_files[2]}), + + # Files in code blocks + (f"```\n{test_files[3]}\n```", {test_files[3]}), + + # Files in code blocks with language specifier + (f"```python\nwith open('{test_files[1]}', 'r') as f:\n data = f.read()\n```", {test_files[1]}), + + # Files with Windows-style paths + (f"Edit the file {test_files[2].replace('/', '\\')}", {test_files[2]}), + + # Files with spaces + (f"Look at '{test_files[4]}'", {test_files[4]}), + + # Files with different quote styles + (f'Check "{test_files[5]}" now', {test_files[5]}), + + # Files mentioned in markdown links + (f"See the file [{test_files[0]}]({test_files[0]})", {test_files[0]}), + + # All files in one complex message + ( + f"First, edit `{test_files[0]}`. Then modify {test_files[1]}.\n" + f"```js\n// Update this file\nconst file = '{test_files[2]}';\n```\n" + f"Finally check {test_files[3].replace('/', '\\')}", + {test_files[0], test_files[1], test_files[2], test_files[3]} + ), + + # Mention with SEARCH/REPLACE format + ( + f"{test_files[1]}\n````python\n<<<<<<< SEARCH\ndef old_function():\n pass\n=======\n" + f"def new_function():\n return True\n>>>>>>> REPLACE\n````", + {test_files[1]} + ), + ] + + for content, expected_mentions in test_cases: + with self.subTest(content=content): + mentioned_files = coder.get_file_mentions(content) + self.assertEqual(mentioned_files, expected_mentions, + f"Failed to extract mentions from: {content}") def test_get_file_mentions_path_formats(self): with GitTemporaryDirectory():