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