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