mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 09:31:22 -05:00
feat(test): Add support for "deno test --compat" (#13235)
This commit is contained in:
parent
1adf8ee545
commit
39a6c94071
16 changed files with 220 additions and 36 deletions
|
@ -102,15 +102,17 @@ fn try_resolve_builtin_module(specifier: &str) -> Option<Url> {
|
|||
|
||||
pub(crate) fn load_cjs_module(
|
||||
js_runtime: &mut JsRuntime,
|
||||
main_module: &str,
|
||||
module: &str,
|
||||
main: bool,
|
||||
) -> Result<(), AnyError> {
|
||||
let source_code = &format!(
|
||||
r#"(async function loadCjsModule(main) {{
|
||||
const Module = await import("{}");
|
||||
Module.default._load(main, null, true);
|
||||
}})('{}');"#,
|
||||
MODULE_URL_STR.as_str(),
|
||||
escape_for_single_quote_string(main_module),
|
||||
r#"(async function loadCjsModule(module) {{
|
||||
const Module = await import("{module_loader}");
|
||||
Module.default._load(module, null, {main});
|
||||
}})('{module}');"#,
|
||||
module_loader = MODULE_URL_STR.as_str(),
|
||||
main = main,
|
||||
module = escape_for_single_quote_string(module),
|
||||
);
|
||||
|
||||
js_runtime.execute_script(&located_script_name!(), source_code)?;
|
||||
|
|
|
@ -1174,6 +1174,7 @@ async fn run_command(
|
|||
compat::load_cjs_module(
|
||||
&mut worker.js_runtime,
|
||||
&main_module.to_file_path().unwrap().display().to_string(),
|
||||
true,
|
||||
)?;
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -52,6 +52,44 @@ itest!(import_esm_from_cjs {
|
|||
output_str: Some("function\n"),
|
||||
});
|
||||
|
||||
itest!(test_runner_cjs {
|
||||
args: "test --compat --unstable -A --quiet compat/test_runner/cjs.js",
|
||||
exit_code: 1,
|
||||
output: "compat/test_runner/cjs.out",
|
||||
});
|
||||
|
||||
itest!(test_runner_esm {
|
||||
args: "test --compat --unstable -A --quiet compat/test_runner/esm.mjs",
|
||||
exit_code: 1,
|
||||
output: "compat/test_runner/esm.out",
|
||||
});
|
||||
|
||||
// Top level assertion test mostly just make sure that the test runner finishes correctly on compat mode
|
||||
// when there is no tests
|
||||
itest!(top_level_assertion_cjs {
|
||||
args: "test --compat --unstable -A --quiet compat/test_runner/top_level_assertion_cjs.js",
|
||||
exit_code: 0,
|
||||
output: "compat/test_runner/top_level_assertion_cjs.out",
|
||||
});
|
||||
|
||||
itest!(top_level_assertion_esm {
|
||||
args: "test --compat --unstable -A --quiet compat/test_runner/top_level_assertion_esm.mjs",
|
||||
exit_code: 0,
|
||||
output: "compat/test_runner/top_level_assertion_esm.out",
|
||||
});
|
||||
|
||||
itest!(top_level_fail_cjs {
|
||||
args: "test --compat --unstable -A --quiet compat/test_runner/top_level_fail_cjs.js",
|
||||
exit_code: 1,
|
||||
output: "compat/test_runner/top_level_fail_cjs.out",
|
||||
});
|
||||
|
||||
itest!(top_level_fail_esm {
|
||||
args: "test --compat --unstable -A --quiet compat/test_runner/top_level_fail_esm.mjs",
|
||||
exit_code: 1,
|
||||
output: "compat/test_runner/top_level_fail_esm.out",
|
||||
});
|
||||
|
||||
#[test]
|
||||
fn globals_in_repl() {
|
||||
let (out, _err) = util::run_and_collect_output_with_args(
|
||||
|
|
9
cli/tests/testdata/compat/test_runner/cjs.js
vendored
Normal file
9
cli/tests/testdata/compat/test_runner/cjs.js
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
const { strictEqual } = require("assert");
|
||||
|
||||
Deno.test("Correct assertion", () => {
|
||||
strictEqual(20, 20);
|
||||
});
|
||||
|
||||
Deno.test("Failed assertion", () => {
|
||||
strictEqual(10, 20);
|
||||
});
|
25
cli/tests/testdata/compat/test_runner/cjs.out
vendored
Normal file
25
cli/tests/testdata/compat/test_runner/cjs.out
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
running 2 tests from [WILDCARD]
|
||||
test Correct assertion ... ok ([WILDCARD])
|
||||
test Failed assertion ... FAILED ([WILDCARD])
|
||||
|
||||
failures:
|
||||
|
||||
Failed assertion
|
||||
AssertionError [ERR_ASSERTION]: Values are not strictly equal:
|
||||
|
||||
|
||||
[Diff] Actual / Expected
|
||||
|
||||
|
||||
- 10
|
||||
+ 20
|
||||
|
||||
[WILDCARD]
|
||||
|
||||
failures:
|
||||
|
||||
[WILDCARD]Failed assertion
|
||||
|
||||
test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out ([WILDCARD])
|
||||
|
||||
error: Test failed
|
9
cli/tests/testdata/compat/test_runner/esm.mjs
vendored
Normal file
9
cli/tests/testdata/compat/test_runner/esm.mjs
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
import { strictEqual } from "assert";
|
||||
|
||||
Deno.test("Correct assertion", () => {
|
||||
strictEqual(20, 20);
|
||||
});
|
||||
|
||||
Deno.test("Failed assertion", () => {
|
||||
strictEqual(10, 20);
|
||||
});
|
25
cli/tests/testdata/compat/test_runner/esm.out
vendored
Normal file
25
cli/tests/testdata/compat/test_runner/esm.out
vendored
Normal file
|
@ -0,0 +1,25 @@
|
|||
running 2 tests from [WILDCARD]
|
||||
test Correct assertion ... ok ([WILDCARD])
|
||||
test Failed assertion ... FAILED ([WILDCARD])
|
||||
|
||||
failures:
|
||||
|
||||
Failed assertion
|
||||
AssertionError [ERR_ASSERTION]: Values are not strictly equal:
|
||||
|
||||
|
||||
[Diff] Actual / Expected
|
||||
|
||||
|
||||
- 10
|
||||
+ 20
|
||||
|
||||
[WILDCARD]
|
||||
|
||||
failures:
|
||||
|
||||
[WILDCARD]Failed assertion
|
||||
|
||||
test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out ([WILDCARD])
|
||||
|
||||
error: Test failed
|
4
cli/tests/testdata/compat/test_runner/top_level_assertion_cjs.js
vendored
Normal file
4
cli/tests/testdata/compat/test_runner/top_level_assertion_cjs.js
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
const { notStrictEqual, strictEqual } = require("assert");
|
||||
|
||||
notStrictEqual(require.main, module, "The module was loaded as a main module");
|
||||
strictEqual(20, 20);
|
4
cli/tests/testdata/compat/test_runner/top_level_assertion_cjs.out
vendored
Normal file
4
cli/tests/testdata/compat/test_runner/top_level_assertion_cjs.out
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
running 0 tests from [WILDCARD]
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ([WILDCARD])
|
||||
|
4
cli/tests/testdata/compat/test_runner/top_level_assertion_esm.mjs
vendored
Normal file
4
cli/tests/testdata/compat/test_runner/top_level_assertion_esm.mjs
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
import assert, { strictEqual } from "assert";
|
||||
|
||||
assert(!import.meta.main, "The module was loaded as a main module");
|
||||
strictEqual(20, 20);
|
4
cli/tests/testdata/compat/test_runner/top_level_assertion_esm.out
vendored
Normal file
4
cli/tests/testdata/compat/test_runner/top_level_assertion_esm.out
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
running 0 tests from [WILDCARD]
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ([WILDCARD])
|
||||
|
4
cli/tests/testdata/compat/test_runner/top_level_fail_cjs.js
vendored
Normal file
4
cli/tests/testdata/compat/test_runner/top_level_fail_cjs.js
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
const { notStrictEqual, strictEqual } = require("assert");
|
||||
|
||||
notStrictEqual(require.main, module, "The module was loaded as a main module");
|
||||
strictEqual(10, 20);
|
13
cli/tests/testdata/compat/test_runner/top_level_fail_cjs.out
vendored
Normal file
13
cli/tests/testdata/compat/test_runner/top_level_fail_cjs.out
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ([WILDCARD])
|
||||
|
||||
error: Uncaught (in promise) AssertionError: Values are not strictly equal:
|
||||
|
||||
|
||||
[Diff] Actual / Expected
|
||||
|
||||
|
||||
- 10
|
||||
+ 20
|
||||
|
||||
[WILDCARD]
|
4
cli/tests/testdata/compat/test_runner/top_level_fail_esm.mjs
vendored
Normal file
4
cli/tests/testdata/compat/test_runner/top_level_fail_esm.mjs
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
import assert, { strictEqual } from "assert";
|
||||
|
||||
assert(!import.meta.main, "The module was loaded as a main module");
|
||||
strictEqual(10, 20);
|
13
cli/tests/testdata/compat/test_runner/top_level_fail_esm.out
vendored
Normal file
13
cli/tests/testdata/compat/test_runner/top_level_fail_esm.out
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out ([WILDCARD])
|
||||
|
||||
error: Uncaught AssertionError: Values are not strictly equal:
|
||||
|
||||
|
||||
[Diff] Actual / Expected
|
||||
|
||||
|
||||
- 10
|
||||
+ 20
|
||||
|
||||
[WILDCARD]
|
|
@ -4,6 +4,7 @@ use crate::ast::Location;
|
|||
use crate::cache;
|
||||
use crate::cache::CacherLoader;
|
||||
use crate::colors;
|
||||
use crate::compat;
|
||||
use crate::create_main_worker;
|
||||
use crate::emit;
|
||||
use crate::file_fetcher::File;
|
||||
|
@ -150,6 +151,15 @@ pub struct TestSummary {
|
|||
pub failures: Vec<(TestDescription, String)>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
struct TestSpecifierOptions {
|
||||
compat_mode: bool,
|
||||
concurrent_jobs: NonZeroUsize,
|
||||
fail_fast: Option<NonZeroUsize>,
|
||||
filter: Option<String>,
|
||||
shuffle: Option<u64>,
|
||||
}
|
||||
|
||||
impl TestSummary {
|
||||
fn new() -> TestSummary {
|
||||
TestSummary {
|
||||
|
@ -448,9 +458,8 @@ async fn test_specifier(
|
|||
permissions: Permissions,
|
||||
specifier: ModuleSpecifier,
|
||||
mode: TestMode,
|
||||
filter: Option<String>,
|
||||
shuffle: Option<u64>,
|
||||
channel: Sender<TestEvent>,
|
||||
options: TestSpecifierOptions,
|
||||
) -> Result<(), AnyError> {
|
||||
let mut worker = create_main_worker(
|
||||
&ps,
|
||||
|
@ -477,8 +486,26 @@ async fn test_specifier(
|
|||
// We only execute the specifier as a module if it is tagged with TestMode::Module or
|
||||
// TestMode::Both.
|
||||
if mode != TestMode::Documentation {
|
||||
// We execute the module module as a side module so that import.meta.main is not set.
|
||||
worker.execute_side_module(&specifier).await?;
|
||||
if options.compat_mode {
|
||||
worker.execute_side_module(&compat::GLOBAL_URL).await?;
|
||||
worker.execute_side_module(&compat::MODULE_URL).await?;
|
||||
|
||||
let use_esm_loader = compat::check_if_should_use_esm_loader(&specifier)?;
|
||||
|
||||
if use_esm_loader {
|
||||
worker.execute_side_module(&specifier).await?;
|
||||
} else {
|
||||
compat::load_cjs_module(
|
||||
&mut worker.js_runtime,
|
||||
&specifier.to_file_path().unwrap().display().to_string(),
|
||||
false,
|
||||
)?;
|
||||
worker.run_event_loop(false).await?;
|
||||
}
|
||||
} else {
|
||||
// We execute the module module as a side module so that import.meta.main is not set.
|
||||
worker.execute_side_module(&specifier).await?;
|
||||
}
|
||||
}
|
||||
|
||||
worker.dispatch_load_event(&located_script_name!())?;
|
||||
|
@ -488,8 +515,8 @@ async fn test_specifier(
|
|||
&format!(
|
||||
r#"Deno[Deno.internal].runTests({})"#,
|
||||
json!({
|
||||
"filter": filter,
|
||||
"shuffle": shuffle,
|
||||
"filter": options.filter,
|
||||
"shuffle": options.shuffle,
|
||||
}),
|
||||
),
|
||||
)?;
|
||||
|
@ -758,13 +785,10 @@ async fn test_specifiers(
|
|||
ps: ProcState,
|
||||
permissions: Permissions,
|
||||
specifiers_with_mode: Vec<(ModuleSpecifier, TestMode)>,
|
||||
fail_fast: Option<NonZeroUsize>,
|
||||
filter: Option<String>,
|
||||
shuffle: Option<u64>,
|
||||
concurrent_jobs: NonZeroUsize,
|
||||
options: TestSpecifierOptions,
|
||||
) -> Result<(), AnyError> {
|
||||
let log_level = ps.flags.log_level;
|
||||
let specifiers_with_mode = if let Some(seed) = shuffle {
|
||||
let specifiers_with_mode = if let Some(seed) = options.shuffle {
|
||||
let mut rng = SmallRng::seed_from_u64(seed);
|
||||
let mut specifiers_with_mode = specifiers_with_mode.clone();
|
||||
specifiers_with_mode.sort_by_key(|(specifier, _)| specifier.clone());
|
||||
|
@ -775,6 +799,8 @@ async fn test_specifiers(
|
|||
};
|
||||
|
||||
let (sender, receiver) = channel::<TestEvent>();
|
||||
let concurrent_jobs = options.concurrent_jobs;
|
||||
let fail_fast = options.fail_fast;
|
||||
|
||||
let join_handles =
|
||||
specifiers_with_mode.iter().map(move |(specifier, mode)| {
|
||||
|
@ -782,20 +808,13 @@ async fn test_specifiers(
|
|||
let permissions = permissions.clone();
|
||||
let specifier = specifier.clone();
|
||||
let mode = mode.clone();
|
||||
let filter = filter.clone();
|
||||
let sender = sender.clone();
|
||||
let options = options.clone();
|
||||
|
||||
tokio::task::spawn_blocking(move || {
|
||||
let join_handle = std::thread::spawn(move || {
|
||||
let future = test_specifier(
|
||||
ps,
|
||||
permissions,
|
||||
specifier,
|
||||
mode,
|
||||
filter,
|
||||
shuffle,
|
||||
sender,
|
||||
);
|
||||
let future =
|
||||
test_specifier(ps, permissions, specifier, mode, sender, options);
|
||||
|
||||
run_basic(future)
|
||||
});
|
||||
|
@ -1029,10 +1048,13 @@ pub async fn run_tests(
|
|||
ps,
|
||||
permissions,
|
||||
specifiers_with_mode,
|
||||
test_flags.fail_fast,
|
||||
test_flags.filter,
|
||||
test_flags.shuffle,
|
||||
test_flags.concurrent_jobs,
|
||||
TestSpecifierOptions {
|
||||
compat_mode: flags.compat,
|
||||
concurrent_jobs: test_flags.concurrent_jobs,
|
||||
fail_fast: test_flags.fail_fast,
|
||||
filter: test_flags.filter,
|
||||
shuffle: test_flags.shuffle,
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
@ -1256,10 +1278,13 @@ pub async fn run_tests_with_watch(
|
|||
ps.clone(),
|
||||
permissions.clone(),
|
||||
specifiers_with_mode,
|
||||
test_flags.fail_fast,
|
||||
filter.clone(),
|
||||
test_flags.shuffle,
|
||||
test_flags.concurrent_jobs,
|
||||
TestSpecifierOptions {
|
||||
compat_mode: flags.compat,
|
||||
concurrent_jobs: test_flags.concurrent_jobs,
|
||||
fail_fast: test_flags.fail_fast,
|
||||
filter: filter.clone(),
|
||||
shuffle: test_flags.shuffle,
|
||||
},
|
||||
)
|
||||
.await?;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue