116 lines
3.7 KiB
Python
116 lines
3.7 KiB
Python
from __future__ import annotations
|
|
|
|
import importlib.util
|
|
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
PIPELINE_PATH = ROOT / "pipelines" / "codebase_genome.py"
|
|
NIGHTLY_PATH = ROOT / "scripts" / "codebase_genome_nightly.py"
|
|
GENOME_PATH = ROOT / "GENOME.md"
|
|
|
|
|
|
def _load_module(path: Path, name: str):
|
|
assert path.exists(), f"missing {path.relative_to(ROOT)}"
|
|
spec = importlib.util.spec_from_file_location(name, path)
|
|
assert spec and spec.loader
|
|
module = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(module)
|
|
return module
|
|
|
|
|
|
def test_generate_genome_markdown_contains_required_sections(tmp_path: Path) -> None:
|
|
genome_mod = _load_module(PIPELINE_PATH, "codebase_genome")
|
|
|
|
repo = tmp_path / "repo"
|
|
(repo / "tests").mkdir(parents=True)
|
|
(repo / "README.md").write_text("# Demo Repo\n\nA tiny example repo.\n")
|
|
(repo / "app.py").write_text(
|
|
"import module\n\n"
|
|
"def main():\n"
|
|
" return module.Helper().answer()\n\n"
|
|
"if __name__ == '__main__':\n"
|
|
" raise SystemExit(main())\n"
|
|
)
|
|
(repo / "module.py").write_text(
|
|
"class Helper:\n"
|
|
" def answer(self):\n"
|
|
" return 42\n"
|
|
)
|
|
(repo / "dangerous.py").write_text(
|
|
"import subprocess\n\n"
|
|
"def run_shell(cmd):\n"
|
|
" return subprocess.run(cmd, shell=True, check=False)\n"
|
|
)
|
|
(repo / "extra.py").write_text("VALUE = 7\n")
|
|
(repo / "tests" / "test_app.py").write_text(
|
|
"from app import main\n\n"
|
|
"def test_main():\n"
|
|
" assert main() == 42\n"
|
|
)
|
|
|
|
genome = genome_mod.generate_genome_markdown(repo, repo_name="org/repo")
|
|
|
|
for heading in (
|
|
"# GENOME.md — org/repo",
|
|
"## Project Overview",
|
|
"## Architecture",
|
|
"```mermaid",
|
|
"## Entry Points",
|
|
"## Data Flow",
|
|
"## Key Abstractions",
|
|
"## API Surface",
|
|
"## Test Coverage Report",
|
|
"## Security Audit Findings",
|
|
"## Dead Code Candidates",
|
|
"## Performance Bottleneck Analysis",
|
|
):
|
|
assert heading in genome
|
|
|
|
assert "app.py" in genome
|
|
assert "module.py" in genome
|
|
assert "dangerous.py" in genome
|
|
assert "extra.py" in genome
|
|
assert "shell=True" in genome
|
|
|
|
|
|
def test_nightly_runner_rotates_repos_and_builds_plan() -> None:
|
|
nightly_mod = _load_module(NIGHTLY_PATH, "codebase_genome_nightly")
|
|
|
|
repos = [
|
|
{"name": "alpha", "full_name": "Timmy_Foundation/alpha", "clone_url": "https://example/alpha.git"},
|
|
{"name": "beta", "full_name": "Timmy_Foundation/beta", "clone_url": "https://example/beta.git"},
|
|
]
|
|
state = {"last_index": 0, "last_repo": "alpha"}
|
|
|
|
next_repo = nightly_mod.select_next_repo(repos, state)
|
|
assert next_repo["name"] == "beta"
|
|
|
|
plan = nightly_mod.build_run_plan(
|
|
repo=next_repo,
|
|
workspace_root=Path("/tmp/repos"),
|
|
output_root=Path("/tmp/genomes"),
|
|
pipeline_script=Path("/tmp/timmy-home/pipelines/codebase_genome.py"),
|
|
)
|
|
|
|
assert plan.repo_dir == Path("/tmp/repos/beta")
|
|
assert plan.output_path == Path("/tmp/genomes/beta/GENOME.md")
|
|
assert "codebase_genome.py" in plan.command[1]
|
|
assert plan.command[-1] == "/tmp/genomes/beta/GENOME.md"
|
|
|
|
|
|
def test_repo_contains_generated_timmy_home_genome() -> None:
|
|
assert GENOME_PATH.exists(), "missing generated GENOME.md for timmy-home"
|
|
text = GENOME_PATH.read_text(encoding="utf-8")
|
|
for snippet in (
|
|
"# GENOME.md — Timmy_Foundation/timmy-home",
|
|
"## Project Overview",
|
|
"## Architecture",
|
|
"## Entry Points",
|
|
"## API Surface",
|
|
"## Test Coverage Report",
|
|
"## Security Audit Findings",
|
|
"## Performance Bottleneck Analysis",
|
|
):
|
|
assert snippet in text
|