from __future__ import annotations import argparse import json from pathlib import Path from reuse_surface.reports import ( cohort_filters_from_args, collect_gap_report, format_cohort_json, format_cohort_markdown, format_gap_markdown, select_cohort, ) SAMPLE_INDEX = { "capabilities": [ { "id": "capability.planning.only", "vector": "D5 / A0 / C2 / R1", "domain": "helix_forge", "consumption_modes": ["planning"], }, { "id": "capability.implementation.ready", "vector": "D5 / A4 / C3 / R3", "domain": "helix_forge", "consumption_modes": ["cli", "service API"], }, { "id": "capability.other.domain", "vector": "D4 / A3 / C2 / R2", "domain": "other", "consumption_modes": ["cli"], }, ] } def test_planning_min_filter(): filters = cohort_filters_from_args( argparse.Namespace( planning_min="D5", implementation_min=None, discovery_min=None, availability_min=None, availability_max=None, domain=None, ) ) matches = select_cohort(filters, SAMPLE_INDEX) assert [item["id"] for item in matches] == ["capability.planning.only"] def test_implementation_min_filter(): filters = cohort_filters_from_args( argparse.Namespace( planning_min=None, implementation_min="A4", discovery_min=None, availability_min=None, availability_max=None, domain=None, ) ) matches = select_cohort(filters, SAMPLE_INDEX) assert [item["id"] for item in matches] == ["capability.implementation.ready"] def test_domain_filter(): filters = {"discovery_min": None, "availability_min": None, "availability_max": None, "domain": "helix_forge"} matches = select_cohort(filters, SAMPLE_INDEX) assert len(matches) == 2 def test_format_cohort_markdown_includes_filters(): filters = {"discovery_min": "D5", "availability_min": None, "availability_max": "A1", "domain": None} text = format_cohort_markdown([SAMPLE_INDEX["capabilities"][0]], filters) assert "planning-min" not in text assert "discovery_min" in text assert "capability.planning.only" in text def test_format_cohort_json_payload(): filters = {"discovery_min": "D5", "availability_min": None, "availability_max": "A1", "domain": None} payload = json.loads( format_cohort_json([SAMPLE_INDEX["capabilities"][0]], filters) ) assert payload["count"] == 1 assert payload["filters"]["discovery_min"] == "D5" def test_collect_gap_report_from_roster(): root = Path(__file__).resolve().parent.parent roster = root / "registry/federation/local-repo-roster.yaml" report = collect_gap_report(roster) assert report["summary"]["total"] == 60 assert len(report["publish_fail"]) == 13 assert report["empty_scaffold_count"] >= 40 def test_format_gap_markdown_lists_publish_fail(): report = { "roster_path": "/tmp/roster.yaml", "summary": {"total": 60, "established": 60, "publish_pass": 47}, "publish_fail": [{"slug": "hub-core", "publish_note": "missing repo"}], "empty_scaffold_count": 1, "empty_scaffolds": ["ops-bridge"], "seeded_repos": [], "dedup_pending_local_owners": [], "local_capability_count": 3, } text = format_gap_markdown(report) assert "hub-core" in text assert "ops-bridge" in text def test_cmd_report_gaps_json(monkeypatch): from reuse_surface.cli import main exit_code = main(["report", "gaps", "--format", "json"]) assert exit_code == 0 def test_cmd_report_cohorts_markdown(monkeypatch): from reuse_surface.cli import main monkeypatch.setattr( "reuse_surface.reports.load_index", lambda: SAMPLE_INDEX, ) exit_code = main(["report", "cohorts", "--planning-min", "D5"]) assert exit_code == 0