summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cli/flags.rs9
-rw-r--r--cli/main.rs5
-rw-r--r--cli/tests/integration/test_tests.rs6
-rw-r--r--cli/tests/test/terse.out11
-rw-r--r--cli/tests/test/terse.ts11
-rw-r--r--cli/tools/test_runner.rs133
6 files changed, 172 insertions, 3 deletions
diff --git a/cli/flags.rs b/cli/flags.rs
index 400798cbd..2d71762ce 100644
--- a/cli/flags.rs
+++ b/cli/flags.rs
@@ -100,6 +100,7 @@ pub enum DenoSubcommand {
no_run: bool,
fail_fast: bool,
quiet: bool,
+ terse: bool,
allow_none: bool,
include: Option<Vec<String>>,
filter: Option<String>,
@@ -1011,6 +1012,11 @@ fn test_subcommand<'a, 'b>() -> App<'a, 'b> {
.takes_value(false),
)
.arg(
+ Arg::with_name("terse")
+ .long("terse")
+ .help("UNSTABLE: Display one character per test instead of one line"),
+ )
+ .arg(
Arg::with_name("filter")
.set(ArgSettings::AllowLeadingHyphen)
.long("filter")
@@ -1699,6 +1705,7 @@ fn test_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
let fail_fast = matches.is_present("fail-fast");
let allow_none = matches.is_present("allow-none");
let quiet = matches.is_present("quiet");
+ let terse = matches.is_present("terse");
let filter = matches.value_of("filter").map(String::from);
let shuffle = if matches.is_present("shuffle") {
@@ -1753,6 +1760,7 @@ fn test_parse(flags: &mut Flags, matches: &clap::ArgMatches) {
doc,
fail_fast,
quiet,
+ terse,
include,
filter,
shuffle,
@@ -3391,6 +3399,7 @@ mod tests {
filter: Some("- foo".to_string()),
allow_none: true,
quiet: false,
+ terse: false,
include: Some(svec!["dir1/", "dir2/"]),
shuffle: None,
concurrent_jobs: 1,
diff --git a/cli/main.rs b/cli/main.rs
index 93bae0220..df6629391 100644
--- a/cli/main.rs
+++ b/cli/main.rs
@@ -988,6 +988,7 @@ async fn test_command(
doc: bool,
fail_fast: bool,
quiet: bool,
+ terse: bool,
allow_none: bool,
filter: Option<String>,
shuffle: Option<u64>,
@@ -1205,6 +1206,7 @@ async fn test_command(
no_run,
fail_fast,
quiet,
+ terse,
true,
filter.clone(),
shuffle,
@@ -1243,6 +1245,7 @@ async fn test_command(
no_run,
fail_fast,
quiet,
+ terse,
allow_none,
filter,
shuffle,
@@ -1350,6 +1353,7 @@ fn get_subcommand(
doc,
fail_fast,
quiet,
+ terse,
include,
allow_none,
filter,
@@ -1362,6 +1366,7 @@ fn get_subcommand(
doc,
fail_fast,
quiet,
+ terse,
allow_none,
filter,
shuffle,
diff --git a/cli/tests/integration/test_tests.rs b/cli/tests/integration/test_tests.rs
index c029b154d..134a2d47b 100644
--- a/cli/tests/integration/test_tests.rs
+++ b/cli/tests/integration/test_tests.rs
@@ -49,6 +49,12 @@ itest!(doc {
output: "test/doc.out",
});
+itest!(terse {
+ args: "test --terse test/terse.ts",
+ exit_code: 1,
+ output: "test/terse.out",
+});
+
itest!(quiet {
args: "test --quiet test/quiet.ts",
exit_code: 0,
diff --git a/cli/tests/test/terse.out b/cli/tests/test/terse.out
new file mode 100644
index 000000000..3d5deaf39
--- /dev/null
+++ b/cli/tests/test/terse.out
@@ -0,0 +1,11 @@
+Check [WILDCARD]/test/terse.ts
+running 3 tests from [WILDCARD]
+.Fi
+failures:
+
+fail
+Error: fail
+ [WILDCARD]
+
+test result: FAILED. 1 passed; 1 failed; 1 ignored; 0 measured; 0 filtered out [WILDCARD]
+
diff --git a/cli/tests/test/terse.ts b/cli/tests/test/terse.ts
new file mode 100644
index 000000000..b2168a0d9
--- /dev/null
+++ b/cli/tests/test/terse.ts
@@ -0,0 +1,11 @@
+Deno.test("ok", function () {});
+
+Deno.test("fail", function () {
+ throw new Error("fail");
+});
+
+Deno.test({
+ name: "ignore",
+ fn() {},
+ ignore: true,
+});
diff --git a/cli/tools/test_runner.rs b/cli/tools/test_runner.rs
index d1a0c6d65..4a8d42e82 100644
--- a/cli/tools/test_runner.rs
+++ b/cli/tools/test_runner.rs
@@ -202,8 +202,128 @@ impl TestReporter for PrettyTestReporter {
}
}
-fn create_reporter(concurrent: bool) -> Box<dyn TestReporter + Send> {
- Box::new(PrettyTestReporter::new(concurrent))
+struct TerseTestReporter {
+ time: Instant,
+ failed: usize,
+ filtered_out: usize,
+ ignored: usize,
+ passed: usize,
+ measured: usize,
+ pending: usize,
+ failures: Vec<(String, String)>,
+}
+
+impl TerseTestReporter {
+ fn new() -> TerseTestReporter {
+ TerseTestReporter {
+ time: Instant::now(),
+ failed: 0,
+ filtered_out: 0,
+ ignored: 0,
+ passed: 0,
+ measured: 0,
+ pending: 0,
+ failures: Vec::new(),
+ }
+ }
+}
+
+impl TestReporter for TerseTestReporter {
+ fn visit_event(&mut self, event: TestEvent) {
+ match &event.message {
+ TestMessage::Plan {
+ pending,
+ filtered,
+ only: _,
+ } => {
+ if *pending == 1 {
+ println!("running {} test from {}", pending, event.origin);
+ } else {
+ println!("running {} tests from {}", pending, event.origin);
+ }
+
+ self.pending += pending;
+ self.filtered_out += filtered;
+ }
+
+ TestMessage::Result {
+ name,
+ duration: _,
+ result,
+ } => {
+ self.pending -= 1;
+
+ match result {
+ TestResult::Ok => {
+ print!("{}", colors::green("."),);
+
+ self.passed += 1;
+ }
+ TestResult::Ignored => {
+ print!("{}", colors::yellow("i"),);
+
+ self.ignored += 1;
+ }
+ TestResult::Failed(error) => {
+ print!("{}", colors::red("F"),);
+
+ self.failed += 1;
+ self.failures.push((name.to_string(), error.to_string()));
+ }
+ }
+ }
+
+ _ => {}
+ }
+ }
+
+ fn done(&mut self) {
+ if !self.failures.is_empty() {
+ println!("\nfailures:\n");
+ for (name, error) in &self.failures {
+ println!("{}", name);
+ println!("{}", error);
+ println!();
+ }
+
+ println!("failures:\n");
+ for (name, _) in &self.failures {
+ println!("\t{}", name);
+ }
+ }
+
+ let status = if self.pending > 0 || !self.failures.is_empty() {
+ colors::red("FAILED").to_string()
+ } else {
+ colors::green("ok").to_string()
+ };
+
+ println!(
+ "\ntest result: {}. {} passed; {} failed; {} ignored; {} measured; {} filtered out {}\n",
+ status,
+ self.passed,
+ self.failed,
+ self.ignored,
+ self.measured,
+ self.filtered_out,
+ colors::gray(format!("({}ms)", self.time.elapsed().as_millis())),
+ );
+ }
+}
+
+enum TestReporterKind {
+ Pretty,
+ Terse,
+}
+
+fn create_reporter(
+ kind: TestReporterKind,
+ concurrent: bool,
+) -> Box<dyn TestReporter + Send> {
+ match kind {
+ TestReporterKind::Pretty => Box::new(PrettyTestReporter::new(concurrent)),
+ TestReporterKind::Terse => Box::new(TerseTestReporter::new()),
+ }
}
pub(crate) fn is_supported(p: &Path) -> bool {
@@ -344,6 +464,7 @@ pub async fn run_tests(
no_run: bool,
fail_fast: bool,
quiet: bool,
+ terse: bool,
allow_none: bool,
filter: Option<String>,
shuffle: Option<u64>,
@@ -510,7 +631,13 @@ pub async fn run_tests(
.buffer_unordered(concurrent_jobs)
.collect::<Vec<Result<Result<(), AnyError>, tokio::task::JoinError>>>();
- let mut reporter = create_reporter(concurrent_jobs > 1);
+ let reporter_kind = if terse {
+ TestReporterKind::Terse
+ } else {
+ TestReporterKind::Pretty
+ };
+
+ let mut reporter = create_reporter(reporter_kind, concurrent_jobs > 1);
let handler = {
tokio::task::spawn_blocking(move || {
let mut used_only = false;