Skip to content

Commit 3f4e9fd

Browse files
committed
fix: make platform-specific tests work on both Unix and Windows
- Split test_split_path into platform-specific versions (Unix/Windows) - Split test_find_external_promptfoo_prevents_recursion for platform paths - Use platform-appropriate node path in test_main_exits_when_neither_external_nor_npx_available - Tests now skip appropriately on incompatible platforms
1 parent 6193feb commit 3f4e9fd

File tree

1 file changed

+49
-5
lines changed

1 file changed

+49
-5
lines changed

tests/test_cli.py

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def test_strip_quotes(self, input_path: str, expected: str) -> None:
104104
"""Quote stripping handles various quote patterns correctly."""
105105
assert _strip_quotes(input_path) == expected
106106

107+
@pytest.mark.skipif(sys.platform == "win32", reason="Unix-style PATH separator test")
107108
@pytest.mark.parametrize(
108109
"path_value,expected",
109110
[
@@ -115,8 +116,24 @@ def test_strip_quotes(self, input_path: str, expected: str) -> None:
115116
(":::", []), # Only separators
116117
],
117118
)
118-
def test_split_path(self, path_value: str, expected: list[str]) -> None:
119-
"""PATH splitting handles quotes, empty entries, and whitespace."""
119+
def test_split_path_unix(self, path_value: str, expected: list[str]) -> None:
120+
"""PATH splitting handles quotes, empty entries, and whitespace on Unix."""
121+
assert _split_path(path_value) == expected
122+
123+
@pytest.mark.skipif(sys.platform != "win32", reason="Windows-style PATH separator test")
124+
@pytest.mark.parametrize(
125+
"path_value,expected",
126+
[
127+
("C:\\bin;C:\\tools", ["C:\\bin", "C:\\tools"]),
128+
('"C:\\bin";C:\\tools', ["C:\\bin", "C:\\tools"]),
129+
("C:\\bin;;C:\\tools", ["C:\\bin", "C:\\tools"]), # Empty entry removed
130+
(" C:\\bin ; C:\\tools ", ["C:\\bin", "C:\\tools"]), # Whitespace
131+
("", []),
132+
(";;;", []), # Only separators
133+
],
134+
)
135+
def test_split_path_windows(self, path_value: str, expected: list[str]) -> None:
136+
"""PATH splitting handles quotes, empty entries, and whitespace on Windows."""
120137
assert _split_path(path_value) == expected
121138

122139

@@ -224,8 +241,9 @@ def test_find_external_promptfoo_when_found(self, monkeypatch: pytest.MonkeyPatc
224241
result = _find_external_promptfoo()
225242
assert result == promptfoo_path
226243

227-
def test_find_external_promptfoo_prevents_recursion(self, monkeypatch: pytest.MonkeyPatch) -> None:
228-
"""Filters out wrapper directory from PATH to prevent recursion."""
244+
@pytest.mark.skipif(sys.platform == "win32", reason="Unix-specific recursion test")
245+
def test_find_external_promptfoo_prevents_recursion_unix(self, monkeypatch: pytest.MonkeyPatch) -> None:
246+
"""Filters out wrapper directory from PATH to prevent recursion on Unix."""
229247
wrapper_path = "/home/user/.local/bin/promptfoo"
230248
real_promptfoo = "/usr/local/bin/promptfoo"
231249

@@ -246,6 +264,29 @@ def mock_which(cmd: str, path: Optional[str] = None) -> Optional[str]:
246264
result = _find_external_promptfoo()
247265
assert result == real_promptfoo
248266

267+
@pytest.mark.skipif(sys.platform != "win32", reason="Windows-specific recursion test")
268+
def test_find_external_promptfoo_prevents_recursion_windows(self, monkeypatch: pytest.MonkeyPatch) -> None:
269+
"""Filters out wrapper directory from PATH to prevent recursion on Windows."""
270+
wrapper_path = "C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python312\\Scripts\\promptfoo.exe"
271+
real_promptfoo = "C:\\npm\\prefix\\promptfoo.cmd"
272+
273+
monkeypatch.setattr(sys, "argv", [wrapper_path])
274+
monkeypatch.setenv("PATH", "C:\\Users\\user\\AppData\\Local\\Programs\\Python\\Python312\\Scripts;C:\\npm\\prefix")
275+
276+
def mock_which(cmd: str, path: Optional[str] = None) -> Optional[str]:
277+
if cmd != "promptfoo":
278+
return None
279+
if path is None:
280+
return wrapper_path
281+
# When called with filtered PATH, return the real one
282+
if "Python312\\Scripts" not in path:
283+
return real_promptfoo
284+
return None
285+
286+
monkeypatch.setattr("shutil.which", mock_which)
287+
result = _find_external_promptfoo()
288+
assert result == real_promptfoo
289+
249290

250291
class TestShellRequirement:
251292
"""Test Windows shell requirement detection for .bat/.cmd files."""
@@ -427,9 +468,12 @@ def test_main_exits_when_neither_external_nor_npx_available(
427468
self, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture
428469
) -> None:
429470
"""Exits with error when neither external promptfoo nor npx found."""
471+
# Use platform-appropriate path for node
472+
node_path = "C:\\Program Files\\nodejs\\node.exe" if sys.platform == "win32" else "/usr/bin/node"
473+
430474
monkeypatch.setattr(sys, "argv", ["promptfoo", "eval"])
431475
monkeypatch.setattr("shutil.which", lambda cmd, path=None: {
432-
"node": "/usr/bin/node"
476+
"node": node_path
433477
}.get(cmd))
434478

435479
with pytest.raises(SystemExit) as exc_info:

0 commit comments

Comments
 (0)