Files
PlantAI-dev/tests/unit/test_run_domain_scope_protein_count.py
2026-08-03 18:42:47 +08:00

116 lines
4.1 KiB
Python
Executable File

import json
import sys
from pathlib import Path
import pytest
def test_domain_scope_records_protein_count_before_manifest(tmp_path, monkeypatch):
from apps.cli import run_domain
ws = tmp_path / "job_scope_domain"
final_dir = ws / "final"
analysis_dir = ws / "domain" / "analysis"
phylogeny_dir = ws / "phylogeny" / "analysis"
final_dir.mkdir(parents=True)
analysis_dir.mkdir(parents=True)
phylogeny_dir.mkdir(parents=True)
scope_id = "SPL.target-Ft.ref-At.target_plus_reference"
scope_file = final_dir / "Ft.SPL.scope.json"
scope_file.write_text(
json.dumps(
{
"family": "SPL",
"prefix": "Ft.SPL",
"scope_id": scope_id,
"scope_mode": "target_plus_reference",
"target_species": ["Ft"],
"reference_species": ["At"],
"comparative_species": [],
"selected_species": ["Ft", "At"],
}
),
encoding="utf-8",
)
protein_file = phylogeny_dir / "scope.pep.fa"
protein_file.write_text(">Ft_gene1\nMAAA\n>At_gene1\nMCCC\n", encoding="utf-8")
tree_file = final_dir / "Target.SPL.target-Ft.ref-At.subfamily_evidence.tree.nwk"
tree_file.write_text("(Ft_gene1,At_gene1);\n", encoding="utf-8")
phylogeny_manifest = final_dir / f"Ft.SPL.{run_domain.sanitize_token(scope_id)}.phylogeny.manifest.json"
phylogeny_manifest.write_text(
json.dumps(
{
"stage": "phylogeny",
"status": "success",
"prefix": "Ft.SPL",
"parameters": {"scope_input_fasta": str(protein_file)},
"artifacts": {"tree": {"path": str(tree_file.relative_to(ws))}},
}
),
encoding="utf-8",
)
pfam_hmm = tmp_path / "Pfam-A.hmm"
pfam_hmm.write_text("HMMER3/f\n", encoding="utf-8")
domtblout = analysis_dir / "scope.domtblout"
tblout = analysis_dir / "scope.tblout"
plot_png = final_dir / "Target.SPL.target-Ft.ref-At.subfamily_evidence.domain.png"
plot_pdf = final_dir / "Target.SPL.target-Ft.ref-At.subfamily_evidence.domain.pdf"
def fake_run_hmmscan(*args, **kwargs):
domtblout.write_text("# empty domtblout\n", encoding="utf-8")
tblout.write_text("# empty tblout\n", encoding="utf-8")
return True, {"elapsed_sec": 0.01, "domtblout": domtblout, "tblout": tblout}
def fake_run_r_plotting(*args, **kwargs):
plot_png.write_text("png", encoding="utf-8")
plot_pdf.write_text("pdf", encoding="utf-8")
return {"success": True, "output_files": [str(plot_png), str(plot_pdf)]}
monkeypatch.setattr(run_domain, "prepare_pfam_database", lambda *args, **kwargs: (pfam_hmm, True, ""))
monkeypatch.setattr(run_domain, "run_hmmscan", fake_run_hmmscan)
monkeypatch.setattr(
run_domain,
"parse_domtblout",
lambda *args, **kwargs: (
[],
{"total_hits": 0, "significant_hits": 0, "unique_proteins": 0, "unique_domains": 0},
),
)
monkeypatch.setattr(run_domain, "run_r_plotting", fake_run_r_plotting)
monkeypatch.setattr(run_domain, "get_tool_versions", lambda: {})
monkeypatch.setattr(
sys,
"argv",
[
"run_domain.py",
"--prefix",
"Ft.SPL",
"--workspace",
str(ws),
"--scope-file",
str(scope_file),
"--analysis-route",
"subfamily_evidence",
"--member-set-id",
f"{scope_id}:subfamily_evidence:domain_refined",
"--tree",
str(tree_file),
"--subfamily",
"NONE",
],
)
with pytest.raises(SystemExit) as exit_info:
run_domain.main()
assert exit_info.value.code == 0
manifest_file = final_dir / "Target.SPL.target-Ft.ref-At.subfamily_evidence.domain.manifest.json"
assert manifest_file.exists()
manifest = json.loads(manifest_file.read_text(encoding="utf-8"))
assert manifest["parameters"]["protein_record_count"] == 2
assert manifest["metrics"]["protein_record_count"] == 2