mirror of
https://github.com/safishamsi/graphify.git
synced 2026-07-12 10:27:11 +00:00
81a43f028f
Java, C, C++, Ruby, C#, Kotlin, Scala, PHP via tree-sitter (13 total) benchmark.py measures BFS subgraph tokens vs corpus tokens 5 skill bug fixes (cohesion crash, dead step, missing MCP tool)
120 lines
4.5 KiB
Python
120 lines
4.5 KiB
Python
"""Tests for graphify/benchmark.py."""
|
|
from __future__ import annotations
|
|
import json
|
|
import pytest
|
|
import networkx as nx
|
|
from networkx.readwrite import json_graph
|
|
|
|
from graphify.benchmark import run_benchmark, print_benchmark, _query_subgraph_tokens, _SAMPLE_QUESTIONS
|
|
|
|
|
|
def _make_graph() -> nx.Graph:
|
|
G = nx.Graph()
|
|
G.add_node("n1", label="authentication", source_file="auth.py", source_location="L1", community=0)
|
|
G.add_node("n2", label="api_handler", source_file="api.py", source_location="L5", community=0)
|
|
G.add_node("n3", label="main_entry", source_file="main.py", source_location="L1", community=1)
|
|
G.add_node("n4", label="error_handler", source_file="errors.py", source_location="L1", community=1)
|
|
G.add_node("n5", label="database_layer", source_file="db.py", source_location="L1", community=2)
|
|
G.add_edge("n1", "n2", relation="calls", confidence="INFERRED")
|
|
G.add_edge("n2", "n3", relation="imports", confidence="EXTRACTED")
|
|
G.add_edge("n3", "n4", relation="uses", confidence="EXTRACTED")
|
|
G.add_edge("n5", "n2", relation="provides", confidence="EXTRACTED")
|
|
return G
|
|
|
|
|
|
def _write_graph(G: nx.Graph, path) -> None:
|
|
data = json_graph.node_link_data(G, edges="links")
|
|
path.write_text(json.dumps(data))
|
|
|
|
|
|
# --- _query_subgraph_tokens ---
|
|
|
|
def test_query_returns_positive_for_matching_question():
|
|
G = _make_graph()
|
|
tokens = _query_subgraph_tokens(G, "how does authentication work")
|
|
assert tokens > 0
|
|
|
|
def test_query_returns_zero_for_no_match():
|
|
G = _make_graph()
|
|
tokens = _query_subgraph_tokens(G, "xyzzy plugh zorkmid")
|
|
assert tokens == 0
|
|
|
|
def test_query_bfs_expands_neighbors():
|
|
G = _make_graph()
|
|
# "authentication" matches n1, BFS depth=3 should reach n2, n3, n4
|
|
tokens_deep = _query_subgraph_tokens(G, "authentication", depth=3)
|
|
tokens_shallow = _query_subgraph_tokens(G, "authentication", depth=1)
|
|
assert tokens_deep >= tokens_shallow
|
|
|
|
|
|
# --- run_benchmark ---
|
|
|
|
def test_run_benchmark_returns_reduction(tmp_path):
|
|
G = _make_graph()
|
|
graph_file = tmp_path / "graph.json"
|
|
_write_graph(G, graph_file)
|
|
result = run_benchmark(str(graph_file), corpus_words=10_000)
|
|
assert "reduction_ratio" in result
|
|
assert result["reduction_ratio"] > 1.0
|
|
|
|
def test_run_benchmark_corpus_tokens_proportional(tmp_path):
|
|
G = _make_graph()
|
|
graph_file = tmp_path / "graph.json"
|
|
_write_graph(G, graph_file)
|
|
r1 = run_benchmark(str(graph_file), corpus_words=1_000)
|
|
r2 = run_benchmark(str(graph_file), corpus_words=10_000)
|
|
# corpus_tokens scales linearly with corpus_words (within integer-division rounding)
|
|
assert abs(r2["corpus_tokens"] - r1["corpus_tokens"] * 10) <= r1["corpus_tokens"]
|
|
|
|
def test_run_benchmark_per_question_list(tmp_path):
|
|
G = _make_graph()
|
|
graph_file = tmp_path / "graph.json"
|
|
_write_graph(G, graph_file)
|
|
result = run_benchmark(str(graph_file), corpus_words=5_000,
|
|
questions=["how does authentication work", "what is the main entry"])
|
|
assert len(result["per_question"]) >= 1
|
|
for p in result["per_question"]:
|
|
assert "question" in p
|
|
assert "query_tokens" in p
|
|
assert "reduction" in p
|
|
|
|
def test_run_benchmark_estimates_corpus_if_no_words(tmp_path):
|
|
G = _make_graph()
|
|
graph_file = tmp_path / "graph.json"
|
|
_write_graph(G, graph_file)
|
|
result = run_benchmark(str(graph_file), corpus_words=None)
|
|
assert result["corpus_words"] > 0
|
|
|
|
def test_run_benchmark_error_on_empty_graph(tmp_path):
|
|
G = nx.Graph()
|
|
graph_file = tmp_path / "empty.json"
|
|
_write_graph(G, graph_file)
|
|
result = run_benchmark(str(graph_file), corpus_words=1_000)
|
|
assert "error" in result
|
|
|
|
def test_run_benchmark_includes_node_edge_counts(tmp_path):
|
|
G = _make_graph()
|
|
graph_file = tmp_path / "graph.json"
|
|
_write_graph(G, graph_file)
|
|
result = run_benchmark(str(graph_file), corpus_words=5_000)
|
|
assert result["nodes"] == G.number_of_nodes()
|
|
assert result["edges"] == G.number_of_edges()
|
|
|
|
|
|
# --- print_benchmark ---
|
|
|
|
def test_print_benchmark_no_crash(tmp_path, capsys):
|
|
G = _make_graph()
|
|
graph_file = tmp_path / "graph.json"
|
|
_write_graph(G, graph_file)
|
|
result = run_benchmark(str(graph_file), corpus_words=5_000)
|
|
print_benchmark(result)
|
|
out = capsys.readouterr().out
|
|
assert "reduction" in out.lower()
|
|
assert "x" in out
|
|
|
|
def test_print_benchmark_error_message(capsys):
|
|
print_benchmark({"error": "test error message"})
|
|
out = capsys.readouterr().out
|
|
assert "test error message" in out
|