From 8e0cc4bad312fc8e9c2eac269c23ba5ba2ad3cfc Mon Sep 17 00:00:00 2001 From: Herman Skogseth Date: Mon, 20 Oct 2025 19:04:26 +0200 Subject: [PATCH] feat: Expose list of tests with less magic Prior to this change the static variable `TESTS` had to be declared in the root of the crate in which the `#[libtest2::test]` macros were used. This was automatically inserted by the `#[libtest2::main]` macro, but if the user did not include this an error would be shown. A consequence of this is that the `#[libtest2::test]` macro could not be used on its own to collect tests, unless the user accessed the hidden, private API exposed in the `_private` module. The obvious downside of this change is that the user will no longer receive an error message if they use the `#[libtest2::test]` macro without `#[libtest2::main]`, and thus no tests will be run. The compiler will, however, still complain if the user is missing a `main` function. --- crates/libtest2/src/lib.rs | 12 ++++++++++++ crates/libtest2/src/macros.rs | 6 ++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/crates/libtest2/src/lib.rs b/crates/libtest2/src/lib.rs index 61f5d17..b95f651 100644 --- a/crates/libtest2/src/lib.rs +++ b/crates/libtest2/src/lib.rs @@ -46,6 +46,11 @@ pub mod _private { pub use crate::_main_parse as main_parse; pub use crate::_test_parse as test_parse; pub use crate::case::DynCase; + + /// Static variable used to collect functions annotated with `#[libtest2::test]` + /// + /// Values are pushed to this by the [`crate::macros::test_parse`](`test_parse`) macro + pub static TESTS: DistributedList = DistributedList::root(); } pub use case::main; @@ -59,3 +64,10 @@ pub use libtest2_proc_macro::test; #[doc = include_str!("../README.md")] #[cfg(doctest)] pub struct ReadmeDoctests; + +/// Get an iterator to all collected test functions +/// +/// Functions can be marked for collection by annotating them with the `#[libtest2::test]` macro +pub fn get_tests() -> impl Iterator { + _private::TESTS.iter().copied() +} diff --git a/crates/libtest2/src/macros.rs b/crates/libtest2/src/macros.rs index 6113b33..37776ff 100644 --- a/crates/libtest2/src/macros.rs +++ b/crates/libtest2/src/macros.rs @@ -1,13 +1,11 @@ #[macro_export] macro_rules! _main_parse { (#[main] fn main $($item:tt)*) => { - static TESTS: $crate::_private::DistributedList<$crate::_private::DynCase> = $crate::_private::DistributedList::root(); - fn main() { fn inner $($item)* inner(); - $crate::main(TESTS.iter().copied()); + $crate::main($crate::get_tests()); } }; } @@ -21,7 +19,7 @@ macro_rules! _test_parse { impl $crate::_private::Case for $name { fn name(&self) -> &str { - $crate::_private::push!(crate::TESTS, _: $crate::_private::DynCase = $crate::_private::DynCase(&$name)); + $crate::_private::push!($crate::_private::TESTS, _: $crate::_private::DynCase = $crate::_private::DynCase(&$name)); stringify!($name) }