summaryrefslogtreecommitdiff
path: root/tests/src
diff options
context:
space:
mode:
Diffstat (limited to 'tests/src')
-rw-r--r--tests/src/args.rs23
-rw-r--r--tests/src/collect.rs25
-rw-r--r--tests/src/logger.rs14
-rw-r--r--tests/src/tests.rs12
4 files changed, 50 insertions, 24 deletions
diff --git a/tests/src/args.rs b/tests/src/args.rs
index fcd4ead1..33935edf 100644
--- a/tests/src/args.rs
+++ b/tests/src/args.rs
@@ -1,19 +1,30 @@
+use std::path::PathBuf;
+
use clap::{Parser, Subcommand};
+use regex::Regex;
/// Typst's test runner.
#[derive(Debug, Clone, Parser)]
+#[command(bin_name = "cargo test --workspace --test tests --")]
#[clap(name = "typst-test", author)]
pub struct CliArguments {
/// The command to run.
#[command(subcommand)]
pub command: Option<Command>,
- /// All the tests that contain the filter string will be run.
- pub filter: Vec<String>,
- /// Runs only the tests with the exact specified `filter` names.
+ /// All the tests whose names match the test name pattern will be run.
+ #[arg(value_parser = Regex::new)]
+ pub pattern: Vec<Regex>,
+ /// Restricts test selection within the given path.
+ #[arg(short, long, value_parser = |s: &str| PathBuf::from(s).canonicalize())]
+ pub path: Vec<PathBuf>,
+ /// Only selects the test that matches with the test name verbatim.
#[arg(short, long)]
pub exact: bool,
- /// Whether to update the reference images of non-passing tests.
- #[arg(short, long)]
+ /// Lists what tests will be run, without actually running them.
+ #[arg(long, group = "action")]
+ pub list: bool,
+ /// Updates the reference images of non-passing tests.
+ #[arg(short, long, group = "action")]
pub update: bool,
/// The scaling factor to render the output image with.
///
@@ -26,7 +37,7 @@ pub struct CliArguments {
/// Exports SVG outputs into the artifact store.
#[arg(long)]
pub svg: bool,
- /// Whether to display the syntax tree.
+ /// Displays the syntax tree.
#[arg(long)]
pub syntax: bool,
/// Prevents the terminal from being cleared of test names.
diff --git a/tests/src/collect.rs b/tests/src/collect.rs
index 44a325f2..ee4f9db9 100644
--- a/tests/src/collect.rs
+++ b/tests/src/collect.rs
@@ -257,7 +257,7 @@ impl<'a> Parser<'a> {
self.collector.large.insert(name.clone());
}
- if !filtered(&name) {
+ if !selected(&name, self.path.canonicalize().unwrap()) {
self.collector.skipped += 1;
continue;
}
@@ -383,14 +383,23 @@ impl<'a> Parser<'a> {
}
}
-/// Whether a test is within the filtered set.
-fn filtered(name: &str) -> bool {
+/// Whether a test is within the selected set to run.
+fn selected(name: &str, abs: PathBuf) -> bool {
+ let paths = &crate::ARGS.path;
+ if !paths.is_empty() && !paths.iter().any(|path| abs.starts_with(path)) {
+ return false;
+ }
+
let exact = crate::ARGS.exact;
- let filter = &crate::ARGS.filter;
- filter.is_empty()
- || filter
- .iter()
- .any(|v| if exact { name == v } else { name.contains(v) })
+ let patterns = &crate::ARGS.pattern;
+ patterns.is_empty()
+ || patterns.iter().any(|pattern: &regex::Regex| {
+ if exact {
+ name == pattern.as_str()
+ } else {
+ pattern.is_match(name)
+ }
+ })
}
/// An error in a test file.
diff --git a/tests/src/logger.rs b/tests/src/logger.rs
index c48650a7..1acf7c14 100644
--- a/tests/src/logger.rs
+++ b/tests/src/logger.rs
@@ -6,7 +6,7 @@ use crate::run::TestResult;
/// Receives status updates by individual test runs.
pub struct Logger<'a> {
- filtered: usize,
+ selected: usize,
passed: usize,
failed: usize,
skipped: usize,
@@ -19,9 +19,9 @@ pub struct Logger<'a> {
impl<'a> Logger<'a> {
/// Create a new logger.
- pub fn new(filtered: usize, skipped: usize) -> Self {
+ pub fn new(selected: usize, skipped: usize) -> Self {
Self {
- filtered,
+ selected,
passed: 0,
failed: 0,
skipped,
@@ -86,10 +86,10 @@ impl<'a> Logger<'a> {
/// Prints a summary and returns whether the test suite passed.
pub fn finish(&self) -> bool {
- let Self { filtered, passed, failed, skipped, .. } = *self;
+ let Self { selected, passed, failed, skipped, .. } = *self;
eprintln!("{passed} passed, {failed} failed, {skipped} skipped");
- assert_eq!(filtered, passed + failed, "not all tests were executed succesfully");
+ assert_eq!(selected, passed + failed, "not all tests were executed succesfully");
if self.mismatched_image {
eprintln!(" pass the --update flag to update the reference images");
@@ -121,7 +121,7 @@ impl<'a> Logger<'a> {
// Print the status line.
let done = self.failed + self.passed;
- if done < self.filtered {
+ if done < self.selected {
if self.last_change.elapsed() > Duration::from_secs(2) {
for test in &self.active {
writeln!(out, "⏰ {test} is taking a long time ...")?;
@@ -131,7 +131,7 @@ impl<'a> Logger<'a> {
}
}
if self.terminal {
- writeln!(out, "💨 {done} / {}", self.filtered)?;
+ writeln!(out, "💨 {done} / {}", self.selected)?;
self.temp_lines += 1;
}
}
diff --git a/tests/src/tests.rs b/tests/src/tests.rs
index 6d58e969..19d9e5e9 100644
--- a/tests/src/tests.rs
+++ b/tests/src/tests.rs
@@ -72,14 +72,20 @@ fn test() {
}
};
- let filtered = tests.len();
- if filtered == 0 {
+ let selected = tests.len();
+ if ARGS.list {
+ for test in tests.iter() {
+ println!("{test}");
+ }
+ eprintln!("{selected} selected, {skipped} skipped");
+ return;
+ } else if selected == 0 {
eprintln!("no test selected");
return;
}
// Run the tests.
- let logger = Mutex::new(Logger::new(filtered, skipped));
+ let logger = Mutex::new(Logger::new(selected, skipped));
std::thread::scope(|scope| {
let logger = &logger;
let (sender, receiver) = std::sync::mpsc::channel();