|
|
@ -13,14 +13,15 @@ use boa_engine::{ |
|
|
|
native_function::NativeFunction, |
|
|
|
native_function::NativeFunction, |
|
|
|
object::FunctionObjectBuilder, |
|
|
|
object::FunctionObjectBuilder, |
|
|
|
optimizer::OptimizerOptions, |
|
|
|
optimizer::OptimizerOptions, |
|
|
|
|
|
|
|
parser::source::ReadChar, |
|
|
|
property::Attribute, |
|
|
|
property::Attribute, |
|
|
|
script::Script, |
|
|
|
script::Script, |
|
|
|
Context, JsArgs, JsError, JsNativeErrorKind, JsValue, Source, |
|
|
|
Context, JsArgs, JsError, JsNativeErrorKind, JsResult, JsValue, Source, |
|
|
|
}; |
|
|
|
}; |
|
|
|
use colored::Colorize; |
|
|
|
use colored::Colorize; |
|
|
|
use rayon::prelude::*; |
|
|
|
use rayon::prelude::*; |
|
|
|
use rustc_hash::FxHashSet; |
|
|
|
use rustc_hash::FxHashSet; |
|
|
|
use std::{cell::RefCell, eprintln, rc::Rc}; |
|
|
|
use std::{cell::RefCell, eprintln, path::Path, rc::Rc}; |
|
|
|
|
|
|
|
|
|
|
|
use self::js262::WorkerHandles; |
|
|
|
use self::js262::WorkerHandles; |
|
|
|
|
|
|
|
|
|
|
@ -193,52 +194,77 @@ impl Test { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Runs the test once, in strict or non-strict mode
|
|
|
|
/// Creates the test result from the outcome and message.
|
|
|
|
fn run_once( |
|
|
|
fn create_result<S: Into<Box<str>>>( |
|
|
|
&self, |
|
|
|
&self, |
|
|
|
harness: &Harness, |
|
|
|
outcome: TestOutcomeResult, |
|
|
|
|
|
|
|
text: S, |
|
|
|
strict: bool, |
|
|
|
strict: bool, |
|
|
|
verbose: u8, |
|
|
|
verbosity: u8, |
|
|
|
optimizer_options: OptimizerOptions, |
|
|
|
|
|
|
|
console: bool, |
|
|
|
|
|
|
|
) -> TestResult { |
|
|
|
) -> TestResult { |
|
|
|
let Ok(source) = Source::from_filepath(&self.path) else { |
|
|
|
let result_text = text.into(); |
|
|
|
if verbose > 1 { |
|
|
|
|
|
|
|
|
|
|
|
if verbosity > 1 { |
|
|
|
println!( |
|
|
|
println!( |
|
|
|
"`{}`{}: {}", |
|
|
|
"`{}`{}: {}", |
|
|
|
self.path.display(), |
|
|
|
self.path.display(), |
|
|
|
if strict { " (strict mode)" } else { "" }, |
|
|
|
if strict { " (strict)" } else { "" }, |
|
|
|
"Invalid file".red() |
|
|
|
match outcome { |
|
|
|
|
|
|
|
TestOutcomeResult::Passed => "Passed".green(), |
|
|
|
|
|
|
|
TestOutcomeResult::Ignored => "Ignored".yellow(), |
|
|
|
|
|
|
|
TestOutcomeResult::Failed => "Failed".red(), |
|
|
|
|
|
|
|
TestOutcomeResult::Panic => "⚠ Panic ⚠".red(), |
|
|
|
|
|
|
|
} |
|
|
|
); |
|
|
|
); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
print!("{}", "F".red()); |
|
|
|
let symbol = match outcome { |
|
|
|
} |
|
|
|
TestOutcomeResult::Passed => ".".green(), |
|
|
|
return TestResult { |
|
|
|
TestOutcomeResult::Ignored => "-".yellow(), |
|
|
|
name: self.name.clone(), |
|
|
|
TestOutcomeResult::Failed | TestOutcomeResult::Panic => "F".red(), |
|
|
|
edition: self.edition, |
|
|
|
|
|
|
|
result: TestOutcomeResult::Failed, |
|
|
|
|
|
|
|
result_text: Box::from("Could not read test file."), |
|
|
|
|
|
|
|
}; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
if self.ignored { |
|
|
|
print!("{symbol}"); |
|
|
|
if verbose > 1 { |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if verbosity > 2 { |
|
|
|
println!( |
|
|
|
println!( |
|
|
|
"`{}`{}: {}", |
|
|
|
"`{}`{}: result text\n{result_text}\n", |
|
|
|
self.path.display(), |
|
|
|
self.path.display(), |
|
|
|
if strict { " (strict mode)" } else { "" }, |
|
|
|
if strict { " (strict)" } else { "" }, |
|
|
|
"Ignored".yellow() |
|
|
|
|
|
|
|
); |
|
|
|
); |
|
|
|
} else { |
|
|
|
|
|
|
|
print!("{}", "-".yellow()); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
return TestResult { |
|
|
|
|
|
|
|
|
|
|
|
TestResult { |
|
|
|
name: self.name.clone(), |
|
|
|
name: self.name.clone(), |
|
|
|
edition: self.edition, |
|
|
|
edition: self.edition, |
|
|
|
result: TestOutcomeResult::Ignored, |
|
|
|
result_text, |
|
|
|
result_text: Box::default(), |
|
|
|
result: outcome, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Runs the test once, in strict or non-strict mode
|
|
|
|
|
|
|
|
fn run_once( |
|
|
|
|
|
|
|
&self, |
|
|
|
|
|
|
|
harness: &Harness, |
|
|
|
|
|
|
|
strict: bool, |
|
|
|
|
|
|
|
verbosity: u8, |
|
|
|
|
|
|
|
optimizer_options: OptimizerOptions, |
|
|
|
|
|
|
|
console: bool, |
|
|
|
|
|
|
|
) -> TestResult { |
|
|
|
|
|
|
|
let Ok(source) = Source::from_filepath(&self.path) else { |
|
|
|
|
|
|
|
return self.create_result( |
|
|
|
|
|
|
|
TestOutcomeResult::Failed, |
|
|
|
|
|
|
|
"Could not read test file", |
|
|
|
|
|
|
|
strict, |
|
|
|
|
|
|
|
verbosity, |
|
|
|
|
|
|
|
); |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if self.ignored { |
|
|
|
|
|
|
|
return self.create_result(TestOutcomeResult::Ignored, "", strict, verbosity); |
|
|
|
} |
|
|
|
} |
|
|
|
if verbose > 1 { |
|
|
|
|
|
|
|
|
|
|
|
if verbosity > 1 { |
|
|
|
println!( |
|
|
|
println!( |
|
|
|
"`{}`{}: starting", |
|
|
|
"`{}`{}: starting", |
|
|
|
self.path.display(), |
|
|
|
self.path.display(), |
|
|
@ -248,47 +274,19 @@ impl Test { |
|
|
|
|
|
|
|
|
|
|
|
let result = std::panic::catch_unwind(|| match self.expected_outcome { |
|
|
|
let result = std::panic::catch_unwind(|| match self.expected_outcome { |
|
|
|
Outcome::Positive => { |
|
|
|
Outcome::Positive => { |
|
|
|
let async_result = AsyncResult::default(); |
|
|
|
let (ref mut context, async_result, mut handles) = |
|
|
|
let loader = Rc::new( |
|
|
|
match self.create_context(harness, optimizer_options, console) { |
|
|
|
SimpleModuleLoader::new( |
|
|
|
Ok(r) => r, |
|
|
|
self.path.parent().expect("test should have a parent dir"), |
|
|
|
Err(e) => return (false, e), |
|
|
|
) |
|
|
|
}; |
|
|
|
.expect("test path should be canonicalizable"), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
let context = &mut Context::builder() |
|
|
|
|
|
|
|
.module_loader(loader.clone()) |
|
|
|
|
|
|
|
.can_block(!self.flags.contains(TestFlags::CAN_BLOCK_IS_FALSE)) |
|
|
|
|
|
|
|
.build() |
|
|
|
|
|
|
|
.expect("cannot fail with default global object"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut handles = WorkerHandles::new(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if let Err(e) = self.set_up_env( |
|
|
|
|
|
|
|
harness, |
|
|
|
|
|
|
|
context, |
|
|
|
|
|
|
|
async_result.clone(), |
|
|
|
|
|
|
|
handles.clone(), |
|
|
|
|
|
|
|
console, |
|
|
|
|
|
|
|
) { |
|
|
|
|
|
|
|
return (false, e); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
context.set_optimizer_options(optimizer_options); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: timeout
|
|
|
|
// TODO: timeout
|
|
|
|
let value = if self.is_module() { |
|
|
|
let value = if self.is_module() { |
|
|
|
let module = match Module::parse(source, None, context) { |
|
|
|
let module = match parse_module_and_register(source, &self.path, context) { |
|
|
|
Ok(module) => module, |
|
|
|
Ok(module) => module, |
|
|
|
Err(err) => return (false, format!("Uncaught {err}")), |
|
|
|
Err(err) => return (false, format!("Uncaught {err}")), |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
loader.insert( |
|
|
|
|
|
|
|
self.path |
|
|
|
|
|
|
|
.canonicalize() |
|
|
|
|
|
|
|
.expect("test path should be canonicalizable"), |
|
|
|
|
|
|
|
module.clone(), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let promise = module.load_link_evaluate(context); |
|
|
|
let promise = module.load_link_evaluate(context); |
|
|
|
|
|
|
|
|
|
|
|
context.run_jobs(); |
|
|
|
context.run_jobs(); |
|
|
@ -337,9 +335,7 @@ impl Test { |
|
|
|
_ => {} |
|
|
|
_ => {} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
let results = handles.join_all(); |
|
|
|
for result in handles.join_all() { |
|
|
|
|
|
|
|
|
|
|
|
for result in results { |
|
|
|
|
|
|
|
match result { |
|
|
|
match result { |
|
|
|
js262::WorkerResult::Err(msg) => return (false, msg), |
|
|
|
js262::WorkerResult::Err(msg) => return (false, msg), |
|
|
|
js262::WorkerResult::Panic(msg) => panic!("Worker thread panicked: {msg}"), |
|
|
|
js262::WorkerResult::Panic(msg) => panic!("Worker thread panicked: {msg}"), |
|
|
@ -362,8 +358,6 @@ impl Test { |
|
|
|
|
|
|
|
|
|
|
|
let context = &mut Context::default(); |
|
|
|
let context = &mut Context::default(); |
|
|
|
|
|
|
|
|
|
|
|
context.set_optimizer_options(OptimizerOptions::OPTIMIZE_ALL); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if self.is_module() { |
|
|
|
if self.is_module() { |
|
|
|
match Module::parse(source, None, context) { |
|
|
|
match Module::parse(source, None, context) { |
|
|
|
Ok(_) => (false, "ModuleItemList parsing should fail".to_owned()), |
|
|
|
Ok(_) => (false, "ModuleItemList parsing should fail".to_owned()), |
|
|
@ -381,29 +375,17 @@ impl Test { |
|
|
|
phase: Phase::Resolution, |
|
|
|
phase: Phase::Resolution, |
|
|
|
error_type, |
|
|
|
error_type, |
|
|
|
} => { |
|
|
|
} => { |
|
|
|
let loader = Rc::new( |
|
|
|
let context = &mut match self.create_context(harness, optimizer_options, console) { |
|
|
|
SimpleModuleLoader::new( |
|
|
|
Ok(r) => r, |
|
|
|
self.path.parent().expect("test should have a parent dir"), |
|
|
|
Err(e) => return (false, e), |
|
|
|
) |
|
|
|
} |
|
|
|
.expect("test path should be canonicalizable"), |
|
|
|
.0; |
|
|
|
); |
|
|
|
|
|
|
|
let context = &mut Context::builder() |
|
|
|
|
|
|
|
.module_loader(loader.clone()) |
|
|
|
|
|
|
|
.build() |
|
|
|
|
|
|
|
.expect("cannot fail with default global object"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let module = match Module::parse(source, None, context) { |
|
|
|
let module = match parse_module_and_register(source, &self.path, context) { |
|
|
|
Ok(module) => module, |
|
|
|
Ok(module) => module, |
|
|
|
Err(err) => return (false, format!("Uncaught {err}")), |
|
|
|
Err(err) => return (false, format!("Uncaught {err}")), |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
loader.insert( |
|
|
|
|
|
|
|
self.path |
|
|
|
|
|
|
|
.canonicalize() |
|
|
|
|
|
|
|
.expect("test path should be canonicalizable"), |
|
|
|
|
|
|
|
module.clone(), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let promise = module.load(context); |
|
|
|
let promise = module.load(context); |
|
|
|
|
|
|
|
|
|
|
|
context.run_jobs(); |
|
|
|
context.run_jobs(); |
|
|
@ -437,44 +419,18 @@ impl Test { |
|
|
|
phase: Phase::Runtime, |
|
|
|
phase: Phase::Runtime, |
|
|
|
error_type, |
|
|
|
error_type, |
|
|
|
} => { |
|
|
|
} => { |
|
|
|
let loader = Rc::new( |
|
|
|
let (ref mut context, _async_result, mut handles) = |
|
|
|
SimpleModuleLoader::new( |
|
|
|
match self.create_context(harness, optimizer_options, console) { |
|
|
|
self.path.parent().expect("test should have a parent dir"), |
|
|
|
Ok(r) => r, |
|
|
|
) |
|
|
|
Err(e) => return (false, e), |
|
|
|
.expect("test path should be canonicalizable"), |
|
|
|
}; |
|
|
|
); |
|
|
|
|
|
|
|
let context = &mut Context::builder() |
|
|
|
|
|
|
|
.module_loader(loader.clone()) |
|
|
|
|
|
|
|
.can_block(!self.flags.contains(TestFlags::CAN_BLOCK_IS_FALSE)) |
|
|
|
|
|
|
|
.build() |
|
|
|
|
|
|
|
.expect("cannot fail with default global object"); |
|
|
|
|
|
|
|
context.strict(strict); |
|
|
|
|
|
|
|
context.set_optimizer_options(optimizer_options); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut handles = WorkerHandles::new(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if let Err(e) = self.set_up_env( |
|
|
|
|
|
|
|
harness, |
|
|
|
|
|
|
|
context, |
|
|
|
|
|
|
|
AsyncResult::default(), |
|
|
|
|
|
|
|
handles.clone(), |
|
|
|
|
|
|
|
console, |
|
|
|
|
|
|
|
) { |
|
|
|
|
|
|
|
return (false, e); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
let error = if self.is_module() { |
|
|
|
let error = if self.is_module() { |
|
|
|
let module = match Module::parse(source, None, context) { |
|
|
|
let module = match parse_module_and_register(source, &self.path, context) { |
|
|
|
Ok(module) => module, |
|
|
|
Ok(module) => module, |
|
|
|
Err(e) => return (false, format!("Uncaught {e}")), |
|
|
|
Err(err) => return (false, format!("Uncaught {err}")), |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
loader.insert( |
|
|
|
|
|
|
|
self.path |
|
|
|
|
|
|
|
.canonicalize() |
|
|
|
|
|
|
|
.expect("test path should be canonicalizable"), |
|
|
|
|
|
|
|
module.clone(), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let promise = module.load(context); |
|
|
|
let promise = module.load(context); |
|
|
|
|
|
|
|
|
|
|
|
context.run_jobs(); |
|
|
|
context.run_jobs(); |
|
|
@ -517,9 +473,7 @@ impl Test { |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
let results = handles.join_all(); |
|
|
|
for result in handles.join_all() { |
|
|
|
|
|
|
|
|
|
|
|
for result in results { |
|
|
|
|
|
|
|
match result { |
|
|
|
match result { |
|
|
|
js262::WorkerResult::Err(msg) => return (false, msg), |
|
|
|
js262::WorkerResult::Err(msg) => return (false, msg), |
|
|
|
js262::WorkerResult::Panic(msg) => panic!("Worker thread panicked: {msg}"), |
|
|
|
js262::WorkerResult::Panic(msg) => panic!("Worker thread panicked: {msg}"), |
|
|
@ -548,65 +502,38 @@ impl Test { |
|
|
|
}, |
|
|
|
}, |
|
|
|
); |
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
if verbose > 1 { |
|
|
|
self.create_result(result, result_text, strict, verbosity) |
|
|
|
println!( |
|
|
|
|
|
|
|
"`{}`{}: {}", |
|
|
|
|
|
|
|
self.path.display(), |
|
|
|
|
|
|
|
if strict { " (strict mode)" } else { "" }, |
|
|
|
|
|
|
|
if result == TestOutcomeResult::Passed { |
|
|
|
|
|
|
|
"Passed".green() |
|
|
|
|
|
|
|
} else if result == TestOutcomeResult::Failed { |
|
|
|
|
|
|
|
"Failed".red() |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
"⚠ Panic ⚠".red() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
print!( |
|
|
|
|
|
|
|
"{}", |
|
|
|
|
|
|
|
if result == TestOutcomeResult::Passed { |
|
|
|
|
|
|
|
".".green() |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
"F".red() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if verbose > 2 { |
|
|
|
|
|
|
|
println!( |
|
|
|
|
|
|
|
"`{}`{}: result text", |
|
|
|
|
|
|
|
self.path.display(), |
|
|
|
|
|
|
|
if strict { " (strict mode)" } else { "" }, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
println!("{result_text}"); |
|
|
|
|
|
|
|
println!(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
TestResult { |
|
|
|
/// Creates the context to run the test.
|
|
|
|
name: self.name.clone(), |
|
|
|
fn create_context( |
|
|
|
edition: self.edition, |
|
|
|
|
|
|
|
result, |
|
|
|
|
|
|
|
result_text: result_text.into_boxed_str(), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Sets the environment up to run the test.
|
|
|
|
|
|
|
|
fn set_up_env( |
|
|
|
|
|
|
|
&self, |
|
|
|
&self, |
|
|
|
harness: &Harness, |
|
|
|
harness: &Harness, |
|
|
|
context: &mut Context, |
|
|
|
optimizer_options: OptimizerOptions, |
|
|
|
async_result: AsyncResult, |
|
|
|
|
|
|
|
handles: WorkerHandles, |
|
|
|
|
|
|
|
console: bool, |
|
|
|
console: bool, |
|
|
|
) -> Result<(), String> { |
|
|
|
) -> Result<(Context, AsyncResult, WorkerHandles), String> { |
|
|
|
|
|
|
|
let async_result = AsyncResult::default(); |
|
|
|
|
|
|
|
let handles = WorkerHandles::new(); |
|
|
|
|
|
|
|
let loader = Rc::new( |
|
|
|
|
|
|
|
SimpleModuleLoader::new(self.path.parent().expect("test should have a parent dir")) |
|
|
|
|
|
|
|
.expect("test path should be canonicalizable"), |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
let mut context = Context::builder() |
|
|
|
|
|
|
|
.module_loader(loader.clone()) |
|
|
|
|
|
|
|
.can_block(!self.flags.contains(TestFlags::CAN_BLOCK_IS_FALSE)) |
|
|
|
|
|
|
|
.build() |
|
|
|
|
|
|
|
.expect("cannot fail with default global object"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
context.set_optimizer_options(optimizer_options); |
|
|
|
|
|
|
|
|
|
|
|
// Register the print() function.
|
|
|
|
// Register the print() function.
|
|
|
|
register_print_fn(context, async_result); |
|
|
|
register_print_fn(&mut context, async_result.clone()); |
|
|
|
|
|
|
|
|
|
|
|
// add the $262 object.
|
|
|
|
// add the $262 object.
|
|
|
|
let _js262 = js262::register_js262(handles, context); |
|
|
|
let _js262 = js262::register_js262(handles.clone(), &mut context); |
|
|
|
|
|
|
|
|
|
|
|
if console { |
|
|
|
if console { |
|
|
|
let console = boa_runtime::Console::init(context); |
|
|
|
let console = boa_runtime::Console::init(&mut context); |
|
|
|
context |
|
|
|
context |
|
|
|
.register_global_property( |
|
|
|
.register_global_property( |
|
|
|
js_string!(boa_runtime::Console::NAME), |
|
|
|
js_string!(boa_runtime::Console::NAME), |
|
|
@ -617,7 +544,7 @@ impl Test { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if self.flags.contains(TestFlags::RAW) { |
|
|
|
if self.flags.contains(TestFlags::RAW) { |
|
|
|
return Ok(()); |
|
|
|
return Ok((context, async_result, handles)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
let assert = Source::from_reader( |
|
|
|
let assert = Source::from_reader( |
|
|
@ -654,7 +581,7 @@ impl Test { |
|
|
|
})?; |
|
|
|
})?; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Ok(()) |
|
|
|
Ok((context, async_result, handles)) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -727,11 +654,31 @@ fn register_print_fn(context: &mut Context, async_result: AsyncResult) { |
|
|
|
.expect("shouldn't fail with the default global"); |
|
|
|
.expect("shouldn't fail with the default global"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Parses a module and registers it into the `ModuleLoader` of the context.
|
|
|
|
|
|
|
|
fn parse_module_and_register( |
|
|
|
|
|
|
|
source: Source<'_, impl ReadChar>, |
|
|
|
|
|
|
|
path: &Path, |
|
|
|
|
|
|
|
context: &mut Context, |
|
|
|
|
|
|
|
) -> JsResult<Module> { |
|
|
|
|
|
|
|
let module = Module::parse(source, None, context)?; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let path = js_string!(&*path |
|
|
|
|
|
|
|
.canonicalize() |
|
|
|
|
|
|
|
.expect("test path should be canonicalizable") |
|
|
|
|
|
|
|
.to_string_lossy()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
context |
|
|
|
|
|
|
|
.module_loader() |
|
|
|
|
|
|
|
.register_module(path, module.clone()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ok(module) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// A `Result` value that is possibly uninitialized.
|
|
|
|
/// A `Result` value that is possibly uninitialized.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// This is mainly used to check if an async test did call `print` to signal the termination of
|
|
|
|
/// This is mainly used to check if an async test did call `print` to signal the termination of
|
|
|
|
/// a test. Otherwise, all async tests that result in `UninitResult::Uninit` are considered
|
|
|
|
/// a test. Otherwise, all async tests that result in `UninitResult::Uninit` are considered
|
|
|
|
/// as failed.
|
|
|
|
/// failures.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// The Test262 [interpreting guide][guide] contains more information about how to run async tests.
|
|
|
|
/// The Test262 [interpreting guide][guide] contains more information about how to run async tests.
|
|
|
|
///
|
|
|
|
///
|
|
|
|