From 806f0d6be0f2c7c0740e318f45959e853c418e69 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 13 Oct 2025 15:38:36 -0500 Subject: [PATCH 1/7] refactor(test2): Pull out main macro --- crates/libtest2/src/lib.rs | 49 ++++++----------------------------- crates/libtest2/src/macros.rs | 40 ++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 41 deletions(-) create mode 100644 crates/libtest2/src/macros.rs diff --git a/crates/libtest2/src/lib.rs b/crates/libtest2/src/lib.rs index a3f834f..d0d57f1 100644 --- a/crates/libtest2/src/lib.rs +++ b/crates/libtest2/src/lib.rs @@ -31,6 +31,14 @@ //#![warn(clippy::print_stderr)] #![warn(clippy::print_stdout)] +mod macros; + +#[doc(hidden)] +pub mod _private { + pub use crate::_main as main; +} + +pub use _private::main as libtest2_main; pub use libtest2_harness::Harness; pub use libtest2_harness::RunError; pub use libtest2_harness::RunResult; @@ -78,47 +86,6 @@ impl Case for Trial { } } -/// Expands to the test harness -#[macro_export] -macro_rules! libtest2_main { - ( $( $test:path ),* $(,)*) => { - fn main() { - let harness = $crate::Harness::new(); - let harness = match harness.with_env() { - Ok(harness) => harness, - Err(err) => { - eprintln!("{err}"); - ::std::process::exit(1); - } - }; - let harness = match harness.parse() { - Ok(harness) => harness, - Err(err) => { - eprintln!("{err}"); - ::std::process::exit(1); - } - }; - let harness = match harness.discover([ - $($crate::Trial::test(::std::stringify!($test), $test)),* - ]) { - Ok(harness) => harness, - Err(err) => { - eprintln!("{err}"); - ::std::process::exit($crate::ERROR_EXIT_CODE) - } - }; - match harness.run() { - Ok(true) => ::std::process::exit(0), - Ok(false) => ::std::process::exit($crate::ERROR_EXIT_CODE), - Err(err) => { - eprintln!("{err}"); - ::std::process::exit($crate::ERROR_EXIT_CODE) - } - } - } - } -} - #[doc = include_str!("../README.md")] #[cfg(doctest)] pub struct ReadmeDoctests; diff --git a/crates/libtest2/src/macros.rs b/crates/libtest2/src/macros.rs new file mode 100644 index 0000000..cd0e772 --- /dev/null +++ b/crates/libtest2/src/macros.rs @@ -0,0 +1,40 @@ +/// Expands to the test harness +#[macro_export] +macro_rules! _main { + ( $( $test:path ),* $(,)*) => { + fn main() { + let harness = $crate::Harness::new(); + let harness = match harness.with_env() { + Ok(harness) => harness, + Err(err) => { + eprintln!("{err}"); + ::std::process::exit(1); + } + }; + let harness = match harness.parse() { + Ok(harness) => harness, + Err(err) => { + eprintln!("{err}"); + ::std::process::exit(1); + } + }; + let harness = match harness.discover([ + $($crate::Trial::test(::std::stringify!($test), $test)),* + ]) { + Ok(harness) => harness, + Err(err) => { + eprintln!("{err}"); + ::std::process::exit($crate::ERROR_EXIT_CODE) + } + }; + match harness.run() { + Ok(true) => ::std::process::exit(0), + Ok(false) => ::std::process::exit($crate::ERROR_EXIT_CODE), + Err(err) => { + eprintln!("{err}"); + ::std::process::exit($crate::ERROR_EXIT_CODE) + } + } + } + } +} From 6c0bf32903cbda7e7c72141b95bd065d5f4aaf87 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 13 Oct 2025 15:40:36 -0500 Subject: [PATCH 2/7] fix(test)!: Rename libtest2_main to main --- crates/libtest2/examples/simple.rs | 2 +- crates/libtest2/src/lib.rs | 7 +++---- crates/libtest2/tests/testsuite/all_passing.rs | 2 +- crates/libtest2/tests/testsuite/argfile.rs | 2 +- crates/libtest2/tests/testsuite/mixed_bag.rs | 2 +- crates/libtest2/tests/testsuite/panic.rs | 2 +- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/crates/libtest2/examples/simple.rs b/crates/libtest2/examples/simple.rs index 040bfce..1ec2b2b 100644 --- a/crates/libtest2/examples/simple.rs +++ b/crates/libtest2/examples/simple.rs @@ -2,7 +2,7 @@ use libtest2::RunError; use libtest2::RunResult; use libtest2::TestContext; -libtest2::libtest2_main!( +libtest2::main!( check_toph, check_katara, check_sokka, diff --git a/crates/libtest2/src/lib.rs b/crates/libtest2/src/lib.rs index d0d57f1..df86c10 100644 --- a/crates/libtest2/src/lib.rs +++ b/crates/libtest2/src/lib.rs @@ -12,18 +12,17 @@ //! harness = false //! ``` //! -//! And in `tests/mytest.rs` you would call [`libtest2_main`], passing it each of your tests: +//! And in `tests/mytest.rs` you would call [`main!`], passing it each of your tests: //! //! ```no_run //! # use libtest2::RunError; //! # use libtest2::RunResult; //! # use libtest2::TestContext; -//! # use libtest2::libtest2_main; //! fn check_toph(_context: &TestContext) -> RunResult { //! Ok(()) //! } //! -//! libtest2_main!(check_toph); +//! libtest2::main!(check_toph); //! ``` //! @@ -38,7 +37,7 @@ pub mod _private { pub use crate::_main as main; } -pub use _private::main as libtest2_main; +pub use _private::main; pub use libtest2_harness::Harness; pub use libtest2_harness::RunError; pub use libtest2_harness::RunResult; diff --git a/crates/libtest2/tests/testsuite/all_passing.rs b/crates/libtest2/tests/testsuite/all_passing.rs index fab4541..7937300 100644 --- a/crates/libtest2/tests/testsuite/all_passing.rs +++ b/crates/libtest2/tests/testsuite/all_passing.rs @@ -7,7 +7,7 @@ fn test_cmd() -> snapbox::cmd::Command { let (bin, current_dir) = BIN.get_or_init(|| { let package_root = crate::util::new_test( r#" -libtest2::libtest2_main!(foo, bar, barro); +libtest2::main!(foo, bar, barro); fn foo(_context: &libtest2::TestContext) -> libtest2::RunResult { Ok(()) diff --git a/crates/libtest2/tests/testsuite/argfile.rs b/crates/libtest2/tests/testsuite/argfile.rs index ad2556b..da6b241 100644 --- a/crates/libtest2/tests/testsuite/argfile.rs +++ b/crates/libtest2/tests/testsuite/argfile.rs @@ -7,7 +7,7 @@ fn test_cmd() -> snapbox::cmd::Command { let (bin, current_dir) = BIN.get_or_init(|| { let package_root = crate::util::new_test( r#" -libtest2::libtest2_main!(one, two, three, one_two); +libtest2::main!(one, two, three, one_two); fn one(_context: &libtest2::TestContext) -> libtest2::RunResult { Ok(()) diff --git a/crates/libtest2/tests/testsuite/mixed_bag.rs b/crates/libtest2/tests/testsuite/mixed_bag.rs index a30cd53..876f920 100644 --- a/crates/libtest2/tests/testsuite/mixed_bag.rs +++ b/crates/libtest2/tests/testsuite/mixed_bag.rs @@ -7,7 +7,7 @@ fn test_cmd() -> snapbox::cmd::Command { let (bin, current_dir) = BIN.get_or_init(|| { let package_root = crate::util::new_test( r#" -libtest2::libtest2_main!(cat, dog, fox, bunny, frog, owl, fly, bear); +libtest2::main!(cat, dog, fox, bunny, frog, owl, fly, bear); fn cat(_context: &libtest2::TestContext) -> libtest2::RunResult { Ok(()) diff --git a/crates/libtest2/tests/testsuite/panic.rs b/crates/libtest2/tests/testsuite/panic.rs index b99d661..6f6fbe1 100644 --- a/crates/libtest2/tests/testsuite/panic.rs +++ b/crates/libtest2/tests/testsuite/panic.rs @@ -7,7 +7,7 @@ fn test_cmd() -> snapbox::cmd::Command { let (bin, current_dir) = BIN.get_or_init(|| { let package_root = crate::util::new_test( r#" -libtest2::libtest2_main!(passes, panics); +libtest2::main!(passes, panics); fn passes(_context: &libtest2::TestContext) -> libtest2::RunResult { Ok(()) From 8c90495071ce126bebd922d20521b37293bbd401 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 13 Oct 2025 16:01:46 -0500 Subject: [PATCH 3/7] refactor(test2): Pull out main body --- crates/libtest2/src/lib.rs | 33 +++++++++++++++++++++++++++++++++ crates/libtest2/src/macros.rs | 33 ++------------------------------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/crates/libtest2/src/lib.rs b/crates/libtest2/src/lib.rs index df86c10..52939d5 100644 --- a/crates/libtest2/src/lib.rs +++ b/crates/libtest2/src/lib.rs @@ -85,6 +85,39 @@ impl Case for Trial { } } +pub fn main(cases: impl IntoIterator) { + let harness = libtest2_harness::Harness::new(); + let harness = match harness.with_env() { + Ok(harness) => harness, + Err(err) => { + eprintln!("{err}"); + ::std::process::exit(1); + } + }; + let harness = match harness.parse() { + Ok(harness) => harness, + Err(err) => { + eprintln!("{err}"); + ::std::process::exit(1); + } + }; + let harness = match harness.discover(cases) { + Ok(harness) => harness, + Err(err) => { + eprintln!("{err}"); + ::std::process::exit(libtest2_harness::ERROR_EXIT_CODE) + } + }; + match harness.run() { + Ok(true) => ::std::process::exit(0), + Ok(false) => ::std::process::exit(libtest2_harness::ERROR_EXIT_CODE), + Err(err) => { + eprintln!("{err}"); + ::std::process::exit(libtest2_harness::ERROR_EXIT_CODE) + } + } +} + #[doc = include_str!("../README.md")] #[cfg(doctest)] pub struct ReadmeDoctests; diff --git a/crates/libtest2/src/macros.rs b/crates/libtest2/src/macros.rs index cd0e772..1b0ab6c 100644 --- a/crates/libtest2/src/macros.rs +++ b/crates/libtest2/src/macros.rs @@ -3,38 +3,9 @@ macro_rules! _main { ( $( $test:path ),* $(,)*) => { fn main() { - let harness = $crate::Harness::new(); - let harness = match harness.with_env() { - Ok(harness) => harness, - Err(err) => { - eprintln!("{err}"); - ::std::process::exit(1); - } - }; - let harness = match harness.parse() { - Ok(harness) => harness, - Err(err) => { - eprintln!("{err}"); - ::std::process::exit(1); - } - }; - let harness = match harness.discover([ + $crate::main([ $($crate::Trial::test(::std::stringify!($test), $test)),* - ]) { - Ok(harness) => harness, - Err(err) => { - eprintln!("{err}"); - ::std::process::exit($crate::ERROR_EXIT_CODE) - } - }; - match harness.run() { - Ok(true) => ::std::process::exit(0), - Ok(false) => ::std::process::exit($crate::ERROR_EXIT_CODE), - Err(err) => { - eprintln!("{err}"); - ::std::process::exit($crate::ERROR_EXIT_CODE) - } - } + ]); } } } From 9107d7373c654ac33490f5cfdf1d3558977f0c40 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 13 Oct 2025 16:02:47 -0500 Subject: [PATCH 4/7] fix(test2)!: Remove Harness, TestKind, ERROR_EXIT_CODE --- crates/libtest2/src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/libtest2/src/lib.rs b/crates/libtest2/src/lib.rs index 52939d5..f6eff19 100644 --- a/crates/libtest2/src/lib.rs +++ b/crates/libtest2/src/lib.rs @@ -38,15 +38,13 @@ pub mod _private { } pub use _private::main; -pub use libtest2_harness::Harness; pub use libtest2_harness::RunError; pub use libtest2_harness::RunResult; pub use libtest2_harness::TestContext; -pub use libtest2_harness::TestKind; -pub use libtest2_harness::ERROR_EXIT_CODE; use libtest2_harness::Case; use libtest2_harness::Source; +use libtest2_harness::TestKind; pub struct Trial { name: String, From c12446cc0dc57f8268448d64a391ea19dee52e5d Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 13 Oct 2025 16:03:42 -0500 Subject: [PATCH 5/7] refactor(test2): Leverage RunResult --- crates/libtest2/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/libtest2/src/lib.rs b/crates/libtest2/src/lib.rs index f6eff19..b63713e 100644 --- a/crates/libtest2/src/lib.rs +++ b/crates/libtest2/src/lib.rs @@ -49,13 +49,13 @@ use libtest2_harness::TestKind; pub struct Trial { name: String, #[allow(clippy::type_complexity)] - runner: Box Result<(), RunError> + Send + Sync>, + runner: Box RunResult + Send + Sync>, } impl Trial { pub fn test( name: impl Into, - runner: impl Fn(&TestContext) -> Result<(), RunError> + Send + Sync + 'static, + runner: impl Fn(&TestContext) -> RunResult + Send + Sync + 'static, ) -> Self { Self { name: name.into(), @@ -78,7 +78,7 @@ impl Case for Trial { false } - fn run(&self, context: &TestContext) -> Result<(), RunError> { + fn run(&self, context: &TestContext) -> RunResult { (self.runner)(context) } } From 06a2551871775dc8ce8d4b7a38b1140c7dbea715 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 13 Oct 2025 16:05:01 -0500 Subject: [PATCH 6/7] refactor(test2): Pull out trial.rs --- crates/libtest2/src/lib.rs | 77 ++---------------------------------- crates/libtest2/src/trial.rs | 76 +++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 74 deletions(-) create mode 100644 crates/libtest2/src/trial.rs diff --git a/crates/libtest2/src/lib.rs b/crates/libtest2/src/lib.rs index b63713e..5d4e5e7 100644 --- a/crates/libtest2/src/lib.rs +++ b/crates/libtest2/src/lib.rs @@ -31,6 +31,7 @@ #![warn(clippy::print_stdout)] mod macros; +mod trial; #[doc(hidden)] pub mod _private { @@ -41,80 +42,8 @@ pub use _private::main; pub use libtest2_harness::RunError; pub use libtest2_harness::RunResult; pub use libtest2_harness::TestContext; - -use libtest2_harness::Case; -use libtest2_harness::Source; -use libtest2_harness::TestKind; - -pub struct Trial { - name: String, - #[allow(clippy::type_complexity)] - runner: Box RunResult + Send + Sync>, -} - -impl Trial { - pub fn test( - name: impl Into, - runner: impl Fn(&TestContext) -> RunResult + Send + Sync + 'static, - ) -> Self { - Self { - name: name.into(), - runner: Box::new(runner), - } - } -} - -impl Case for Trial { - fn name(&self) -> &str { - &self.name - } - fn kind(&self) -> TestKind { - Default::default() - } - fn source(&self) -> Option<&Source> { - None - } - fn exclusive(&self, _: &TestContext) -> bool { - false - } - - fn run(&self, context: &TestContext) -> RunResult { - (self.runner)(context) - } -} - -pub fn main(cases: impl IntoIterator) { - let harness = libtest2_harness::Harness::new(); - let harness = match harness.with_env() { - Ok(harness) => harness, - Err(err) => { - eprintln!("{err}"); - ::std::process::exit(1); - } - }; - let harness = match harness.parse() { - Ok(harness) => harness, - Err(err) => { - eprintln!("{err}"); - ::std::process::exit(1); - } - }; - let harness = match harness.discover(cases) { - Ok(harness) => harness, - Err(err) => { - eprintln!("{err}"); - ::std::process::exit(libtest2_harness::ERROR_EXIT_CODE) - } - }; - match harness.run() { - Ok(true) => ::std::process::exit(0), - Ok(false) => ::std::process::exit(libtest2_harness::ERROR_EXIT_CODE), - Err(err) => { - eprintln!("{err}"); - ::std::process::exit(libtest2_harness::ERROR_EXIT_CODE) - } - } -} +pub use trial::main; +pub use trial::Trial; #[doc = include_str!("../README.md")] #[cfg(doctest)] diff --git a/crates/libtest2/src/trial.rs b/crates/libtest2/src/trial.rs new file mode 100644 index 0000000..456ffcf --- /dev/null +++ b/crates/libtest2/src/trial.rs @@ -0,0 +1,76 @@ +use libtest2_harness::Case; +use libtest2_harness::Source; +use libtest2_harness::TestKind; + +use crate::RunResult; +use crate::TestContext; + +pub struct Trial { + name: String, + #[allow(clippy::type_complexity)] + runner: Box RunResult + Send + Sync>, +} + +impl Trial { + pub fn test( + name: impl Into, + runner: impl Fn(&TestContext) -> RunResult + Send + Sync + 'static, + ) -> Self { + Self { + name: name.into(), + runner: Box::new(runner), + } + } +} + +impl Case for Trial { + fn name(&self) -> &str { + &self.name + } + fn kind(&self) -> TestKind { + Default::default() + } + fn source(&self) -> Option<&Source> { + None + } + fn exclusive(&self, _: &TestContext) -> bool { + false + } + + fn run(&self, context: &TestContext) -> RunResult { + (self.runner)(context) + } +} + +pub fn main(cases: impl IntoIterator) { + let harness = libtest2_harness::Harness::new(); + let harness = match harness.with_env() { + Ok(harness) => harness, + Err(err) => { + eprintln!("{err}"); + ::std::process::exit(1); + } + }; + let harness = match harness.parse() { + Ok(harness) => harness, + Err(err) => { + eprintln!("{err}"); + ::std::process::exit(1); + } + }; + let harness = match harness.discover(cases) { + Ok(harness) => harness, + Err(err) => { + eprintln!("{err}"); + ::std::process::exit(libtest2_harness::ERROR_EXIT_CODE) + } + }; + match harness.run() { + Ok(true) => ::std::process::exit(0), + Ok(false) => ::std::process::exit(libtest2_harness::ERROR_EXIT_CODE), + Err(err) => { + eprintln!("{err}"); + ::std::process::exit(libtest2_harness::ERROR_EXIT_CODE) + } + } +} From e74d06c2ceb858d0445dfe5015be39aa7537897d Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 13 Oct 2025 16:15:31 -0500 Subject: [PATCH 7/7] fix(test2): Rename Trial to FnCase --- crates/libtest2/examples/tidy.rs | 8 ++++---- crates/libtest2/src/{trial.rs => case.rs} | 6 +++--- crates/libtest2/src/lib.rs | 6 +++--- crates/libtest2/src/macros.rs | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) rename crates/libtest2/src/{trial.rs => case.rs} (97%) diff --git a/crates/libtest2/examples/tidy.rs b/crates/libtest2/examples/tidy.rs index 7c9b588..752c85d 100644 --- a/crates/libtest2/examples/tidy.rs +++ b/crates/libtest2/examples/tidy.rs @@ -1,6 +1,6 @@ +use libtest2::FnCase; use libtest2::RunError; use libtest2::RunResult; -use libtest2::Trial; fn main() -> std::io::Result<()> { let harness = ::libtest2_harness::Harness::new(); @@ -23,8 +23,8 @@ fn main() -> std::io::Result<()> { /// Creates one test for each `.rs` file in the current directory or /// sub-directories of the current directory. -fn collect_tests() -> std::io::Result> { - fn visit_dir(path: &std::path::Path, tests: &mut Vec) -> std::io::Result<()> { +fn collect_tests() -> std::io::Result> { + fn visit_dir(path: &std::path::Path, tests: &mut Vec) -> std::io::Result<()> { let current_dir = std::env::current_dir()?; for entry in std::fs::read_dir(path)? { let entry = entry?; @@ -44,7 +44,7 @@ fn collect_tests() -> std::io::Result> { .to_string_lossy() .into_owned(); - let test = Trial::test(name, move |_| check_file(&path)); + let test = FnCase::test(name, move |_| check_file(&path)); tests.push(test); } } else if file_type.is_dir() { diff --git a/crates/libtest2/src/trial.rs b/crates/libtest2/src/case.rs similarity index 97% rename from crates/libtest2/src/trial.rs rename to crates/libtest2/src/case.rs index 456ffcf..914cc4e 100644 --- a/crates/libtest2/src/trial.rs +++ b/crates/libtest2/src/case.rs @@ -5,13 +5,13 @@ use libtest2_harness::TestKind; use crate::RunResult; use crate::TestContext; -pub struct Trial { +pub struct FnCase { name: String, #[allow(clippy::type_complexity)] runner: Box RunResult + Send + Sync>, } -impl Trial { +impl FnCase { pub fn test( name: impl Into, runner: impl Fn(&TestContext) -> RunResult + Send + Sync + 'static, @@ -23,7 +23,7 @@ impl Trial { } } -impl Case for Trial { +impl Case for FnCase { fn name(&self) -> &str { &self.name } diff --git a/crates/libtest2/src/lib.rs b/crates/libtest2/src/lib.rs index 5d4e5e7..06254d3 100644 --- a/crates/libtest2/src/lib.rs +++ b/crates/libtest2/src/lib.rs @@ -30,8 +30,8 @@ //#![warn(clippy::print_stderr)] #![warn(clippy::print_stdout)] +mod case; mod macros; -mod trial; #[doc(hidden)] pub mod _private { @@ -39,11 +39,11 @@ pub mod _private { } pub use _private::main; +pub use case::main; +pub use case::FnCase; pub use libtest2_harness::RunError; pub use libtest2_harness::RunResult; pub use libtest2_harness::TestContext; -pub use trial::main; -pub use trial::Trial; #[doc = include_str!("../README.md")] #[cfg(doctest)] diff --git a/crates/libtest2/src/macros.rs b/crates/libtest2/src/macros.rs index 1b0ab6c..82e44ef 100644 --- a/crates/libtest2/src/macros.rs +++ b/crates/libtest2/src/macros.rs @@ -4,7 +4,7 @@ macro_rules! _main { ( $( $test:path ),* $(,)*) => { fn main() { $crate::main([ - $($crate::Trial::test(::std::stringify!($test), $test)),* + $($crate::FnCase::test(::std::stringify!($test), $test)),* ]); } }