Files
document-haness/tests/test_providers.py
T

114 lines
4.8 KiB
Python

from __future__ import annotations
import sys
import tempfile
import textwrap
import types
import unittest
from pathlib import Path
from unittest.mock import patch
from claridoc.models import ProviderSpec
from claridoc.providers.antigravity import AntigravityProvider
from claridoc.providers.base import ProviderRequest
from claridoc.providers.claude import ClaudeProvider
from claridoc.providers.codex import CodexProvider
class ProviderAdapterTests(unittest.TestCase):
def _script(self, directory: Path, name: str, body: str) -> Path:
path = directory / name
path.write_text("#!/usr/bin/env python3\n" + textwrap.dedent(body), encoding="utf-8")
path.chmod(0o755)
return path
def test_codex_adapter_reads_output_last_message(self) -> None:
with tempfile.TemporaryDirectory() as temp:
directory = Path(temp)
script = self._script(directory, "fake_codex.py", r'''
import json, pathlib, sys
prompt = sys.stdin.read()
index = sys.argv.index("--output-last-message")
pathlib.Path(sys.argv[index + 1]).write_text(json.dumps({"ok": True, "prompt": prompt}), encoding="utf-8")
''')
provider = CodexProvider(ProviderSpec(provider="codex", options={"binary": str(script)}))
response = provider.generate(ProviderRequest("plan", "hello", directory))
self.assertIn('"ok": true', response.text)
self.assertIn("hello", response.text)
self.assertIn("--sandbox", response.command)
self.assertIn("read-only", response.command)
def test_claude_adapter_pipes_prompt(self) -> None:
with tempfile.TemporaryDirectory() as temp:
directory = Path(temp)
script = self._script(directory, "fake_claude.py", r'''
import sys
data = sys.stdin.read()
print("received:" + data)
''')
provider = ClaudeProvider(ProviderSpec(provider="claude", options={"binary": str(script)}))
response = provider.generate(ProviderRequest("draft", "payload", directory))
self.assertEqual(response.text, "received:payload")
self.assertEqual(response.command[1:4], ["-p", "--output-format", "text"])
def test_antigravity_adapter_uses_sdk_contract_and_isolates_cwd(self) -> None:
state: dict[str, object] = {}
fake_google = types.ModuleType("google")
fake_google.__path__ = [] # type: ignore[attr-defined]
fake_sdk = types.ModuleType("google.antigravity")
class FakeLocalAgentConfig:
def __init__(self, **kwargs: object) -> None:
state["config"] = kwargs
class FakeResponse:
async def text(self) -> str:
return "sdk-response"
class FakeAgent:
def __init__(self, config: FakeLocalAgentConfig) -> None:
state["agent_config"] = config
async def __aenter__(self) -> "FakeAgent":
state["cwd"] = str(Path.cwd())
return self
async def __aexit__(self, exc_type: object, exc: object, traceback: object) -> None:
return None
async def chat(self, prompt: str) -> FakeResponse:
state["prompt"] = prompt
return FakeResponse()
fake_sdk.Agent = FakeAgent # type: ignore[attr-defined]
fake_sdk.LocalAgentConfig = FakeLocalAgentConfig # type: ignore[attr-defined]
original_cwd = Path.cwd()
with tempfile.TemporaryDirectory() as temp:
directory = Path(temp).resolve()
with patch.dict(sys.modules, {"google": fake_google, "google.antigravity": fake_sdk}):
provider = AntigravityProvider(
ProviderSpec(
provider="antigravity",
model="model-under-test",
options={"config": {"temperature": 0.2}},
)
)
response = provider.generate(ProviderRequest("review", "inspect this", directory))
self.assertEqual(response.text, "sdk-response")
self.assertEqual(state["prompt"], "inspect this")
self.assertEqual(state["cwd"], str(directory))
self.assertEqual(state["config"], {"temperature": 0.2, "model": "model-under-test"})
self.assertEqual(Path.cwd(), original_cwd)
def test_antigravity_doctor_handles_missing_sdk(self) -> None:
provider = AntigravityProvider(ProviderSpec(provider="antigravity"))
with patch("claridoc.providers.antigravity.importlib.util.find_spec", side_effect=ModuleNotFoundError):
result = provider.check()
self.assertFalse(result["available"])
if __name__ == "__main__":
unittest.main()