1 //! Test harness which supports ignoring tests at runtime. 2 3 pub mod runner; 4 5 // Re-export the attribute macros. 6 pub use rdroidtest_macro::{ignore_if, rdroidtest}; 7 8 #[doc(hidden)] 9 pub use libtest_mimic as _libtest_mimic; 10 #[doc(hidden)] 11 pub use linkme as _linkme; 12 #[doc(hidden)] 13 pub use paste as _paste; 14 15 /// Macro to generate the main function for the test harness. 16 #[macro_export] 17 macro_rules! test_main { 18 () => { 19 #[cfg(test)] 20 fn main() { 21 $crate::runner::main() 22 } 23 }; 24 } 25 26 /// Macro to generate a wrapper function for a single test. 27 /// 28 /// # Usage 29 /// 30 /// ``` 31 /// use rdroidtest::test; 32 /// 33 /// test!(test_string_equality); 34 /// fn test_string_equality() { 35 /// assert_eq!("", ""); 36 /// } 37 /// ``` 38 #[macro_export] 39 macro_rules! test { 40 ($test_name:ident) => { 41 $crate::_paste::paste!( 42 #[$crate::_linkme::distributed_slice($crate::runner::RDROIDTEST_TESTS)] 43 fn [< __test_ $test_name >]() -> $crate::_libtest_mimic::Trial { 44 $crate::_libtest_mimic::Trial::test( 45 ::std::stringify!($test_name), 46 move || $crate::runner::run($test_name), 47 ) 48 } 49 ); 50 }; 51 ($test_name:ident, ignore_if: $ignore_expr:expr) => { 52 $crate::_paste::paste!( 53 #[$crate::_linkme::distributed_slice($crate::runner::RDROIDTEST_TESTS)] 54 fn [< __test_ $test_name >]() -> $crate::_libtest_mimic::Trial { 55 $crate::_libtest_mimic::Trial::test( 56 ::std::stringify!($test_name), 57 move || $crate::runner::run($test_name), 58 ).with_ignored_flag($ignore_expr) 59 } 60 ); 61 }; 62 } 63 64 /// Macro to generate a wrapper function for a parameterized test. 65 /// 66 /// # Usage 67 /// 68 /// ``` 69 /// use rdroidtest::ptest; 70 /// 71 /// /// Return (param name, param value) tuples of type `(String, T)`. 72 /// /// The parameter value can be any type T (not just `u32`). 73 /// fn my_instances() -> Vec<(String, u32)> { 74 /// vec![ 75 /// ("one".to_string(), 1), 76 /// ("two".to_string(), 2), 77 /// ("three".to_string(), 3), 78 /// ] 79 /// } 80 /// 81 /// ptest!(is_even, my_instances()); 82 /// fn is_even(param: u32) { 83 /// // Test method takes a parameter of type T. 84 /// assert_eq!(param % 2, 0); 85 /// } 86 /// ``` 87 #[macro_export] 88 macro_rules! ptest { 89 ($test_name:ident, $param_gen:expr) => { 90 $crate::_paste::paste!( 91 #[$crate::_linkme::distributed_slice($crate::runner::RDROIDTEST_PTESTS)] 92 fn [< __ptest_ $test_name >]() -> Vec<$crate::_libtest_mimic::Trial> { 93 $param_gen.into_iter().map(|(name, val)| { 94 $crate::_libtest_mimic::Trial::test( 95 format!("{}/{}", ::std::stringify!($test_name), name), 96 move || $crate::runner::run(|| $test_name(val)), 97 ) 98 }).collect() 99 } 100 ); 101 }; 102 ($test_name:ident, $param_gen:expr, ignore_if: $ignore_expr:expr) => { 103 $crate::_paste::paste!( 104 #[$crate::_linkme::distributed_slice($crate::runner::RDROIDTEST_PTESTS)] 105 fn [< __ptest_ $test_name >]() -> Vec<$crate::_libtest_mimic::Trial> { 106 $param_gen.into_iter().map(|(name, val)| { 107 let ignored = $ignore_expr(&val); 108 $crate::_libtest_mimic::Trial::test( 109 format!("{}/{}", ::std::stringify!($test_name), name), 110 move || $crate::runner::run(|| $test_name(val)), 111 ).with_ignored_flag(ignored) 112 }).collect() 113 } 114 ); 115 }; 116 } 117