171 lines
5.0 KiB
Python
171 lines
5.0 KiB
Python
"""Tests for report QC integration."""
|
|
|
|
import json
|
|
|
|
|
|
def test_load_bambu_qc_exists(tmp_path):
|
|
"""Test loading bambu QC stats when file exists."""
|
|
from workflow_glue.report import _load_bambu_qc
|
|
|
|
cohort_dir = tmp_path / "cohort"
|
|
cohort_dir.mkdir()
|
|
|
|
qc_data = {
|
|
"samples": 4,
|
|
"library_sizes": {"sample1": 1000000, "sample2": 2000000},
|
|
"median_library_size": 1500000,
|
|
"library_size_warning": "2.0x variation (>3x threshold)",
|
|
}
|
|
|
|
with open(cohort_dir / "bambu_qc_stats.json", "w") as f:
|
|
json.dump(qc_data, f)
|
|
|
|
result = _load_bambu_qc(cohort_dir)
|
|
assert result is not None
|
|
assert result["samples"] == 4
|
|
assert result["median_library_size"] == 1500000
|
|
|
|
|
|
def test_load_bambu_qc_missing(tmp_path):
|
|
"""Test loading bambu QC stats when file missing."""
|
|
from workflow_glue.report import _load_bambu_qc
|
|
|
|
cohort_dir = tmp_path / "cohort"
|
|
cohort_dir.mkdir()
|
|
|
|
result = _load_bambu_qc(cohort_dir)
|
|
assert result is None
|
|
|
|
|
|
def test_load_de_qc_exists(tmp_path):
|
|
"""Test loading DE QC stats when file exists."""
|
|
from workflow_glue.report import _load_de_qc
|
|
|
|
de_dir = tmp_path / "de_analysis"
|
|
de_dir.mkdir()
|
|
|
|
qc_data = {
|
|
"total_samples": 6,
|
|
"num_contrasts": 2,
|
|
"sample_size_warnings": "Some groups have n<3",
|
|
"contrasts": {
|
|
"contrast1": {
|
|
"dge_significant_fdr05": 123,
|
|
"dtu_status": "SUCCESS",
|
|
},
|
|
},
|
|
}
|
|
|
|
with open(de_dir / "de_qc_stats.json", "w") as f:
|
|
json.dump(qc_data, f)
|
|
|
|
result = _load_de_qc(de_dir)
|
|
assert result is not None
|
|
assert result["total_samples"] == 6
|
|
assert result["num_contrasts"] == 2
|
|
assert "contrasts" in result
|
|
|
|
|
|
def test_load_de_qc_missing(tmp_path):
|
|
"""Test loading DE QC stats when file missing."""
|
|
from workflow_glue.report import _load_de_qc
|
|
|
|
de_dir = tmp_path / "de_analysis"
|
|
de_dir.mkdir()
|
|
|
|
result = _load_de_qc(de_dir)
|
|
assert result is None
|
|
|
|
|
|
def test_warning_banner_creation():
|
|
"""Test that warning banner can be created."""
|
|
from workflow_glue.report import _create_warning_banner
|
|
from dominate import document
|
|
|
|
doc = document()
|
|
with doc:
|
|
_create_warning_banner("Test warning message", level="warning")
|
|
|
|
html = doc.render()
|
|
assert "Test warning message" in html
|
|
assert "background-color" in html
|
|
|
|
|
|
def test_bambu_qc_with_warnings():
|
|
"""Test bambu QC data structure with warnings."""
|
|
qc_data = {
|
|
"samples": 3,
|
|
"library_sizes": {"s1": 1000000, "s2": 4000000, "s3": 2000000},
|
|
"min_library_size": 1000000,
|
|
"max_library_size": 4000000,
|
|
"median_library_size": 2000000,
|
|
"library_size_ratio": 4.0,
|
|
"library_size_warning": "4.0x variation (>3x threshold)",
|
|
"total_transcripts_before_filter": 50000,
|
|
"total_transcripts_after_filter": 45000,
|
|
"transcripts_filtered": 5000,
|
|
"transcriptome_mode": "discover",
|
|
"ndr_used": 0.1,
|
|
}
|
|
|
|
# Verify structure
|
|
assert qc_data["library_size_warning"] is not None
|
|
assert qc_data["library_size_ratio"] > 3.0
|
|
|
|
|
|
def test_de_qc_with_multiple_warnings():
|
|
"""Test DE QC data structure with multiple warning types."""
|
|
qc_data = {
|
|
"total_samples": 4,
|
|
"num_contrasts": 2,
|
|
"sample_size_warnings": "Some groups have n<3",
|
|
"multiple_testing_note": "Testing 2 contrasts yields FWER ~9.8%",
|
|
"samples_per_group": {"control": 2, "treated": 2},
|
|
"contrasts": {
|
|
"condition_treated_vs_control": {
|
|
"n_samples": 4,
|
|
"n_target": 2,
|
|
"n_reference": 2,
|
|
"dge_significant_fdr05": 50,
|
|
"dtu_status": "FAILED",
|
|
"dtu_power_warning": "DTU may be underpowered (n=4)",
|
|
},
|
|
},
|
|
}
|
|
|
|
# Verify warnings are captured
|
|
assert qc_data["sample_size_warnings"] != "none"
|
|
assert qc_data["multiple_testing_note"] is not None
|
|
contrast = qc_data["contrasts"]["condition_treated_vs_control"]
|
|
assert contrast["dtu_status"] == "FAILED"
|
|
assert contrast["dtu_power_warning"] is not None
|
|
|
|
|
|
def test_de_qc_no_warnings():
|
|
"""Test DE QC data structure with no warnings."""
|
|
qc_data = {
|
|
"total_samples": 6,
|
|
"num_contrasts": 1,
|
|
"sample_size_warnings": "none",
|
|
"samples_per_group": {"control": 3, "treated": 3},
|
|
"contrasts": {
|
|
"condition_treated_vs_control": {
|
|
"n_samples": 6,
|
|
"n_target": 3,
|
|
"n_reference": 3,
|
|
"dge_significant_fdr05": 150,
|
|
"dtu_status": "SUCCESS",
|
|
"dtu_significant_genes": 25,
|
|
},
|
|
},
|
|
}
|
|
|
|
# Verify no warnings
|
|
assert qc_data["sample_size_warnings"] == "none"
|
|
assert (
|
|
"multiple_testing_note" not in qc_data
|
|
or qc_data.get("multiple_testing_note") is None
|
|
)
|
|
contrast = qc_data["contrasts"]["condition_treated_vs_control"]
|
|
assert contrast["dtu_status"] == "SUCCESS"
|