chromium/base/test/gmock_expected_support.h

// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_TEST_GMOCK_EXPECTED_SUPPORT_H_
#define BASE_TEST_GMOCK_EXPECTED_SUPPORT_H_

#include <ostream>
#include <string>
#include <type_traits>
#include <utility>

#include "base/strings/strcat.h"
#include "base/strings/to_string.h"
#include "base/types/expected.h"
#include "base/types/expected_internal.h"
#include "base/types/expected_macros.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base::test {

namespace internal {

// `HasVoidValueType<T>` is true iff `T` satisfies
// `base::internal::IsExpected<T>` and `T`'s `value_type` is `void`.
HasVoidValueType;

// Implementation for matcher `HasValue`.
class HasValueMatcher {};

// Implementation for matcher `ValueIs`.
template <typename T>
class ValueIsMatcher {};

// Implementation for matcher `ErrorIs`.
template <typename T>
class ErrorIsMatcher {};

}  // namespace internal

// Returns a gMock matcher that matches an `expected<T, E>` which has a value.
inline internal::HasValueMatcher HasValue() {}

// Returns a gMock matcher that matches an `expected<T, E>` which has a non-void
// value which matches the inner matcher.
template <typename T>
inline internal::ValueIsMatcher<typename std::decay_t<T>> ValueIs(T&& matcher) {}

// Returns a gMock matcher that matches an `expected<T, E>` which has an error
// which matches the inner matcher.
template <typename T>
inline internal::ErrorIsMatcher<typename std::decay_t<T>> ErrorIs(T&& matcher) {}

}  // namespace base::test

// Executes an expression that returns an `expected<T, E>` or some subclass
// thereof, and assigns the contained `T` to `lhs` if the result is a value. If
// the result is an error, generates a test failure and returns from the current
// function, which must have a `void` return type. For more usage examples and
// caveats, see the documentation for `ASSIGN_OR_RETURN`.
//
// Example: Declaring and initializing a new value:
//   ASSERT_OK_AND_ASSIGN(ValueType value, MaybeGetValue(arg));
//
// Example: Assigning to an existing value:
//   ValueType value;
//   ASSERT_OK_AND_ASSIGN(value, MaybeGetValue(arg));
#define ASSERT_OK_AND_ASSIGN(lhs, rexpr)

namespace base {
template <typename T, typename E>
void PrintTo(const expected<T, E>& expected, ::std::ostream* os) {}

template <typename T>
void PrintTo(const ok<T>& a, ::std::ostream* os) {}

template <typename T>
void PrintTo(const unexpected<T>& a, ::std::ostream* os) {}
}  // namespace base

#endif  // BASE_TEST_GMOCK_EXPECTED_SUPPORT_H_