diff --git a/src/intersections.rs b/src/intersections.rs index 8963337..77e1246 100644 --- a/src/intersections.rs +++ b/src/intersections.rs @@ -140,47 +140,11 @@ impl Intersections { #[cfg(test)] mod tests { use super::*; - use crate::intersection::Intersection; use crate::interval::Interval; - use std::sync::Arc; - - fn make_intersections(a: Interval, bs: Vec) -> Intersections { - let base = Position::Interval(a); - let overlapping = bs - .into_iter() - .enumerate() - .map(|(i, b)| Intersection { - interval: Arc::new(Position::Interval(b.dup())), - id: i as u32, - }) - .collect(); - Intersections { - base_interval: Arc::new(base), - overlapping, - } - } + use crate::tests::parse_intersections::parse_intersections; fn make_example() -> Intersections { - // make a single Intersections - let base = Interval { - chrom: String::from("chr1"), - start: 1, - stop: 10, - fields: Default::default(), - }; - let o1 = Interval { - chrom: String::from("chr1"), - start: 3, - stop: 6, - fields: Default::default(), - }; - let o2 = Interval { - chrom: String::from("chr1"), - start: 8, - stop: 12, - fields: Default::default(), - }; - make_intersections(base, vec![o1, o2]) + parse_intersections("a: 1-10\nb: 3-6, 8-12") } #[test] diff --git a/src/lib.rs b/src/lib.rs index cbcb882..68f69bc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -26,3 +26,5 @@ pub mod bedder_bed; #[cfg(feature = "vcf")] /// Vcf parser implementing the PositionedIterator trait. pub mod bedder_vcf; + +mod tests; diff --git a/src/tests/mod.rs b/src/tests/mod.rs new file mode 100644 index 0000000..1431bb4 --- /dev/null +++ b/src/tests/mod.rs @@ -0,0 +1,2 @@ +#[cfg(test)] +pub mod parse_intersections; diff --git a/src/tests/parse_intersections.rs b/src/tests/parse_intersections.rs new file mode 100644 index 0000000..8feb90a --- /dev/null +++ b/src/tests/parse_intersections.rs @@ -0,0 +1,92 @@ +use crate::intersection::{Intersection, Intersections}; +use crate::interval::Interval; +use crate::position::Position; +use crate::string::String; +use linear_map::LinearMap; +use std::sync::Arc; + +#[cfg(test)] +pub(crate) fn parse_intersections(input: &str) -> Intersections { + let mut intersections = Vec::new(); + let mut base_interval = None; + + for line in input.lines() { + let line = line.trim(); + + if line.is_empty() { + continue; + } + + let mut parts = line.split(':'); + let mut id = 0; + + if let (Some(name), Some(ranges)) = (parts.next(), parts.next()) { + let name = name.trim(); + id += 1; + + let ranges: Vec<(u64, u64)> = ranges + .split(',') + .map(|range| { + let range = range.trim(); + let mut range_parts = range.split('-'); + + if let (Some(start), Some(end)) = (range_parts.next(), range_parts.next()) { + if let (Ok(start), Ok(end)) = (start.parse(), end.parse()) { + return (start, end); + } + } + + panic!("Invalid range format: {}", range); + }) + .collect(); + + if name == "a" { + assert_eq!(ranges.len(), 1); + let interval = Interval { + chrom: String::from("chr1"), + start: ranges[0].0, + stop: ranges[0].1, + fields: LinearMap::new(), + }; + base_interval = Some(interval); + } else { + for se in ranges { + let interval = Interval { + chrom: String::from("chr1"), + start: se.0, + stop: se.1, + fields: LinearMap::new(), + }; + + intersections.push(Intersection { + interval: Arc::new(Position::Interval(interval)), + id: id, + }); + } + } + } + } + + let base_interval = base_interval.expect("No base interval found"); + + Intersections { + base_interval: Arc::new(Position::Interval(base_interval)), + overlapping: intersections, + } +} + +#[test] +fn test_parse() { + let input = "a: 1-10\nb: 3-6, 8-12"; + let intersections = parse_intersections(input); + + // Access the generated Intersections struct + assert_eq!(intersections.base_interval.start(), 1); + assert_eq!(intersections.base_interval.stop(), 10); + eprintln!("{:?}", intersections.overlapping); + assert_eq!(intersections.overlapping.len(), 2); + assert_eq!(intersections.overlapping[0].interval.start(), 3); + assert_eq!(intersections.overlapping[0].interval.stop(), 6); + assert_eq!(intersections.overlapping[1].interval.start(), 8); + assert_eq!(intersections.overlapping[1].interval.stop(), 12); +}