From 4f8f05fa726fbc82bdec2ab5f3aae9634cce65fe Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 30 Oct 2025 16:36:21 -0500 Subject: [PATCH 1/2] feat(harness): Allow Box, Arc Cases --- crates/libtest2-harness/src/case.rs | 38 +++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/crates/libtest2-harness/src/case.rs b/crates/libtest2-harness/src/case.rs index ac9930b..896876b 100644 --- a/crates/libtest2-harness/src/case.rs +++ b/crates/libtest2-harness/src/case.rs @@ -17,6 +17,44 @@ pub trait Case: Send + Sync + 'static { fn run(&self, state: &TestContext) -> Result<(), RunError>; } +impl Case for Box { + fn name(&self) -> &str { + self.as_ref().name() + } + fn kind(&self) -> TestKind { + self.as_ref().kind() + } + fn source(&self) -> Option<&Source> { + self.as_ref().source() + } + fn exclusive(&self, state: &TestContext) -> bool { + self.as_ref().exclusive(state) + } + + fn run(&self, state: &TestContext) -> Result<(), RunError> { + self.as_ref().run(state) + } +} + +impl Case for std::sync::Arc { + fn name(&self) -> &str { + self.as_ref().name() + } + fn kind(&self) -> TestKind { + self.as_ref().kind() + } + fn source(&self) -> Option<&Source> { + self.as_ref().source() + } + fn exclusive(&self, state: &TestContext) -> bool { + self.as_ref().exclusive(state) + } + + fn run(&self, state: &TestContext) -> Result<(), RunError> { + self.as_ref().run(state) + } +} + /// Type of the test according to the [rust book](https://doc.rust-lang.org/cargo/guide/tests.html) /// conventions. #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)] From e9ea611f5fcd3c467ecf739326f5caf1f36b323a Mon Sep 17 00:00:00 2001 From: Ed Page Date: Thu, 30 Oct 2025 16:36:41 -0500 Subject: [PATCH 2/2] fix(test2)!: Dont require boxing in FnCase --- crates/libtest2/examples/tidy.rs | 7 ++++--- crates/libtest2/src/case.rs | 22 ++++++++++++---------- crates/libtest2/src/lib.rs | 2 +- crates/libtest2/src/macros.rs | 2 +- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/crates/libtest2/examples/tidy.rs b/crates/libtest2/examples/tidy.rs index 752c85d..11cbe5c 100644 --- a/crates/libtest2/examples/tidy.rs +++ b/crates/libtest2/examples/tidy.rs @@ -1,3 +1,4 @@ +use libtest2::Case; use libtest2::FnCase; use libtest2::RunError; use libtest2::RunResult; @@ -23,8 +24,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?; @@ -45,7 +46,7 @@ fn collect_tests() -> std::io::Result> { .into_owned(); let test = FnCase::test(name, move |_| check_file(&path)); - tests.push(test); + tests.push(Box::new(test)); } } else if file_type.is_dir() { // Handle directories diff --git a/crates/libtest2/src/case.rs b/crates/libtest2/src/case.rs index 079e45b..970eea6 100644 --- a/crates/libtest2/src/case.rs +++ b/crates/libtest2/src/case.rs @@ -27,25 +27,27 @@ impl Case for DynCase { } } -pub struct FnCase { +pub struct FnCase { name: String, - #[allow(clippy::type_complexity)] - runner: Box RunResult + Send + Sync>, + runner: R, } -impl FnCase { - pub fn test( - name: impl Into, - runner: impl Fn(&TestContext) -> RunResult + Send + Sync + 'static, - ) -> Self { +impl FnCase +where + R: Fn(&TestContext) -> RunResult + Send + Sync + 'static, +{ + pub fn test(name: impl Into, runner: R) -> Self { Self { name: name.into(), - runner: Box::new(runner), + runner, } } } -impl Case for FnCase { +impl Case for FnCase +where + R: Fn(&TestContext) -> RunResult + Send + Sync + 'static, +{ fn name(&self) -> &str { &self.name } diff --git a/crates/libtest2/src/lib.rs b/crates/libtest2/src/lib.rs index 17634d2..36a98f9 100644 --- a/crates/libtest2/src/lib.rs +++ b/crates/libtest2/src/lib.rs @@ -59,7 +59,6 @@ pub mod panic; pub mod _private { pub use distributed_list::push; pub use distributed_list::DistributedList; - pub use libtest2_harness::Case; pub use libtest2_harness::Source; pub use libtest2_harness::TestKind; @@ -72,6 +71,7 @@ pub mod _private { pub use case::main; pub use case::FnCase; +pub use libtest2_harness::Case; pub use libtest2_harness::IntoRunResult; pub use libtest2_harness::RunError; pub use libtest2_harness::RunResult; diff --git a/crates/libtest2/src/macros.rs b/crates/libtest2/src/macros.rs index 9441dbb..d52d5a7 100644 --- a/crates/libtest2/src/macros.rs +++ b/crates/libtest2/src/macros.rs @@ -106,7 +106,7 @@ macro_rules! _test_parse { #[allow(non_camel_case_types)] struct $name; - impl $crate::_private::Case for $name { + impl $crate::Case for $name { fn name(&self) -> &str { $crate::_private::push!(crate::TESTS, _: $crate::_private::DynCase = $crate::_private::DynCase(&$name));