|
2 | 2 |
|
3 | 3 | import importlib.util |
4 | 4 | from pathlib import Path |
| 5 | +from contextlib import contextmanager |
| 6 | +from collections.abc import Iterator |
5 | 7 |
|
6 | 8 | import pytest |
7 | 9 |
|
@@ -37,27 +39,55 @@ def test_resolve_binary_path_defaults_cache_version_to_package_version( |
37 | 39 | monkeypatch.delenv("STAGEHAND_SEA_BINARY", raising=False) |
38 | 40 | monkeypatch.delenv("STAGEHAND_VERSION", raising=False) |
39 | 41 |
|
40 | | - def _fake_resource_binary_path(_filename: str) -> Path: |
| 42 | + def _fake_resource_binary_path(_filename: str, *, version: str) -> Path: |
| 43 | + captured["version"] = version |
41 | 44 | return resource_path |
42 | 45 |
|
43 | 46 | monkeypatch.setattr(sea_binary, "_resource_binary_path", _fake_resource_binary_path) |
44 | 47 |
|
45 | | - def _fake_copy_to_cache(*, src: Path, filename: str, version: str) -> Path: |
46 | | - captured["src"] = src |
47 | | - captured["filename"] = filename |
48 | | - captured["version"] = version |
49 | | - return tmp_path / "cache" / filename |
50 | | - |
51 | | - monkeypatch.setattr(sea_binary, "_copy_to_cache", _fake_copy_to_cache) |
52 | | - |
53 | 48 | resolved = sea_binary.resolve_binary_path() |
54 | 49 |
|
55 | | - assert resolved == tmp_path / "cache" / sea_binary.default_binary_filename() |
56 | | - assert captured["src"] == resource_path |
57 | | - assert captured["filename"] == sea_binary.default_binary_filename() |
| 50 | + assert resolved == resource_path |
58 | 51 | assert captured["version"] == __version__ |
59 | 52 |
|
60 | 53 |
|
| 54 | +def test_resolve_binary_path_caches_resource_before_context_exits( |
| 55 | + monkeypatch: pytest.MonkeyPatch, |
| 56 | + tmp_path: Path, |
| 57 | +) -> None: |
| 58 | + class FakeResource: |
| 59 | + def joinpath(self, _name: str) -> FakeResource: |
| 60 | + return self |
| 61 | + |
| 62 | + def is_file(self) -> bool: |
| 63 | + return True |
| 64 | + |
| 65 | + extracted = tmp_path / "temporary-binary" |
| 66 | + |
| 67 | + @contextmanager |
| 68 | + def fake_as_file(_resource: object) -> Iterator[Path]: |
| 69 | + extracted.write_bytes(b"binary") |
| 70 | + try: |
| 71 | + yield extracted |
| 72 | + finally: |
| 73 | + extracted.unlink() |
| 74 | + |
| 75 | + def fake_files(_package: str) -> FakeResource: |
| 76 | + return FakeResource() |
| 77 | + |
| 78 | + monkeypatch.delenv("STAGEHAND_SEA_BINARY", raising=False) |
| 79 | + monkeypatch.setattr(sea_binary.importlib_resources, "files", fake_files) |
| 80 | + monkeypatch.setattr(sea_binary.importlib_resources, "as_file", fake_as_file) |
| 81 | + monkeypatch.setattr(sea_binary, "_cache_dir", lambda: tmp_path / "cache") |
| 82 | + monkeypatch.setattr(sea_binary, "default_binary_filename", lambda: "stagehand-test") |
| 83 | + |
| 84 | + resolved = sea_binary.resolve_binary_path(version="test") |
| 85 | + |
| 86 | + assert resolved == tmp_path / "cache" / "test" / "stagehand-test" |
| 87 | + assert resolved.read_bytes() == b"binary" |
| 88 | + assert not extracted.exists() |
| 89 | + |
| 90 | + |
61 | 91 | def test_parse_server_tag_rejects_prerelease_tags() -> None: |
62 | 92 | assert download_binary._parse_server_tag("stagehand-server-v3/v3.20.0-dev") is None |
63 | 93 | assert download_binary._parse_server_tag("stagehand-server-v3/v3.20.0+build.1") is None |
|
0 commit comments