@@ -54,9 +54,6 @@ async def test_allowed_to_edit(self):
5454
5555 assert not coder .need_commit_before_edits
5656
57- @pytest .mark .xfail (
58- reason = "Bug in io.py:970 - UnboundLocalError when exceptions occur before line assigned"
59- )
6057 async def test_allowed_to_edit_no (self ):
6158 with GitTemporaryDirectory ():
6259 repo = git .Repo ()
@@ -71,8 +68,8 @@ async def test_allowed_to_edit_no(self):
7168
7269 repo .git .commit ("-m" , "init" )
7370
74- # say NO
7571 io = InputOutput (yes = False )
72+ io .confirm_ask = AsyncMock (return_value = False )
7673
7774 coder = await Coder .create (self .GPT35 , None , io , fnames = ["added.txt" ])
7875
@@ -126,14 +123,12 @@ async def test_get_files_content(self):
126123 assert "file1.txt" in all_file_names
127124 assert "file2.txt" in all_file_names
128125
129- @pytest .mark .xfail (
130- reason = "Bug in io.py:970 - UnboundLocalError when exceptions occur before line assigned"
131- )
132126 async def test_check_for_filename_mentions (self ):
133127 with GitTemporaryDirectory ():
134128 repo = git .Repo ()
135129
136130 mock_io = MagicMock ()
131+ mock_io .confirm_ask = AsyncMock (return_value = True )
137132
138133 fname1 = Path ("file1.txt" )
139134 fname2 = Path ("file2.py" )
@@ -145,13 +140,11 @@ async def test_check_for_filename_mentions(self):
145140 repo .git .add (str (fname2 ))
146141 repo .git .commit ("-m" , "new" )
147142
148- # Initialize the Coder object with the mocked IO and mocked repo
149- coder = await Coder .create (self .GPT35 , None , mock_io )
143+ mock_args = MagicMock ( tui = False )
144+ coder = await Coder .create (self .GPT35 , None , mock_io , args = mock_args )
150145
151- # Call the check_for_file_mentions method
152- coder .check_for_file_mentions ("Please check file1.txt and file2.py" )
146+ await coder .check_for_file_mentions ("Please check file1.txt and file2.py" )
153147
154- # Check if coder.abs_fnames contains both files
155148 expected_files = set (
156149 [
157150 str (Path (coder .root ) / fname1 ),
@@ -161,13 +154,11 @@ async def test_check_for_filename_mentions(self):
161154
162155 assert coder .abs_fnames == expected_files
163156
164- @pytest .mark .xfail (
165- reason = "Bug in io.py:970 - UnboundLocalError when exceptions occur before line assigned"
166- )
167157 async def test_check_for_ambiguous_filename_mentions_of_longer_paths (self ):
168158 with GitTemporaryDirectory ():
169159 io = InputOutput (pretty = False , yes = True )
170- coder = await Coder .create (self .GPT35 , None , io )
160+ mock_args = MagicMock (tui = False )
161+ coder = await Coder .create (self .GPT35 , None , io , args = mock_args )
171162
172163 fname = Path ("file1.txt" )
173164 fname .touch ()
@@ -180,8 +171,7 @@ async def test_check_for_ambiguous_filename_mentions_of_longer_paths(self):
180171 mock .return_value = set ([str (fname ), str (other_fname )])
181172 coder .repo .get_tracked_files = mock
182173
183- # Call the check_for_file_mentions method
184- coder .check_for_file_mentions (f"Please check { fname } !" )
174+ await coder .check_for_file_mentions (f"Please check { fname } !" )
185175
186176 assert coder .abs_fnames == {str (fname .resolve ())}
187177
@@ -216,83 +206,54 @@ async def test_skip_duplicate_basename_mentions(self):
216206 mentioned = coder .get_file_mentions (f"Check { fname1 } and { fname3 } " )
217207 assert mentioned == {str (fname3 )}
218208
219- @pytest .mark .xfail (
220- reason = "Bug in io.py:970 - UnboundLocalError when exceptions occur before line assigned"
221- )
222209 async def test_check_for_file_mentions_read_only (self ):
223210 with GitTemporaryDirectory ():
224- io = InputOutput (
225- pretty = False ,
226- yes = True ,
227- )
211+ io = InputOutput (pretty = False , yes = True )
228212 coder = await Coder .create (self .GPT35 , None , io )
229213
230214 fname = Path ("readonly_file.txt" )
231215 fname .touch ()
232216
233217 coder .abs_read_only_fnames .add (str (fname .resolve ()))
234218
235- # Mock the get_tracked_files method
236219 mock = MagicMock ()
237220 mock .return_value = set ([str (fname )])
238221 coder .repo .get_tracked_files = mock
239222
240- # Call the check_for_file_mentions method
241- result = coder .check_for_file_mentions (f"Please check { fname } !" )
223+ result = await coder .check_for_file_mentions (f"Please check { fname } !" )
242224
243- # Assert that the method returns None (user not asked to add the file)
244225 assert result is None
245-
246- # Assert that abs_fnames is still empty (file not added)
247226 assert coder .abs_fnames == set ()
248227
249- @pytest .mark .xfail (
250- reason = "Bug in io.py:970 - UnboundLocalError when exceptions occur before line assigned"
251- )
252228 async def test_check_for_file_mentions_with_mocked_confirm (self ):
253229 with GitTemporaryDirectory ():
254230 io = InputOutput (pretty = False )
255- coder = await Coder .create (self .GPT35 , None , io )
231+ io .confirm_ask = AsyncMock (side_effect = [False , True , True ])
232+ mock_args = MagicMock (tui = False )
233+ coder = await Coder .create (self .GPT35 , None , io , args = mock_args )
256234
257- # Mock get_file_mentions to return two file names
258235 coder .get_file_mentions = MagicMock (return_value = set (["file1.txt" , "file2.txt" ]))
259236
260- # Mock confirm_ask to return False for the first call and True for the second
261- io .confirm_ask = AsyncMock (side_effect = [False , True , True ])
262-
263- # First call to check_for_file_mentions
264237 await coder .check_for_file_mentions ("Please check file1.txt for the info" )
265238
266- # Assert that confirm_ask was called twice
267239 assert io .confirm_ask .call_count == 2
268-
269- # Assert that only file2.txt was added to abs_fnames
270240 assert len (coder .abs_fnames ) == 1
271241 assert "file2.txt" in str (coder .abs_fnames )
272242
273- # Reset the mock
274243 io .confirm_ask .reset_mock ()
275244
276- # Second call to check_for_file_mentions
277245 await coder .check_for_file_mentions ("Please check file1.txt and file2.txt again" )
278246
279- # Assert that confirm_ask was called only once (for file1.txt)
280247 assert io .confirm_ask .call_count == 1
281-
282- # Assert that abs_fnames still contains only file2.txt
283248 assert len (coder .abs_fnames ) == 1
284249 assert "file2.txt" in str (coder .abs_fnames )
285-
286- # Assert that file1.txt is in ignore_mentions
287250 assert "file1.txt" in coder .ignore_mentions
288251
289- @pytest .mark .xfail (
290- reason = "Bug in io.py:970 - UnboundLocalError when exceptions occur before line assigned"
291- )
292252 async def test_check_for_subdir_mention (self ):
293253 with GitTemporaryDirectory ():
294254 io = InputOutput (pretty = False , yes = True )
295- coder = await Coder .create (self .GPT35 , None , io )
255+ mock_args = MagicMock (tui = False )
256+ coder = await Coder .create (self .GPT35 , None , io , args = mock_args )
296257
297258 fname = Path ("other" ) / "file1.txt"
298259 fname .parent .mkdir (parents = True , exist_ok = True )
@@ -302,8 +263,7 @@ async def test_check_for_subdir_mention(self):
302263 mock .return_value = set ([str (fname )])
303264 coder .repo .get_tracked_files = mock
304265
305- # Call the check_for_file_mentions method
306- coder .check_for_file_mentions (f"Please check `{ fname } `" )
266+ await coder .check_for_file_mentions (f"Please check `{ fname } `" )
307267
308268 assert coder .abs_fnames == {str (fname .resolve ())}
309269
@@ -460,12 +420,6 @@ async def test_get_file_mentions_path_formats(self):
460420 mentioned_files == expected_files
461421 ), f"Failed for content: { content } , addable_files: { addable_files } "
462422
463- @pytest .mark .xfail (
464- reason = (
465- "Behavior change: deleted files are filtered out during processing but not removed from"
466- " abs_fnames"
467- )
468- )
469423 async def test_run_with_file_deletion (self ):
470424 # Create a few temporary files
471425
@@ -896,12 +850,20 @@ async def test_skip_gitignored_files_on_init(self):
896850 f"Skipping { ignored_file .name } that matches gitignore spec."
897851 )
898852
899- @pytest .mark .xfail (reason = "Commands.cmd_web method not implemented" )
900853 async def test_check_for_urls (self ):
901854 io = InputOutput (yes = True )
902- coder = await Coder .create (self .GPT35 , None , io = io )
903- coder .commands .scraper = MagicMock ()
904- coder .commands .scraper .scrape = MagicMock (return_value = "some content" )
855+ mock_args = MagicMock ()
856+ mock_args .yes_always_commands = False
857+ mock_args .disable_scraping = False
858+ coder = await Coder .create (self .GPT35 , None , io = io , args = mock_args )
859+
860+ # Mock the do_run command to return scraped content
861+ async def mock_do_run (cmd_name , url , ** kwargs ):
862+ if cmd_name == "web" and kwargs .get ("return_content" ):
863+ return f"Scraped content from { url } "
864+ return None
865+
866+ coder .commands .do_run = mock_do_run
905867
906868 # Test various URL formats
907869 test_cases = [
@@ -1051,18 +1013,34 @@ async def test_no_suggest_shell_commands(self):
10511013 coder = await Coder .create (self .GPT35 , "diff" , io = io , suggest_shell_commands = False )
10521014 assert not coder .suggest_shell_commands
10531015
1054- @pytest .mark .xfail (reason = "Commands.cmd_web method not implemented" )
10551016 async def test_detect_urls_enabled (self ):
10561017 with GitTemporaryDirectory ():
10571018 io = InputOutput (yes = True )
1058- coder = await Coder .create (self .GPT35 , "diff" , io = io , detect_urls = True )
1059- coder .commands .scraper = MagicMock ()
1060- coder .commands .scraper .scrape = MagicMock (return_value = "some content" )
1019+ mock_args = MagicMock ()
1020+ mock_args .yes_always_commands = False
1021+ mock_args .disable_scraping = False
1022+ coder = await Coder .create (self .GPT35 , "diff" , io = io , detect_urls = True , args = mock_args )
1023+
1024+ # Track calls to do_run
1025+ do_run_calls = []
1026+
1027+ async def mock_do_run (cmd_name , url , ** kwargs ):
1028+ do_run_calls .append ((cmd_name , url , kwargs ))
1029+ if cmd_name == "web" and kwargs .get ("return_content" ):
1030+ return f"Scraped content from { url } "
1031+ return None
1032+
1033+ coder .commands .do_run = mock_do_run
10611034
10621035 # Test with a message containing a URL
10631036 message = "Check out https://example.com"
10641037 await coder .check_for_urls (message )
1065- coder .commands .scraper .scrape .assert_called_once_with ("https://example.com" )
1038+
1039+ # Verify do_run was called with the web command and correct URL
1040+ assert len (do_run_calls ) == 1
1041+ assert do_run_calls [0 ][0 ] == "web"
1042+ assert do_run_calls [0 ][1 ] == "https://example.com"
1043+ assert do_run_calls [0 ][2 ].get ("return_content" ) is True
10661044
10671045 async def test_detect_urls_disabled (self ):
10681046 with GitTemporaryDirectory ():
0 commit comments