|  | // Copyright 2022 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | // TODO(danakj): Reuse code for comparison macros with an expect_op!() macro? | 
|  |  | 
|  | /// Internal helper to log an expectation failure. Other expect_* macros invoke | 
|  | /// it with their standard expectation message, plus optionally a user-provided | 
|  | /// custom string. | 
|  | /// | 
|  | /// Both the the expectation message and the user-provided message are format | 
|  | /// strings with arguments. To disambiguate between them, the expectation | 
|  | /// message is wrapped in extra parentheses. | 
|  | #[macro_export] | 
|  | macro_rules! internal_add_expectation_failure { | 
|  | // Rule that both the below are forwarded to. | 
|  | (@imp $fmt:literal, $($arg:tt)+) => { | 
|  | $crate::__private::add_failure_at( | 
|  | file!(), | 
|  | line!(), | 
|  | &format!($fmt, $($arg)+), | 
|  | ) | 
|  | }; | 
|  |  | 
|  | // Add a failure with the standard message. | 
|  | (($expectation:literal, $($e:tt)+)) => { | 
|  | $crate::internal_add_expectation_failure!(@imp $expectation, $($e)+) | 
|  | }; | 
|  |  | 
|  | // Add a failure with the standard message plus an additional message. | 
|  | (($expectation:literal, $($e:tt)+), $($arg:tt)+) => { | 
|  | $crate::internal_add_expectation_failure!(@imp | 
|  | "{}\n\n{}", | 
|  | format_args!($expectation, $($e)+), | 
|  | format_args!($($arg)+), | 
|  | ) | 
|  | }; | 
|  | } | 
|  |  | 
|  | /// Evaluates the given expression. If false, a failure is reported to Gtest. | 
|  | /// | 
|  | /// # Examples | 
|  | /// ``` | 
|  | /// expect_true(check_the_status_is_true()); | 
|  | /// ``` | 
|  | #[macro_export] | 
|  | macro_rules! expect_true { | 
|  | ($e:expr $(, $($arg:tt)*)?) => { | 
|  | match &$e { | 
|  | val => { | 
|  | if !(*val) { | 
|  | $crate::internal_add_expectation_failure!( | 
|  | ( | 
|  | "Expected: {} is true\nActual: {} is {:?}", | 
|  | stringify!($e), | 
|  | stringify!($e), | 
|  | *val | 
|  | ) | 
|  | $(, $($arg)*)? | 
|  | ) | 
|  | } | 
|  | } | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | /// Evaluates the given expression. If true, a failure is reported to Gtest. | 
|  | /// | 
|  | /// # Examples | 
|  | /// ``` | 
|  | /// expect_false(check_the_status_is_false()); | 
|  | /// ``` | 
|  | #[macro_export] | 
|  | macro_rules! expect_false { | 
|  | ($e:expr $(, $($arg:tt)*)?) => { | 
|  | match &$e { | 
|  | val => { | 
|  | if *val { | 
|  | $crate::internal_add_expectation_failure!( | 
|  | ( | 
|  | "Expected: {} is false\nActual: {} is {:?}", | 
|  | stringify!($e), | 
|  | stringify!($e), | 
|  | *val | 
|  | ) | 
|  | $(, $($arg)*)? | 
|  | ) | 
|  | } | 
|  | } | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | /// Evaluates and compares the two given expressions. If not equal, a failure is reported to Gtest. | 
|  | /// The expressions must evaluate to the same type, which must be PartialEq. | 
|  | /// | 
|  | /// # Examples | 
|  | /// ``` | 
|  | /// expect_eq(1 + 1, 2); | 
|  | /// ``` | 
|  | #[macro_export] | 
|  | macro_rules! expect_eq { | 
|  | ($e1:expr, $e2:expr $(, $($arg:tt)*)?) => { | 
|  | match (&$e1, &$e2) { | 
|  | (val1, val2) => { | 
|  | if !(*val1 == *val2) { | 
|  | $crate::internal_add_expectation_failure!( | 
|  | ( | 
|  | "Expected: {} == {}\nActual: {:?} vs {:?}", | 
|  | stringify!($e1), | 
|  | stringify!($e2), | 
|  | *val1, | 
|  | *val2 | 
|  | ) | 
|  | $(, $($arg)*)? | 
|  | ) | 
|  | } | 
|  | } | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | /// Evaluates and compares the two given expressions. If equal, a failure is reported to Gtest. | 
|  | /// The expressions must evaluate to the same type, which must be PartialEq. | 
|  | /// | 
|  | /// # Examples | 
|  | /// ``` | 
|  | /// expect_ne(1 + 1, 3); | 
|  | /// ``` | 
|  | #[macro_export] | 
|  | macro_rules! expect_ne { | 
|  | ($e1:expr, $e2:expr $(, $($arg:tt)*)?) => { | 
|  | match (&$e1, &$e2) { | 
|  | (val1, val2) => { | 
|  | if !(*val1 != *val2) { | 
|  | $crate::internal_add_expectation_failure!( | 
|  | ( | 
|  | "Expected: {} != {}\nActual: {:?} vs {:?}", | 
|  | stringify!($e1), | 
|  | stringify!($e2), | 
|  | *val1, | 
|  | *val2 | 
|  | ) | 
|  | $(, $($arg)*)? | 
|  | ) | 
|  | } | 
|  | } | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | /// Evaluates and compares the two given expressions. If the first is not greater than the second, a | 
|  | /// failure is reported to Gtest. The expressions must evaluate to the same type, which must be | 
|  | /// PartialOrd. If a PartialOrd comparison fails, the result is false. | 
|  | /// | 
|  | /// # Examples | 
|  | /// ``` | 
|  | /// expect_gt(1 + 1, 1); | 
|  | /// ``` | 
|  | #[macro_export] | 
|  | macro_rules! expect_gt { | 
|  | ($e1:expr, $e2:expr $(, $($arg:tt)*)?) => { | 
|  | match (&$e1, &$e2) { | 
|  | (val1, val2) => { | 
|  | if !(*val1 > *val2) { | 
|  | $crate::internal_add_expectation_failure!( | 
|  | ( | 
|  | "Expected: {} > {}\nActual: {:?} vs {:?}", | 
|  | stringify!($e1), | 
|  | stringify!($e2), | 
|  | *val1, | 
|  | *val2 | 
|  | ) | 
|  | $(, $($arg)*)? | 
|  | ) | 
|  | } | 
|  | } | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | /// Evaluates and compares the two given expressions. If the first is not less than the second, a | 
|  | /// failure is reported to Gtest. The expressions must evaluate to the same type, which must be | 
|  | /// PartialOrd. If a PartialOrd comparison fails, the result is false. | 
|  | /// | 
|  | /// # Examples | 
|  | /// ``` | 
|  | /// expect_lt(1 + 1, 1 + 2); | 
|  | /// ``` | 
|  | #[macro_export] | 
|  | macro_rules! expect_lt { | 
|  | ($e1:expr, $e2:expr $(, $($arg:tt)*)?) => { | 
|  | match (&$e1, &$e2) { | 
|  | (val1, val2) => { | 
|  | if !(*val1 < *val2) { | 
|  | $crate::internal_add_expectation_failure!( | 
|  | ( | 
|  | "Expected: {} < {}\nActual: {:?} vs {:?}", | 
|  | stringify!($e1), | 
|  | stringify!($e2), | 
|  | *val1, | 
|  | *val2 | 
|  | ) | 
|  | $(, $($arg)*)? | 
|  | ) | 
|  | } | 
|  | } | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | /// Evaluates and compares the two given expressions. If the first is not greater than or equal to | 
|  | /// the second, a failure is reported to Gtest. The expressions must evaluate to the same type, | 
|  | /// which must be PartialOrd. If a PartialOrd comparison fails, the result is false. | 
|  | /// | 
|  | /// # Examples | 
|  | /// ``` | 
|  | /// expect_ge(1 + 1, 2); | 
|  | /// ``` | 
|  | #[macro_export] | 
|  | macro_rules! expect_ge { | 
|  | ($e1:expr, $e2:expr $(, $($arg:tt)*)?) => { | 
|  | match (&$e1, &$e2) { | 
|  | (val1, val2) => { | 
|  | if !(*val1 >= *val2) { | 
|  | $crate::internal_add_expectation_failure!( | 
|  | ( | 
|  | "Expected: {} >= {}\nActual: {:?} vs {:?}", | 
|  | stringify!($e1), | 
|  | stringify!($e2), | 
|  | *val1, | 
|  | *val2 | 
|  | ) $(, $($arg)*)? | 
|  | ) | 
|  | } | 
|  | } | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | /// Evaluates and compares the two given expressions. If the first is not less than or equal to the | 
|  | /// second, a failure is reported to Gtest. The expressions must evaluate to the same type, /which | 
|  | /// must be PartialOrd. If a PartialOrd comparison fails, the result is false. | 
|  | /// | 
|  | /// # Examples | 
|  | /// ``` | 
|  | /// expect_le(2, 1 + 1); | 
|  | /// ``` | 
|  | #[macro_export] | 
|  | macro_rules! expect_le { | 
|  | ($e1:expr, $e2:expr $(, $($arg:tt)*)?) => { | 
|  | match (&$e1, &$e2) { | 
|  | (val1, val2) => { | 
|  | if !(*val1 <= *val2) { | 
|  | $crate::internal_add_expectation_failure!( | 
|  | ( | 
|  | "Expected: {} <= {}\nActual: {:?} vs {:?}", | 
|  | stringify!($e1), | 
|  | stringify!($e2), | 
|  | *val1, | 
|  | *val2 | 
|  | ) $(, $($arg)*)? | 
|  | ) | 
|  | } | 
|  | } | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | // TODO(danakj): There's a bunch more useful macros to write, even ignoring gmock: | 
|  | // - EXPECT_NONFATAL_FAILURE | 
|  | // - SCOPED_TRACE | 
|  | // - EXPECT_DEATH | 
|  | // - FAIL (fatal failure, would this work?) | 
|  | // - ADD_FAILURE | 
|  | // - SUCCEED | 
|  | // - EXPECT_PANIC (catch_unwind() with an error if no panic, but this depends on us using a stdlib | 
|  | //   with -Cpanic=unwind in tests, currently we use -Cpanic=abort.) | 
|  | // - EXPECT_NO_PANIC (Like above, depende on -Cpanic=unwind, or else all panics just abort the | 
|  | //   process.) | 
|  | // - EXPECT_FLOAT_EQ (Comparison for equality within a small range.) | 
|  | // - EXPECT_NEAR (Comparison for equality within a user-specified range.) |