mirror of
https://github.com/denoland/deno.git
synced 2024-11-25 15:29:32 -05:00
refactor(testing): redirect console output via reporter (#11911)
This feeds console output to the reporter and handles silencing there instead of in the JavaScript code.
This commit is contained in:
parent
44ca3ce6ae
commit
ce79cb5797
3 changed files with 65 additions and 33 deletions
|
@ -313,27 +313,27 @@ unitTest(function consoleTestStringifyCircular() {
|
||||||
"JSON {}",
|
"JSON {}",
|
||||||
);
|
);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
stringify(console),
|
stringify(new Console(() => {})),
|
||||||
`console {
|
`console {
|
||||||
log: [Function: bound ],
|
log: [Function: log],
|
||||||
debug: [Function: bound ],
|
debug: [Function: debug],
|
||||||
info: [Function: bound ],
|
info: [Function: info],
|
||||||
dir: [Function: bound ],
|
dir: [Function: dir],
|
||||||
dirxml: [Function: bound ],
|
dirxml: [Function: dir],
|
||||||
warn: [Function: bound ],
|
warn: [Function: warn],
|
||||||
error: [Function: bound ],
|
error: [Function: error],
|
||||||
assert: [Function: bound ],
|
assert: [Function: assert],
|
||||||
count: [Function: bound ],
|
count: [Function: count],
|
||||||
countReset: [Function: bound ],
|
countReset: [Function: countReset],
|
||||||
table: [Function: bound ],
|
table: [Function: table],
|
||||||
time: [Function: bound ],
|
time: [Function: time],
|
||||||
timeLog: [Function: bound ],
|
timeLog: [Function: timeLog],
|
||||||
timeEnd: [Function: bound ],
|
timeEnd: [Function: timeEnd],
|
||||||
group: [Function: bound ],
|
group: [Function: group],
|
||||||
groupCollapsed: [Function: bound ],
|
groupCollapsed: [Function: group],
|
||||||
groupEnd: [Function: bound ],
|
groupEnd: [Function: groupEnd],
|
||||||
clear: [Function: bound ],
|
clear: [Function: clear],
|
||||||
trace: [Function: bound ],
|
trace: [Function: trace],
|
||||||
indentLevel: 0,
|
indentLevel: 0,
|
||||||
[Symbol(isConsoleInstance)]: true
|
[Symbol(isConsoleInstance)]: true
|
||||||
}`,
|
}`,
|
||||||
|
|
|
@ -68,6 +68,13 @@ pub struct TestDescription {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub enum TestOutput {
|
||||||
|
// TODO(caspervonb): add stdout and stderr redirection.
|
||||||
|
Console(String),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub enum TestResult {
|
pub enum TestResult {
|
||||||
|
@ -90,6 +97,7 @@ pub struct TestPlan {
|
||||||
pub enum TestEvent {
|
pub enum TestEvent {
|
||||||
Plan(TestPlan),
|
Plan(TestPlan),
|
||||||
Wait(TestDescription),
|
Wait(TestDescription),
|
||||||
|
Output(TestOutput),
|
||||||
Result(TestDescription, TestResult, u64),
|
Result(TestDescription, TestResult, u64),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +137,7 @@ impl TestSummary {
|
||||||
trait TestReporter {
|
trait TestReporter {
|
||||||
fn report_plan(&mut self, plan: &TestPlan);
|
fn report_plan(&mut self, plan: &TestPlan);
|
||||||
fn report_wait(&mut self, description: &TestDescription);
|
fn report_wait(&mut self, description: &TestDescription);
|
||||||
|
fn report_output(&mut self, output: &TestOutput);
|
||||||
fn report_result(
|
fn report_result(
|
||||||
&mut self,
|
&mut self,
|
||||||
description: &TestDescription,
|
description: &TestDescription,
|
||||||
|
@ -140,11 +149,15 @@ trait TestReporter {
|
||||||
|
|
||||||
struct PrettyTestReporter {
|
struct PrettyTestReporter {
|
||||||
concurrent: bool,
|
concurrent: bool,
|
||||||
|
echo_output: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PrettyTestReporter {
|
impl PrettyTestReporter {
|
||||||
fn new(concurrent: bool) -> PrettyTestReporter {
|
fn new(concurrent: bool, echo_output: bool) -> PrettyTestReporter {
|
||||||
PrettyTestReporter { concurrent }
|
PrettyTestReporter {
|
||||||
|
concurrent,
|
||||||
|
echo_output,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,6 +173,14 @@ impl TestReporter for PrettyTestReporter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn report_output(&mut self, output: &TestOutput) {
|
||||||
|
if self.echo_output {
|
||||||
|
match output {
|
||||||
|
TestOutput::Console(line) => println!("{}", line),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn report_result(
|
fn report_result(
|
||||||
&mut self,
|
&mut self,
|
||||||
description: &TestDescription,
|
description: &TestDescription,
|
||||||
|
@ -217,8 +238,11 @@ impl TestReporter for PrettyTestReporter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_reporter(concurrent: bool) -> Box<dyn TestReporter + Send> {
|
fn create_reporter(
|
||||||
Box::new(PrettyTestReporter::new(concurrent))
|
concurrent: bool,
|
||||||
|
echo_output: bool,
|
||||||
|
) -> Box<dyn TestReporter + Send> {
|
||||||
|
Box::new(PrettyTestReporter::new(concurrent, echo_output))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Test a single specifier as documentation containing test programs, an executable test module or
|
/// Test a single specifier as documentation containing test programs, an executable test module or
|
||||||
|
@ -248,7 +272,6 @@ async fn test_specifier(
|
||||||
test_source.push_str(&format!(
|
test_source.push_str(&format!(
|
||||||
"await Deno[Deno.internal].runTests({});\n",
|
"await Deno[Deno.internal].runTests({});\n",
|
||||||
json!({
|
json!({
|
||||||
"disableLog": program_state.flags.log_level == Some(Level::Error),
|
|
||||||
"filter": filter,
|
"filter": filter,
|
||||||
"shuffle": shuffle,
|
"shuffle": shuffle,
|
||||||
}),
|
}),
|
||||||
|
@ -558,6 +581,7 @@ async fn test_specifiers(
|
||||||
shuffle: Option<u64>,
|
shuffle: Option<u64>,
|
||||||
concurrent_jobs: NonZeroUsize,
|
concurrent_jobs: NonZeroUsize,
|
||||||
) -> Result<(), AnyError> {
|
) -> Result<(), AnyError> {
|
||||||
|
let log_level = program_state.flags.log_level;
|
||||||
let specifiers_with_mode = if let Some(seed) = shuffle {
|
let specifiers_with_mode = if let Some(seed) = shuffle {
|
||||||
let mut rng = SmallRng::seed_from_u64(seed);
|
let mut rng = SmallRng::seed_from_u64(seed);
|
||||||
let mut specifiers_with_mode = specifiers_with_mode.clone();
|
let mut specifiers_with_mode = specifiers_with_mode.clone();
|
||||||
|
@ -602,7 +626,9 @@ async fn test_specifiers(
|
||||||
.buffer_unordered(concurrent_jobs.get())
|
.buffer_unordered(concurrent_jobs.get())
|
||||||
.collect::<Vec<Result<Result<(), AnyError>, tokio::task::JoinError>>>();
|
.collect::<Vec<Result<Result<(), AnyError>, tokio::task::JoinError>>>();
|
||||||
|
|
||||||
let mut reporter = create_reporter(concurrent_jobs.get() > 1);
|
let mut reporter =
|
||||||
|
create_reporter(concurrent_jobs.get() > 1, log_level != Some(Level::Error));
|
||||||
|
|
||||||
let handler = {
|
let handler = {
|
||||||
tokio::task::spawn_blocking(move || {
|
tokio::task::spawn_blocking(move || {
|
||||||
let earlier = Instant::now();
|
let earlier = Instant::now();
|
||||||
|
@ -626,6 +652,10 @@ async fn test_specifiers(
|
||||||
reporter.report_wait(&description);
|
reporter.report_wait(&description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestEvent::Output(output) => {
|
||||||
|
reporter.report_output(&output);
|
||||||
|
}
|
||||||
|
|
||||||
TestEvent::Result(description, result, elapsed) => {
|
TestEvent::Result(description, result, elapsed) => {
|
||||||
match &result {
|
match &result {
|
||||||
TestResult::Ok => {
|
TestResult::Ok => {
|
||||||
|
|
|
@ -228,15 +228,19 @@ finishing test case.`;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function runTests({
|
async function runTests({
|
||||||
disableLog = false,
|
|
||||||
filter = null,
|
filter = null,
|
||||||
shuffle = null,
|
shuffle = null,
|
||||||
} = {}) {
|
} = {}) {
|
||||||
const origin = getTestOrigin();
|
const origin = getTestOrigin();
|
||||||
const originalConsole = globalThis.console;
|
const originalConsole = globalThis.console;
|
||||||
if (disableLog) {
|
|
||||||
globalThis.console = new Console(() => {});
|
globalThis.console = new Console((line) => {
|
||||||
}
|
dispatchTestEvent({
|
||||||
|
output: {
|
||||||
|
console: line,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
const only = ArrayPrototypeFilter(tests, (test) => test.only);
|
const only = ArrayPrototypeFilter(tests, (test) => test.only);
|
||||||
const filtered = ArrayPrototypeFilter(
|
const filtered = ArrayPrototypeFilter(
|
||||||
|
@ -286,9 +290,7 @@ finishing test case.`;
|
||||||
dispatchTestEvent({ result: [description, result, elapsed] });
|
dispatchTestEvent({ result: [description, result, elapsed] });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (disableLog) {
|
globalThis.console = originalConsole;
|
||||||
globalThis.console = originalConsole;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.__bootstrap.internals = {
|
window.__bootstrap.internals = {
|
||||||
|
|
Loading…
Reference in a new issue