1 /* 2 * This file is derived from src/macros/mod.rs in the Rust libcore, used under 3 * the Apache License, Version 2.0. The following is the original copyright 4 * information from the Rust project: 5 * 6 * Copyrights in the Rust project are retained by their contributors. No 7 * copyright assignment is required to contribute to the Rust project. 8 * 9 * Some files include explicit copyright notices and/or license notices. 10 * For full authorship information, see the version control history or 11 * https://thanks.rust-lang.org 12 * 13 * Except as otherwise noted (below and/or in individual files), Rust is 14 * licensed under the Apache License, Version 2.0 <LICENSE-APACHE> or 15 * <http://www.apache.org/licenses/LICENSE-2.0> or the MIT license 16 * <LICENSE-MIT> or <http://opensource.org/licenses/MIT>, at your option. 17 * 18 * 19 * Licensed under the Apache License, Version 2.0 (the "License"); 20 * you may not use this file except in compliance with the License. 21 * You may obtain a copy of the License at 22 * 23 * http://www.apache.org/licenses/LICENSE-2.0 24 * 25 * Unless required by applicable law or agreed to in writing, software 26 * distributed under the License is distributed on an "AS IS" BASIS, 27 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 28 * See the License for the specific language governing permissions and 29 * limitations under the License. 30 */ 31 32 /// Expects two expressions are equal to each other (using [`PartialEq`]). 33 /// 34 /// On failure, this macro will print the values of the expressions with their 35 /// debug representations and signal the failure to the test framework. The test 36 /// will continue past the failure. 37 /// 38 /// Like [`assert!`], this macro has a second form, where a custom 39 /// error message can be provided. 40 /// 41 /// # Examples 42 /// 43 /// ``` 44 /// let a = 3; 45 /// let b = 1 + 2; 46 /// expect_eq!(a, b); 47 /// 48 /// expect_eq!(a, b, "we are testing addition with {} and {}", a, b); 49 /// ``` 50 #[macro_export] 51 macro_rules! expect_eq { 52 ($left:expr, $right:expr $(,)?) => ({ 53 match (&$left, &$right) { 54 (left_val, right_val) => { 55 if !(*left_val == *right_val) { 56 let kind = $crate::asserts::AssertKind::Eq; 57 // The reborrows below are intentional. Without them, the stack slot for the 58 // borrow is initialized even before the values are compared, leading to a 59 // noticeable slow down. 60 $crate::asserts::assert_failed(kind, &*left_val, &*right_val, core::option::Option::None); 61 } 62 } 63 } 64 }); 65 ($left:expr, $right:expr, $($arg:tt)+) => ({ 66 match (&$left, &$right) { 67 (left_val, right_val) => { 68 if !(*left_val == *right_val) { 69 let kind = $crate::asserts::AssertKind::Eq; 70 // The reborrows below are intentional. Without them, the stack slot for the 71 // borrow is initialized even before the values are compared, leading to a 72 // noticeable slow down. 73 $crate::asserts::assert_failed(kind, &*left_val, &*right_val, core::option::Option::Some(core::format_args!($($arg)+))); 74 } 75 } 76 } 77 }); 78 } 79 80 /// Asserts that two expressions are equal to each other (using [`PartialEq`]). 81 /// 82 /// Unlike [`core::assert_eq!`], this macro will not panic, but instead returns 83 /// early from a test function. 84 /// 85 /// Like [`assert!`], this macro has a second form, where a custom 86 /// panic message can be provided. 87 /// 88 /// # Examples 89 /// 90 /// ``` 91 /// let a = 3; 92 /// let b = 1 + 2; 93 /// assert_eq!(a, b); 94 /// 95 /// assert_eq!(a, b, "we are testing addition with {} and {}", a, b); 96 /// ``` 97 #[macro_export] 98 macro_rules! assert_eq { 99 ($left:expr, $right:expr $(,)?) => ({ 100 match (&$left, &$right) { 101 (left_val, right_val) => { 102 if !(*left_val == *right_val) { 103 let kind = $crate::asserts::AssertKind::Eq; 104 // The reborrows below are intentional. Without them, the stack slot for the 105 // borrow is initialized even before the values are compared, leading to a 106 // noticeable slow down. 107 $crate::asserts::assert_failed(kind, &*left_val, &*right_val, core::option::Option::None); 108 return; 109 } 110 } 111 } 112 }); 113 ($left:expr, $right:expr, $($arg:tt)+) => ({ 114 match (&$left, &$right) { 115 (left_val, right_val) => { 116 if !(*left_val == *right_val) { 117 let kind = $crate::asserts::AssertKind::Eq; 118 // The reborrows below are intentional. Without them, the stack slot for the 119 // borrow is initialized even before the values are compared, leading to a 120 // noticeable slow down. 121 $crate::asserts::assert_failed(kind, &*left_val, &*right_val, core::option::Option::Some(core::format_args!($($arg)+))); 122 return; 123 } 124 } 125 } 126 }); 127 } 128 129 /// Expects that two expressions are not equal to each other (using [`PartialEq`]). 130 /// 131 /// On failure, this macro will print the values of the expressions with their 132 /// debug representations and signal the failure to the test framework. The test 133 /// will continue past the failure. 134 /// 135 /// Like [`assert!`], this macro has a second form, where a custom 136 /// panic message can be provided. 137 /// 138 /// # Examples 139 /// 140 /// ``` 141 /// let a = 3; 142 /// let b = 2; 143 /// expect_ne!(a, b); 144 /// 145 /// expect_ne!(a, b, "we are testing that the values are not equal"); 146 /// ``` 147 #[macro_export] 148 macro_rules! expect_ne { 149 ($left:expr, $right:expr $(,)?) => ({ 150 match (&$left, &$right) { 151 (left_val, right_val) => { 152 if *left_val == *right_val { 153 let kind = $crate::asserts::AssertKind::Ne; 154 // The reborrows below are intentional. Without them, the stack slot for the 155 // borrow is initialized even before the values are compared, leading to a 156 // noticeable slow down. 157 $crate::asserts::assert_failed(kind, &*left_val, &*right_val, core::option::Option::None); 158 } 159 } 160 } 161 }); 162 ($left:expr, $right:expr, $($arg:tt)+) => ({ 163 match (&($left), &($right)) { 164 (left_val, right_val) => { 165 if *left_val == *right_val { 166 let kind = $crate::asserts::AssertKind::Ne; 167 // The reborrows below are intentional. Without them, the stack slot for the 168 // borrow is initialized even before the values are compared, leading to a 169 // noticeable slow down. 170 $crate::asserts::assert_failed(kind, &*left_val, &*right_val, core::option::Option::Some(core::format_args!($($arg)+))); 171 } 172 } 173 } 174 }); 175 } 176 177 /// Asserts that two expressions are not equal to each other (using [`PartialEq`]). 178 /// 179 /// Unlike [`core::assert_ne!`], this macro will not panic, but instead returns 180 /// early from a test function. 181 /// 182 /// Like [`assert!`], this macro has a second form, where a custom 183 /// panic message can be provided. 184 /// 185 /// # Examples 186 /// 187 /// ``` 188 /// let a = 3; 189 /// let b = 2; 190 /// assert_ne!(a, b); 191 /// 192 /// assert_ne!(a, b, "we are testing that the values are not equal"); 193 /// ``` 194 #[macro_export] 195 macro_rules! assert_ne { 196 ($left:expr, $right:expr $(,)?) => ({ 197 match (&$left, &$right) { 198 (left_val, right_val) => { 199 if *left_val == *right_val { 200 let kind = $crate::asserts::AssertKind::Ne; 201 // The reborrows below are intentional. Without them, the stack slot for the 202 // borrow is initialized even before the values are compared, leading to a 203 // noticeable slow down. 204 $crate::asserts::assert_failed(kind, &*left_val, &*right_val, core::option::Option::None); 205 return; 206 } 207 } 208 } 209 }); 210 ($left:expr, $right:expr, $($arg:tt)+) => ({ 211 match (&($left), &($right)) { 212 (left_val, right_val) => { 213 if *left_val == *right_val { 214 let kind = $crate::asserts::AssertKind::Ne; 215 // The reborrows below are intentional. Without them, the stack slot for the 216 // borrow is initialized even before the values are compared, leading to a 217 // noticeable slow down. 218 $crate::asserts::assert_failed(kind, &*left_val, &*right_val, core::option::Option::Some(core::format_args!($($arg)+))); 219 return; 220 } 221 } 222 } 223 }); 224 } 225 226 /// Asserts that a `Result` expression is `Ok` 227 /// 228 /// On failure, this macro will print an error message containing the `Err` 229 /// (The `Err` value must implement [`std::fmt::Display`].) value and signal 230 /// the failure to the test framework. On success, the macro expression will 231 /// evaluate to the unwrapped `Ok` value. 232 /// 233 /// Like [`assert!`], this macro has a second form, where a custom error 234 /// message can be provided with or without arguments for formatting. See 235 /// [`core::fmt`] for syntax for this form. Expressions used as format arguments 236 /// will only be evaluated if the assertion fails. 237 /// 238 /// # Examples 239 /// 240 /// ``` 241 /// let x: Result<usize, String> = Ok(4); 242 /// let x: usize = assert_ok!(x); 243 /// 244 /// let y: Result<usize, String> = Ok(x); 245 /// assert_ok!(y, "something went wrong; x was {}", x); 246 /// ``` 247 #[macro_export] 248 macro_rules! assert_ok { 249 ($result:expr $(,)?) => ({ 250 match ($result) { 251 Ok(t) => t, 252 Err(e) => { 253 $crate::asserts::assert_err(core::stringify!($result), &e, core::option::Option::None); 254 return; 255 } 256 } 257 }); 258 ($result:expr, $($arg:tt)+) => ({ 259 match ($result) { 260 Ok(t) => t, 261 Err(e) => { 262 $crate::asserts::assert_err(core::stringify!($result), &e, core::option::Option::Some(core::format_args!($($arg)+))); 263 return; 264 } 265 } 266 }); 267 } 268 269 /// Expects that a boolean expression is `true` at runtime. 270 /// 271 /// On failure, this macro will print an error message and signal the failure to 272 /// the test framework. The test will continue past the failure. 273 /// 274 /// # Custom Messages 275 /// 276 /// This macro has a second form, where a custom error message can 277 /// be provided with or without arguments for formatting. See [`core::fmt`] 278 /// for syntax for this form. Expressions used as format arguments will only 279 /// be evaluated if the assertion fails. 280 #[macro_export] 281 macro_rules! expect { 282 ($cond:expr $(,)?) => ({ 283 match (&($cond)) { 284 (cond) => { 285 if (!*cond) { 286 $crate::asserts::simple_assert_failed(core::stringify!($cond), core::option::Option::None); 287 } 288 } 289 } 290 }); 291 ($cond:expr, $($arg:tt)+) => ({ 292 match (&($cond)) { 293 (cond) => { 294 if (!*cond) { 295 $crate::asserts::simple_assert_failed(core::stringify!($cond), core::option::Option::Some(core::format_args!($($arg)+))); 296 } 297 } 298 } 299 }); 300 } 301 302 /// Asserts that a boolean expression is `true` at runtime. 303 /// 304 /// Unlike [`core::assert!`], this macro will not panic, but instead returns 305 /// early from a test function. 306 /// 307 /// # Custom Messages 308 /// 309 /// This macro has a second form, where a custom error message can 310 /// be provided with or without arguments for formatting. See [`core::fmt`] 311 /// for syntax for this form. Expressions used as format arguments will only 312 /// be evaluated if the assertion fails. 313 #[macro_export] 314 macro_rules! assert { 315 ($cond:expr $(,)?) => ({ 316 match (&($cond)) { 317 (cond) => { 318 if (!*cond) { 319 $crate::asserts::simple_assert_failed(core::stringify!($cond), core::option::Option::None); 320 return; 321 } 322 } 323 } 324 }); 325 ($cond:expr, $($arg:tt)+) => ({ 326 match (&($cond)) { 327 (cond) => { 328 if (!*cond) { 329 $crate::asserts::simple_assert_failed(core::stringify!($cond), core::option::Option::Some(core::format_args!($($arg)+))); 330 return; 331 } 332 } 333 } 334 }); 335 } 336 337 /// Fails the test and diverges. 338 /// 339 /// Unlike [`core::panic!`], this macro will not unwind/abort, but instead returns 340 /// early from a test function. 341 /// 342 /// This macro can be used with or without providing a custom error message. 343 /// Formatting is supported; see [`core::fmt`] for syntax. 344 #[macro_export] 345 macro_rules! fail { 346 () => ({ 347 $crate::asserts::simple_assert_failed("encountered test failure", core::option::Option::None); 348 return; 349 }); 350 ($($arg:tt)+) => ({ 351 $crate::asserts::simple_assert_failed("encountered test failure", core::option::Option::Some(core::format_args!($($arg)+))); 352 return; 353 }); 354 } 355 356 /// Marks the test as skipped. 357 /// 358 /// This macro can be used with or without providing a custom error message. 359 /// Formatting is supported; see [`core::fmt`] for syntax. 360 #[macro_export] 361 macro_rules! skip { 362 () => ({ 363 $crate::skip(); 364 return; 365 }); 366 ($($arg:tt)+) => ({ 367 std::eprintln!("test skipped: {}, {}", core::format_args!($($arg)+), std::panic::Location::caller()); 368 $crate::skip(); 369 return; 370 }); 371 } 372