blob: ab1f97acd34274cf5128b34b5fd5969d63aa8ecd [file] [log] [blame] [edit]
// 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_