use lcov::filter::{FilterMap, LineNum}; use lcov::{Reader, Record, Report}; use std::collections::HashMap; use std::fs::File; use std::io::{self, BufRead, BufReader, Read, Write}; use std::iter::FromIterator; use std::path::{Path, PathBuf}; const FIXTURE_DIR: &str = "./tests/fixtures"; const FIXTURE_GLOB: &str = "./tests/fixtures/*.info"; type Error = Box; fn open_fixture

(file: P) -> Result>, Error> where P: AsRef, { Ok(Reader::open_file(Path::new(FIXTURE_DIR).join(file))?) } fn check_report_same(report1: Report, report2: Report) { assert_eq!(report1, report2); for (rec1, rec2) in report1.into_records().zip(report2.into_records()) { assert_eq!(rec1, rec2); } } #[test] fn is_identical_parse() { fn execute() -> Result<(), Error> { for entry in glob::glob(FIXTURE_GLOB)? { let file = File::open(entry?)?; let reader = BufReader::new(file); for line in reader.lines() { let line = line?; let rec = line.parse::()?; assert_eq!(line, rec.to_string()); } } Ok(()) } execute().expect("error"); } #[test] fn is_identical_reader() { fn execute() -> Result<(), Error> { for entry in glob::glob(FIXTURE_GLOB)? { let mut file = File::open(entry?)?; let mut input = String::new(); file.read_to_string(&mut input)?; let reader = Reader::new(BufReader::new(input.as_bytes())); let mut output = vec![]; for rec in reader { writeln!(output, "{}", rec?)?; } assert_eq!(input.as_bytes(), output.as_slice()); } Ok(()) } execute().expect("error"); } #[test] fn is_identical_report() { fn execute() -> Result<(), Error> { for entry in glob::glob(FIXTURE_GLOB)? { let reader = Reader::open_file(entry?)?; let records = reader.collect::, _>>()?; let report1 = Report::from_reader::<_, io::Error>(records.iter().cloned().map(Ok))?; let report2 = Report::from_reader::<_, io::Error>(report1.clone().into_records().map(Ok))?; check_report_same(report1, report2); } Ok(()) } execute().expect("error"); } #[test] fn merge_report() { fn execute() -> Result<(), Error> { for merged_file in &["report_checksum.info", "report.info"] { let merged_file = PathBuf::from(merged_file); let mut init_file = merged_file.clone(); init_file.set_extension("init.info"); let mut run_file = merged_file.clone(); run_file.set_extension("run.info"); let merged = open_fixture(merged_file)?; let init = open_fixture(init_file)?; let run = open_fixture(run_file)?; let report1 = Report::from_reader(merged)?; let mut report2 = Report::new(); report2.merge(Report::from_reader(init)?)?; report2.merge(Report::from_reader(run)?)?; check_report_same(report1, report2); } Ok(()) } execute().expect("error"); } #[test] fn line_filter() { fn execute() -> Result<(), Error> { let mut filter = HashMap::new(); filter.insert( PathBuf::from("/home/nksm/rhq/github.com/gifnksm/lcov/tests/fixtures/src/div.c"), LineNum::from_iter([3..4].iter().cloned()), ); filter.insert( PathBuf::from("/home/nksm/rhq/github.com/gifnksm/lcov/tests/fixtures/src/fizzbuzz.c"), LineNum::from_iter([3..7, 14..u32::max_value()].iter().cloned()), ); filter.insert( PathBuf::from("/home/nksm/rhq/github.com/gifnksm/lcov/tests/fixtures/src/main.c"), LineNum::from_iter([12..16, 25..31].iter().cloned()), ); let original = open_fixture("report.info")?; let mut original_report = Report::from_reader(original)?; original_report.sections.filter_map(|(key, mut value)| { filter.get(&key.source_file).and_then(|filter| { filter.apply(&mut value); if value.is_empty() { None } else { Some((key, value)) } }) }); let filtered = open_fixture("report.filtered.info")?; let filtered_report = Report::from_reader(filtered)?; check_report_same(original_report, filtered_report); Ok(()) } execute().expect("error"); }