test_resolve_path.py
1 """Tests for _resolve_path() — TERMINAL_CWD-aware path resolution in file_tools.""" 2 3 import os 4 from pathlib import Path 5 from types import SimpleNamespace 6 7 import pytest 8 9 10 class TestResolvePath: 11 """Verify _resolve_path respects TERMINAL_CWD for worktree isolation.""" 12 13 def test_relative_path_uses_terminal_cwd(self, monkeypatch, tmp_path): 14 """Relative paths resolve against TERMINAL_CWD, not process CWD.""" 15 monkeypatch.setenv("TERMINAL_CWD", str(tmp_path)) 16 from tools.file_tools import _resolve_path 17 18 result = _resolve_path("foo/bar.py") 19 assert result == (tmp_path / "foo" / "bar.py") 20 21 def test_absolute_path_ignores_terminal_cwd(self, monkeypatch, tmp_path): 22 """Absolute paths are unaffected by TERMINAL_CWD.""" 23 monkeypatch.setenv("TERMINAL_CWD", str(tmp_path)) 24 from tools.file_tools import _resolve_path 25 26 absolute = (tmp_path / "already-absolute.txt").resolve() 27 result = _resolve_path(str(absolute)) 28 assert result == absolute 29 30 def test_falls_back_to_cwd_without_terminal_cwd(self, monkeypatch): 31 """Without TERMINAL_CWD, falls back to os.getcwd().""" 32 monkeypatch.delenv("TERMINAL_CWD", raising=False) 33 from tools.file_tools import _resolve_path 34 35 result = _resolve_path("some_file.txt") 36 assert result == Path(os.getcwd()) / "some_file.txt" 37 38 def test_tilde_expansion(self, monkeypatch, tmp_path): 39 """~ is expanded before TERMINAL_CWD join (already absolute).""" 40 monkeypatch.setenv("TERMINAL_CWD", str(tmp_path)) 41 from tools.file_tools import _resolve_path 42 43 result = _resolve_path("~/notes.txt") 44 # After expanduser, ~/notes.txt becomes absolute → TERMINAL_CWD ignored 45 assert result == Path.home() / "notes.txt" 46 47 def test_result_is_resolved(self, monkeypatch, tmp_path): 48 """Output path has no '..' components.""" 49 monkeypatch.setenv("TERMINAL_CWD", str(tmp_path)) 50 from tools.file_tools import _resolve_path 51 52 result = _resolve_path("a/../b/file.txt") 53 assert ".." not in str(result) 54 assert result == (tmp_path / "b" / "file.txt") 55 56 def test_relative_path_prefers_live_file_ops_cwd(self, monkeypatch, tmp_path): 57 """Live env.cwd must win after the terminal session changes directory.""" 58 start_dir = tmp_path / "start" 59 live_dir = tmp_path / "worktree" 60 start_dir.mkdir() 61 live_dir.mkdir() 62 monkeypatch.setenv("TERMINAL_CWD", str(start_dir)) 63 64 from tools import file_tools 65 66 task_id = "live-cwd" 67 fake_ops = SimpleNamespace( 68 env=SimpleNamespace(cwd=str(live_dir)), 69 cwd=str(start_dir), 70 ) 71 72 with file_tools._file_ops_lock: 73 previous = file_tools._file_ops_cache.get(task_id) 74 file_tools._file_ops_cache[task_id] = fake_ops 75 76 try: 77 result = file_tools._resolve_path("nested/file.txt", task_id=task_id) 78 finally: 79 with file_tools._file_ops_lock: 80 if previous is None: 81 file_tools._file_ops_cache.pop(task_id, None) 82 else: 83 file_tools._file_ops_cache[task_id] = previous 84 85 assert result == live_dir / "nested" / "file.txt"