104 lines
4.1 KiB
Python
104 lines
4.1 KiB
Python
|
|
"""Tests for tool connectors: Docs, DB, CodeRunner."""
|
||
|
|
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
from fusionagi.tools.connectors.code_runner import CodeRunnerConnector
|
||
|
|
from fusionagi.tools.connectors.db import DBConnector
|
||
|
|
from fusionagi.tools.connectors.docs import DocsConnector
|
||
|
|
|
||
|
|
|
||
|
|
class TestDocsConnector:
|
||
|
|
def test_read_text_file(self, tmp_path: Path) -> None:
|
||
|
|
(tmp_path / "test.txt").write_text("hello world")
|
||
|
|
conn = DocsConnector(base_path=str(tmp_path))
|
||
|
|
result = conn.invoke("read", {"path": "test.txt"})
|
||
|
|
assert result["content"] == "hello world"
|
||
|
|
assert result["error"] is None
|
||
|
|
|
||
|
|
def test_read_missing_file(self, tmp_path: Path) -> None:
|
||
|
|
conn = DocsConnector(base_path=str(tmp_path))
|
||
|
|
result = conn.invoke("read", {"path": "missing.txt"})
|
||
|
|
assert result["error"] is not None
|
||
|
|
|
||
|
|
def test_search(self, tmp_path: Path) -> None:
|
||
|
|
(tmp_path / "a.txt").write_text("foo bar baz")
|
||
|
|
(tmp_path / "b.txt").write_text("no match here")
|
||
|
|
conn = DocsConnector(base_path=str(tmp_path))
|
||
|
|
result = conn.invoke("search", {"query": "bar", "path": "."})
|
||
|
|
assert len(result["results"]) == 1
|
||
|
|
|
||
|
|
def test_list_files(self, tmp_path: Path) -> None:
|
||
|
|
(tmp_path / "a.txt").write_text("x")
|
||
|
|
(tmp_path / "b.md").write_text("y")
|
||
|
|
conn = DocsConnector(base_path=str(tmp_path))
|
||
|
|
result = conn.invoke("list", {"path": ".", "pattern": "*"})
|
||
|
|
assert len(result["files"]) == 2
|
||
|
|
|
||
|
|
def test_schema(self) -> None:
|
||
|
|
conn = DocsConnector()
|
||
|
|
s = conn.schema()
|
||
|
|
assert s["name"] == "docs"
|
||
|
|
assert "read" in s["actions"]
|
||
|
|
|
||
|
|
|
||
|
|
class TestDBConnector:
|
||
|
|
def test_sqlite_crud(self) -> None:
|
||
|
|
conn = DBConnector(connection_string=":memory:", driver="sqlite", allow_write=True)
|
||
|
|
conn.invoke("execute", {"query": "CREATE TABLE t (id INTEGER, name TEXT)"})
|
||
|
|
conn.invoke("execute", {"query": "INSERT INTO t VALUES (1, 'alice')"})
|
||
|
|
result = conn.invoke("query", {"query": "SELECT * FROM t"})
|
||
|
|
assert result["count"] == 1
|
||
|
|
assert result["rows"][0]["name"] == "alice"
|
||
|
|
|
||
|
|
def test_list_tables(self) -> None:
|
||
|
|
conn = DBConnector(connection_string=":memory:", driver="sqlite", allow_write=True)
|
||
|
|
conn.invoke("execute", {"query": "CREATE TABLE demo (id INTEGER)"})
|
||
|
|
result = conn.invoke("tables", {})
|
||
|
|
assert any(r.get("name") == "demo" for r in result["rows"])
|
||
|
|
|
||
|
|
def test_read_only_blocks_write(self) -> None:
|
||
|
|
conn = DBConnector(connection_string=":memory:", driver="sqlite", allow_write=False)
|
||
|
|
result = conn.invoke("execute", {"query": "CREATE TABLE t (id INTEGER)"})
|
||
|
|
assert "error" in result or "disallowed" in str(result.get("error", ""))
|
||
|
|
|
||
|
|
def test_schema(self) -> None:
|
||
|
|
conn = DBConnector()
|
||
|
|
s = conn.schema()
|
||
|
|
assert s["name"] == "db"
|
||
|
|
|
||
|
|
|
||
|
|
class TestCodeRunnerConnector:
|
||
|
|
def test_run_python(self) -> None:
|
||
|
|
conn = CodeRunnerConnector(timeout=10.0)
|
||
|
|
result = conn.invoke("run", {"code": "print('hello')", "language": "python"})
|
||
|
|
assert result["exit_code"] == 0
|
||
|
|
assert "hello" in result["stdout"]
|
||
|
|
|
||
|
|
def test_run_empty_code(self) -> None:
|
||
|
|
conn = CodeRunnerConnector()
|
||
|
|
result = conn.invoke("run", {"code": "", "language": "python"})
|
||
|
|
assert result["error"] == "Empty code"
|
||
|
|
|
||
|
|
def test_unsupported_language(self) -> None:
|
||
|
|
conn = CodeRunnerConnector()
|
||
|
|
result = conn.invoke("run", {"code": "x", "language": "cobol"})
|
||
|
|
assert result["error"] is not None
|
||
|
|
assert "Unsupported" in str(result["error"])
|
||
|
|
|
||
|
|
def test_timeout(self) -> None:
|
||
|
|
conn = CodeRunnerConnector(timeout=1.0)
|
||
|
|
result = conn.invoke("run", {"code": "import time; time.sleep(10)", "language": "python", "timeout": 1.0})
|
||
|
|
assert result["error"] == "timeout"
|
||
|
|
|
||
|
|
def test_list_languages(self) -> None:
|
||
|
|
conn = CodeRunnerConnector()
|
||
|
|
result = conn.invoke("languages", {})
|
||
|
|
assert "python" in result["languages"]
|
||
|
|
|
||
|
|
def test_schema(self) -> None:
|
||
|
|
conn = CodeRunnerConnector()
|
||
|
|
s = conn.schema()
|
||
|
|
assert s["name"] == "code_runner"
|