Ctrl K
ComunidadGuías…

tests/test_confidence_score_output.py

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

Archivo original ↗Preguntar a KiBot
"""Edge confidence scores in `path`, `explain` and neighbor output (#4882).

graph.json stores `confidence_score` next to `confidence` (interface dispatch
writes 0.85 / 0.75 / 0.65 by implementer count), but the text renderers only
printed the bare tag, so `[INFERRED]` hid whether an edge was a strong or a
weak inference. A scored non-EXTRACTED edge now renders as `[INFERRED 0.75]`;
EXTRACTED and unscored edges keep the bare tag.
"""
from __future__ import annotations

import json
import os
import tempfile
from pathlib import Path

import pytest
from networkx.readwrite import json_graph

import graphify.__main__ as mainmod
from graphify.build import build_from_json
from graphify.export import to_json
from graphify.extract import extract
from graphify.serve import _confidence_tag, _neighbor_lines, _shortest_path_text

_REPORT_CS = (
    "public interface IReport { string Build(); }\n"
    'public class PdfReport : IReport { public string Build() { return "pdf"; } }\n'
    'public class CsvReport : IReport { public string Build() { return "csv"; } }\n'
    "public class Exporter {\n"
    "  private readonly IReport _report;\n"
    "  public Exporter(IReport report) { _report = report; }\n"
    "  public string Run() { return _report.Build(); }\n"
    "}\n"
)


@pytest.mark.parametrize("edge, expected", [
    ({"confidence": "INFERRED", "confidence_score": 0.75}, "INFERRED 0.75"),
    ({"confidence": "INFERRED", "confidence_score": 0.8}, "INFERRED 0.80"),
    ({"confidence": "AMBIGUOUS", "confidence_score": 0.2}, "AMBIGUOUS 0.20"),
    ({"confidence": "INFERRED"}, "INFERRED"),
    ({"confidence": "INFERRED", "confidence_score": None}, "INFERRED"),
    ({"confidence": "INFERRED", "confidence_score": "0.75"}, "INFERRED"),
    ({"confidence": "INFERRED", "confidence_score": True}, "INFERRED"),
    ({"confidence": "INFERRED", "confidence_score": float("nan")}, "INFERRED"),
    ({"confidence": "EXTRACTED", "confidence_score": 1.0}, "EXTRACTED"),
    ({"confidence_score": 0.75}, ""),
    ({}, ""),
])
def test_confidence_tag(edge, expected):
    assert _confidence_tag(edge) == expected


@pytest.fixture
def report_graph(tmp_path):
    """The issue's Report.cs repro, extracted and written as graph.json."""
    (tmp_path / "Report.cs").write_text(_REPORT_CS)
    old = os.getcwd()
    try:
        os.chdir(tmp_path)
        extraction = extract([Path("Report.cs")], cache_root=Path(tempfile.mkdtemp()))
    finally:
        os.chdir(old)
    scores = {(e["source"], e["relation"], e["target"]): e.get("confidence_score")
              for e in extraction["edges"] if e.get("confidence") == "INFERRED"}
    assert scores == {
        ("report_exporter_run", "calls", "report_ireport_build"): 0.85,
        ("report_ireport_build", "dispatches_to", "report_pdfreport_build"): 0.75,
        ("report_ireport_build", "dispatches_to", "report_csvreport_build"): 0.75,
    }
    G = build_from_json(extraction, root=tmp_path)
    out = tmp_path / "graph.json"
    to_json(G, {0: list(G.nodes)}, str(out))
    return out


def _cli(monkeypatch, capsys, *argv):
    monkeypatch.setattr(mainmod, "_check_skill_version", lambda _: None)
    monkeypatch.setattr(mainmod.sys, "argv", ["graphify", *argv])
    mainmod.main()
    return capsys.readouterr().out


def _load(graph_path):
    raw = json.loads(graph_path.read_text())
    return json_graph.node_link_graph({**raw, "directed": True}, edges="links")


def test_explain_prints_scores(report_graph, monkeypatch, capsys):
    out = _cli(monkeypatch, capsys, "explain", "report_ireport_build",
               "--graph", str(report_graph))
    assert out.count("[dispatches_to] [INFERRED 0.75]") == 2
    assert "<-- Exporter.Run() [calls] [INFERRED 0.85]" in out
    assert "[method] [EXTRACTED]" in out
    assert "[INFERRED]" not in out


def test_cli_path_prints_scores(report_graph, monkeypatch, capsys):
    out = _cli(monkeypatch, capsys, "path", "report_exporter_run",
               "report_pdfreport_build", "--graph", str(report_graph))
    assert ("--calls [INFERRED 0.85]--> IReport.Build() "
            "--dispatches_to [INFERRED 0.75]--> PdfReport.Build()") in out


def test_mcp_path_prints_scores(report_graph):
    out = _shortest_path_text(_load(report_graph), {
        "source": "report_exporter_run", "target": "report_pdfreport_build",
    })
    assert ("--calls [INFERRED 0.85]--> IReport.Build() "
            "--dispatches_to [INFERRED 0.75]--> PdfReport.Build()") in out


def test_mcp_neighbors_print_scores(report_graph):
    lines = _neighbor_lines(_load(report_graph), "report_ireport_build")
    assert sum("[dispatches_to] [INFERRED 0.75]" in ln for ln in lines) == 2
    assert any(ln.startswith("  <-- Exporter.Run() [calls] [INFERRED 0.85]") for ln in lines)
    assert any("[method] [EXTRACTED] " in ln for ln in lines)