Ctrl K
ComunidadGuías…

tests/plugins/test_findings.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""ReportFindings: Claude Code's schema, a count for the model, and the
findings as structured data in a notice for front ends."""

from __future__ import annotations

from typing import Any

from noeta.core.tool import ToolContext
from noeta.plugins.findings import MAX_FINDINGS, SCHEMA, ReportFindingsTool


def _ctx(records: list[tuple[str, str, Any]]) -> ToolContext:
    return ToolContext(task_id="t", call_id="c", env=None,  # type: ignore[arg-type]
                       state={}, record=lambda e, k, d: records.append((e, k, d)))


def test_schema_matches_claude_codes_shape() -> None:
    assert SCHEMA["required"] == ["findings"] and SCHEMA["additionalProperties"] is False
    item = SCHEMA["properties"]["findings"]["items"]
    assert SCHEMA["properties"]["findings"]["maxItems"] == MAX_FINDINGS == 32
    assert item["required"] == ["file", "summary", "failure_scenario"]
    assert set(item["properties"]) == {"file", "line", "summary", "short_summary",
                                       "failure_scenario", "category", "verdict", "outcome"}
    assert item["properties"]["short_summary"]["maxLength"] == 60
    assert item["properties"]["category"]["maxLength"] == 40
    assert SCHEMA["properties"]["level"]["enum"] == ["low", "medium", "high", "xhigh", "max"]


async def test_findings_reach_front_ends_as_data_and_the_model_gets_a_count() -> None:
    records: list[tuple[str, str, Any]] = []
    finding = {"file": "a.py", "line": 3, "summary": "Off by one.", "failure_scenario": "n=0",
               "short_summary": "off by one"}
    out = await ReportFindingsTool().run({"level": "high", "findings": [finding]},
                                         _ctx(records))
    assert out.content[0].text == "Recorded 1 finding."  # type: ignore[union-attr]
    [(ext, kind, data)] = records
    assert (ext, kind, data["kind"]) == ("core", "notice", "findings")
    assert data["data"] == {"level": "high", "findings": [finding]}
    assert "a.py:3 — off by one" in data["text"]


async def test_no_findings_and_malformed_ones() -> None:
    records: list[tuple[str, str, Any]] = []
    out = await ReportFindingsTool().run({"findings": []}, _ctx(records))
    assert out.content[0].text == "Recorded no findings."  # type: ignore[union-attr]
    bad = await ReportFindingsTool().run({"findings": [{"file": "a.py"}]}, _ctx(records))
    assert bad.is_error


async def test_values_outside_the_schema_are_refused() -> None:
    ok = {"file": "a.py", "summary": "s", "failure_scenario": "f"}
    for call in ({"level": "huge", "findings": [ok]},
                 {"findings": [{**ok, "short_summary": "x" * 61}]},
                 {"findings": [{**ok, "category": "x" * 41}]},
                 {"findings": [{**ok, "verdict": "MAYBE"}]},
                 {"findings": [{**ok, "outcome": "done"}]},
                 {"findings": [{**ok, "line": "3"}]},
                 {"findings": [{**ok, "severity": "high"}]}):
        records: list[tuple[str, str, Any]] = []
        out = await ReportFindingsTool().run(call, _ctx(records))
        assert out.is_error and records == [], call