diff --git a/cli/tests/integration_tests.rs b/cli/tests/integration_tests.rs index 31d6342745..cd222f0b4e 100644 --- a/cli/tests/integration_tests.rs +++ b/cli/tests/integration_tests.rs @@ -3316,6 +3316,12 @@ itest!(deno_test_coverage { exit_code: 0, }); +itest!(deno_test_branch_coverage { + args: "test --coverage --unstable test_branch_coverage.ts", + output: "test_branch_coverage.out", + exit_code: 0, +}); + itest!(deno_test_coverage_explicit { args: "test --coverage=.test_coverage --unstable test_coverage.ts", output: "test_coverage.out", diff --git a/cli/tests/subdir/branch.ts b/cli/tests/subdir/branch.ts new file mode 100644 index 0000000000..bb7aec9ebe --- /dev/null +++ b/cli/tests/subdir/branch.ts @@ -0,0 +1,7 @@ +export function branch(condition: boolean): boolean { + if (condition) { + return true; + } else { + return false; + } +} diff --git a/cli/tests/test_branch_coverage.out b/cli/tests/test_branch_coverage.out new file mode 100644 index 0000000000..69e81f8818 --- /dev/null +++ b/cli/tests/test_branch_coverage.out @@ -0,0 +1,10 @@ +Check [WILDCARD]/tests/$deno$test.ts +running 1 tests +test branch ... ok ([WILDCARD]) + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ([WILDCARD]) + +cover [WILDCARD]/tests/subdir/branch.ts ... 66.667% (6/9) + 5 | else { + 6 | return false; + 7 | } diff --git a/cli/tests/test_branch_coverage.ts b/cli/tests/test_branch_coverage.ts new file mode 100644 index 0000000000..7e3adb737d --- /dev/null +++ b/cli/tests/test_branch_coverage.ts @@ -0,0 +1,5 @@ +import { branch } from "./subdir/branch.ts"; + +Deno.test("branch", function () { + branch(true); +}); diff --git a/cli/tools/coverage.rs b/cli/tools/coverage.rs index 2b030333ca..020d358bad 100644 --- a/cli/tools/coverage.rs +++ b/cli/tools/coverage.rs @@ -127,7 +127,7 @@ impl PrettyCoverageReporter { script_coverage: &ScriptCoverage, script_source: &str, ) { - let lines = script_source.lines().collect::>(); + let lines = script_source.split('\n').collect::>(); let mut covered_lines: Vec = Vec::new(); let mut uncovered_lines: Vec = Vec::new(); @@ -137,27 +137,47 @@ impl PrettyCoverageReporter { let line_end_offset = line_start_offset + line.len(); let mut count = 0; + + // Count the hits of ranges that include the entire line which will always be at-least one + // as long as the code has been evaluated. for function in &script_coverage.functions { for range in &function.ranges { if range.start_offset <= line_start_offset && range.end_offset >= line_end_offset { - if range.count == 0 { - count = 0; - break; - } - count += range.count; } } - - line_start_offset = line_end_offset; } + + // Reset the count if any block intersects with the current line has a count of + // zero. + // + // We check for intersection instead of inclusion here because a block may be anywhere + // inside a line. + for function in &script_coverage.functions { + for range in &function.ranges { + if range.count > 0 { + continue; + } + + if (range.start_offset < line_start_offset + && range.end_offset > line_start_offset) + || (range.start_offset < line_end_offset + && range.end_offset > line_end_offset) + { + count = 0; + } + } + } + if count > 0 { covered_lines.push(index); } else { uncovered_lines.push(index); } + + line_start_offset += line.len() + 1; } if !self.quiet {