| // Copyright 2020 The Fuchsia Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #ifndef SRC_LIB_TESTING_PREDICATES_STATUS_H_ | |
| #define SRC_LIB_TESTING_PREDICATES_STATUS_H_ | |
| #include <lib/fit/result.h> | |
| #include <zircon/status.h> | |
| #include <gtest/gtest.h> | |
| // Helper macro that asserts that `condition` equals `ZX_OK`, `fit::ok()`, | |
| // or `zx::ok()`. Behaves similarly to `ASSERT_EQ(condition, ZX_OK)` but with | |
| // prettier output. | |
| #define ASSERT_OK(condition) \ | |
| GTEST_PRED_FORMAT1_(::testing_predicates::CmpOk, condition, GTEST_FATAL_FAILURE_) | |
| // Helper macro that expects that `condition` equals `ZX_OK`, `fit::ok()`, | |
| // or `zx::ok()`. Behaves similarly to `EXPECT_EQ(condition, ZX_OK)` but with | |
| // prettier output. | |
| #define EXPECT_OK(condition) \ | |
| GTEST_PRED_FORMAT1_(::testing_predicates::CmpOk, condition, GTEST_NONFATAL_FAILURE_) | |
| // Helper macro that asserts equality between `zx_status_t` expressions `val1` and `val2`. | |
| // Behaves similarly to `ASSERT_EQ(val1, val2)` but with prettier output. | |
| #define ASSERT_STATUS(val1, val2) \ | |
| GTEST_PRED_FORMAT2_(::testing_predicates::CmpStatus, val1, val2, GTEST_FATAL_FAILURE_) | |
| // Helper macro that expects equality between `zx_status_t` expressions `val1` and `val2`. | |
| // Behaves similarly to `EXPECT_EQ(val1, val2)` but with prettier output. | |
| #define EXPECT_STATUS(val1, val2) \ | |
| GTEST_PRED_FORMAT2_(::testing_predicates::CmpStatus, val1, val2, GTEST_NONFATAL_FAILURE_) | |
| namespace testing_predicates { | |
| ::testing::AssertionResult CmpOk(const char* l_expr, zx_status_t l); | |
| namespace internal { | |
| zx_status_t StatusValue(zx_status_t status); | |
| template <typename... Ts> | |
| zx_status_t StatusValue(const fit::result<zx_status_t, Ts...>& r) { | |
| if (r.is_ok()) { | |
| return ZX_OK; | |
| } | |
| return r.error_value(); | |
| } | |
| template <typename... Ts> | |
| ::testing::AssertionResult CmpOkImpl(const char* l_expr, const fit::result<zx_status_t, Ts...>& l) { | |
| return CmpOk(l_expr, StatusValue(l)); | |
| } | |
| template <typename E, typename... Ts> | |
| ::testing::AssertionResult CmpOkImpl(const char* l_expr, const fit::result<E, Ts...>& l) { | |
| if (l.is_ok()) { | |
| return ::testing::AssertionSuccess(); | |
| } | |
| return ::testing::AssertionFailure() | |
| << l_expr << " is fit::error(" << l.error_value() << "), expected fit::ok()."; | |
| } | |
| } // namespace internal | |
| template <typename E> | |
| ::testing::AssertionResult CmpOk(const char* l_expr, const fit::result<E>& l) { | |
| return internal::CmpOkImpl(l_expr, l); | |
| } | |
| template <typename E, typename T> | |
| ::testing::AssertionResult CmpOk(const char* l_expr, const fit::result<E, T>& l) { | |
| return internal::CmpOkImpl(l_expr, l); | |
| } | |
| // Nine variants of CmpStatus, accepting zx_status_t, fit::result<zx_status_t>, | |
| // or fit::result<zx_status_t, T> for each argument. The latter 8 | |
| // implementations all delegate to the first. | |
| ::testing::AssertionResult CmpStatus(const char* l_expr, const char* r_expr, zx_status_t l, | |
| zx_status_t r); | |
| ::testing::AssertionResult CmpStatus(const char* l_expr, const char* r_expr, zx_status_t l, | |
| const fit::result<zx_status_t>& r); | |
| template <typename R> | |
| ::testing::AssertionResult CmpStatus(const char* l_expr, const char* r_expr, zx_status_t l, | |
| const fit::result<zx_status_t, R>& r) { | |
| return CmpStatus(l_expr, r_expr, internal::StatusValue(l), internal::StatusValue(r)); | |
| } | |
| ::testing::AssertionResult CmpStatus(const char* l_expr, const char* r_expr, | |
| const fit::result<zx_status_t>& l, zx_status_t r); | |
| ::testing::AssertionResult CmpStatus(const char* l_expr, const char* r_expr, | |
| const fit::result<zx_status_t>& l, | |
| const fit::result<zx_status_t>& r); | |
| template <typename R> | |
| ::testing::AssertionResult CmpStatus(const char* l_expr, const char* r_expr, | |
| const fit::result<zx_status_t>& l, | |
| const fit::result<zx_status_t, R>& r) { | |
| return CmpStatus(l_expr, r_expr, internal::StatusValue(l), internal::StatusValue(r)); | |
| } | |
| template <typename L> | |
| ::testing::AssertionResult CmpStatus(const char* l_expr, const char* r_expr, | |
| const fit::result<zx_status_t, L>& l, zx_status_t r) { | |
| return CmpStatus(l_expr, r_expr, internal::StatusValue(l), internal::StatusValue(r)); | |
| } | |
| template <typename L> | |
| ::testing::AssertionResult CmpStatus(const char* l_expr, const char* r_expr, | |
| const fit::result<zx_status_t, L>& l, | |
| const fit::result<zx_status_t>& r) { | |
| return CmpStatus(l_expr, r_expr, internal::StatusValue(l), internal::StatusValue(r)); | |
| } | |
| template <typename L, typename R> | |
| ::testing::AssertionResult CmpStatus(const char* l_expr, const char* r_expr, | |
| const fit::result<zx_status_t, L>& l, | |
| const fit::result<zx_status_t, R>& r) { | |
| return CmpStatus(l_expr, r_expr, internal::StatusValue(l), internal::StatusValue(r)); | |
| } | |
| } // namespace testing_predicates | |
| #endif // SRC_LIB_TESTING_PREDICATES_STATUS_H_ |