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