diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2023-08-02 18:38:10 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-02 18:38:10 +0200 |
commit | 029bdf0cd55e96f393614ca566d57e4330ac9135 (patch) | |
tree | ccc9f64068c70fcae1fcceba3920b375bcc19ce2 /cli/tools/test/mod.rs | |
parent | d9c85e016f054fd3b6c68a54213e7c0ad8c3a8f4 (diff) |
feat(cli): Add dot test reporter (#19804)
This commit adds a "dot" reporter to "deno test" subcommand,
that can be activated using "--dot" flag.
It provides a concise output using:
- "." for passing test
- "," for ignored test
- "!" for failing test
User output is silenced and not printed to the console.
In non-TTY environments each result is printed on a separate line.
Diffstat (limited to 'cli/tools/test/mod.rs')
-rw-r--r-- | cli/tools/test/mod.rs | 103 |
1 files changed, 29 insertions, 74 deletions
diff --git a/cli/tools/test/mod.rs b/cli/tools/test/mod.rs index a2abc2a32..c3fb6f772 100644 --- a/cli/tools/test/mod.rs +++ b/cli/tools/test/mod.rs @@ -4,6 +4,7 @@ use crate::args::CliOptions; use crate::args::FilesConfig; use crate::args::Flags; use crate::args::TestFlags; +use crate::args::TestReporterConfig; use crate::colors; use crate::display; use crate::factory::CliFactory; @@ -80,8 +81,12 @@ use tokio::sync::mpsc::unbounded_channel; use tokio::sync::mpsc::UnboundedSender; use tokio::sync::mpsc::WeakUnboundedSender; +pub mod fmt; mod reporters; + +pub use fmt::format_test_error; use reporters::CompoundTestReporter; +use reporters::DotTestReporter; use reporters::JunitTestReporter; use reporters::PrettyTestReporter; use reporters::TestReporter; @@ -355,7 +360,7 @@ struct TestSpecifiersOptions { fail_fast: Option<NonZeroUsize>, log_level: Option<log::Level>, specifier: TestSpecifierOptions, - junit_path: Option<String>, + reporter: TestReporterConfig, } #[derive(Debug, Clone)] @@ -388,79 +393,29 @@ impl TestSummary { } fn get_test_reporter(options: &TestSpecifiersOptions) -> Box<dyn TestReporter> { - let pretty = Box::new(PrettyTestReporter::new( - options.concurrent_jobs.get() > 1, - options.log_level != Some(Level::Error), - )); - if let Some(junit_path) = &options.junit_path { - let junit = Box::new(JunitTestReporter::new(junit_path.clone())); - // If junit is writing to stdout, only enable the junit reporter - if junit_path == "-" { - junit - } else { - Box::new(CompoundTestReporter::new(vec![pretty, junit])) - } - } else { - pretty - } -} - -fn abbreviate_test_error(js_error: &JsError) -> JsError { - let mut js_error = js_error.clone(); - let frames = std::mem::take(&mut js_error.frames); - - // check if there are any stack frames coming from user code - let should_filter = frames.iter().any(|f| { - if let Some(file_name) = &f.file_name { - !(file_name.starts_with("[ext:") || file_name.starts_with("ext:")) - } else { - true + let parallel = options.concurrent_jobs.get() > 1; + match &options.reporter { + TestReporterConfig::Dot => Box::new(DotTestReporter::new()), + TestReporterConfig::Pretty => Box::new(PrettyTestReporter::new( + parallel, + options.log_level != Some(Level::Error), + )), + TestReporterConfig::Junit(path) => { + let junit = Box::new(JunitTestReporter::new(path.clone())); + // If junit is writing to stdout, only enable the junit reporter + if path == "-" { + junit + } else { + Box::new(CompoundTestReporter::new(vec![ + Box::new(PrettyTestReporter::new( + parallel, + options.log_level != Some(Level::Error), + )), + junit, + ])) + } } - }); - - if should_filter { - let mut frames = frames - .into_iter() - .rev() - .skip_while(|f| { - if let Some(file_name) = &f.file_name { - file_name.starts_with("[ext:") || file_name.starts_with("ext:") - } else { - false - } - }) - .collect::<Vec<_>>(); - frames.reverse(); - js_error.frames = frames; - } else { - js_error.frames = frames; } - - js_error.cause = js_error - .cause - .as_ref() - .map(|e| Box::new(abbreviate_test_error(e))); - js_error.aggregated = js_error - .aggregated - .as_ref() - .map(|es| es.iter().map(abbreviate_test_error).collect()); - js_error -} - -// This function prettifies `JsError` and applies some changes specifically for -// test runner purposes: -// -// - filter out stack frames: -// - if stack trace consists of mixed user and internal code, the frames -// below the first user code frame are filtered out -// - if stack trace consists only of internal code it is preserved as is -pub fn format_test_error(js_error: &JsError) -> String { - let mut js_error = abbreviate_test_error(js_error); - js_error.exception_message = js_error - .exception_message - .trim_start_matches("Uncaught ") - .to_string(); - format_js_error(&js_error) } /// Test a single specifier as documentation containing test programs, an executable test module or @@ -1206,7 +1161,7 @@ pub async fn run_tests( concurrent_jobs: test_options.concurrent_jobs, fail_fast: test_options.fail_fast, log_level, - junit_path: test_options.junit_path, + reporter: test_options.reporter, specifier: TestSpecifierOptions { filter: TestFilter::from_flag(&test_options.filter), shuffle: test_options.shuffle, @@ -1337,7 +1292,7 @@ pub async fn run_tests_with_watch( concurrent_jobs: test_options.concurrent_jobs, fail_fast: test_options.fail_fast, log_level, - junit_path: test_options.junit_path, + reporter: test_options.reporter, specifier: TestSpecifierOptions { filter: TestFilter::from_flag(&test_options.filter), shuffle: test_options.shuffle, |