Merge dfa3474d955dd9eef68c748feb4a39e0ca1c03c4 into 7140cd416cecd7462a8aae488024abeee55598e4

This commit is contained in:
Unseen 2026-06-02 21:56:23 -04:00 committed by GitHub
commit 1561c9062a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 509 additions and 316 deletions

View File

@ -42,7 +42,7 @@
#include <limits.h>
#include <memory>
#include <ostream> // NOLINT
#include <iosfwd> // NOLINT
#include "gmock/internal/gmock-port.h"
#include "gtest/gtest.h"

View File

@ -264,8 +264,7 @@
#include <iterator>
#include <limits>
#include <memory>
#include <ostream> // NOLINT
#include <sstream>
#include <iosfwd>
#include <string>
#include <tuple>
#include <type_traits>
@ -305,16 +304,17 @@ namespace testing {
// A match result listener that stores the explanation in a string.
class [[nodiscard]] StringMatchResultListener : public MatchResultListener {
public:
StringMatchResultListener() : MatchResultListener(&ss_) {}
StringMatchResultListener();
~StringMatchResultListener() override;
// Returns the explanation accumulated so far.
std::string str() const { return ss_.str(); }
std::string str() const;
// Clears the explanation accumulated so far.
void Clear() { ss_.str(""); }
void Clear();
private:
::std::stringstream ss_;
const std::unique_ptr< ::std::ostream> ss_;
StringMatchResultListener(const StringMatchResultListener&) = delete;
StringMatchResultListener& operator=(const StringMatchResultListener&) =
@ -578,12 +578,8 @@ struct Rank1 : Rank0 {};
using HighestRank = Rank1;
// If the explanation is not empty, prints it to the ostream.
inline void PrintIfNotEmpty(const std::string& explanation,
::std::ostream* os) {
if (!explanation.empty() && os != nullptr) {
*os << ", " << explanation;
}
}
GTEST_API_ void PrintIfNotEmpty(const std::string& explanation,
::std::ostream* os);
// Returns true if the given type name is easy to read by a human.
// This is used to decide whether printing the type of a value might
@ -657,9 +653,9 @@ class [[nodiscard]] TuplePrefix {
const Value& value = std::get<N - 1>(values);
StringMatchResultListener listener;
if (!matcher.MatchAndExplain(value, &listener)) {
*os << " Expected arg #" << N - 1 << ": ";
::testing::internal::StreamTo(os, " Expected arg #"); ::testing::internal::StreamTo(os, N - 1); ::testing::internal::StreamTo(os, ": ");
std::get<N - 1>(matchers).DescribeTo(os);
*os << "\n Actual: ";
::testing::internal::StreamTo(os, "\n Actual: ");
// We remove the reference in type Value to prevent the
// universal printer from printing the address of value, which
// isn't interesting to the user most of the time. The
@ -667,7 +663,7 @@ class [[nodiscard]] TuplePrefix {
// the address is interesting.
internal::UniversalPrint(value, os);
PrintIfNotEmpty(listener.str(), os);
*os << "\n";
::testing::internal::StreamTo(os, "\n");
}
}
};
@ -766,12 +762,12 @@ class [[nodiscard]] AnythingMatcher {
bool MatchAndExplain(const T& /* x */, std::ostream* /* listener */) const {
return true;
}
void DescribeTo(std::ostream* os) const { *os << "is anything"; }
void DescribeTo(std::ostream* os) const { ::testing::internal::StreamTo(os, "is anything"); }
void DescribeNegationTo(::std::ostream* os) const {
// This is mostly for completeness' sake, as it's not very useful
// to write Not(A<bool>()). However we cannot completely rule out
// such a possibility, and it doesn't hurt to be prepared.
*os << "never matches";
::testing::internal::StreamTo(os, "never matches");
}
};
@ -785,8 +781,8 @@ class [[nodiscard]] IsNullMatcher {
return p == nullptr;
}
void DescribeTo(::std::ostream* os) const { *os << "is NULL"; }
void DescribeNegationTo(::std::ostream* os) const { *os << "isn't NULL"; }
void DescribeTo(::std::ostream* os) const { ::testing::internal::StreamTo(os, "is NULL"); }
void DescribeNegationTo(::std::ostream* os) const { ::testing::internal::StreamTo(os, "isn't NULL"); }
};
// Implements the polymorphic NotNull() matcher, which matches any raw or smart
@ -799,8 +795,8 @@ class [[nodiscard]] NotNullMatcher {
return p != nullptr;
}
void DescribeTo(::std::ostream* os) const { *os << "isn't NULL"; }
void DescribeNegationTo(::std::ostream* os) const { *os << "is NULL"; }
void DescribeTo(::std::ostream* os) const { ::testing::internal::StreamTo(os, "isn't NULL"); }
void DescribeNegationTo(::std::ostream* os) const { ::testing::internal::StreamTo(os, "is NULL"); }
};
// Ref(variable) matches any argument that is a reference to
@ -857,12 +853,12 @@ class [[nodiscard]] RefMatcher<T&> {
}
void DescribeTo(::std::ostream* os) const override {
*os << "references the variable ";
::testing::internal::StreamTo(os, "references the variable ");
UniversalPrinter<Super&>::Print(object_, os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "does not reference the variable ";
::testing::internal::StreamTo(os, "does not reference the variable ");
UniversalPrinter<Super&>::Print(object_, os);
}
@ -962,10 +958,10 @@ class [[nodiscard]] StrEqualityMatcher {
private:
void DescribeToHelper(bool expect_eq, ::std::ostream* os) const {
*os << (expect_eq ? "is " : "isn't ");
*os << "equal to ";
::testing::internal::StreamTo(os, (expect_eq ? "is " : "isn't "));
::testing::internal::StreamTo(os, "equal to ");
if (!case_sensitive_) {
*os << "(ignoring case) ";
::testing::internal::StreamTo(os, "(ignoring case) ");
}
UniversalPrint(string_, os);
}
@ -1016,12 +1012,12 @@ class [[nodiscard]] HasSubstrMatcher {
// Describes what this matcher matches.
void DescribeTo(::std::ostream* os) const {
*os << "has substring ";
::testing::internal::StreamTo(os, "has substring ");
UniversalPrint(substring_, os);
}
void DescribeNegationTo(::std::ostream* os) const {
*os << "has no substring ";
::testing::internal::StreamTo(os, "has no substring ");
UniversalPrint(substring_, os);
}
@ -1070,12 +1066,12 @@ class [[nodiscard]] StartsWithMatcher {
}
void DescribeTo(::std::ostream* os) const {
*os << "starts with ";
::testing::internal::StreamTo(os, "starts with ");
UniversalPrint(prefix_, os);
}
void DescribeNegationTo(::std::ostream* os) const {
*os << "doesn't start with ";
::testing::internal::StreamTo(os, "doesn't start with ");
UniversalPrint(prefix_, os);
}
@ -1124,12 +1120,12 @@ class [[nodiscard]] EndsWithMatcher {
}
void DescribeTo(::std::ostream* os) const {
*os << "ends with ";
::testing::internal::StreamTo(os, "ends with ");
UniversalPrint(suffix_, os);
}
void DescribeNegationTo(::std::ostream* os) const {
*os << "doesn't end with ";
::testing::internal::StreamTo(os, "doesn't end with ");
UniversalPrint(suffix_, os);
}
@ -1163,12 +1159,12 @@ class [[nodiscard]] WhenBase64UnescapedMatcher {
}
void DescribeTo(::std::ostream* os) const {
*os << "matches after Base64Unescape ";
::testing::internal::StreamTo(os, "matches after Base64Unescape ");
internal_matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const {
*os << "does not match after Base64Unescape ";
::testing::internal::StreamTo(os, "does not match after Base64Unescape ");
internal_matcher_.DescribeTo(os);
}
@ -1209,10 +1205,10 @@ class [[nodiscard]] PairMatchBase {
return Op()(::std::get<0>(args), ::std::get<1>(args));
}
void DescribeTo(::std::ostream* os) const override {
*os << "are " << GetDesc;
::testing::internal::StreamTo(os, "are "); ::testing::internal::StreamTo(os, GetDesc);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "aren't " << GetDesc;
::testing::internal::StreamTo(os, "aren't "); ::testing::internal::StreamTo(os, GetDesc);
}
};
};
@ -1302,21 +1298,21 @@ class [[nodiscard]] AllOfMatcherImpl : public MatcherInterface<const T&> {
: matchers_(std::move(matchers)) {}
void DescribeTo(::std::ostream* os) const override {
*os << "(";
::testing::internal::StreamTo(os, "(");
for (size_t i = 0; i < matchers_.size(); ++i) {
if (i != 0) *os << ") and (";
if (i != 0) ::testing::internal::StreamTo(os, ") and (");
matchers_[i].DescribeTo(os);
}
*os << ")";
::testing::internal::StreamTo(os, ")");
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "(";
::testing::internal::StreamTo(os, "(");
for (size_t i = 0; i < matchers_.size(); ++i) {
if (i != 0) *os << ") or (";
if (i != 0) ::testing::internal::StreamTo(os, ") or (");
matchers_[i].DescribeNegationTo(os);
}
*os << ")";
::testing::internal::StreamTo(os, ")");
}
bool MatchAndExplain(const T& x,
@ -1438,21 +1434,21 @@ class [[nodiscard]] AnyOfMatcherImpl : public MatcherInterface<const T&> {
: matchers_(std::move(matchers)) {}
void DescribeTo(::std::ostream* os) const override {
*os << "(";
::testing::internal::StreamTo(os, "(");
for (size_t i = 0; i < matchers_.size(); ++i) {
if (i != 0) *os << ") or (";
if (i != 0) ::testing::internal::StreamTo(os, ") or (");
matchers_[i].DescribeTo(os);
}
*os << ")";
::testing::internal::StreamTo(os, ")");
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "(";
::testing::internal::StreamTo(os, "(");
for (size_t i = 0; i < matchers_.size(); ++i) {
if (i != 0) *os << ") and (";
if (i != 0) ::testing::internal::StreamTo(os, ") and (");
matchers_[i].DescribeNegationTo(os);
}
*os << ")";
::testing::internal::StreamTo(os, ")");
}
bool MatchAndExplain(const T& x,
@ -1600,11 +1596,11 @@ class [[nodiscard]] TrulyMatcher {
}
void DescribeTo(::std::ostream* os) const {
*os << "satisfies the given predicate";
::testing::internal::StreamTo(os, "satisfies the given predicate");
}
void DescribeNegationTo(::std::ostream* os) const {
*os << "doesn't satisfy the given predicate";
::testing::internal::StreamTo(os, "doesn't satisfy the given predicate");
}
private:
@ -1717,8 +1713,8 @@ class [[nodiscard]] IsNanMatcher {
return (::std::isnan)(f);
}
void DescribeTo(::std::ostream* os) const { *os << "is NaN"; }
void DescribeNegationTo(::std::ostream* os) const { *os << "isn't NaN"; }
void DescribeTo(::std::ostream* os) const { ::testing::internal::StreamTo(os, "is NaN"); }
void DescribeNegationTo(::std::ostream* os) const { ::testing::internal::StreamTo(os, "isn't NaN"); }
};
// Implements the polymorphic floating point equality matcher, which matches
@ -1801,14 +1797,16 @@ class [[nodiscard]] FloatingEqMatcher {
os->precision(::std::numeric_limits<FloatType>::digits10 + 2);
if (FloatingPoint<FloatType>(expected_).is_nan()) {
if (nan_eq_nan_) {
*os << "is NaN";
::testing::internal::StreamTo(os, "is NaN");
} else {
*os << "never matches";
::testing::internal::StreamTo(os, "never matches");
}
} else {
*os << "is approximately " << expected_;
::testing::internal::StreamTo(os, "is approximately "); ::testing::internal::StreamTo(os, expected_);
if (HasMaxAbsError()) {
*os << " (absolute error <= " << max_abs_error_ << ")";
::testing::internal::StreamTo(os, " (absolute error <= ");
::testing::internal::StreamTo(os, max_abs_error_);
::testing::internal::StreamTo(os, ")");
}
}
os->precision(old_precision);
@ -1820,14 +1818,14 @@ class [[nodiscard]] FloatingEqMatcher {
os->precision(::std::numeric_limits<FloatType>::digits10 + 2);
if (FloatingPoint<FloatType>(expected_).is_nan()) {
if (nan_eq_nan_) {
*os << "isn't NaN";
::testing::internal::StreamTo(os, "isn't NaN");
} else {
*os << "is anything";
::testing::internal::StreamTo(os, "is anything");
}
} else {
*os << "isn't approximately " << expected_;
::testing::internal::StreamTo(os, "isn't approximately "); ::testing::internal::StreamTo(os, expected_);
if (HasMaxAbsError()) {
*os << " (absolute error > " << max_abs_error_ << ")";
::testing::internal::StreamTo(os, " (absolute error > "); ::testing::internal::StreamTo(os, max_abs_error_); ::testing::internal::StreamTo(os, ")");
}
}
// Restore original precision.
@ -1924,10 +1922,10 @@ class [[nodiscard]] FloatingEq2Matcher {
}
}
void DescribeTo(::std::ostream* os) const override {
*os << "are " << GetDesc;
::testing::internal::StreamTo(os, "are "); ::testing::internal::StreamTo(os, GetDesc);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "aren't " << GetDesc;
::testing::internal::StreamTo(os, "aren't "); ::testing::internal::StreamTo(os, GetDesc);
}
private:
@ -1976,12 +1974,12 @@ class [[nodiscard]] PointeeMatcher {
: matcher_(MatcherCast<const Pointee&>(matcher)) {}
void DescribeTo(::std::ostream* os) const override {
*os << "points to a value that ";
::testing::internal::StreamTo(os, "points to a value that ");
matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "does not point to a value that ";
::testing::internal::StreamTo(os, "does not point to a value that ");
matcher_.DescribeTo(os);
}
@ -2035,12 +2033,12 @@ class [[nodiscard]] PointerMatcher {
: matcher_(MatcherCast<Pointer>(matcher)) {}
void DescribeTo(::std::ostream* os) const override {
*os << "is a pointer that ";
::testing::internal::StreamTo(os, "is a pointer that ");
matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "is not a pointer that ";
::testing::internal::StreamTo(os, "is not a pointer that ");
matcher_.DescribeTo(os);
}
@ -2088,7 +2086,7 @@ class [[nodiscard]] WhenDynamicCastToMatcherBase {
private:
static void GetCastTypeDescription(::std::ostream* os) {
*os << "when dynamic_cast to " << GetToName() << ", ";
::testing::internal::StreamTo(os, "when dynamic_cast to "); ::testing::internal::StreamTo(os, GetToName()); ::testing::internal::StreamTo(os, ", ");
}
};
@ -2146,12 +2144,12 @@ class [[nodiscard]] FieldMatcher {
whose_field_("whose field `" + field_name + "` ") {}
void DescribeTo(::std::ostream* os) const {
*os << "is an object " << whose_field_;
::testing::internal::StreamTo(os, "is an object "); ::testing::internal::StreamTo(os, whose_field_);
matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const {
*os << "is an object " << whose_field_;
::testing::internal::StreamTo(os, "is an object "); ::testing::internal::StreamTo(os, whose_field_);
matcher_.DescribeNegationTo(os);
}
@ -2213,12 +2211,12 @@ class [[nodiscard]] PropertyMatcher {
whose_property_("whose property `" + property_name + "` ") {}
void DescribeTo(::std::ostream* os) const {
*os << "is an object " << whose_property_;
::testing::internal::StreamTo(os, "is an object "); ::testing::internal::StreamTo(os, whose_property_);
matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const {
*os << "is an object " << whose_property_;
::testing::internal::StreamTo(os, "is an object "); ::testing::internal::StreamTo(os, whose_property_);
matcher_.DescribeNegationTo(os);
}
@ -2333,18 +2331,18 @@ class [[nodiscard]] ResultOfMatcher {
void DescribeTo(::std::ostream* os) const override {
if (result_description_.empty()) {
*os << "is mapped by the given callable to a value that ";
::testing::internal::StreamTo(os, "is mapped by the given callable to a value that ");
} else {
*os << "whose " << result_description_ << " ";
::testing::internal::StreamTo(os, "whose "); ::testing::internal::StreamTo(os, result_description_); ::testing::internal::StreamTo(os, " ");
}
matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const override {
if (result_description_.empty()) {
*os << "is mapped by the given callable to a value that ";
::testing::internal::StreamTo(os, "is mapped by the given callable to a value that ");
} else {
*os << "whose " << result_description_ << " ";
::testing::internal::StreamTo(os, "whose "); ::testing::internal::StreamTo(os, result_description_); ::testing::internal::StreamTo(os, " ");
}
matcher_.DescribeNegationTo(os);
}
@ -2400,11 +2398,11 @@ class [[nodiscard]] SizeIsMatcher {
: size_matcher_(MatcherCast<SizeType>(size_matcher)) {}
void DescribeTo(::std::ostream* os) const override {
*os << "has a size that ";
::testing::internal::StreamTo(os, "has a size that ");
size_matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "has a size that ";
::testing::internal::StreamTo(os, "has a size that ");
size_matcher_.DescribeNegationTo(os);
}
@ -2453,11 +2451,11 @@ class [[nodiscard]] BeginEndDistanceIsMatcher {
: distance_matcher_(MatcherCast<DistanceType>(distance_matcher)) {}
void DescribeTo(::std::ostream* os) const override {
*os << "distance between begin() and end() ";
::testing::internal::StreamTo(os, "distance between begin() and end() ");
distance_matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "distance between begin() and end() ";
::testing::internal::StreamTo(os, "distance between begin() and end() ");
distance_matcher_.DescribeNegationTo(os);
}
@ -2511,11 +2509,11 @@ class [[nodiscard]] ContainerEqMatcher {
: expected_(View::Copy(expected)) {}
void DescribeTo(::std::ostream* os) const {
*os << "equals ";
::testing::internal::StreamTo(os, "equals ");
UniversalPrint(expected_, os);
}
void DescribeNegationTo(::std::ostream* os) const {
*os << "does not equal ";
::testing::internal::StreamTo(os, "does not equal ");
UniversalPrint(expected_, os);
}
@ -2537,9 +2535,9 @@ class [[nodiscard]] ContainerEqMatcher {
if (internal::ArrayAwareFind(expected_.begin(), expected_.end(), *it) ==
expected_.end()) {
if (printed_header) {
*os << ", ";
::testing::internal::StreamTo(os, ", ");
} else {
*os << "which has these unexpected elements: ";
::testing::internal::StreamTo(os, "which has these unexpected elements: ");
printed_header = true;
}
UniversalPrint(*it, os);
@ -2553,10 +2551,10 @@ class [[nodiscard]] ContainerEqMatcher {
lhs_stl_container.end(),
*it) == lhs_stl_container.end()) {
if (printed_header2) {
*os << ", ";
::testing::internal::StreamTo(os, ", ");
} else {
*os << (printed_header ? ",\nand" : "which")
<< " doesn't have these expected elements: ";
::testing::internal::StreamTo(os, (printed_header ? ",\nand" : "which"));
::testing::internal::StreamTo(os, " doesn't have these expected elements: ");
printed_header2 = true;
}
UniversalPrint(*it, os);
@ -2610,12 +2608,12 @@ class [[nodiscard]] WhenSortedByMatcher {
: comparator_(comparator), matcher_(matcher) {}
void DescribeTo(::std::ostream* os) const override {
*os << "(when sorted) ";
::testing::internal::StreamTo(os, "(when sorted) ");
matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "(when sorted) ";
::testing::internal::StreamTo(os, "(when sorted) ");
matcher_.DescribeNegationTo(os);
}
@ -2714,18 +2712,20 @@ class [[nodiscard]] PointwiseMatcher {
rhs_(rhs) {}
void DescribeTo(::std::ostream* os) const override {
*os << "contains " << rhs_.size()
<< " values, where each value and its corresponding value in ";
::testing::internal::StreamTo(os, "contains ");
::testing::internal::StreamTo(os, rhs_.size());
::testing::internal::StreamTo(os, " values, where each value and its corresponding value in ");
UniversalPrinter<RhsStlContainer>::Print(rhs_, os);
*os << " ";
::testing::internal::StreamTo(os, " ");
mono_tuple_matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "doesn't contain exactly " << rhs_.size()
<< " values, or contains a value x at some index i"
<< " where x and the i-th value of ";
::testing::internal::StreamTo(os, "doesn't contain exactly ");
::testing::internal::StreamTo(os, rhs_.size());
::testing::internal::StreamTo(os, " values, or contains a value x at some index i");
::testing::internal::StreamTo(os, " where x and the i-th value of ");
UniversalPrint(rhs_, os);
*os << " ";
::testing::internal::StreamTo(os, " ");
mono_tuple_matcher_.DescribeNegationTo(os);
}
@ -2880,12 +2880,12 @@ class [[nodiscard]] ContainsMatcherImpl
// Describes what this matcher does.
void DescribeTo(::std::ostream* os) const override {
*os << "contains at least one element that ";
::testing::internal::StreamTo(os, "contains at least one element that ");
this->inner_matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "doesn't contain any element that ";
::testing::internal::StreamTo(os, "doesn't contain any element that ");
this->inner_matcher_.DescribeTo(os);
}
@ -2919,12 +2919,12 @@ class [[nodiscard]] DistanceFromMatcherImpl : public MatcherInterface<V> {
// Describes what this matcher does.
void DescribeTo(::std::ostream* os) const override {
distance_matcher_.DescribeTo(os);
*os << " away from " << PrintToString(target_);
::testing::internal::StreamTo(os, " away from "); ::testing::internal::StreamTo(os, PrintToString(target_));
}
void DescribeNegationTo(::std::ostream* os) const override {
distance_matcher_.DescribeNegationTo(os);
*os << " away from " << PrintToString(target_);
::testing::internal::StreamTo(os, " away from "); ::testing::internal::StreamTo(os, PrintToString(target_));
}
bool MatchAndExplain(V value, MatchResultListener* listener) const override {
@ -2954,12 +2954,12 @@ class [[nodiscard]] EachMatcherImpl : public QuantifierMatcherImpl<Container> {
// Describes what this matcher does.
void DescribeTo(::std::ostream* os) const override {
*os << "only contains elements that ";
::testing::internal::StreamTo(os, "only contains elements that ");
this->inner_matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "contains some element that ";
::testing::internal::StreamTo(os, "contains some element that ");
this->inner_matcher_.DescribeNegationTo(os);
}
@ -2982,16 +2982,16 @@ class [[nodiscard]] ContainsTimesMatcherImpl
count_matcher_(std::move(count_matcher)) {}
void DescribeTo(::std::ostream* os) const override {
*os << "quantity of elements that match ";
::testing::internal::StreamTo(os, "quantity of elements that match ");
this->inner_matcher_.DescribeTo(os);
*os << " ";
::testing::internal::StreamTo(os, " ");
count_matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "quantity of elements that match ";
::testing::internal::StreamTo(os, "quantity of elements that match ");
this->inner_matcher_.DescribeTo(os);
*os << " ";
::testing::internal::StreamTo(os, " ");
count_matcher_.DescribeNegationTo(os);
}
@ -3156,13 +3156,13 @@ class [[nodiscard]] KeyMatcherImpl : public MatcherInterface<PairType> {
// Describes what this matcher does.
void DescribeTo(::std::ostream* os) const override {
*os << "has a key that ";
::testing::internal::StreamTo(os, "has a key that ");
inner_matcher_.DescribeTo(os);
}
// Describes what the negation of this matcher does.
void DescribeNegationTo(::std::ostream* os) const override {
*os << "doesn't have a key that ";
::testing::internal::StreamTo(os, "doesn't have a key that ");
inner_matcher_.DescribeTo(os);
}
@ -3207,12 +3207,12 @@ class [[nodiscard]] AddressMatcher {
: matcher_(MatcherCast<Address>(matcher)) {}
void DescribeTo(::std::ostream* os) const override {
*os << "has address that ";
::testing::internal::StreamTo(os, "has address that ");
matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "does not have address that ";
::testing::internal::StreamTo(os, "does not have address that ");
matcher_.DescribeTo(os);
}
@ -3247,17 +3247,17 @@ class [[nodiscard]] PairMatcherImpl : public MatcherInterface<PairType> {
// Describes what this matcher does.
void DescribeTo(::std::ostream* os) const override {
*os << "has a first field that ";
::testing::internal::StreamTo(os, "has a first field that ");
first_matcher_.DescribeTo(os);
*os << ", and has a second field that ";
::testing::internal::StreamTo(os, ", and has a second field that ");
second_matcher_.DescribeTo(os);
}
// Describes what the negation of this matcher does.
void DescribeNegationTo(::std::ostream* os) const override {
*os << "has a first field that ";
::testing::internal::StreamTo(os, "has a first field that ");
first_matcher_.DescribeNegationTo(os);
*os << ", or has a second field that ";
::testing::internal::StreamTo(os, ", or has a second field that ");
second_matcher_.DescribeNegationTo(os);
}
@ -3519,13 +3519,19 @@ class [[nodiscard]] FieldsAreMatcherImpl<Struct, std::index_sequence<I...>>
void DescribeTo(::std::ostream* os) const override {
const char* separator = "";
VariadicExpand(
{(*os << separator << "has field #" << I << " that ",
{(::testing::internal::StreamTo(os, separator),
::testing::internal::StreamTo(os, "has field #"),
::testing::internal::StreamTo(os, I),
::testing::internal::StreamTo(os, " that "),
std::get<I>(matchers_).DescribeTo(os), separator = ", and ")...});
}
void DescribeNegationTo(::std::ostream* os) const override {
const char* separator = "";
VariadicExpand({(*os << separator << "has field #" << I << " that ",
VariadicExpand({(::testing::internal::StreamTo(os, separator),
::testing::internal::StreamTo(os, "has field #"),
::testing::internal::StreamTo(os, I),
::testing::internal::StreamTo(os, " that "),
std::get<I>(matchers_).DescribeNegationTo(os),
separator = ", or ")...});
}
@ -3615,17 +3621,17 @@ class [[nodiscard]] ElementsAreMatcherImpl
// Describes what this matcher does.
void DescribeTo(::std::ostream* os) const override {
if (count() == 0) {
*os << "is empty";
::testing::internal::StreamTo(os, "is empty");
} else if (count() == 1) {
*os << "has 1 element that ";
::testing::internal::StreamTo(os, "has 1 element that ");
matchers_[0].DescribeTo(os);
} else {
*os << "has " << Elements(count()) << " where\n";
::testing::internal::StreamTo(os, "has "); ::testing::internal::StreamTo(os, Elements(count())); ::testing::internal::StreamTo(os, " where\n");
for (size_t i = 0; i != count(); ++i) {
*os << "element #" << i << " ";
::testing::internal::StreamTo(os, "element #"); ::testing::internal::StreamTo(os, i); ::testing::internal::StreamTo(os, " ");
matchers_[i].DescribeTo(os);
if (i + 1 < count()) {
*os << ",\n";
::testing::internal::StreamTo(os, ",\n");
}
}
}
@ -3634,16 +3640,16 @@ class [[nodiscard]] ElementsAreMatcherImpl
// Describes what the negation of this matcher does.
void DescribeNegationTo(::std::ostream* os) const override {
if (count() == 0) {
*os << "isn't empty";
::testing::internal::StreamTo(os, "isn't empty");
return;
}
*os << "doesn't have " << Elements(count()) << ", or\n";
::testing::internal::StreamTo(os, "doesn't have "); ::testing::internal::StreamTo(os, Elements(count())); ::testing::internal::StreamTo(os, ", or\n");
for (size_t i = 0; i != count(); ++i) {
*os << "element #" << i << " ";
::testing::internal::StreamTo(os, "element #"); ::testing::internal::StreamTo(os, i); ::testing::internal::StreamTo(os, " ");
matchers_[i].DescribeNegationTo(os);
if (i + 1 < count()) {
*os << ", or\n";
::testing::internal::StreamTo(os, ", or\n");
}
}
}
@ -4231,9 +4237,9 @@ class [[nodiscard]] BoundSecondMatcher {
second_value_(second) {}
void DescribeTo(::std::ostream* os) const override {
*os << "and ";
::testing::internal::StreamTo(os, "and ");
UniversalPrint(second_value_, os);
*os << " ";
::testing::internal::StreamTo(os, " ");
mono_tuple2_matcher_.DescribeTo(os);
}
@ -4306,12 +4312,12 @@ class [[nodiscard]] OptionalMatcher {
: value_matcher_(MatcherCast<ValueType>(value_matcher)) {}
void DescribeTo(::std::ostream* os) const override {
*os << "value ";
::testing::internal::StreamTo(os, "value ");
value_matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "value ";
::testing::internal::StreamTo(os, "value ");
value_matcher_.DescribeNegationTo(os);
}
@ -4379,14 +4385,16 @@ class [[nodiscard]] VariantMatcher {
}
void DescribeTo(std::ostream* os) const {
*os << "is a variant<> with value of type '" << GetTypeName()
<< "' and the value ";
::testing::internal::StreamTo(os, "is a variant<> with value of type '");
::testing::internal::StreamTo(os, GetTypeName());
::testing::internal::StreamTo(os, "' and the value ");
matcher_.DescribeTo(os);
}
void DescribeNegationTo(std::ostream* os) const {
*os << "is a variant<> with value of type other than '" << GetTypeName()
<< "' or the value ";
::testing::internal::StreamTo(os, "is a variant<> with value of type other than '");
::testing::internal::StreamTo(os, GetTypeName());
::testing::internal::StreamTo(os, "' or the value ");
matcher_.DescribeNegationTo(os);
}
@ -4440,14 +4448,16 @@ class [[nodiscard]] AnyCastMatcher {
}
void DescribeTo(std::ostream* os) const {
*os << "is an 'any' type with value of type '" << GetTypeName()
<< "' and the value ";
::testing::internal::StreamTo(os, "is an 'any' type with value of type '");
::testing::internal::StreamTo(os, GetTypeName());
::testing::internal::StreamTo(os, "' and the value ");
matcher_.DescribeTo(os);
}
void DescribeNegationTo(std::ostream* os) const {
*os << "is an 'any' type with value of type other than '" << GetTypeName()
<< "' or the value ";
::testing::internal::StreamTo(os, "is an 'any' type with value of type other than '");
::testing::internal::StreamTo(os, GetTypeName());
::testing::internal::StreamTo(os, "' or the value ");
matcher_.DescribeNegationTo(os);
}
@ -4497,13 +4507,13 @@ class [[nodiscard]] ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
}
void DescribeTo(::std::ostream* os) const override {
*os << "are a tuple ";
::testing::internal::StreamTo(os, "are a tuple ");
PrintIndices(os);
inner_matcher_.DescribeTo(os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << "are a tuple ";
::testing::internal::StreamTo(os, "are a tuple ");
PrintIndices(os);
inner_matcher_.DescribeNegationTo(os);
}
@ -4511,7 +4521,7 @@ class [[nodiscard]] ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
private:
// Prints the indices of the selected fields.
static void PrintIndices(::std::ostream* os) {
*os << "whose fields (";
::testing::internal::StreamTo(os, "whose fields (");
const char* sep = "";
// Workaround spurious C4189 on MSVC<=15.7 when k is empty.
(void)sep;
@ -4520,9 +4530,12 @@ class [[nodiscard]] ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
// and may have been trying to use the first operation of the comma operator
// as a member of the array, so Clang warns that we may have made a mistake.
const char* dummy[] = {
"", (static_cast<void>(*os << sep << "#" << k), sep = ", ")...};
"", (static_cast<void>(::testing::internal::StreamTo(os, sep),
::testing::internal::StreamTo(os, "#"),
::testing::internal::StreamTo(os, k)),
sep = ", ")...};
(void)dummy;
*os << ") ";
::testing::internal::StreamTo(os, ") ");
}
MonomorphicInnerMatcher inner_matcher_;
@ -5734,12 +5747,12 @@ class [[nodiscard]] WithWhatMatcherImpl {
: matcher_(std::move(matcher)) {}
void DescribeTo(std::ostream* os) const {
*os << "contains .what() that ";
::testing::internal::StreamTo(os, "contains .what() that ");
matcher_.DescribeTo(os);
}
void DescribeNegationTo(std::ostream* os) const {
*os << "contains .what() that does not ";
::testing::internal::StreamTo(os, "contains .what() that does not ");
matcher_.DescribeTo(os);
}
@ -5800,14 +5813,16 @@ class [[nodiscard]] ExceptionMatcherImpl {
: matcher_(std::move(matcher)) {}
void DescribeTo(std::ostream* os) const {
*os << "throws an exception which is a " << GetTypeName<Err>();
*os << " which ";
::testing::internal::StreamTo(os, "throws an exception which is a ");
::testing::internal::StreamTo(os, GetTypeName<Err>());
::testing::internal::StreamTo(os, " which ");
matcher_.DescribeTo(os);
}
void DescribeNegationTo(std::ostream* os) const {
*os << "throws an exception which is not a " << GetTypeName<Err>();
*os << " which ";
::testing::internal::StreamTo(os, "throws an exception which is not a ");
::testing::internal::StreamTo(os, GetTypeName<Err>());
::testing::internal::StreamTo(os, " which ");
matcher_.DescribeNegationTo(os);
}

View File

@ -40,7 +40,7 @@
#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_
#include <ostream>
#include <iosfwd>
#include <string>
#include "gmock/gmock-matchers.h"
@ -80,9 +80,13 @@ class [[nodiscard]] IsEmptyMatcher {
}
// Describes what this matcher matches.
void DescribeTo(std::ostream* os) const { *os << "is empty"; }
void DescribeTo(std::ostream* os) const {
::testing::internal::StreamTo(os, "is empty");
}
void DescribeNegationTo(std::ostream* os) const { *os << "isn't empty"; }
void DescribeNegationTo(std::ostream* os) const {
::testing::internal::StreamTo(os, "isn't empty");
}
};
} // namespace internal

View File

@ -65,9 +65,8 @@
#include <functional>
#include <map>
#include <memory>
#include <ostream>
#include <iosfwd>
#include <set>
#include <sstream>
#include <string>
#include <type_traits>
#include <utility>
@ -698,7 +697,8 @@ class GTEST_API_ ExpectationBase {
// Describes the source file location of this expectation.
void DescribeLocationTo(::std::ostream* os) const {
*os << FormatFileLocation(file(), line()) << " ";
::testing::internal::StreamTo(os, FormatFileLocation(file(), line()));
::testing::internal::StreamTo(os, " ");
}
// Describes how many times a function call matching this
@ -1084,9 +1084,9 @@ class TypedExpectation<R(Args...)> : public ExpectationBase {
// describes it to the ostream.
void MaybeDescribeExtraMatcherTo(::std::ostream* os) override {
if (extra_matcher_specified_) {
*os << " Expected args: ";
::testing::internal::StreamTo(os, " Expected args: ");
extra_matcher_.DescribeTo(os);
*os << "\n";
::testing::internal::StreamTo(os, "\n");
}
}
@ -1140,40 +1140,42 @@ class TypedExpectation<R(Args...)> : public ExpectationBase {
g_gmock_mutex.AssertHeld();
if (is_retired()) {
*os << " Expected: the expectation is active\n"
<< " Actual: it is retired\n";
::testing::internal::StreamTo(os, " Expected: the expectation is active\n");
::testing::internal::StreamTo(os, " Actual: it is retired\n");
} else if (!Matches(args)) {
if (!TupleMatches(matchers_, args)) {
ExplainMatchFailureTupleTo(matchers_, args, os);
}
StringMatchResultListener listener;
if (!extra_matcher_.MatchAndExplain(args, &listener)) {
*os << " Expected args: ";
::testing::internal::StreamTo(os, " Expected args: ");
extra_matcher_.DescribeTo(os);
*os << "\n Actual: don't match";
::testing::internal::StreamTo(os, "\n Actual: don't match");
internal::PrintIfNotEmpty(listener.str(), os);
*os << "\n";
::testing::internal::StreamTo(os, "\n");
}
} else if (!AllPrerequisitesAreSatisfied()) {
*os << " Expected: all pre-requisites are satisfied\n"
<< " Actual: the following immediate pre-requisites "
<< "are not satisfied:\n";
::testing::internal::StreamTo(os, " Expected: all pre-requisites are satisfied\n");
::testing::internal::StreamTo(os, " Actual: the following immediate pre-requisites ");
::testing::internal::StreamTo(os, "are not satisfied:\n");
ExpectationSet unsatisfied_prereqs;
FindUnsatisfiedPrerequisites(&unsatisfied_prereqs);
int i = 0;
for (ExpectationSet::const_iterator it = unsatisfied_prereqs.begin();
it != unsatisfied_prereqs.end(); ++it) {
it->expectation_base()->DescribeLocationTo(os);
*os << "pre-requisite #" << i++ << "\n";
::testing::internal::StreamTo(os, "pre-requisite #");
::testing::internal::StreamTo(os, i++);
::testing::internal::StreamTo(os, "\n");
}
*os << " (end of pre-requisites)\n";
::testing::internal::StreamTo(os, " (end of pre-requisites)\n");
} else {
// This line is here just for completeness' sake. It will never
// be executed as currently the ExplainMatchResultTo() function
// is called only when the mock function call does NOT match the
// expectation.
*os << "The call matches the expectation.\n";
::testing::internal::StreamTo(os, "The call matches the expectation.\n");
}
}
@ -1602,11 +1604,12 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
const OnCallSpec<F>* const spec = FindOnCallSpec(args);
if (spec == nullptr) {
*os << (std::is_void<Result>::value ? "returning directly.\n"
: "returning default value.\n");
::testing::internal::StreamTo(os, (std::is_void<Result>::value ? "returning directly.\n"
: "returning default value.\n"));
} else {
*os << "taking default action specified at:\n"
<< FormatFileLocation(spec->file(), spec->line()) << "\n";
::testing::internal::StreamTo(os, "taking default action specified at:\n");
::testing::internal::StreamTo(os, FormatFileLocation(spec->file(), spec->line()));
::testing::internal::StreamTo(os, "\n");
}
}
@ -1618,9 +1621,10 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
GTEST_LOCK_EXCLUDED_(g_gmock_mutex) {
const ArgumentTuple& args =
*static_cast<const ArgumentTuple*>(untyped_args);
*os << "Uninteresting mock function call - ";
::testing::internal::StreamTo(os, "Uninteresting mock function call - ");
DescribeDefaultActionTo(args, os);
*os << " Function call: " << Name();
::testing::internal::StreamTo(os, " Function call: ");
::testing::internal::StreamTo(os, Name());
UniversalPrint(args, os);
}
@ -1697,7 +1701,7 @@ class FunctionMocker<R(Args...)> final : public UntypedFunctionMockerBase {
::std::ostream* why) const
GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) {
g_gmock_mutex.AssertHeld();
*os << "\nUnexpected mock function call - ";
::testing::internal::StreamTo(os, "\nUnexpected mock function call - ");
DescribeDefaultActionTo(args, os);
PrintTriedExpectationsLocked(args, why);
}

View File

@ -42,7 +42,6 @@
#include <stdio.h>
#include <iterator>
#include <ostream> // NOLINT
#include <string>
#include <type_traits>
#include <utility>

View File

@ -44,7 +44,6 @@
#include <stdlib.h>
#include <cstdint>
#include <iostream>
// Most of the utilities needed for porting Google Mock are also
// required for Google Test and are defined in gtest-port.h.

View File

@ -42,8 +42,29 @@
#include <vector>
namespace testing {
StringMatchResultListener::StringMatchResultListener()
: MatchResultListener(new ::std::stringstream),
ss_(static_cast< ::std::stringstream*>(stream())) {}
StringMatchResultListener::~StringMatchResultListener() = default;
std::string StringMatchResultListener::str() const {
return static_cast<const ::std::stringstream*>(stream())->str();
}
void StringMatchResultListener::Clear() {
static_cast< ::std::stringstream*>(stream())->str("");
}
namespace internal {
void PrintIfNotEmpty(const std::string& explanation, ::std::ostream* os) {
if (explanation != "" && os != nullptr) {
*os << "\n " << explanation;
}
}
// Returns the description for a matcher defined using the MATCHER*()
// macro where the user-supplied description string is "", if
// 'negation' is false; otherwise returns the description of the

View File

@ -39,7 +39,7 @@
#define GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_
#include <memory>
#include <ostream>
#include <iosfwd>
#include <string>
#include <type_traits>

View File

@ -43,7 +43,7 @@
#include <cstddef>
#include <functional>
#include <memory>
#include <ostream>
#include <iosfwd>
#include <string>
#include <type_traits>
@ -88,12 +88,12 @@ class [[nodiscard]] MatchResultListener {
// is NULL.
template <typename T>
MatchResultListener& operator<<(const T& x) {
if (stream_ != nullptr) *stream_ << x;
if (stream_ != nullptr) internal::StreamTo(stream_, x);
return *this;
}
// Returns the underlying ostream.
::std::ostream* stream() { return stream_; }
::std::ostream* stream() const { return stream_; }
// Returns true if and only if the listener is interested in an explanation
// of the match result. A matcher's MatchAndExplain() method can use
@ -129,11 +129,7 @@ class GTEST_API_ [[nodiscard]] MatcherDescriberInterface {
// You are not required to override this when implementing
// MatcherInterface, but it is highly advised so that your matcher
// can produce good error messages.
virtual void DescribeNegationTo(::std::ostream* os) const {
*os << "not (";
DescribeTo(os);
*os << ")";
}
virtual void DescribeNegationTo(::std::ostream* os) const;
};
// The implementation of a matcher.
@ -801,11 +797,11 @@ class [[nodiscard]] ImplicitCastEqMatcher {
}
void DescribeTo(std::ostream* os) const {
*os << "is equal to ";
internal::StreamTo(os, "is equal to ");
UniversalPrint(rhs(), os);
}
void DescribeNegationTo(std::ostream* os) const {
*os << "isn't equal to ";
internal::StreamTo(os, "isn't equal to ");
UniversalPrint(rhs(), os);
}
@ -857,13 +853,15 @@ class [[nodiscard]] MatchesRegexMatcher {
}
void DescribeTo(::std::ostream* os) const {
*os << (full_match_ ? "matches" : "contains") << " regular expression ";
internal::StreamTo(os, full_match_ ? "matches" : "contains");
internal::StreamTo(os, " regular expression ");
UniversalPrinter<std::string>::Print(regex_->pattern(), os);
}
void DescribeNegationTo(::std::ostream* os) const {
*os << "doesn't " << (full_match_ ? "match" : "contain")
<< " regular expression ";
internal::StreamTo(os, "doesn't ");
internal::StreamTo(os, full_match_ ? "match" : "contain");
internal::StreamTo(os, " regular expression ");
UniversalPrinter<std::string>::Print(regex_->pattern(), os);
}

View File

@ -50,8 +50,7 @@
#include <limits>
#include <memory>
#include <ostream>
#include <sstream>
#include <iosfwd>
#include <string>
#include "gtest/internal/gtest-port.h"
@ -109,18 +108,24 @@ class GTEST_API_ Message {
Message();
// Copy constructor.
Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT
*ss_ << msg.GetString();
}
Message(const Message& msg);
// Destructor.
~Message();
// Constructs a Message from a C-string.
explicit Message(const char* str) : ss_(new ::std::stringstream) {
*ss_ << str;
}
explicit Message(const char* str);
// Streams a non-pointer value to this object. If building a version of
// GoogleTest with ABSL, this overload is only enabled if the value does not
// have an AbslStringify definition.
Message& operator<<(const char* s);
Message& operator<<(const std::string& s);
Message& operator<<(int n);
Message& operator<<(long n);
Message& operator<<(double n);
Message& operator<<(const void* p);
template <
typename T
#ifdef GTEST_HAS_ABSL
@ -179,12 +184,7 @@ class GTEST_API_ Message {
// as "(null)".
template <typename T>
inline Message& operator<<(T* const& pointer) { // NOLINT
if (pointer == nullptr) {
*ss_ << "(null)";
} else {
*ss_ << pointer;
}
return *this;
return (*this << static_cast<const void*>(pointer));
}
// Since the basic IO manipulators are overloaded for both narrow
@ -193,10 +193,7 @@ class GTEST_API_ Message {
// templatized version above. Without this definition, streaming
// endl or other basic IO manipulators to Message will confuse the
// compiler.
Message& operator<<(BasicNarrowIoManip val) {
*ss_ << val;
return *this;
}
Message& operator<<(BasicNarrowIoManip val);
// Instead of 1/0, we want to see true/false for bool values.
Message& operator<<(bool b) { return *this << (b ? "true" : "false"); }
@ -220,7 +217,7 @@ class GTEST_API_ Message {
private:
// We'll hold the text streamed to this object here.
const std::unique_ptr< ::std::stringstream> ss_;
const std::unique_ptr< ::std::ostream> ss_;
// We declare (but don't implement) this to prevent the compiler
// from implementing the assignment operator.

View File

@ -108,7 +108,7 @@
#include <functional>
#include <memory>
#include <optional>
#include <ostream> // NOLINT
#include <iosfwd>
#include <sstream>
#include <string>
#include <string_view>
@ -135,11 +135,30 @@
#endif // GTEST_INTERNAL_HAS_COMPARE_LIB
namespace testing {
class Message;
// Definitions in the internal* namespaces are subject to change without notice.
// DO NOT USE THEM IN USER CODE!
namespace internal {
GTEST_API_ ::std::string PrintToStringWithPrinter(
const void* value, void (*printer)(::std::ostream*, const void*));
GTEST_API_ void StreamTo(::std::ostream* os, char c);
GTEST_API_ void StreamTo(::std::ostream* os, const char* s);
GTEST_API_ void StreamTo(::std::ostream* os, const std::string& s);
GTEST_API_ void StreamTo(::std::ostream* os, const void* p);
GTEST_API_ void StreamTo(::std::ostream* os, bool b);
GTEST_API_ void StreamTo(::std::ostream* os, float f);
GTEST_API_ void StreamTo(::std::ostream* os, double d);
GTEST_API_ void StreamTo(::std::ostream* os, int n);
GTEST_API_ void StreamTo(::std::ostream* os, unsigned int n);
GTEST_API_ void StreamTo(::std::ostream* os, long n);
GTEST_API_ void StreamTo(::std::ostream* os, unsigned long n);
GTEST_API_ void StreamTo(::std::ostream* os, long long n);
GTEST_API_ void StreamTo(::std::ostream* os, unsigned long long n);
GTEST_API_ void StreamTo(::std::ostream* os, const Message& msg);
template <typename T>
void UniversalPrint(const T& value, ::std::ostream* os);
@ -171,17 +190,17 @@ struct ContainerPrinter {
IsStdSpan<T>::value>::type>
static void PrintValue(const T& container, std::ostream* os) {
const size_t kMaxCount = 32; // The maximum number of elements to print.
*os << '{';
StreamTo(os, '{');
size_t count = 0;
for (auto&& elem : container) {
if (count > 0) {
*os << ',';
StreamTo(os, ',');
if (count == kMaxCount) { // Enough has been printed.
*os << " ...";
StreamTo(os, " ...");
break;
}
}
*os << ' ';
StreamTo(os, ' ');
// We cannot call PrintTo(elem, os) here as PrintTo() doesn't
// handle `elem` being a native array.
internal::UniversalPrint(elem, os);
@ -189,9 +208,9 @@ struct ContainerPrinter {
}
if (count > 0) {
*os << ' ';
StreamTo(os, ' ');
}
*os << '}';
StreamTo(os, '}');
}
};
@ -206,12 +225,12 @@ struct FunctionPointerPrinter {
std::is_function<T>::value>::type>
static void PrintValue(T* p, ::std::ostream* os) {
if (p == nullptr) {
*os << "NULL";
StreamTo(os, "NULL");
} else {
// T is a function type, so '*os << p' doesn't do what we want
// (it just prints p as bool). We want to print p as a const
// void*.
*os << reinterpret_cast<const void*>(p);
StreamTo(os, reinterpret_cast<const void*>(p));
}
}
};
@ -220,12 +239,12 @@ struct PointerPrinter {
template <typename T>
static void PrintValue(T* p, ::std::ostream* os) {
if (p == nullptr) {
*os << "NULL";
StreamTo(os, "NULL");
} else {
// T is not a function type. We just call << to print p,
// relying on ADL to pick up user-defined << for their pointer
// types, if any.
*os << p;
StreamTo(os, p);
}
}
};
@ -273,7 +292,9 @@ struct ProtobufPrinter {
if (pretty_str.length() > kProtobufOneLinerMaxLength) {
pretty_str = "\n" + value.DebugString();
}
*os << ("<" + pretty_str + ">");
StreamTo(os, "<");
StreamTo(os, pretty_str);
StreamTo(os, ">");
}
};
@ -286,7 +307,7 @@ struct ConvertibleToIntegerPrinter {
// T is not an enum, printing it as an integer is the best we can do
// given that it has no user-defined printer.
static void PrintValue(internal::BiggestInt value, ::std::ostream* os) {
*os << value;
StreamTo(os, value);
}
};
@ -304,7 +325,7 @@ struct ConvertibleToAbslStringifyPrinter {
typename = typename std::enable_if<
absl::HasAbslStringify<T>::value>::type> // NOLINT
static void PrintValue(const T& value, ::std::ostream* os) {
*os << absl::StrCat(value);
StreamTo(os, absl::StrCat(value));
}
};
#endif // GTEST_HAS_ABSL
@ -328,7 +349,7 @@ struct RawBytesPrinter {
struct FallbackPrinter {
template <typename T>
static void PrintValue(const T&, ::std::ostream* os) {
*os << "(incomplete type)";
StreamTo(os, "(incomplete type)");
}
};
@ -511,7 +532,7 @@ inline void PrintTo(char c, ::std::ostream* os) {
// Overloads for other simple built-in types.
inline void PrintTo(bool x, ::std::ostream* os) {
*os << (x ? "true" : "false");
StreamTo(os, x ? "true" : "false");
}
// Overload for wchar_t type.
@ -624,19 +645,8 @@ int AppropriateResolution(FloatType val) {
return full;
}
inline void PrintTo(float f, ::std::ostream* os) {
auto old_precision = os->precision();
os->precision(AppropriateResolution(f));
*os << f;
os->precision(old_precision);
}
inline void PrintTo(double d, ::std::ostream* os) {
auto old_precision = os->precision();
os->precision(AppropriateResolution(d));
*os << d;
os->precision(old_precision);
}
GTEST_API_ void PrintTo(float f, ::std::ostream* os);
GTEST_API_ void PrintTo(double d, ::std::ostream* os);
// Overloads for C strings.
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
@ -784,10 +794,12 @@ inline const void* VoidifyPointer(volatile const void* p) {
template <typename T, typename Ptr>
void PrintSmartPointer(const Ptr& ptr, std::ostream* os, char) {
if (ptr == nullptr) {
*os << "(nullptr)";
StreamTo(os, "(nullptr)");
} else {
// We can't print the value. Just print the pointer..
*os << "(" << (VoidifyPointer)(ptr.get()) << ")";
StreamTo(os, "(");
StreamTo(os, (VoidifyPointer)(ptr.get()));
StreamTo(os, ")");
}
}
template <typename T, typename Ptr,
@ -795,11 +807,13 @@ template <typename T, typename Ptr,
!std::is_array<T>::value>::type>
void PrintSmartPointer(const Ptr& ptr, std::ostream* os, int) {
if (ptr == nullptr) {
*os << "(nullptr)";
StreamTo(os, "(nullptr)");
} else {
*os << "(ptr = " << (VoidifyPointer)(ptr.get()) << ", value = ";
StreamTo(os, "(ptr = ");
StreamTo(os, (VoidifyPointer)(ptr.get()));
StreamTo(os, ", value = ");
UniversalPrinter<T>::Print(*ptr, os);
*os << ")";
StreamTo(os, ")");
}
}
@ -861,7 +875,7 @@ void PrintTupleTo(const T& t, std::integral_constant<size_t, I>,
GTEST_INTENTIONAL_CONST_COND_PUSH_()
if (I > 1) {
GTEST_INTENTIONAL_CONST_COND_POP_()
*os << ", ";
StreamTo(os, ", ");
}
UniversalPrinter<typename std::tuple_element<I - 1, T>::type>::Print(
std::get<I - 1>(t), os);
@ -923,9 +937,10 @@ class [[nodiscard]] UniversalPrinter<std::any> {
public:
static void Print(const std::any& value, ::std::ostream* os) {
if (value.has_value()) {
*os << "value of type " << GetTypeName(value);
StreamTo(os, "value of type ");
StreamTo(os, GetTypeName(value));
} else {
*os << "no value";
StreamTo(os, "no value");
}
}
@ -945,20 +960,20 @@ template <typename T>
class [[nodiscard]] UniversalPrinter<std::optional<T>> {
public:
static void Print(const std::optional<T>& value, ::std::ostream* os) {
*os << '(';
StreamTo(os, '(');
if (!value) {
*os << "nullopt";
StreamTo(os, "nullopt");
} else {
UniversalPrint(*value, os);
}
*os << ')';
StreamTo(os, ')');
}
};
template <>
class [[nodiscard]] UniversalPrinter<std::nullopt_t> {
public:
static void Print(std::nullopt_t, ::std::ostream* os) { *os << "(nullopt)"; }
static void Print(std::nullopt_t, ::std::ostream* os) { StreamTo(os, "(nullopt)"); }
};
// Printer for std::variant
@ -966,17 +981,20 @@ template <typename... T>
class [[nodiscard]] UniversalPrinter<std::variant<T...>> {
public:
static void Print(const std::variant<T...>& value, ::std::ostream* os) {
*os << '(';
StreamTo(os, '(');
std::visit(Visitor{os, value.index()}, value);
*os << ')';
StreamTo(os, ')');
}
private:
struct Visitor {
template <typename U>
void operator()(const U& u) const {
*os << "'" << GetTypeName<U>() << "(index = " << index
<< ")' with value ";
StreamTo(os, "'");
StreamTo(os, GetTypeName<U>());
StreamTo(os, "(index = ");
StreamTo(os, index);
StreamTo(os, ")' with value ");
UniversalPrint(u, os);
}
::std::ostream* os;
@ -989,9 +1007,9 @@ class [[nodiscard]] UniversalPrinter<std::variant<T...>> {
template <typename T>
void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
if (len == 0) {
*os << "{}";
StreamTo(os, "{}");
} else {
*os << "{ ";
StreamTo(os, "{ ");
const size_t kThreshold = 18;
const size_t kChunkSize = 8;
// If the array has more than kThreshold elements, we'll have to
@ -1001,10 +1019,10 @@ void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
PrintRawArrayTo(begin, len, os);
} else {
PrintRawArrayTo(begin, kChunkSize, os);
*os << ", ..., ";
StreamTo(os, ", ..., ");
PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os);
}
*os << " }";
StreamTo(os, " }");
}
}
// This overload prints a (const) char array compactly.
@ -1051,7 +1069,9 @@ class [[nodiscard]] UniversalPrinter<T&> {
static void Print(const T& value, ::std::ostream* os) {
// Prints the address of the value. We use reinterpret_cast here
// as static_cast doesn't compile when T is a function type.
*os << "@" << reinterpret_cast<const void*>(&value) << " ";
StreamTo(os, "@");
StreamTo(os, reinterpret_cast<const void*>(&value));
StreamTo(os, " ");
// Then prints the value itself.
UniversalPrint(value, os);
@ -1097,7 +1117,7 @@ class [[nodiscard]] UniversalTersePrinter<const char*> {
public:
static void Print(const char* str, ::std::ostream* os) {
if (str == nullptr) {
*os << "NULL";
StreamTo(os, "NULL");
} else {
UniversalPrint(std::string(str), os);
}
@ -1113,7 +1133,7 @@ class [[nodiscard]] UniversalTersePrinter<const char8_t*> {
public:
static void Print(const char8_t* str, ::std::ostream* os) {
if (str == nullptr) {
*os << "NULL";
StreamTo(os, "NULL");
} else {
UniversalPrint(::std::u8string(str), os);
}
@ -1129,7 +1149,7 @@ class [[nodiscard]] UniversalTersePrinter<const char16_t*> {
public:
static void Print(const char16_t* str, ::std::ostream* os) {
if (str == nullptr) {
*os << "NULL";
StreamTo(os, "NULL");
} else {
UniversalPrint(::std::u16string(str), os);
}
@ -1144,7 +1164,7 @@ class [[nodiscard]] UniversalTersePrinter<const char32_t*> {
public:
static void Print(const char32_t* str, ::std::ostream* os) {
if (str == nullptr) {
*os << "NULL";
StreamTo(os, "NULL");
} else {
UniversalPrint(::std::u32string(str), os);
}
@ -1160,7 +1180,7 @@ class [[nodiscard]] UniversalTersePrinter<const wchar_t*> {
public:
static void Print(const wchar_t* str, ::std::ostream* os) {
if (str == nullptr) {
*os << "NULL";
StreamTo(os, "NULL");
} else {
UniversalPrint(::std::wstring(str), os);
}

View File

@ -35,7 +35,6 @@
#define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#include <iosfwd>
#include <ostream>
#include <string>
#include <string_view>
#include <vector>

View File

@ -53,9 +53,8 @@
#include <cstdint>
#include <limits>
#include <memory>
#include <ostream>
#include <iosfwd>
#include <set>
#include <sstream>
#include <string>
#include <string_view>
#include <type_traits>
@ -1593,17 +1592,9 @@ AssertionResult CmpHelperFloatingPointEQ(const char* lhs_expression,
return AssertionSuccess();
}
::std::stringstream lhs_ss;
lhs_ss.precision(std::numeric_limits<RawType>::digits10 + 2);
lhs_ss << lhs_value;
::std::stringstream rhs_ss;
rhs_ss.precision(std::numeric_limits<RawType>::digits10 + 2);
rhs_ss << rhs_value;
return EqFailure(lhs_expression, rhs_expression,
StringStreamToString(&lhs_ss), StringStreamToString(&rhs_ss),
false);
(Message() << lhs_value).GetString(),
(Message() << rhs_value).GetString(), false);
}
// Helper function for implementing ASSERT_NEAR.

View File

@ -43,7 +43,7 @@
#include <iterator>
#include <map>
#include <memory>
#include <ostream>
#include <iosfwd>
#include <set>
#include <string>
#include <tuple>
@ -250,7 +250,7 @@ class [[nodiscard]] RangeGenerator : public ParamGeneratorInterface<T> {
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
<< "from different generators." << "\n";
const int other_index =
CheckedDowncastToActualType<const Iterator>(&other)->index_;
return index_ == other_index;
@ -347,7 +347,7 @@ class [[nodiscard]] ValuesInIteratorRangeGenerator
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
<< "from different generators." << "\n";
return iterator_ ==
CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
}
@ -586,11 +586,11 @@ class [[nodiscard]] ParameterizedTestSuiteInfo
<< "Parameterized test name '" << param_name
<< "' is invalid (contains spaces, dashes, or any "
"non-alphanumeric characters other than underscores), in "
<< file << " line " << line << "" << std::endl;
<< file << " line " << line << "" << "\n";
GTEST_CHECK_(test_param_names.count(param_name) == 0)
<< "Duplicate parameterized test name '" << param_name << "', in "
<< file << " line " << line << std::endl;
<< file << " line " << line << "\n";
if (!test_info->test_base_name.empty()) {
test_name.append(test_info->test_base_name).append("/");
@ -882,7 +882,7 @@ class [[nodiscard]] CartesianProductGenerator
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
<< "from different generators." << "\n";
const IteratorImpl* typed_other =
CheckedDowncastToActualType<const IteratorImpl>(&other);
@ -1004,7 +1004,7 @@ class [[nodiscard]] ParamGeneratorConverter
// iterator is of the same type and we can downcast.
GTEST_CHECK_(BaseGenerator() == other.BaseGenerator())
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
<< "from different generators." << "\n";
const ParamIterator<From> other_it =
CheckedDowncastToActualType<const Iterator>(&other)->it_;
return it_ == other_it;

View File

@ -289,11 +289,10 @@
#include <cerrno>
// #include <condition_variable> // Guarded by GTEST_IS_THREADSAFE below
#include <cstdint>
#include <iostream>
#include <iosfwd>
#include <limits>
#include <locale>
#include <memory>
#include <ostream>
#include <string>
// #include <mutex> // Guarded by GTEST_IS_THREADSAFE below
#include <tuple>
@ -1046,7 +1045,19 @@ class GTEST_API_ [[nodiscard]] GTestLog {
// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
~GTestLog();
::std::ostream& GetStream() { return ::std::cerr; }
GTestLog& operator<<(const char* message);
GTestLog& operator<<(const std::string& message);
GTestLog& operator<<(int error_code);
GTestLog& operator<<(const void* pointer);
GTestLog& operator<<(::std::ostream& (*manipulator)(::std::ostream&));
template <typename T>
GTestLog& operator<<(const T& val) {
GetStream() << val;
return *this;
}
::std::ostream& GetStream();
private:
const GTestLogSeverity severity_;
@ -1059,8 +1070,7 @@ class GTEST_API_ [[nodiscard]] GTestLog {
#define GTEST_LOG_(severity) \
::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \
__FILE__, __LINE__) \
.GetStream()
__FILE__, __LINE__)
inline void LogToStderr() {}
inline void FlushInfoLog() { fflush(nullptr); }
@ -1683,28 +1693,14 @@ class [[nodiscard]] ThreadLocal : public ThreadLocalBase {
class [[nodiscard]] MutexBase {
public:
// Acquires this mutex.
void lock() {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
owner_ = pthread_self();
has_owner_ = true;
}
void lock();
// Releases this mutex.
void unlock() {
// Since the lock is being released the owner_ field should no longer be
// considered valid. We don't protect writing to has_owner_ here, as it's
// the caller's responsibility to ensure that the current thread holds the
// mutex when this is called.
has_owner_ = false;
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_));
}
void unlock();
// Does nothing if the current thread holds the mutex. Otherwise, crashes
// with high probability.
void AssertHeld() const {
GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self()))
<< "The current thread is not holding the mutex @" << this;
}
void AssertHeld() const;
// A static mutex may be used before main() is entered. It may even
// be used before the dynamic initialization stage. Therefore we
@ -1740,11 +1736,8 @@ class [[nodiscard]] MutexBase {
// shares its API with MutexBase otherwise.
class [[nodiscard]] Mutex : public MutexBase {
public:
Mutex() {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr));
has_owner_ = false;
}
~Mutex() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); }
Mutex();
~Mutex();
private:
Mutex(const Mutex&) = delete;

View File

@ -51,7 +51,7 @@
#include <string.h>
#include <cstdint>
#include <sstream>
#include <iosfwd>
#include <string>
#include "gtest/internal/gtest-port.h"
@ -170,7 +170,7 @@ class GTEST_API_ [[nodiscard]] String {
// Gets the content of the stringstream's buffer as an std::string. Each '\0'
// character in the buffer is replaced with "\\0".
GTEST_API_ std::string StringStreamToString(::std::stringstream* stream);
GTEST_API_ std::string StringStreamToString(::std::ostream* stream);
} // namespace internal
} // namespace testing

View File

@ -34,6 +34,7 @@
#include "gtest/gtest-matchers.h"
#include <ostream>
#include <string>
#include "gtest/internal/gtest-internal.h"
@ -41,6 +42,12 @@
namespace testing {
void MatcherDescriberInterface::DescribeNegationTo(::std::ostream* os) const {
*os << "not (";
DescribeTo(os);
*os << ")";
}
// Constructs a matcher that matches a const std::string& whose value is
// equal to s.
Matcher<const std::string&>::Matcher(const std::string& s) { *this = Eq(s); }

View File

@ -36,6 +36,7 @@
#include <cstdint>
#include <fstream>
#include <iostream>
#include <memory>
#include <ostream>
#include <string>
@ -1065,6 +1066,60 @@ GTestLog::~GTestLog() {
}
}
::std::ostream& GTestLog::GetStream() { return ::std::cerr; }
GTestLog& GTestLog::operator<<(const char* message) {
GetStream() << message;
return *this;
}
GTestLog& GTestLog::operator<<(const std::string& message) {
GetStream() << message;
return *this;
}
GTestLog& GTestLog::operator<<(int error_code) {
GetStream() << error_code;
return *this;
}
GTestLog& GTestLog::operator<<(const void* pointer) {
GetStream() << pointer;
return *this;
}
GTestLog& GTestLog::operator<<(::std::ostream& (*manipulator)(::std::ostream&)) {
GetStream() << manipulator;
return *this;
}
#if GTEST_HAS_PTHREAD
void MutexBase::lock() {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_));
owner_ = pthread_self();
has_owner_ = true;
}
void MutexBase::unlock() {
has_owner_ = false;
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_));
}
void MutexBase::AssertHeld() const {
GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self()))
<< "The current thread is not holding the mutex @" << this;
}
Mutex::Mutex() {
GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, nullptr));
has_owner_ = false;
}
Mutex::~Mutex() { GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); }
#endif // GTEST_HAS_PTHREAD
#if GTEST_HAS_STREAM_REDIRECTION
// Disable Microsoft deprecation warnings for POSIX functions called from

View File

@ -41,8 +41,9 @@
// defines Foo.
#include "gtest/gtest-printers.h"
#include "gtest/gtest-message.h"
#include <stdio.h>
#include <ctype.h>
#include <cctype>
#include <cstdint>
@ -331,6 +332,20 @@ void PrintTo(__int128_t v, ::std::ostream* os) {
}
#endif // __SIZEOF_INT128__
void PrintTo(float f, ::std::ostream* os) {
auto old_precision = os->precision();
os->precision(AppropriateResolution(f));
*os << f;
os->precision(old_precision);
}
void PrintTo(double d, ::std::ostream* os) {
auto old_precision = os->precision();
os->precision(AppropriateResolution(d));
*os << d;
os->precision(old_precision);
}
// Prints the given array of characters to the ostream. CharType must be either
// char, char8_t, char16_t, char32_t, or wchar_t.
// The array starts at begin (which may be nullptr) and contains len characters.
@ -550,6 +565,28 @@ void PrintWideStringTo(::std::wstring_view s, ostream* os) {
}
#endif // GTEST_HAS_STD_WSTRING
std::string PrintToStringWithPrinter(
const void* value, void (*printer)(::std::ostream*, const void*)) {
::std::stringstream ss;
printer(&ss, value);
return ss.str();
}
void StreamTo(::std::ostream* os, char c) { *os << c; }
void StreamTo(::std::ostream* os, const char* s) { *os << s; }
void StreamTo(::std::ostream* os, const std::string& s) { *os << s; }
void StreamTo(::std::ostream* os, const void* p) { *os << p; }
void StreamTo(::std::ostream* os, bool b) { *os << (b ? "true" : "false"); }
void StreamTo(::std::ostream* os, float f) { *os << f; }
void StreamTo(::std::ostream* os, double d) { *os << d; }
void StreamTo(::std::ostream* os, int n) { *os << n; }
void StreamTo(::std::ostream* os, unsigned int n) { *os << n; }
void StreamTo(::std::ostream* os, long n) { *os << n; }
void StreamTo(::std::ostream* os, unsigned long n) { *os << n; }
void StreamTo(::std::ostream* os, long long n) { *os << n; }
void StreamTo(::std::ostream* os, unsigned long long n) { *os << n; }
void StreamTo(::std::ostream* os, const Message& msg) { *os << msg.GetString(); }
} // namespace internal
} // namespace testing

View File

@ -1348,6 +1348,58 @@ Message::Message() : ss_(new ::std::stringstream) {
*ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2);
}
// Copy constructor.
Message::Message(const Message& msg) : ss_(new ::std::stringstream) {
*ss_ << msg.GetString();
}
// Destructor.
Message::~Message() = default;
// Constructs a Message from a C-string.
Message::Message(const char* str) : ss_(new ::std::stringstream) {
*ss_ << str;
}
Message& Message::operator<<(const char* s) {
*ss_ << (s == nullptr ? "(null)" : s);
return *this;
}
Message& Message::operator<<(const std::string& s) {
*ss_ << s;
return *this;
}
Message& Message::operator<<(int n) {
*ss_ << n;
return *this;
}
Message& Message::operator<<(long n) {
*ss_ << n;
return *this;
}
Message& Message::operator<<(double n) {
*ss_ << n;
return *this;
}
Message& Message::operator<<(const void* p) {
if (p == nullptr) {
*ss_ << "(null)";
} else {
*ss_ << p;
}
return *this;
}
Message& Message::operator<<(::std::ostream& (*val)(::std::ostream&)) {
*ss_ << val;
return *this;
}
// These two overloads allow streaming a wide C string to a Message
// using the UTF-8 encoding.
Message& Message::operator<<(const wchar_t* wide_c_str) {
@ -2298,8 +2350,8 @@ std::string String::FormatByte(unsigned char value) {
// Converts the buffer in a stringstream to an std::string, converting NUL
// bytes to "\\0" along the way.
std::string StringStreamToString(::std::stringstream* ss) {
const ::std::string& str = ss->str();
std::string StringStreamToString(::std::ostream* ss) {
const ::std::string& str = static_cast<const ::std::stringstream*>(ss)->str();
const char* const start = str.c_str();
const char* const end = start + str.length();

View File

@ -30,6 +30,8 @@
// This file tests the internal cross-platform support utilities.
#include <stdio.h>
#include <iostream>
#include "gtest/internal/gtest-port.h"
#ifdef GTEST_OS_MAC