1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-25 15:29:32 -05:00

feat(unstable): Add deno test --no-run (#8093)

This commit adds new flag to "deno test" subcommand
called "--no-run" that allows to preload, cache an type
check.
This commit is contained in:
Nayeem Rahman 2020-11-22 13:06:51 +00:00 committed by GitHub
parent 686a17fc07
commit 14877f7fe2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 98 additions and 155 deletions

View file

@ -66,6 +66,7 @@ pub enum DenoSubcommand {
script: String, script: String,
}, },
Test { Test {
no_run: bool,
fail_fast: bool, fail_fast: bool,
quiet: bool, quiet: bool,
allow_none: bool, allow_none: bool,
@ -572,8 +573,9 @@ fn run_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
fn test_parse(flags: &mut Flags, matches: &clap::ArgMatches) { fn test_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
runtime_args_parse(flags, matches, true); runtime_args_parse(flags, matches, true);
let no_run = matches.is_present("no-run");
let failfast = matches.is_present("failfast"); let failfast = matches.is_present("failfast");
let allow_none = matches.is_present("allow_none"); let allow_none = matches.is_present("allow-none");
let quiet = matches.is_present("quiet"); let quiet = matches.is_present("quiet");
let filter = matches.value_of("filter").map(String::from); let filter = matches.value_of("filter").map(String::from);
let coverage = matches.is_present("coverage"); let coverage = matches.is_present("coverage");
@ -606,6 +608,7 @@ fn test_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
}; };
flags.subcommand = DenoSubcommand::Test { flags.subcommand = DenoSubcommand::Test {
no_run,
fail_fast: failfast, fail_fast: failfast,
quiet, quiet,
include, include,
@ -1147,6 +1150,13 @@ Deno allows specifying the filename '-' to read the file from stdin.
fn test_subcommand<'a, 'b>() -> App<'a, 'b> { fn test_subcommand<'a, 'b>() -> App<'a, 'b> {
runtime_args(SubCommand::with_name("test"), true) runtime_args(SubCommand::with_name("test"), true)
.setting(AppSettings::TrailingVarArg) .setting(AppSettings::TrailingVarArg)
.arg(
Arg::with_name("no-run")
.long("no-run")
.help("Cache test modules, but don't run tests")
.takes_value(false)
.requires("unstable"),
)
.arg( .arg(
Arg::with_name("failfast") Arg::with_name("failfast")
.long("failfast") .long("failfast")
@ -1154,7 +1164,7 @@ fn test_subcommand<'a, 'b>() -> App<'a, 'b> {
.takes_value(false), .takes_value(false),
) )
.arg( .arg(
Arg::with_name("allow_none") Arg::with_name("allow-none")
.long("allow-none") .long("allow-none")
.help("Don't return error code if no test files are found") .help("Don't return error code if no test files are found")
.takes_value(false), .takes_value(false),
@ -2838,109 +2848,23 @@ mod tests {
} }
#[test] #[test]
fn test_with_allow_net() { fn test_with_flags() {
let r = flags_from_vec_safe(svec![ #[rustfmt::skip]
"deno", let r = flags_from_vec_safe(svec!["deno", "test", "--unstable", "--no-run", "--filter", "- foo", "--coverage", "--allow-net", "--allow-none", "dir1/", "dir2/", "--", "arg1", "arg2"]);
"test",
"--allow-net",
"--allow-none",
"dir1/",
"dir2/"
]);
assert_eq!( assert_eq!(
r.unwrap(), r.unwrap(),
Flags { Flags {
subcommand: DenoSubcommand::Test { subcommand: DenoSubcommand::Test {
no_run: true,
fail_fast: false, fail_fast: false,
filter: None, filter: Some("- foo".to_string()),
allow_none: true, allow_none: true,
quiet: false, quiet: false,
include: Some(svec!["dir1/", "dir2/"]), include: Some(svec!["dir1/", "dir2/"]),
}, },
allow_net: true,
..Flags::default()
}
);
}
#[test]
fn test_filter() {
let r = flags_from_vec_safe(svec!["deno", "test", "--filter=foo", "dir1"]);
assert_eq!(
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Test {
fail_fast: false,
allow_none: false,
quiet: false,
filter: Some("foo".to_string()),
include: Some(svec!["dir1"]),
},
..Flags::default()
}
);
}
#[test]
fn test_filter_leading_hyphen() {
let r =
flags_from_vec_safe(svec!["deno", "test", "--filter", "- foo", "dir1"]);
assert_eq!(
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Test {
fail_fast: false,
allow_none: false,
quiet: false,
filter: Some("- foo".to_string()),
include: Some(svec!["dir1"]),
},
..Flags::default()
}
);
}
#[test]
fn test_coverage() {
let r = flags_from_vec_safe(svec![
"deno",
"test",
"--unstable",
"--coverage",
"dir1"
]);
assert_eq!(
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Test {
fail_fast: false,
allow_none: false,
quiet: false,
filter: None,
include: Some(svec!["dir1"]),
},
coverage: true,
unstable: true, unstable: true,
..Flags::default() coverage: true,
} allow_net: true,
);
}
#[test]
fn test_double_hyphen() {
let r = flags_from_vec_safe(svec![
"deno", "test", "test.ts", "--", "arg1", "arg2"
]);
assert_eq!(
r.unwrap(),
Flags {
subcommand: DenoSubcommand::Test {
fail_fast: false,
allow_none: false,
quiet: false,
filter: None,
include: Some(svec!["test.ts"]),
},
argv: svec!["arg1", "arg2"], argv: svec!["arg1", "arg2"],
..Flags::default() ..Flags::default()
} }

View file

@ -60,7 +60,6 @@ use deno_core::futures::future::FutureExt;
use deno_core::futures::Future; use deno_core::futures::Future;
use deno_core::serde_json; use deno_core::serde_json;
use deno_core::serde_json::json; use deno_core::serde_json::json;
use deno_core::url::Url;
use deno_core::v8_set_flags; use deno_core::v8_set_flags;
use deno_core::ModuleSpecifier; use deno_core::ModuleSpecifier;
use deno_doc as doc; use deno_doc as doc;
@ -625,6 +624,7 @@ async fn run_command(flags: Flags, script: String) -> Result<(), AnyError> {
async fn test_command( async fn test_command(
flags: Flags, flags: Flags,
include: Option<Vec<String>>, include: Option<Vec<String>>,
no_run: bool,
fail_fast: bool, fail_fast: bool,
quiet: bool, quiet: bool,
allow_none: bool, allow_none: bool,
@ -644,32 +644,45 @@ async fn test_command(
} }
return Ok(()); return Ok(());
} }
let main_module = ModuleSpecifier::resolve_path("$deno$test.ts")?;
let test_file_path = cwd.join("$deno$test.ts");
let test_file_url =
Url::from_file_path(&test_file_path).expect("Should be valid file url");
let test_file = tools::test_runner::render_test_file(
test_modules.clone(),
fail_fast,
quiet,
filter,
);
let main_module =
ModuleSpecifier::resolve_url(&test_file_url.to_string()).unwrap();
let mut worker =
MainWorker::new(&program_state, main_module.clone(), permissions);
// Create a dummy source file. // Create a dummy source file.
let source_file = File { let source_file = File {
local: test_file_url.to_file_path().unwrap(), local: main_module.as_url().to_file_path().unwrap(),
maybe_types: None, maybe_types: None,
media_type: MediaType::TypeScript, media_type: MediaType::TypeScript,
source: test_file.clone(), source: tools::test_runner::render_test_file(
specifier: ModuleSpecifier::from(test_file_url.clone()), test_modules.clone(),
fail_fast,
quiet,
filter,
),
specifier: main_module.clone(),
}; };
// Save our fake file into file fetcher cache // Save our fake file into file fetcher cache
// to allow module access by TS compiler // to allow module access by TS compiler
program_state.file_fetcher.insert_cached(source_file); program_state.file_fetcher.insert_cached(source_file);
if no_run {
let lib = if flags.unstable {
module_graph::TypeLib::UnstableDenoWindow
} else {
module_graph::TypeLib::DenoWindow
};
program_state
.prepare_module_load(
main_module.clone(),
lib,
Permissions::allow_all(),
false,
program_state.maybe_import_map.clone(),
)
.await?;
return Ok(());
}
let mut worker =
MainWorker::new(&program_state, main_module.clone(), permissions);
let mut maybe_coverage_collector = if flags.coverage { let mut maybe_coverage_collector = if flags.coverage {
let session = worker.create_inspector_session(); let session = worker.create_inspector_session();
let mut coverage_collector = let mut coverage_collector =
@ -694,7 +707,7 @@ async fn test_command(
let filtered_coverages = tools::coverage::filter_script_coverages( let filtered_coverages = tools::coverage::filter_script_coverages(
coverages, coverages,
test_file_url, main_module.as_url().clone(),
test_modules, test_modules,
); );
@ -815,13 +828,16 @@ pub fn main() {
DenoSubcommand::Repl => run_repl(flags).boxed_local(), DenoSubcommand::Repl => run_repl(flags).boxed_local(),
DenoSubcommand::Run { script } => run_command(flags, script).boxed_local(), DenoSubcommand::Run { script } => run_command(flags, script).boxed_local(),
DenoSubcommand::Test { DenoSubcommand::Test {
no_run,
fail_fast, fail_fast,
quiet, quiet,
include, include,
allow_none, allow_none,
filter, filter,
} => test_command(flags, include, fail_fast, quiet, allow_none, filter) } => {
.boxed_local(), test_command(flags, include, no_run, fail_fast, quiet, allow_none, filter)
.boxed_local()
}
DenoSubcommand::Completions { buf } => { DenoSubcommand::Completions { buf } => {
if let Err(e) = write_to_stdout_ignore_sigpipe(&buf) { if let Err(e) = write_to_stdout_ignore_sigpipe(&buf) {
eprintln!("{}", e); eprintln!("{}", e);

View file

@ -294,46 +294,38 @@ fn serialize_worker_event(event: WorkerEvent) -> Value {
match event { match event {
WorkerEvent::Message(buf) => json!({ "type": "msg", "data": buf }), WorkerEvent::Message(buf) => json!({ "type": "msg", "data": buf }),
WorkerEvent::TerminalError(error) => match error.downcast::<JsError>() { WorkerEvent::TerminalError(error) => match error.downcast::<JsError>() {
Ok(js_error) => { Ok(js_error) => json!({
json!({ "type": "terminalError",
"type": "terminalError", "error": {
"error": { "message": js_error.message,
"message": js_error.message, "fileName": js_error.script_resource_name,
"fileName": js_error.script_resource_name, "lineNumber": js_error.line_number,
"lineNumber": js_error.line_number, "columnNumber": js_error.start_column,
"columnNumber": js_error.start_column, }
} }),
}) Err(error) => json!({
} "type": "terminalError",
Err(error) => { "error": {
json!({ "message": error.to_string(),
"type": "terminalError", }
"error": { }),
"message": error.to_string(),
}
})
}
}, },
WorkerEvent::Error(error) => match error.downcast::<JsError>() { WorkerEvent::Error(error) => match error.downcast::<JsError>() {
Ok(js_error) => { Ok(js_error) => json!({
json!({ "type": "error",
"type": "error", "error": {
"error": { "message": js_error.message,
"message": js_error.message, "fileName": js_error.script_resource_name,
"fileName": js_error.script_resource_name, "lineNumber": js_error.line_number,
"lineNumber": js_error.line_number, "columnNumber": js_error.start_column,
"columnNumber": js_error.start_column, }
} }),
}) Err(error) => json!({
} "type": "error",
Err(error) => { "error": {
json!({ "message": error.to_string(),
"type": "error", }
"error": { }),
"message": error.to_string(),
}
})
}
}, },
} }
} }

View file

@ -0,0 +1,4 @@
[WILDCARD]error: TS2322 [ERROR]: Type 'number' is not assignable to type 'string'.
const a: string = 1;
^
at [WILDCARD]foo_test.ts[WILDCARD]

View file

@ -2185,6 +2185,12 @@ fn _066_prompt() {
util::test_pty(args, output, input); util::test_pty(args, output, input);
} }
itest!(_067_test_no_run_type_error {
args: "test --unstable --no-run test_type_error",
output: "067_test_no_run_type_error.out",
exit_code: 1,
});
itest!(_073_worker_error { itest!(_073_worker_error {
args: "run -A 073_worker_error.ts", args: "run -A 073_worker_error.ts",
output: "073_worker_error.ts.out", output: "073_worker_error.ts.out",

View file

@ -0,0 +1 @@
const a: string = 1;

View file

@ -149,7 +149,7 @@ impl ModuleSpecifier {
/// Converts a string representing a relative or absolute path into a /// Converts a string representing a relative or absolute path into a
/// ModuleSpecifier. A relative path is considered relative to the current /// ModuleSpecifier. A relative path is considered relative to the current
/// working directory. /// working directory.
fn resolve_path( pub fn resolve_path(
path_str: &str, path_str: &str,
) -> Result<ModuleSpecifier, ModuleResolutionError> { ) -> Result<ModuleSpecifier, ModuleResolutionError> {
let path = current_dir().unwrap().join(path_str); let path = current_dir().unwrap().join(path_str);