Files
harness-tools/skills/document/artifact-presenter/tests/test_present.py
T

229 lines
6.9 KiB
Python

from __future__ import annotations
import importlib.util
import json
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
MODULE_PATH = Path(__file__).parents[1] / "scripts" / "present.py"
SPEC = importlib.util.spec_from_file_location("artifact_presenter", MODULE_PATH)
assert SPEC and SPEC.loader
MODULE = importlib.util.module_from_spec(SPEC)
sys.modules[SPEC.name] = MODULE
SPEC.loader.exec_module(MODULE)
class FakeRunner:
def __init__(
self,
panes: list[dict[str, str]] | None = None,
*,
failed_run_panes: set[str] | None = None,
fail_rename: bool = False,
) -> None:
self.panes = panes or []
self.failed_run_panes = failed_run_panes or set()
self.fail_rename = fail_rename
self.calls: list[list[str]] = []
def __call__(self, command, **_kwargs):
argv = [str(value) for value in command]
self.calls.append(argv)
if argv[1:3] == ["pane", "run"] and argv[3] in self.failed_run_panes:
raise subprocess.CalledProcessError(1, argv)
if argv[1:3] == ["pane", "rename"] and self.fail_rename:
raise subprocess.CalledProcessError(1, argv)
if argv[1:3] == ["pane", "list"]:
output = {"result": {"panes": self.panes}}
elif argv[1:3] == ["pane", "split"]:
output = {"result": {"pane": {"pane_id": "workspace:p-new"}}}
else:
output = {}
return subprocess.CompletedProcess(argv, 0, json.dumps(output), "")
class ArtifactPresenterTests(unittest.TestCase):
def setUp(self) -> None:
self.tempdir = tempfile.TemporaryDirectory()
self.artifact = Path(self.tempdir.name) / "report.md"
self.artifact.write_text("# Report\n", encoding="utf-8")
self.env = {
"HERDR_WORKSPACE_ID": "workspace",
"HERDR_PANE_ID": "workspace:p-source",
}
self.executables = {"herdr": "/usr/bin/herdr", "mcat": "/usr/bin/mcat"}
def tearDown(self) -> None:
self.tempdir.cleanup()
def which(self, name: str) -> str | None:
return self.executables.get(name)
def test_reuses_named_pane(self) -> None:
runner = FakeRunner(
[{"pane_id": "workspace:p-viewer", "label": MODULE.PANE_LABEL}],
)
result = MODULE.present_document(
self.artifact,
env=self.env,
which=self.which,
run=runner,
)
self.assertEqual(result.status, "reused")
self.assertEqual(result.pane_id, "workspace:p-viewer")
self.assertIn(
[
"/usr/bin/herdr",
"pane",
"run",
"workspace:p-viewer",
"/usr/bin/mcat",
str(self.artifact.resolve()),
],
runner.calls,
)
self.assertFalse(any(call[1:3] == ["pane", "split"] for call in runner.calls))
def test_tries_each_named_pane_before_creating_another(self) -> None:
runner = FakeRunner(
[
{"pane_id": "workspace:p-stale", "label": MODULE.PANE_LABEL},
{"pane_id": "workspace:p-viewer", "label": MODULE.PANE_LABEL},
],
failed_run_panes={"workspace:p-stale"},
)
result = MODULE.present_document(
self.artifact,
env=self.env,
which=self.which,
run=runner,
)
self.assertEqual(result.status, "reused")
self.assertEqual(result.pane_id, "workspace:p-viewer")
self.assertIn(
[
"/usr/bin/herdr",
"pane",
"rename",
"workspace:p-stale",
f"{MODULE.PANE_LABEL} stale",
],
runner.calls,
)
self.assertFalse(any(call[1:3] == ["pane", "split"] for call in runner.calls))
def test_presents_non_markdown_file_directly_with_mcat(self) -> None:
video = self.artifact.with_name("review.mp4")
video.write_bytes(b"video fixture")
runner = FakeRunner(
[{"pane_id": "workspace:p-viewer", "label": MODULE.PANE_LABEL}],
)
result = MODULE.present_document(
video,
env=self.env,
which=self.which,
run=runner,
)
self.assertEqual(result.status, "reused")
self.assertIn(
[
"/usr/bin/herdr",
"pane",
"run",
"workspace:p-viewer",
"/usr/bin/mcat",
str(video.resolve()),
],
runner.calls,
)
def test_creates_right_pane_when_viewer_is_absent(self) -> None:
runner = FakeRunner()
result = MODULE.present_document(
self.artifact,
env=self.env,
which=self.which,
run=runner,
)
self.assertEqual(result.status, "opened")
split = next(call for call in runner.calls if call[1:3] == ["pane", "split"])
self.assertEqual(
split,
[
"/usr/bin/herdr",
"pane",
"split",
"--pane",
"workspace:p-source",
"--direction",
"right",
"--cwd",
str(self.artifact.parent.resolve()),
"--no-focus",
],
)
self.assertIn(
[
"/usr/bin/herdr",
"pane",
"rename",
"workspace:p-new",
MODULE.PANE_LABEL,
],
runner.calls,
)
def test_closes_new_pane_when_rename_fails(self) -> None:
runner = FakeRunner(fail_rename=True)
result = MODULE.present_document(
self.artifact,
env=self.env,
which=self.which,
run=runner,
)
self.assertEqual(result.status, "artifact-only")
self.assertIn("could not initialize Herdr viewer", result.reason)
self.assertIn(
["/usr/bin/herdr", "pane", "close", "workspace:p-new"],
runner.calls,
)
def test_falls_back_to_artifact_when_mcat_is_unavailable(self) -> None:
self.executables.pop("mcat")
result = MODULE.present_document(
self.artifact,
env=self.env,
which=self.which,
run=FakeRunner(),
)
self.assertEqual(result.status, "artifact-only")
self.assertEqual(result.reason, "mcat is unavailable")
def test_rejects_missing_artifact(self) -> None:
with self.assertRaisesRegex(ValueError, "artifact is not a file"):
MODULE.present_document(
self.artifact.with_name("missing.md"),
env=self.env,
which=self.which,
run=FakeRunner(),
)
if __name__ == "__main__":
unittest.main()