• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
33 /// [std::cmp::PartialEq]).
34 ///
35 /// On failure, this macro will print the values of the expressions with their
36 /// debug representations and signal the failure to the test framework. The test
37 /// will continue past the failure.
38 ///
39 /// Like [`assert!`], this macro has a second form, where a custom
40 /// error message can be provided.
41 ///
42 /// # Examples
43 ///
44 /// ```
45 /// let a = 3;
46 /// let b = 1 + 2;
47 /// expect_eq!(a, b);
48 ///
49 /// expect_eq!(a, b, "we are testing addition with {} and {}", a, b);
50 /// ```
51 #[macro_export]
52 macro_rules! expect_eq {
53     ($left:expr, $right:expr $(,)?) => ({
54         match (&$left, &$right) {
55             (left_val, right_val) => {
56                 if !(*left_val == *right_val) {
57                     let kind = $crate::__internal_macro_utils::AssertKind::Eq;
58                     // The reborrows below are intentional. Without them, the
59                     // stack slot for the borrow is initialized even before the
60                     // values are compared, leading to a noticeable slow down.
61                     $crate::__internal_macro_utils::assert_failed(
62                         kind,
63                         &*left_val,
64                         &*right_val,
65                         core::option::Option::None
66                     );
67                 }
68             }
69         }
70     });
71     ($left:expr, $right:expr, $($arg:tt)+) => ({
72         match (&$left, &$right) {
73             (left_val, right_val) => {
74                 if !(*left_val == *right_val) {
75                     let kind = $crate::__internal_macro_utils::AssertKind::Eq;
76                     // The reborrows below are intentional. Without them, the
77                     // stack slot for the borrow is initialized even before the
78                     // values are compared, leading to a noticeable slow down.
79                     $crate::__internal_macro_utils::assert_failed(
80                         kind,
81                         &*left_val,
82                         &*right_val,
83                         core::option::Option::Some(core::format_args!($($arg)+))
84                     );
85                 }
86             }
87         }
88     });
89 }
90 
91 /// Asserts that two expressions are equal to each other (using
92 /// [std::cmp::PartialEq]).
93 ///
94 /// Unlike [`core::assert_eq!`], this macro will not panic, but instead returns
95 /// early from a test function.
96 ///
97 /// Like [`assert!`], this macro has a second form, where a custom
98 /// panic message can be provided.
99 ///
100 /// # Examples
101 ///
102 /// ```
103 /// let a = 3;
104 /// let b = 1 + 2;
105 /// assert_eq!(a, b);
106 ///
107 /// assert_eq!(a, b, "we are testing addition with {} and {}", a, b);
108 /// ```
109 #[macro_export]
110 macro_rules! assert_eq {
111     ($left:expr, $right:expr $(,)?) => ({
112         match (&$left, &$right) {
113             (left_val, right_val) => {
114                 if !(*left_val == *right_val) {
115                     let kind = $crate::__internal_macro_utils::AssertKind::Eq;
116                     // The reborrows below are intentional. Without them, the
117                     // stack slot for the borrow is initialized even before the
118                     // values are compared, leading to a noticeable slow down.
119                     $crate::__internal_macro_utils::assert_failed(
120                         kind,
121                         &*left_val,
122                         &*right_val,
123                         core::option::Option::None
124                     );
125                     return;
126                 }
127             }
128         }
129     });
130     ($left:expr, $right:expr, $($arg:tt)+) => ({
131         match (&$left, &$right) {
132             (left_val, right_val) => {
133                 if !(*left_val == *right_val) {
134                     let kind = $crate::__internal_macro_utils::AssertKind::Eq;
135                     // The reborrows below are intentional. Without them, the
136                     // stack slot for the borrow is initialized even before the
137                     // values are compared, leading to a noticeable slow down.
138                     $crate::__internal_macro_utils::assert_failed(
139                         kind,
140                         &*left_val,
141                         &*right_val,
142                         core::option::Option::Some(core::format_args!($($arg)+))
143                     );
144                     return;
145                 }
146             }
147         }
148     });
149 }
150 
151 /// Expects that two expressions are not equal to each other (using
152 /// [std::cmp::PartialEq]).
153 ///
154 /// On failure, this macro will print the values of the expressions with their
155 /// debug representations and signal the failure to the test framework. The test
156 /// will continue past the failure.
157 ///
158 /// Like [`assert!`], this macro has a second form, where a custom
159 /// panic message can be provided.
160 ///
161 /// # Examples
162 ///
163 /// ```
164 /// let a = 3;
165 /// let b = 2;
166 /// expect_ne!(a, b);
167 ///
168 /// expect_ne!(a, b, "we are testing that the values are not equal");
169 /// ```
170 #[macro_export]
171 macro_rules! expect_ne {
172     ($left:expr, $right:expr $(,)?) => ({
173         match (&$left, &$right) {
174             (left_val, right_val) => {
175                 if *left_val == *right_val {
176                     let kind = $crate::__internal_macro_utils::AssertKind::Ne;
177                     // The reborrows below are intentional. Without them, the
178                     // stack slot for the borrow is initialized even before the
179                     // values are compared, leading to a noticeable slow down.
180                     $crate::__internal_macro_utils::assert_failed(
181                         kind,
182                         &*left_val,
183                         &*right_val,
184                         core::option::Option::None
185                     );
186                 }
187             }
188         }
189     });
190     ($left:expr, $right:expr, $($arg:tt)+) => ({
191         match (&($left), &($right)) {
192             (left_val, right_val) => {
193                 if *left_val == *right_val {
194                     let kind = $crate::__internal_macro_utils::AssertKind::Ne;
195                     // The reborrows below are intentional. Without them, the
196                     // stack slot for the borrow is initialized even before the
197                     // values are compared, leading to a noticeable slow down.
198                     $crate::__internal_macro_utils::assert_failed(
199                         kind,
200                         &*left_val,
201                         &*right_val,
202                         core::option::Option::Some(core::format_args!($($arg)+))
203                     );
204                 }
205             }
206         }
207     });
208 }
209 
210 /// Asserts that two expressions are not equal to each other (using
211 /// [std::cmp::PartialEq]).
212 ///
213 /// Unlike [`core::assert_ne!`], this macro will not panic, but instead returns
214 /// early from a test function.
215 ///
216 /// Like [`assert!`], this macro has a second form, where a custom
217 /// panic message can be provided.
218 ///
219 /// # Examples
220 ///
221 /// ```
222 /// let a = 3;
223 /// let b = 2;
224 /// assert_ne!(a, b);
225 ///
226 /// assert_ne!(a, b, "we are testing that the values are not equal");
227 /// ```
228 #[macro_export]
229 macro_rules! assert_ne {
230     ($left:expr, $right:expr $(,)?) => ({
231         match (&$left, &$right) {
232             (left_val, right_val) => {
233                 if *left_val == *right_val {
234                     let kind = $crate::__internal_macro_utils::AssertKind::Ne;
235                     // The reborrows below are intentional. Without them, the
236                     // stack slot for the borrow is initialized even before the
237                     // values are compared, leading to a noticeable slow down.
238                     $crate::__internal_macro_utils::assert_failed(
239                         kind,
240                         &*left_val,
241                         &*right_val,
242                         core::option::Option::None
243                     );
244                     return;
245                 }
246             }
247         }
248     });
249     ($left:expr, $right:expr, $($arg:tt)+) => ({
250         match (&($left), &($right)) {
251             (left_val, right_val) => {
252                 if *left_val == *right_val {
253                     let kind = $crate::__internal_macro_utils::AssertKind::Ne;
254                     // The reborrows below are intentional. Without them, the
255                     // stack slot for the borrow is initialized even before the
256                     // values are compared, leading to a noticeable slow down.
257                     $crate::__internal_macro_utils::assert_failed(
258                         kind,
259                         &*left_val,
260                         &*right_val,
261                         core::option::Option::Some(core::format_args!($($arg)+))
262                     );
263                     return;
264                 }
265             }
266         }
267     });
268 }
269 
270 /// Asserts that a `Result` expression is `Ok`
271 ///
272 /// On failure, this macro will print an error message containing the `Err`
273 /// value and signal the failure to the test framework. On success, the macro
274 /// expression will evaluate to the unwrapped `Ok` value.
275 ///
276 /// Like [`assert!`], this macro has a second form, where a custom error
277 /// message can be provided with or without arguments for formatting. See
278 /// [`core::fmt`] for syntax for this form. Expressions used as format arguments
279 /// will only be evaluated if the assertion fails.
280 ///
281 /// Failures will include a best-effort representation of the error value in the
282 /// error message. It will use the [std::fmt::Display], [std::fmt::Debug], or
283 /// [std::any::type_name] in that order of priority, depending on which ones are
284 /// implemented for the error type. (This is implemented with
285 /// [autoderef specialization], so it will work for concrete types, but using it
286 /// for unconstrained generic `T` will always use the [std::any::type_name]
287 /// impl, regardless of what traits the type actually implements. Similarly, if
288 /// the type is declared as `T: Debug`, the [std::fmt::Debug] impl will be
289 /// invoked, even if the concrete type implements [std::fmt::Display] as well.)
290 ///
291 /// # Examples
292 ///
293 /// ```
294 /// let x: Result<usize, String> = Ok(4);
295 /// let x: usize = assert_ok!(x);
296 ///
297 /// let y: Result<usize, String> = Ok(x);
298 /// assert_ok!(y, "something went wrong; x was {}", x);
299 /// ```
300 ///
301 /// [autoderef specialization]: https://lukaskalbertodt.github.io/2019/12/05/generalized-autoref-based-specialization.html
302 #[macro_export]
303 macro_rules! assert_ok {
304     ($result:expr $(,)?) => ({
305         match ($result) {
306             Ok(t) => t,
307             Err(e) => {
308                 use $crate::__internal_macro_utils::{
309                     DisplayKind as _,
310                     DebugKind as _,
311                     TypenameKind as _,
312                 };
313                 $crate::__internal_macro_utils::assert_ok_failed(
314                     core::stringify!($result),
315                     (&&&$crate::__internal_macro_utils::BestEffortDisplay(&e))
316                         .display_kind()
317                         .wrap(e),
318                     core::option::Option::None
319                 );
320                 return;
321             }
322         }
323     });
324     ($result:expr, $($arg:tt)+) => ({
325         match ($result) {
326             Ok(t) => t,
327             Err(e) => {
328                 use $crate::__internal_macro_utils::{
329                     DisplayKind as _,
330                     DebugKind as _,
331                     TypenameKind as _,
332                 };
333                 $crate::__internal_macro_utils::assert_ok_failed(
334                     core::stringify!($result),
335                     (&&&$crate::__internal_macro_utils::BestEffortDisplay(&e))
336                         .display_kind()
337                         .wrap(e),
338                     core::option::Option::Some(core::format_args!($($arg)+))
339                 );
340                 return;
341             }
342         }
343     });
344 }
345 
346 /// Expects that a boolean expression is `true` at runtime.
347 ///
348 /// On failure, this macro will print an error message and signal the failure to
349 /// the test framework. The test will continue past the failure.
350 ///
351 /// # Custom Messages
352 ///
353 /// This macro has a second form, where a custom error message can
354 /// be provided with or without arguments for formatting. See [`core::fmt`]
355 /// for syntax for this form. Expressions used as format arguments will only
356 /// be evaluated if the assertion fails.
357 #[macro_export]
358 macro_rules! expect {
359     ($cond:expr $(,)?) => ({
360         match (&($cond)) {
361             (cond) => {
362                 if (!*cond) {
363                     $crate::__internal_macro_utils::simple_assert_failed(
364                         core::stringify!($cond),
365                         core::option::Option::None
366                     );
367                 }
368             }
369         }
370     });
371     ($cond:expr, $($arg:tt)+) => ({
372         match (&($cond)) {
373             (cond) => {
374                 if (!*cond) {
375                     $crate::__internal_macro_utils::simple_assert_failed(
376                         core::stringify!($cond),
377                         core::option::Option::Some(core::format_args!($($arg)+))
378                     );
379                 }
380             }
381         }
382     });
383 }
384 
385 /// Asserts that a boolean expression is `true` at runtime.
386 ///
387 /// Unlike [`core::assert!`], this macro will not panic, but instead returns
388 /// early from a test function.
389 ///
390 /// # Custom Messages
391 ///
392 /// This macro has a second form, where a custom error message can
393 /// be provided with or without arguments for formatting. See [`core::fmt`]
394 /// for syntax for this form. Expressions used as format arguments will only
395 /// be evaluated if the assertion fails.
396 #[macro_export]
397 macro_rules! assert {
398     ($cond:expr $(,)?) => ({
399         match (&($cond)) {
400             (cond) => {
401                 if (!*cond) {
402                     $crate::__internal_macro_utils::simple_assert_failed(
403                         core::stringify!($cond),
404                         core::option::Option::None
405                     );
406                     return;
407                 }
408             }
409         }
410     });
411     ($cond:expr, $($arg:tt)+) => ({
412         match (&($cond)) {
413             (cond) => {
414                 if (!*cond) {
415                     $crate::__internal_macro_utils::simple_assert_failed(
416                         core::stringify!($cond),
417                         core::option::Option::Some(core::format_args!($($arg)+))
418                     );
419                     return;
420                 }
421             }
422         }
423     });
424 }
425 
426 /// Fails the test and diverges.
427 ///
428 /// Unlike [`core::panic!`], this macro will not unwind/abort, but instead returns
429 /// early from a test function.
430 ///
431 /// This macro can be used with or without providing a custom error message.
432 /// Formatting is supported; see [`core::fmt`] for syntax.
433 #[macro_export]
434 macro_rules! fail {
435     () => ({
436         $crate::__internal_macro_utils::simple_assert_failed(
437             "encountered test failure",
438             core::option::Option::None
439         );
440         return;
441     });
442     ($($arg:tt)+) => ({
443         $crate::__internal_macro_utils::simple_assert_failed(
444             "encountered test failure",
445             core::option::Option::Some(core::format_args!($($arg)+))
446         );
447         return;
448     });
449 }
450 
451 /// Marks the test as skipped.
452 ///
453 /// This macro can be used with or without providing a custom error message.
454 /// Formatting is supported; see [`core::fmt`] for syntax.
455 #[macro_export]
456 macro_rules! skip {
457     () => ({
458         $crate::skip();
459         return;
460     });
461     ($($arg:tt)+) => ({
462         std::eprintln!(
463             "test skipped: {}, {}",
464             core::format_args!($($arg)+),
465             std::panic::Location::caller()
466         );
467         $crate::skip();
468         return;
469     });
470 }
471