Skip to content

Commit

Permalink
fix(coverage): don't type check (#13324)
Browse files Browse the repository at this point in the history
This commit changes "deno coverage" command not to type check.

Instead of relying on infrastructure for module loading in "deno run";
the code now directly reaches into cache for original and transpiled
sources. In case sources are not available the error is returned to the
user, suggesting to first run "deno test --coverage" command.
  • Loading branch information
bartlomieju authored and crowlKats committed Jan 12, 2022
1 parent 357ff7b commit d2456ec
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 34 deletions.
2 changes: 1 addition & 1 deletion cli/file_fetcher.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ impl FileFetcher {
/// Fetch cached remote file.
///
/// This is a recursive operation if source file has redirections.
fn fetch_cached(
pub(crate) fn fetch_cached(
&self,
specifier: &ModuleSpecifier,
redirect_limit: i64,
Expand Down
14 changes: 9 additions & 5 deletions cli/tests/integration/coverage_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ fn final_blankline() {
}

fn run_coverage_text(test_name: &str, extension: &str) {
let deno_dir = TempDir::new().expect("tempdir fail");
let tempdir = TempDir::new().expect("tempdir fail");
let tempdir = tempdir.path().join("cov");
let status = util::deno_cmd()

let status = util::deno_cmd_with_deno_dir(deno_dir.path())
.current_dir(util::testdata_path())
.arg("test")
.arg("--quiet")
Expand All @@ -36,17 +38,19 @@ fn run_coverage_text(test_name: &str, extension: &str) {

assert!(status.success());

let output = util::deno_cmd()
let output = util::deno_cmd_with_deno_dir(deno_dir.path())
.current_dir(util::testdata_path())
.arg("coverage")
.arg("--quiet")
.arg("--unstable")
.arg(format!("{}/", tempdir.to_str().unwrap()))
.stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::inherit())
.stderr(std::process::Stdio::piped())
.output()
.expect("failed to spawn coverage reporter");

// Verify there's no "Check" being printed
assert!(output.stderr.is_empty());

let actual =
util::strip_ansi_codes(std::str::from_utf8(&output.stdout).unwrap())
.to_string();
Expand All @@ -64,7 +68,7 @@ fn run_coverage_text(test_name: &str, extension: &str) {

assert!(output.status.success());

let output = util::deno_cmd()
let output = util::deno_cmd_with_deno_dir(deno_dir.path())
.current_dir(util::testdata_path())
.arg("coverage")
.arg("--quiet")
Expand Down
85 changes: 57 additions & 28 deletions cli/tools/coverage.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.

use crate::colors;
use crate::emit;
use crate::flags::CoverageFlags;
use crate::flags::Flags;
use crate::fs_util::collect_files;
Expand All @@ -11,11 +10,12 @@ use crate::tools::fmt::format_json;

use deno_ast::MediaType;
use deno_ast::ModuleSpecifier;
use deno_core::anyhow::anyhow;
use deno_core::anyhow::Context;
use deno_core::error::AnyError;
use deno_core::serde_json;
use deno_core::url::Url;
use deno_core::LocalInspectorSession;
use deno_runtime::permissions::Permissions;
use regex::Regex;
use serde::Deserialize;
use serde::Serialize;
Expand Down Expand Up @@ -643,40 +643,69 @@ pub async fn cover_files(
for script_coverage in script_coverages {
let module_specifier =
deno_core::resolve_url_or_path(&script_coverage.url)?;
ps.prepare_module_load(
vec![module_specifier.clone()],
false,
emit::TypeLib::UnstableDenoWindow,
Permissions::allow_all(),
Permissions::allow_all(),
false,
)
.await?;

let module_source = ps.load(module_specifier.clone(), None, false)?;
let script_source = &module_source.code;

let maybe_file = if module_specifier.scheme() == "file" {
ps.file_fetcher.get_source(&module_specifier)
} else {
ps.file_fetcher
.fetch_cached(&module_specifier, 10)
.with_context(|| {
format!("Failed to fetch \"{}\" from cache.", module_specifier)
})?
};
let file = maybe_file.ok_or_else(|| {
anyhow!("Failed to fetch \"{}\" from cache.
Before generating coverage report, run `deno test --coverage` to ensure consistent state.",
module_specifier
)
})?;

// Check if file was transpiled
let transpiled_source = match file.media_type {
MediaType::JavaScript
| MediaType::Unknown
| MediaType::Cjs
| MediaType::Mjs
| MediaType::Json => file.source.as_ref().clone(),
MediaType::Dts | MediaType::Dmts | MediaType::Dcts => "".to_string(),
MediaType::TypeScript
| MediaType::Jsx
| MediaType::Mts
| MediaType::Cts
| MediaType::Tsx => {
let emit_path = ps
.dir
.gen_cache
.get_cache_filename_with_extension(&file.specifier, "js")
.unwrap_or_else(|| {
unreachable!("Unable to get cache filename: {}", &file.specifier)
});
match ps.dir.gen_cache.get(&emit_path) {
Ok(b) => String::from_utf8(b).unwrap(),
Err(_) => {
return Err(anyhow!(
"Missing transpiled source code for: \"{}\".
Before generating coverage report, run `deno test --coverage` to ensure consistent state.",
file.specifier,
))
}
}
}
MediaType::Wasm | MediaType::TsBuildInfo | MediaType::SourceMap => {
unreachable!()
}
};

let original_source = &file.source;
let maybe_source_map = ps.get_source_map(&script_coverage.url);
let maybe_cached_source = ps
.file_fetcher
.get_source(&module_specifier)
.map(|f| f.source);

let coverage_report = generate_coverage_report(
&script_coverage,
script_source,
&transpiled_source,
&maybe_source_map,
);

let file_text = if let Some(original_source) =
maybe_source_map.and(maybe_cached_source.as_ref())
{
original_source.as_str()
} else {
script_source
};

reporter.report(&coverage_report, file_text);
reporter.report(&coverage_report, original_source);
}

reporter.done();
Expand Down

0 comments on commit d2456ec

Please sign in to comment.