generated from coulomb/repo-seed
Repo stats and features as aggregates
This commit is contained in:
@@ -208,3 +208,39 @@ def test_candidate_generator_uses_generic_io_for_unknown_interfaces():
|
||||
capability = graph[0].capabilities[0]
|
||||
assert capability.inputs == ["caller input"]
|
||||
assert capability.outputs == ["callable interface result"]
|
||||
|
||||
|
||||
def test_candidate_generator_groups_many_interface_facts_into_behavioral_features():
|
||||
repository = Repository(
|
||||
id=1,
|
||||
name="Registry",
|
||||
url="/tmp/registry",
|
||||
description=None,
|
||||
branch="main",
|
||||
status="analyzed",
|
||||
)
|
||||
facts = [
|
||||
fact(1, "documentation", "README", "README.md"),
|
||||
fact(2, "interface", "python route decorator", "src/api.py", '@app.get("/repos")'),
|
||||
fact(3, "interface", "python route decorator", "src/api.py", '@app.post("/repos")'),
|
||||
fact(
|
||||
4,
|
||||
"interface",
|
||||
"python route decorator",
|
||||
"src/api.py",
|
||||
'@app.post("/repos/{repository_id}/analysis-runs")',
|
||||
),
|
||||
fact(5, "test", "test_api.py", "tests/test_api.py"),
|
||||
]
|
||||
|
||||
graph = CandidateGraphGenerator().generate(repository, facts)
|
||||
|
||||
capability = graph[0].capabilities[0]
|
||||
assert len(capability.features) == 1
|
||||
feature = capability.features[0]
|
||||
assert feature.name == (
|
||||
"HTTP API surface: GET /repos, POST /repos, POST /repos/{repository_id}/analysis-runs"
|
||||
)
|
||||
assert feature.type == "API"
|
||||
assert feature.location == "src/api.py"
|
||||
assert len(feature.source_refs) == 3
|
||||
|
||||
@@ -267,7 +267,6 @@ def test_search_filters_by_status_language_and_framework(tmp_path):
|
||||
" return {}\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
service = make_service(tmp_path)
|
||||
repository = service.register_repository(name="Filterable", url=str(source))
|
||||
summary = service.analyze_repository(repository.id)
|
||||
@@ -327,7 +326,7 @@ def test_fixture_breadth_python_cli_repo_extracts_reviewable_cli_claims(tmp_path
|
||||
assert summary.analysis_run.status == "completed"
|
||||
assert capability.name == "Expose Repository Interface"
|
||||
assert capability.features[0].type == "CLI"
|
||||
assert capability.features[0].name == "CLI command main"
|
||||
assert capability.features[0].name.startswith("CLI command surface:")
|
||||
assert capability.evidence[0].reference == "tests/test_cli.py"
|
||||
assert service.ability_map(repository.id).abilities == []
|
||||
|
||||
@@ -523,7 +522,6 @@ def test_analyze_repository_records_snapshot_and_observed_facts(tmp_path):
|
||||
" return {}\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
service = make_service(tmp_path)
|
||||
repository = service.register_repository(
|
||||
name="Example",
|
||||
@@ -660,6 +658,13 @@ def test_approve_candidate_graph_publishes_ability_map_once(tmp_path):
|
||||
" return {}\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(source / "cli.py").write_text(
|
||||
"import click\n\n"
|
||||
"@click.command()\n"
|
||||
"def health():\n"
|
||||
" click.echo('ok')\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
service = make_service(tmp_path)
|
||||
repository = service.register_repository(name="Example", url=str(source))
|
||||
@@ -1150,6 +1155,13 @@ def test_merge_candidate_feature_and_evidence_omits_duplicate_leaves(tmp_path):
|
||||
" return {}\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(source / "cli.py").write_text(
|
||||
"import click\n\n"
|
||||
"@click.command()\n"
|
||||
"def health():\n"
|
||||
" click.echo('ok')\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
service = make_service(tmp_path)
|
||||
repository = service.register_repository(name="Merge Leaves", url=str(source))
|
||||
@@ -1224,6 +1236,36 @@ def test_analyze_repository_clones_git_url_before_scanning(tmp_path):
|
||||
assert ("framework", "pytest", "requirements.txt") in fact_names
|
||||
|
||||
|
||||
def test_analyze_repository_can_use_cached_checkout_without_fetching(tmp_path, monkeypatch):
|
||||
service = make_service(tmp_path)
|
||||
url = "https://example.com/private/repo.git"
|
||||
cached = tmp_path / "checkouts" / "repo-b5d250ec3c59"
|
||||
cached.mkdir(parents=True)
|
||||
(cached / "README.md").write_text("# Cached Repo\n", encoding="utf-8")
|
||||
|
||||
def fail_run_git(*args, **kwargs):
|
||||
raise AssertionError("cached analysis should not run git")
|
||||
|
||||
monkeypatch.setattr(service.ingestion, "_run_git", fail_run_git)
|
||||
repository = service.register_repository(
|
||||
name="Cached",
|
||||
url=url,
|
||||
description="Already cloned.",
|
||||
)
|
||||
|
||||
summary = service.analyze_repository(
|
||||
repository.id,
|
||||
use_cached_checkout=True,
|
||||
)
|
||||
|
||||
assert summary.analysis_run.status == "completed"
|
||||
assert summary.snapshot is not None
|
||||
assert str(cached) == summary.snapshot.source_path
|
||||
assert ("documentation", "README", "README.md") in {
|
||||
(fact.kind, fact.name, fact.path) for fact in summary.facts
|
||||
}
|
||||
|
||||
|
||||
def test_operational_logging_records_analysis_and_review_events(caplog, tmp_path):
|
||||
source = tmp_path / "repo"
|
||||
source.mkdir()
|
||||
|
||||
@@ -1031,7 +1031,10 @@ def test_api_source_linked_candidate_and_repo_update_loop(tmp_path):
|
||||
for capability in ability["capabilities"]
|
||||
for feature in capability["features"]
|
||||
}
|
||||
assert {"GET /status", "GET /ready"} <= second_features
|
||||
assert any(
|
||||
"GET /status" in feature_name and "GET /ready" in feature_name
|
||||
for feature_name in second_features
|
||||
)
|
||||
|
||||
approved_after_reanalysis = client.get(f"/repos/{repository_id}/ability-map")
|
||||
assert approved_after_reanalysis.status_code == 200
|
||||
@@ -1060,6 +1063,13 @@ def test_ui_register_analyze_and_approve_loop(tmp_path):
|
||||
" return {}\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(source / "cli.py").write_text(
|
||||
"import click\n\n"
|
||||
"@click.command()\n"
|
||||
"def status():\n"
|
||||
" click.echo('ok')\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
def override_settings():
|
||||
return Settings(
|
||||
@@ -1095,6 +1105,7 @@ def test_ui_register_analyze_and_approve_loop(tmp_path):
|
||||
assert detail_response.status_code == 200
|
||||
assert "Run Analysis" in detail_response.text
|
||||
assert "Running analysis..." in detail_response.text
|
||||
assert "Analyze cached checkout without fetching upstream" in detail_response.text
|
||||
assert "Repository Metadata" in detail_response.text
|
||||
|
||||
edit_repository_response = client.post(
|
||||
@@ -1127,6 +1138,10 @@ def test_ui_register_analyze_and_approve_loop(tmp_path):
|
||||
run_detail = client.get(run_path)
|
||||
assert run_detail.status_code == 200
|
||||
assert "Candidate Graph" in run_detail.text
|
||||
assert "1 abilities" in run_detail.text
|
||||
assert "2 capabilities" in run_detail.text
|
||||
assert "2 features" in run_detail.text
|
||||
assert "7 facts" in run_detail.text
|
||||
assert "Content Chunks" in run_detail.text
|
||||
assert "README.md:1-1" in run_detail.text
|
||||
assert "ID " in run_detail.text
|
||||
@@ -1141,6 +1156,9 @@ def test_ui_register_analyze_and_approve_loop(tmp_path):
|
||||
approved_detail = client.get(approve_response.headers["location"])
|
||||
assert approved_detail.status_code == 200
|
||||
assert "Approved Ability Map" in approved_detail.text
|
||||
assert "1 abilities" in approved_detail.text
|
||||
assert "2 capabilities" in approved_detail.text
|
||||
assert "2 features" in approved_detail.text
|
||||
assert "Review UI Repo Edited Repository Usefulness" in approved_detail.text
|
||||
assert "Language: Python" in approved_detail.text
|
||||
assert "Framework: FastAPI" in approved_detail.text
|
||||
@@ -1635,7 +1653,6 @@ def test_api_rejects_candidate_capability_feature_and_evidence(tmp_path):
|
||||
" return {}\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
def override_settings():
|
||||
return Settings(
|
||||
database_path=str(tmp_path / "api-reject.sqlite3"),
|
||||
@@ -1723,7 +1740,6 @@ def test_api_relinks_candidate_feature_and_evidence(tmp_path):
|
||||
" return {}\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
def override_settings():
|
||||
return Settings(
|
||||
database_path=str(tmp_path / "api-relink.sqlite3"),
|
||||
@@ -1798,6 +1814,13 @@ def test_api_merges_candidate_capability_feature_and_evidence(tmp_path):
|
||||
" return {}\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
(source / "cli.py").write_text(
|
||||
"import click\n\n"
|
||||
"@click.command()\n"
|
||||
"def status_cli():\n"
|
||||
" click.echo('ok')\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
|
||||
def override_settings():
|
||||
return Settings(
|
||||
|
||||
Reference in New Issue
Block a user