From c9273da27582e8bd14c3480edb8d79f6e4dd65b7 Mon Sep 17 00:00:00 2001 From: Ben J Woodcroft Date: Wed, 12 Nov 2025 09:48:16 +1000 Subject: [PATCH 1/2] Ensure concatenated reference FASTA has extension --- src/coverage_printer.rs | 5 ++--- src/mapping_index_maintenance.rs | 38 +++++++++++++++++++++++++++++++- src/mapping_parameters.rs | 10 ++++----- 3 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/coverage_printer.rs b/src/coverage_printer.rs index 80b084e..b766a19 100644 --- a/src/coverage_printer.rs +++ b/src/coverage_printer.rs @@ -197,9 +197,8 @@ pub fn print_sparse_cached_coverage_taker( } coverage_totals[*i] = Some(total_coverage); - if reads_mapped_per_sample.is_some() { - let reads_mapped = - &reads_mapped_per_sample.as_ref().unwrap()[current_stoit_index]; + if let Some(reads_mapped_per_sample) = reads_mapped_per_sample.as_ref() { + let reads_mapped = &reads_mapped_per_sample[current_stoit_index]; let fraction_mapped = reads_mapped.num_mapped_reads as f32 / reads_mapped.num_reads as f32; coverage_multipliers[*i] = Some(fraction_mapped); diff --git a/src/mapping_index_maintenance.rs b/src/mapping_index_maintenance.rs index a375d9a..599936f 100644 --- a/src/mapping_index_maintenance.rs +++ b/src/mapping_index_maintenance.rs @@ -185,7 +185,7 @@ fn check_for_bwa_index_existence(reference_path: &str, mapping_program: &Mapping if num_existing == 0 { false } else if num_existing == num_extensions { - return true; + true } else { error!("BWA index appears to be incomplete, cannot continue."); process::exit(1); @@ -258,6 +258,7 @@ pub fn generate_minimap2_index( pub fn generate_concatenated_fasta_file(fasta_file_paths: &Vec) -> NamedTempFile { let tmpfile: NamedTempFile = Builder::new() .prefix("coverm-concatenated-fasta") + .suffix(".fasta") .tempfile() .unwrap(); let mut something_written_at_all = false; @@ -365,3 +366,38 @@ impl MappingIndex for PregeneratedStrobealignIndexStruct { "--use-index" } } + +#[cfg(test)] +mod tests { + use super::*; + use std::io::Write; + use tempfile::Builder; + + #[test] + fn concatenated_fasta_file_has_required_extension() { + let mut input_fasta = Builder::new() + .prefix("coverm-test-genome") + .suffix(".fasta") + .tempfile() + .unwrap(); + write!(input_fasta, ">contig1\nACGT\n").unwrap(); + input_fasta.flush().unwrap(); + + let input_path = input_fasta + .path() + .to_str() + .expect("temporary file should have valid UTF-8 path") + .to_string(); + + let concatenated = generate_concatenated_fasta_file(&vec![input_path]); + let concatenated_path = concatenated.path(); + + assert_eq!( + concatenated_path.extension().and_then(|ext| ext.to_str()), + Some("fasta") + ); + + let contents = std::fs::read_to_string(concatenated_path).unwrap(); + assert!(contents.contains("ACGT")); + } +} diff --git a/src/mapping_parameters.rs b/src/mapping_parameters.rs index 5c850f2..6070130 100644 --- a/src/mapping_parameters.rs +++ b/src/mapping_parameters.rs @@ -248,27 +248,27 @@ impl<'a> Iterator for SingleReferenceMappingParameters<'a> { } else if self.iter_interleaved_index < self.interleaved.len() { let i = self.iter_interleaved_index; self.iter_interleaved_index += 1; - return Some(OneSampleMappingParameters { + Some(OneSampleMappingParameters { reference: self.reference, read_format: ReadFormat::Interleaved, read1: self.interleaved[i], read2: None, threads: self.threads, mapping_options: self.mapping_options, - }); + }) } else if self.iter_unpaired_index < self.unpaired.len() { let i = self.iter_unpaired_index; self.iter_unpaired_index += 1; - return Some(OneSampleMappingParameters { + Some(OneSampleMappingParameters { reference: self.reference, read_format: ReadFormat::Single, read1: self.unpaired[i], read2: None, threads: self.threads, mapping_options: self.mapping_options, - }); + }) } else { - return None; + None } } } From d2015385cc02cf416bb2cf5d1a6dd44c741f2951 Mon Sep 17 00:00:00 2001 From: Ben J Woodcroft Date: Wed, 12 Nov 2025 10:06:23 +1000 Subject: [PATCH 2/2] Add x-mapper genome CLI test using genome-fasta-files --- tests/test_cmdline.rs | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/test_cmdline.rs b/tests/test_cmdline.rs index fce7b7f..dcd52d6 100644 --- a/tests/test_cmdline.rs +++ b/tests/test_cmdline.rs @@ -3999,6 +3999,41 @@ genome6~random_sequence_length_11003 0 0 0 assert!(stdout.contains("genome5")); } + #[test] + fn test_coverm_genome_fasta_files_x_mapper() { + let reference = PathBuf::from("tests/data/7seqs.fna") + .canonicalize() + .unwrap(); + let r1 = PathBuf::from("tests/data/7seqs.reads_for_7.1.fq") + .canonicalize() + .unwrap(); + let r2 = PathBuf::from("tests/data/7seqs.reads_for_7.2.fq") + .canonicalize() + .unwrap(); + + let output = Command::new(env!("CARGO_BIN_EXE_coverm")) + .args([ + "genome", + "--genome-fasta-files", + reference.to_str().unwrap(), + "-1", + r1.to_str().unwrap(), + "-2", + r2.to_str().unwrap(), + "-p", + "x-mapper", + "--threads", + "1", + ]) + .output() + .expect("failed to run coverm genome with genome-fasta-files and x-mapper"); + assert!(output.status.success()); + let stdout = String::from_utf8(output.stdout).unwrap(); + assert!(stdout.starts_with("Genome")); + assert!(stdout.contains("Relative Abundance")); + assert!(stdout.contains("7seqs")); + } + #[test] fn test_coverm_make_x_mapper() { let tmp = tempdir().unwrap();