114 lines
4.8 KiB
Python
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()
|