fix(cli/coverage): print lines with no coverage to stdout (#7640)

This commit is contained in:
Casper Beyer 2020-09-24 02:12:24 +08:00 committed by GitHub
parent e1b61d6794
commit 6254bd41b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 71 additions and 63 deletions

View file

@ -240,35 +240,23 @@ pub struct GetScriptSourceResult {
} }
pub struct PrettyCoverageReporter { pub struct PrettyCoverageReporter {
coverages: Vec<Coverage>, quiet: bool,
} }
// TODO(caspervonb) add support for lcov output (see geninfo(1) for format spec). // TODO(caspervonb) add support for lcov output (see geninfo(1) for format spec).
impl PrettyCoverageReporter { impl PrettyCoverageReporter {
pub fn new(coverages: Vec<Coverage>) -> PrettyCoverageReporter { pub fn new(quiet: bool) -> PrettyCoverageReporter {
PrettyCoverageReporter { coverages } PrettyCoverageReporter { quiet }
} }
pub fn get_report(&self) -> String { pub fn visit_coverage(&mut self, coverage: &Coverage) {
let mut report = String::from("test coverage:\n"); let lines = coverage.script_source.lines().collect::<Vec<_>>();
for coverage in &self.coverages { let mut covered_lines: Vec<usize> = Vec::new();
if let Some(coverage_report) = Self::get_coverage_report(coverage) { let mut uncovered_lines: Vec<usize> = Vec::new();
report.push_str(&format!("{}\n", coverage_report))
}
}
report let mut line_start_offset = 0;
} for (index, line) in lines.iter().enumerate() {
fn get_coverage_report(coverage: &Coverage) -> Option<String> {
let mut total_lines = 0;
let mut covered_lines = 0;
let mut line_offset = 0;
for line in coverage.script_source.lines() {
let line_start_offset = line_offset;
let line_end_offset = line_start_offset + line.len(); let line_end_offset = line_start_offset + line.len();
let mut count = 0; let mut count = 0;
@ -277,47 +265,53 @@ impl PrettyCoverageReporter {
if range.start_offset <= line_start_offset if range.start_offset <= line_start_offset
&& range.end_offset >= line_end_offset && range.end_offset >= line_end_offset
{ {
count += range.count;
if range.count == 0 { if range.count == 0 {
count = 0; count = 0;
break; break;
} }
count += range.count;
} }
} }
}
line_start_offset = line_end_offset;
}
if count > 0 { if count > 0 {
covered_lines += 1; covered_lines.push(index);
} else {
uncovered_lines.push(index);
} }
total_lines += 1;
line_offset += line.len();
} }
let line_ratio = covered_lines as f32 / total_lines as f32; if !self.quiet {
let line_coverage = format!("{:.3}%", line_ratio * 100.0); print!("cover {} ... ", coverage.script_coverage.url);
let line = if line_ratio >= 0.9 { let line_coverage_ratio = covered_lines.len() as f32 / lines.len() as f32;
format!( let line_coverage = format!(
"{} {}", "{:.3}% ({}/{})",
coverage.script_coverage.url, line_coverage_ratio * 100.0,
colors::green(&line_coverage) covered_lines.len(),
) lines.len()
} else if line_ratio >= 0.75 { );
format!(
"{} {}",
coverage.script_coverage.url,
colors::yellow(&line_coverage)
)
} else {
format!(
"{} {}",
coverage.script_coverage.url,
colors::red(&line_coverage)
)
};
Some(line) if line_coverage_ratio >= 0.9 {
println!("{}", colors::green(&line_coverage));
} else if line_coverage_ratio >= 0.75 {
println!("{}", colors::yellow(&line_coverage));
} else {
println!("{}", colors::red(&line_coverage));
}
for line_index in uncovered_lines {
println!(
"{:width$}{} {}",
line_index + 1,
colors::gray(" |"),
colors::red(&lines[line_index]),
width = 4
);
}
}
} }
} }

View file

@ -609,19 +609,16 @@ async fn test_command(
(&mut *worker).await?; (&mut *worker).await?;
if let Some(coverage_collector) = maybe_coverage_collector.as_mut() { if let Some(coverage_collector) = maybe_coverage_collector.as_mut() {
let script_coverage = coverage_collector.collect().await?; let coverages = coverage_collector.collect().await?;
coverage_collector.stop_collecting().await?; coverage_collector.stop_collecting().await?;
let filtered_coverage = coverage::filter_script_coverages( let filtered_coverages =
script_coverage, coverage::filter_script_coverages(coverages, test_file_url, test_modules);
test_file_url,
test_modules,
);
let pretty_coverage_reporter = let mut coverage_reporter = PrettyCoverageReporter::new(quiet);
PrettyCoverageReporter::new(filtered_coverage); for coverage in filtered_coverages {
let report = pretty_coverage_reporter.get_report(); coverage_reporter.visit_coverage(&coverage);
print!("{}", report) }
} }
Ok(()) Ok(())

View file

@ -4,7 +4,24 @@ test returnsHiSuccess ... ok ([WILDCARD])
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ([WILDCARD]) test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ([WILDCARD])
test coverage: cover [WILDCARD]/cli/tests/subdir/mod1.ts ... 35.714% (5/14)
file://[WILDCARD]/cli/tests/subdir/mod1.ts 57.143% 5 | export function returnsFoo2() {
file://[WILDCARD]/cli/tests/subdir/subdir2/mod2.ts 50.000% 6 | return returnsFoo();
file://[WILDCARD]/cli/tests/subdir/print_hello.ts 50.000% 7 | }
8 | export function printHello3() {
9 | printHello2();
10 | }
11 | export function throwsError() {
12 | throw Error("exception from mod1");
13 | }
cover [WILDCARD]/cli/tests/subdir/subdir2/mod2.ts ... 25.000% (2/8)
2 | export function returnsFoo() {
3 | return "Foo";
4 | }
5 | export function printHello2() {
6 | printHello();
7 | }
cover [WILDCARD]/cli/tests/subdir/print_hello.ts ... 25.000% (1/4)
1 | export function printHello() {
2 | console.log("Hello");
3 | }