Skip to main content

ciri_toolkit/
tests.rs

1//! High-level integration-oriented tests for the public pipeline stages.
2
3#[cfg(test)]
4mod tests {
5    use crate::scan2::Scan2;
6    use crate::utils::{
7        bsj1_path_for_output, bsj2_path_for_output, fsj_path_for_output, result_path_for_output,
8    };
9    use std::fs::File;
10    use tempfile::tempdir;
11
12    #[test]
13    /// Verifies that the three pipeline stages can run end-to-end on a tiny mock input.
14    fn test_full_pipeline_mock() {
15        use crate::annotation::Annotation;
16        use crate::fasta::FastaReader;
17        use crate::scan1::Scan1;
18        use crate::summary::Summary;
19        use std::io::Write;
20
21        let dir = tempdir().unwrap();
22        let fa_path = dir.path().join("test.fa");
23        let gtf_path = dir.path().join("test.gtf");
24        let sam_path = dir.path().join("test.sam");
25        let out_prefix = dir.path().join("out").to_str().unwrap().to_string();
26
27        {
28            let mut fa_file = File::create(&fa_path).unwrap();
29            writeln!(fa_file, ">chr1\n{}", "N".repeat(1000)).unwrap();
30
31            let mut gtf_file = File::create(&gtf_path).unwrap();
32            writeln!(
33                gtf_file,
34                "chr1\tTEST\texon\t100\t200\t.\t+\t.\tgene_id \"G1\";"
35            )
36            .unwrap();
37
38            let mut sam_file = File::create(&sam_path).unwrap();
39            writeln!(sam_file, "@HD\tVN:1.6\tSO:queryname").unwrap();
40        }
41
42        let mut fasta = FastaReader::new();
43        fasta.read_fasta(fa_path.to_str().unwrap()).unwrap();
44
45        let mut annotation = Annotation::new();
46        annotation.read_gtf(gtf_path.to_str().unwrap()).unwrap();
47
48        let mut scan1 = Scan1::new(10, 100, 100000, 5);
49        let _ = scan1
50            .run(
51                sam_path.to_str().unwrap(),
52                &out_prefix,
53                &fasta.chr_tcga_map,
54                &annotation,
55            )
56            .unwrap();
57
58        let mut scan2 = Scan2::new(10, 5, 100);
59        let bsj1_path = bsj1_path_for_output(&out_prefix);
60        let bsj2_path = bsj2_path_for_output(&out_prefix);
61        let fsj_path = fsj_path_for_output(&out_prefix);
62        let result_path = result_path_for_output(&out_prefix);
63        // Ensure the file exists if scan1 didn't find anything
64        if !std::path::Path::new(&bsj1_path).exists() {
65            File::create(&bsj1_path).unwrap();
66        }
67        scan2.build_index(&bsj1_path).unwrap();
68        scan2
69            .run(
70                sam_path.to_str().unwrap(),
71                &bsj2_path,
72                &fsj_path,
73                &fasta.chr_tcga_map,
74            )
75            .unwrap();
76
77        let mut summary = Summary::new(0);
78        summary
79            .run_from_bsj_files(
80                &[&bsj1_path, &bsj2_path],
81                &result_path,
82                &scan2.fsj_map,
83                &fasta.chr_tcga_map,
84                &annotation,
85            )
86            .unwrap();
87
88        assert!(std::path::Path::new(&result_path).exists());
89    }
90
91    #[test]
92    #[ignore]
93    /// Smoke test for a real BAM input when local test fixtures are available.
94    fn test_integration_real_bam() {
95        use crate::annotation::Annotation;
96        use crate::fasta::FastaReader;
97        use crate::scan1::Scan1;
98        use crate::summary::Summary;
99
100        let bam_path = "tests/test.bam";
101        let fa_path = "tests/chr1.fa";
102        let gtf_path = "tests/chr1.gtf";
103
104        let dir = tempdir().unwrap();
105        let out_prefix = dir.path().join("integration").to_str().unwrap().to_string();
106
107        if !std::path::Path::new(bam_path).exists() {
108            return;
109        }
110
111        let mut fasta = FastaReader::new();
112        fasta.read_fasta(fa_path).unwrap();
113        let mut annotation = Annotation::new();
114        annotation.read_gtf(gtf_path).unwrap();
115
116        let mut scan1 = Scan1::new(10, 140, 200000, 5);
117        scan1
118            .run(bam_path, &out_prefix, &fasta.chr_tcga_map, &annotation)
119            .unwrap();
120
121        let mut scan2 = Scan2::new(10, 5, 100);
122        let bsj1_path = bsj1_path_for_output(&out_prefix);
123        let bsj2_path = bsj2_path_for_output(&out_prefix);
124        let fsj_path = fsj_path_for_output(&out_prefix);
125        let result_path = result_path_for_output(&out_prefix);
126        scan2.build_index(&bsj1_path).unwrap();
127        scan2
128            .run(bam_path, &bsj2_path, &fsj_path, &fasta.chr_tcga_map)
129            .unwrap();
130
131        let mut summary = Summary::new(0);
132        summary
133            .run_from_bsj_files(
134                &[&bsj1_path, &bsj2_path],
135                &result_path,
136                &scan2.fsj_map,
137                &fasta.chr_tcga_map,
138                &annotation,
139            )
140            .unwrap();
141
142        assert!(std::path::Path::new(&result_path).exists());
143    }
144}