Skip to content

Commit

Permalink
feat(coverage): add html reporter (denoland#21495)
Browse files Browse the repository at this point in the history
Co-authored-by: Bartek Iwańczuk <[email protected]>
  • Loading branch information
kt3k and bartlomieju committed Dec 8, 2023
1 parent c5c5dea commit d68d1e2
Show file tree
Hide file tree
Showing 10 changed files with 996 additions and 14 deletions.
31 changes: 26 additions & 5 deletions cli/args/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,20 @@ pub struct CompletionsFlags {
pub buf: Box<[u8]>,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum CoverageType {
Pretty,
Lcov,
Html,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct CoverageFlags {
pub files: FileFlags,
pub output: Option<PathBuf>,
pub include: Vec<String>,
pub exclude: Vec<String>,
pub lcov: bool,
pub r#type: CoverageType,
}

#[derive(Clone, Debug, Eq, PartialEq)]
Expand Down Expand Up @@ -1397,6 +1404,14 @@ Generate html reports from lcov:
.require_equals(true)
.value_hint(ValueHint::FilePath),
)
.arg(
Arg::new("html")
.long("html")
.help(
"Output coverage report in HTML format in the given directory",
)
.action(ArgAction::SetTrue),
)
.arg(
Arg::new("files")
.num_args(1..)
Expand Down Expand Up @@ -3298,7 +3313,13 @@ fn coverage_parse(flags: &mut Flags, matches: &mut ArgMatches) {
Some(f) => f.collect(),
None => vec![],
};
let lcov = matches.get_flag("lcov");
let r#type = if matches.get_flag("lcov") {
CoverageType::Lcov
} else if matches.get_flag("html") {
CoverageType::Html
} else {
CoverageType::Pretty
};
let output = matches.remove_one::<PathBuf>("output");
flags.subcommand = DenoSubcommand::Coverage(CoverageFlags {
files: FileFlags {
Expand All @@ -3308,7 +3329,7 @@ fn coverage_parse(flags: &mut Flags, matches: &mut ArgMatches) {
output,
include,
exclude,
lcov,
r#type,
});
}

Expand Down Expand Up @@ -7867,7 +7888,7 @@ mod tests {
output: None,
include: vec![r"^file:".to_string()],
exclude: vec![r"test\.(js|mjs|ts|jsx|tsx)$".to_string()],
lcov: false,
r#type: CoverageType::Pretty
}),
..Flags::default()
}
Expand All @@ -7893,7 +7914,7 @@ mod tests {
},
include: vec![r"^file:".to_string()],
exclude: vec![r"test\.(js|mjs|ts|jsx|tsx)$".to_string()],
lcov: true,
r#type: CoverageType::Lcov,
output: Some(PathBuf::from("foo.lcov")),
}),
..Flags::default()
Expand Down
69 changes: 69 additions & 0 deletions cli/tests/integration/coverage_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,3 +504,72 @@ fn no_internal_node_code() {
assert_starts_with!(url, "file:");
}
}

#[test]
fn test_html_reporter() {
let context = TestContext::default();
let tempdir = context.temp_dir();
let tempdir = tempdir.path().join("cov");

let output = context
.new_command()
.args_vec(vec![
"test".to_string(),
"--quiet".to_string(),
format!("--coverage={}", tempdir),
"coverage/multisource".to_string(),
])
.run();

output.assert_exit_code(0);
output.skip_output_check();

let output = context
.new_command()
.args_vec(vec![
"coverage".to_string(),
"--html".to_string(),
format!("{}/", tempdir),
])
.run();

output.assert_exit_code(0);
output.assert_matches_text("HTML coverage report has been generated at [WILDCARD]/cov/html/index.html\n");

let index_html =
fs::read_to_string(tempdir.join("html").join("index.html")).unwrap();
assert!(index_html.contains("<h1>Coverage report for all files</h1>"));
assert!(index_html.contains("baz/"));
assert!(index_html.contains("href='baz/index.html'"));
assert!(index_html.contains("foo.ts"));
assert!(index_html.contains("href='foo.ts.html'"));
assert!(index_html.contains("bar.ts"));
assert!(index_html.contains("href='bar.ts.html'"));

let foo_ts_html =
fs::read_to_string(tempdir.join("html").join("foo.ts.html")).unwrap();
assert!(foo_ts_html.contains("<h1>Coverage report for foo.ts</h1>"));

let bar_ts_html =
fs::read_to_string(tempdir.join("html").join("bar.ts.html")).unwrap();
assert!(bar_ts_html.contains("<h1>Coverage report for bar.ts</h1>"));

let baz_index_html =
fs::read_to_string(tempdir.join("html").join("baz").join("index.html"))
.unwrap();
assert!(baz_index_html.contains("<h1>Coverage report for baz/</h1>"));
assert!(baz_index_html.contains("qux.ts"));
assert!(baz_index_html.contains("href='qux.ts.html'"));
assert!(baz_index_html.contains("quux.ts"));
assert!(baz_index_html.contains("href='quux.ts.html'"));

let baz_qux_ts_html =
fs::read_to_string(tempdir.join("html").join("baz").join("qux.ts.html"))
.unwrap();
assert!(baz_qux_ts_html.contains("<h1>Coverage report for baz/qux.ts</h1>"));

let baz_quux_ts_html =
fs::read_to_string(tempdir.join("html").join("baz").join("quux.ts.html"))
.unwrap();
assert!(baz_quux_ts_html.contains("<h1>Coverage report for baz/quux.ts</h1>"));
}
7 changes: 7 additions & 0 deletions cli/tests/testdata/coverage/multisource/bar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function bar(cond: boolean) {
if (cond) {
return 1;
} else {
return 2;
}
}
7 changes: 7 additions & 0 deletions cli/tests/testdata/coverage/multisource/baz/quux.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function quux(cond: boolean) {
if (cond) {
return 1;
} else {
return 2;
}
}
7 changes: 7 additions & 0 deletions cli/tests/testdata/coverage/multisource/baz/qux.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function qux(cond: boolean) {
if (cond) {
return 1;
} else {
return 2;
}
}
7 changes: 7 additions & 0 deletions cli/tests/testdata/coverage/multisource/foo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export function foo(cond: boolean) {
if (cond) {
return 1;
} else {
return 2;
}
}
20 changes: 20 additions & 0 deletions cli/tests/testdata/coverage/multisource/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { foo } from "./foo.ts";
import { bar } from "./bar.ts";
import { qux } from "./baz/qux.ts";
import { quux } from "./baz/quux.ts";

Deno.test("foo", () => {
foo(true);
});

Deno.test("bar", () => {
bar(false);
});

Deno.test("qux", () => {
qux(true);
});

Deno.test("quux", () => {
quux(false);
});

0 comments on commit d68d1e2

Please sign in to comment.