1
0
Fork 0
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:
Casper Beyer 2021-09-04 21:16:35 +08:00 committed by GitHub
parent 44ca3ce6ae
commit ce79cb5797
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 33 deletions

View file

@ -313,27 +313,27 @@ unitTest(function consoleTestStringifyCircular() {
"JSON {}",
);
assertEquals(
stringify(console),
stringify(new Console(() => {})),
`console {
log: [Function: bound ],
debug: [Function: bound ],
info: [Function: bound ],
dir: [Function: bound ],
dirxml: [Function: bound ],
warn: [Function: bound ],
error: [Function: bound ],
assert: [Function: bound ],
count: [Function: bound ],
countReset: [Function: bound ],
table: [Function: bound ],
time: [Function: bound ],
timeLog: [Function: bound ],
timeEnd: [Function: bound ],
group: [Function: bound ],
groupCollapsed: [Function: bound ],
groupEnd: [Function: bound ],
clear: [Function: bound ],
trace: [Function: bound ],
log: [Function: log],
debug: [Function: debug],
info: [Function: info],
dir: [Function: dir],
dirxml: [Function: dir],
warn: [Function: warn],
error: [Function: error],
assert: [Function: assert],
count: [Function: count],
countReset: [Function: countReset],
table: [Function: table],
time: [Function: time],
timeLog: [Function: timeLog],
timeEnd: [Function: timeEnd],
group: [Function: group],
groupCollapsed: [Function: group],
groupEnd: [Function: groupEnd],
clear: [Function: clear],
trace: [Function: trace],
indentLevel: 0,
[Symbol(isConsoleInstance)]: true
}`,

View file

@ -68,6 +68,13 @@ pub struct TestDescription {
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)]
#[serde(rename_all = "camelCase")]
pub enum TestResult {
@ -90,6 +97,7 @@ pub struct TestPlan {
pub enum TestEvent {
Plan(TestPlan),
Wait(TestDescription),
Output(TestOutput),
Result(TestDescription, TestResult, u64),
}
@ -129,6 +137,7 @@ impl TestSummary {
trait TestReporter {
fn report_plan(&mut self, plan: &TestPlan);
fn report_wait(&mut self, description: &TestDescription);
fn report_output(&mut self, output: &TestOutput);
fn report_result(
&mut self,
description: &TestDescription,
@ -140,11 +149,15 @@ trait TestReporter {
struct PrettyTestReporter {
concurrent: bool,
echo_output: bool,
}
impl PrettyTestReporter {
fn new(concurrent: bool) -> PrettyTestReporter {
PrettyTestReporter { concurrent }
fn new(concurrent: bool, echo_output: bool) -> PrettyTestReporter {
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(
&mut self,
description: &TestDescription,
@ -217,8 +238,11 @@ impl TestReporter for PrettyTestReporter {
}
}
fn create_reporter(concurrent: bool) -> Box<dyn TestReporter + Send> {
Box::new(PrettyTestReporter::new(concurrent))
fn create_reporter(
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
@ -248,7 +272,6 @@ async fn test_specifier(
test_source.push_str(&format!(
"await Deno[Deno.internal].runTests({});\n",
json!({
"disableLog": program_state.flags.log_level == Some(Level::Error),
"filter": filter,
"shuffle": shuffle,
}),
@ -558,6 +581,7 @@ async fn test_specifiers(
shuffle: Option<u64>,
concurrent_jobs: NonZeroUsize,
) -> Result<(), AnyError> {
let log_level = program_state.flags.log_level;
let specifiers_with_mode = if let Some(seed) = shuffle {
let mut rng = SmallRng::seed_from_u64(seed);
let mut specifiers_with_mode = specifiers_with_mode.clone();
@ -602,7 +626,9 @@ async fn test_specifiers(
.buffer_unordered(concurrent_jobs.get())
.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 = {
tokio::task::spawn_blocking(move || {
let earlier = Instant::now();
@ -626,6 +652,10 @@ async fn test_specifiers(
reporter.report_wait(&description);
}
TestEvent::Output(output) => {
reporter.report_output(&output);
}
TestEvent::Result(description, result, elapsed) => {
match &result {
TestResult::Ok => {

View file

@ -228,15 +228,19 @@ finishing test case.`;
}
async function runTests({
disableLog = false,
filter = null,
shuffle = null,
} = {}) {
const origin = getTestOrigin();
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 filtered = ArrayPrototypeFilter(
@ -286,9 +290,7 @@ finishing test case.`;
dispatchTestEvent({ result: [description, result, elapsed] });
}
if (disableLog) {
globalThis.console = originalConsole;
}
globalThis.console = originalConsole;
}
window.__bootstrap.internals = {