dep/googletest: Update to v1.17.0

This commit is contained in:
Stenzek
2025-08-31 18:32:36 +10:00
parent b8952dafac
commit db2f563db6
39 changed files with 6758 additions and 4588 deletions

View File

@@ -1,5 +1,6 @@
set(SRCS
src/gtest.cc
src/gtest-assertion-result.cc
src/gtest-death-test.cc
src/gtest-filepath.cc
src/gtest-matchers.cc

View File

@@ -3,6 +3,7 @@
<Import Project="..\msvc\vsprops\Configurations.props" />
<ItemGroup>
<ClInclude Include="include\gtest\gtest-assertion-result.h" />
<ClInclude Include="include\gtest\gtest-death-test.h" />
<ClInclude Include="include\gtest\gtest-matchers.h" />
<ClInclude Include="include\gtest\gtest-message.h" />
@@ -17,6 +18,7 @@
<ClInclude Include="src\gtest-internal-inl.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\gtest-assertion-result.cc" />
<ClCompile Include="src\gtest-death-test.cc" />
<ClCompile Include="src\gtest-filepath.cc" />
<ClCompile Include="src\gtest-matchers.cc" />

View File

@@ -13,6 +13,7 @@
<ClInclude Include="include\gtest\gtest-test-part.h" />
<ClInclude Include="include\gtest\gtest-typed-test.h" />
<ClInclude Include="src\gtest-internal-inl.h" />
<ClInclude Include="include\gtest\gtest-assertion-result.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\gtest.cc" />
@@ -23,5 +24,6 @@
<ClCompile Include="src\gtest-printers.cc" />
<ClCompile Include="src\gtest-test-part.cc" />
<ClCompile Include="src\gtest-typed-test.cc" />
<ClCompile Include="src\gtest-assertion-result.cc" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,244 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The Google C++ Testing and Mocking Framework (Google Test)
//
// This file implements the AssertionResult type.
// IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_
#include <memory>
#include <ostream>
#include <string>
#include <type_traits>
#include "gtest/gtest-message.h"
#include "gtest/internal/gtest-port.h"
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
namespace testing {
// A class for indicating whether an assertion was successful. When
// the assertion wasn't successful, the AssertionResult object
// remembers a non-empty message that describes how it failed.
//
// To create an instance of this class, use one of the factory functions
// (AssertionSuccess() and AssertionFailure()).
//
// This class is useful for two purposes:
// 1. Defining predicate functions to be used with Boolean test assertions
// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts
// 2. Defining predicate-format functions to be
// used with predicate assertions (ASSERT_PRED_FORMAT*, etc).
//
// For example, if you define IsEven predicate:
//
// testing::AssertionResult IsEven(int n) {
// if ((n % 2) == 0)
// return testing::AssertionSuccess();
// else
// return testing::AssertionFailure() << n << " is odd";
// }
//
// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5)))
// will print the message
//
// Value of: IsEven(Fib(5))
// Actual: false (5 is odd)
// Expected: true
//
// instead of a more opaque
//
// Value of: IsEven(Fib(5))
// Actual: false
// Expected: true
//
// in case IsEven is a simple Boolean predicate.
//
// If you expect your predicate to be reused and want to support informative
// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up
// about half as often as positive ones in our tests), supply messages for
// both success and failure cases:
//
// testing::AssertionResult IsEven(int n) {
// if ((n % 2) == 0)
// return testing::AssertionSuccess() << n << " is even";
// else
// return testing::AssertionFailure() << n << " is odd";
// }
//
// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print
//
// Value of: IsEven(Fib(6))
// Actual: true (8 is even)
// Expected: false
//
// NB: Predicates that support negative Boolean assertions have reduced
// performance in positive ones so be careful not to use them in tests
// that have lots (tens of thousands) of positive Boolean assertions.
//
// To use this class with EXPECT_PRED_FORMAT assertions such as:
//
// // Verifies that Foo() returns an even number.
// EXPECT_PRED_FORMAT1(IsEven, Foo());
//
// you need to define:
//
// testing::AssertionResult IsEven(const char* expr, int n) {
// if ((n % 2) == 0)
// return testing::AssertionSuccess();
// else
// return testing::AssertionFailure()
// << "Expected: " << expr << " is even\n Actual: it's " << n;
// }
//
// If Foo() returns 5, you will see the following message:
//
// Expected: Foo() is even
// Actual: it's 5
//
// Returned AssertionResult objects may not be ignored.
// Note: Disabled for SWIG as it doesn't parse attributes correctly.
#if !defined(SWIG)
class [[nodiscard]] AssertionResult;
#endif // !SWIG
class GTEST_API_ AssertionResult {
public:
// Copy constructor.
// Used in EXPECT_TRUE/FALSE(assertion_result).
AssertionResult(const AssertionResult& other);
// C4800 is a level 3 warning in Visual Studio 2015 and earlier.
// This warning is not emitted in Visual Studio 2017.
// This warning is off by default starting in Visual Studio 2019 but can be
// enabled with command-line options.
#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */)
#endif
// Used in the EXPECT_TRUE/FALSE(bool_expression).
//
// T must be contextually convertible to bool.
//
// The second parameter prevents this overload from being considered if
// the argument is implicitly convertible to AssertionResult. In that case
// we want AssertionResult's copy constructor to be used.
template <typename T>
explicit AssertionResult(
const T& success,
typename std::enable_if<
!std::is_convertible<T, AssertionResult>::value>::type*
/*enabler*/
= nullptr)
: success_(success) {}
#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)
GTEST_DISABLE_MSC_WARNINGS_POP_()
#endif
// Assignment operator.
AssertionResult& operator=(AssertionResult other) {
swap(other);
return *this;
}
// Returns true if and only if the assertion succeeded.
operator bool() const { return success_; } // NOLINT
// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
AssertionResult operator!() const;
// Returns the text streamed into this AssertionResult. Test assertions
// use it when they fail (i.e., the predicate's outcome doesn't match the
// assertion's expectation). When nothing has been streamed into the
// object, returns an empty string.
const char* message() const {
return message_ != nullptr ? message_->c_str() : "";
}
// Deprecated; please use message() instead.
const char* failure_message() const { return message(); }
// Streams a custom failure message into this object.
template <typename T>
AssertionResult& operator<<(const T& value) {
AppendMessage(Message() << value);
return *this;
}
// Allows streaming basic output manipulators such as endl or flush into
// this object.
AssertionResult& operator<<(
::std::ostream& (*basic_manipulator)(::std::ostream& stream)) {
AppendMessage(Message() << basic_manipulator);
return *this;
}
private:
// Appends the contents of message to message_.
void AppendMessage(const Message& a_message) {
if (message_ == nullptr) message_ = ::std::make_unique<::std::string>();
message_->append(a_message.GetString().c_str());
}
// Swap the contents of this AssertionResult with other.
void swap(AssertionResult& other);
// Stores result of the assertion predicate.
bool success_;
// Stores the message describing the condition in case the expectation
// construct is not satisfied with the predicate's outcome.
// Referenced via a pointer to avoid taking too much stack frame space
// with test assertions.
std::unique_ptr< ::std::string> message_;
};
// Makes a successful assertion result.
GTEST_API_ AssertionResult AssertionSuccess();
// Makes a failed assertion result.
GTEST_API_ AssertionResult AssertionFailure();
// Makes a failed assertion result with the given failure message.
// Deprecated; use AssertionFailure() << msg.
GTEST_API_ AssertionResult AssertionFailure(const Message& msg);
} // namespace testing
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_ASSERTION_RESULT_H_

View File

@@ -27,21 +27,21 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The Google C++ Testing and Mocking Framework (Google Test)
//
// This header file defines the public API for death tests. It is
// #included by gtest.h so a user doesn't need to include this
// directly.
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
// IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#include "gtest/internal/gtest-death-test-internal.h"
namespace testing {
// This flag controls the style of death tests. Valid values are "threadsafe",
// meaning that the death test child process will re-execute the test binary
// from the start, running only a single death test, or "fast",
@@ -49,7 +49,9 @@ namespace testing {
// after forking.
GTEST_DECLARE_string_(death_test_style);
#if GTEST_HAS_DEATH_TEST
namespace testing {
#ifdef GTEST_HAS_DEATH_TEST
namespace internal {
@@ -97,9 +99,12 @@ GTEST_API_ bool InDeathTestChild();
//
// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
//
// The final parameter to each of these macros is a matcher applied to any data
// the sub-process wrote to stderr. For compatibility with existing tests, a
// bare string is interpreted as a regular expression matcher.
//
// On the regular expressions used in death tests:
//
// GOOGLETEST_CM0005 DO NOT DELETE
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
// which uses the POSIX extended regex syntax.
//
@@ -162,27 +167,27 @@ GTEST_API_ bool InDeathTestChild();
// directory in PATH.
//
// Asserts that a given statement causes the program to exit, with an
// integer exit status that satisfies predicate, and emitting error output
// that matches regex.
# define ASSERT_EXIT(statement, predicate, regex) \
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_)
// Asserts that a given `statement` causes the program to exit, with an
// integer exit status that satisfies `predicate`, and emitting error output
// that matches `matcher`.
#define ASSERT_EXIT(statement, predicate, matcher) \
GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_FATAL_FAILURE_)
// Like ASSERT_EXIT, but continues on to successive tests in the
// Like `ASSERT_EXIT`, but continues on to successive tests in the
// test suite, if any:
# define EXPECT_EXIT(statement, predicate, regex) \
GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_)
#define EXPECT_EXIT(statement, predicate, matcher) \
GTEST_DEATH_TEST_(statement, predicate, matcher, GTEST_NONFATAL_FAILURE_)
// Asserts that a given statement causes the program to exit, either by
// Asserts that a given `statement` causes the program to exit, either by
// explicitly exiting with a nonzero exit code or being killed by a
// signal, and emitting error output that matches regex.
# define ASSERT_DEATH(statement, regex) \
ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
// signal, and emitting error output that matches `matcher`.
#define ASSERT_DEATH(statement, matcher) \
ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher)
// Like ASSERT_DEATH, but continues on to successive tests in the
// Like `ASSERT_DEATH`, but continues on to successive tests in the
// test suite, if any:
# define EXPECT_DEATH(statement, regex) \
EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex)
#define EXPECT_DEATH(statement, matcher) \
EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, matcher)
// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*:
@@ -190,26 +195,26 @@ GTEST_API_ bool InDeathTestChild();
class GTEST_API_ ExitedWithCode {
public:
explicit ExitedWithCode(int exit_code);
ExitedWithCode(const ExitedWithCode&) = default;
void operator=(const ExitedWithCode& other) = delete;
bool operator()(int exit_status) const;
private:
// No implementation - assignment is unsupported.
void operator=(const ExitedWithCode& other);
private:
const int exit_code_;
};
# if !GTEST_OS_WINDOWS && !GTEST_OS_FUCHSIA
#if !defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_FUCHSIA)
// Tests that an exit code describes an exit due to termination by a
// given signal.
// GOOGLETEST_CM0006 DO NOT DELETE
class GTEST_API_ KilledBySignal {
public:
explicit KilledBySignal(int signum);
bool operator()(int exit_status) const;
private:
const int signum_;
};
# endif // !GTEST_OS_WINDOWS
#endif // !GTEST_OS_WINDOWS
// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode.
// The death testing framework causes this to have interesting semantics,
@@ -254,23 +259,21 @@ class GTEST_API_ KilledBySignal {
// EXPECT_EQ(12, DieInDebugOr12(&sideeffect));
// }, "death");
//
# ifdef NDEBUG
#ifdef NDEBUG
# define EXPECT_DEBUG_DEATH(statement, regex) \
#define EXPECT_DEBUG_DEATH(statement, regex) \
GTEST_EXECUTE_STATEMENT_(statement, regex)
# define ASSERT_DEBUG_DEATH(statement, regex) \
#define ASSERT_DEBUG_DEATH(statement, regex) \
GTEST_EXECUTE_STATEMENT_(statement, regex)
# else
#else
# define EXPECT_DEBUG_DEATH(statement, regex) \
EXPECT_DEATH(statement, regex)
#define EXPECT_DEBUG_DEATH(statement, regex) EXPECT_DEATH(statement, regex)
# define ASSERT_DEBUG_DEATH(statement, regex) \
ASSERT_DEATH(statement, regex)
#define ASSERT_DEBUG_DEATH(statement, regex) ASSERT_DEATH(statement, regex)
# endif // NDEBUG for EXPECT_DEBUG_DEATH
#endif // NDEBUG for EXPECT_DEBUG_DEATH
#endif // GTEST_HAS_DEATH_TEST
// This macro is used for implementing macros such as
@@ -290,8 +293,8 @@ class GTEST_API_ KilledBySignal {
// statement is compiled but not executed, to ensure that
// EXPECT_DEATH_IF_SUPPORTED compiles with a certain
// parameter if and only if EXPECT_DEATH compiles with it.
// regex - A regex that a macro such as EXPECT_DEATH would use to test
// the output of statement. This parameter has to be
// regex_or_matcher - A regex that a macro such as EXPECT_DEATH would use
// to test the output of statement. This parameter has to be
// compiled but not evaluated by this macro, to ensure that
// this macro only accepts expressions that a macro such as
// EXPECT_DEATH would accept.
@@ -308,36 +311,35 @@ class GTEST_API_ KilledBySignal {
// statement unconditionally returns or throws. The Message constructor at
// the end allows the syntax of streaming additional messages into the
// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
# define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, terminator) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
GTEST_LOG_(WARNING) \
<< "Death tests are not supported on this platform.\n" \
<< "Statement '" #statement "' cannot be verified."; \
} else if (::testing::internal::AlwaysFalse()) { \
::testing::internal::RE::PartialMatch(".*", (regex)); \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
terminator; \
} else \
::testing::Message()
#define GTEST_UNSUPPORTED_DEATH_TEST(statement, regex_or_matcher, terminator) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
GTEST_LOG_(WARNING) << "Death tests are not supported on this platform.\n" \
<< "Statement '" #statement "' cannot be verified."; \
} else if (::testing::internal::AlwaysFalse()) { \
::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
terminator; \
} else \
::testing::Message()
// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and
// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if
// death tests are supported; otherwise they just issue a warning. This is
// useful when you are combining death test assertions with normal test
// assertions in one test.
#if GTEST_HAS_DEATH_TEST
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
EXPECT_DEATH(statement, regex)
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
ASSERT_DEATH(statement, regex)
#ifdef GTEST_HAS_DEATH_TEST
#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
EXPECT_DEATH(statement, regex)
#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
ASSERT_DEATH(statement, regex)
#else
# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, )
# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return)
#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \
GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, )
#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \
GTEST_UNSUPPORTED_DEATH_TEST(statement, regex, return)
#endif
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_

View File

@@ -32,13 +32,15 @@
// This file implements just enough of the matcher interface to allow
// EXPECT_DEATH and friends to accept a matcher argument.
// IWYU pragma: private, include "testing/base/public/gunit.h"
// IWYU pragma: friend third_party/googletest/googlemock/.*
// IWYU pragma: friend third_party/googletest/googletest/.*
// IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
#define GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
#include <atomic>
#include <functional>
#include <memory>
#include <ostream>
#include <string>
@@ -63,20 +65,16 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(
namespace testing {
// To implement a matcher Foo for type T, define:
// 1. a class FooMatcherImpl that implements the
// MatcherInterface<T> interface, and
// 1. a class FooMatcherMatcher that implements the matcher interface:
// using is_gtest_matcher = void;
// bool MatchAndExplain(const T&, std::ostream*) const;
// (MatchResultListener* can also be used instead of std::ostream*)
// void DescribeTo(std::ostream*) const;
// void DescribeNegationTo(std::ostream*) const;
//
// 2. a factory function that creates a Matcher<T> object from a
// FooMatcherImpl*.
//
// The two-level delegation design makes it possible to allow a user
// to write "v" instead of "Eq(v)" where a Matcher is expected, which
// is impossible if we pass matchers by pointers. It also eases
// ownership management as Matcher objects can now be copied like
// plain values.
// FooMatcherMatcher.
// MatchResultListener is an abstract class. Its << operator can be
// used by a matcher to explain why a value matches or doesn't match.
//
class MatchResultListener {
public:
// Creates a listener object with the given underlying ostream. The
@@ -105,17 +103,17 @@ class MatchResultListener {
private:
::std::ostream* const stream_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(MatchResultListener);
MatchResultListener(const MatchResultListener&) = delete;
MatchResultListener& operator=(const MatchResultListener&) = delete;
};
inline MatchResultListener::~MatchResultListener() {
}
inline MatchResultListener::~MatchResultListener() = default;
// An instance of a subclass of this knows how to describe itself as a
// matcher.
class MatcherDescriberInterface {
class GTEST_API_ MatcherDescriberInterface {
public:
virtual ~MatcherDescriberInterface() {}
virtual ~MatcherDescriberInterface() = default;
// Describes this matcher to an ostream. The function should print
// a verb phrase that describes the property a value matching this
@@ -181,63 +179,14 @@ class MatcherInterface : public MatcherDescriberInterface {
namespace internal {
// Converts a MatcherInterface<T> to a MatcherInterface<const T&>.
template <typename T>
class MatcherInterfaceAdapter : public MatcherInterface<const T&> {
public:
explicit MatcherInterfaceAdapter(const MatcherInterface<T>* impl)
: impl_(impl) {}
~MatcherInterfaceAdapter() override { delete impl_; }
void DescribeTo(::std::ostream* os) const override { impl_->DescribeTo(os); }
void DescribeNegationTo(::std::ostream* os) const override {
impl_->DescribeNegationTo(os);
}
bool MatchAndExplain(const T& x,
MatchResultListener* listener) const override {
return impl_->MatchAndExplain(x, listener);
}
private:
const MatcherInterface<T>* const impl_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(MatcherInterfaceAdapter);
};
struct AnyEq {
template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a == b; }
};
struct AnyNe {
template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a != b; }
};
struct AnyLt {
template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a < b; }
};
struct AnyGt {
template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a > b; }
};
struct AnyLe {
template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a <= b; }
};
struct AnyGe {
template <typename A, typename B>
bool operator()(const A& a, const B& b) const { return a >= b; }
};
// A match result listener that ignores the explanation.
class DummyMatchResultListener : public MatchResultListener {
public:
DummyMatchResultListener() : MatchResultListener(nullptr) {}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(DummyMatchResultListener);
DummyMatchResultListener(const DummyMatchResultListener&) = delete;
DummyMatchResultListener& operator=(const DummyMatchResultListener&) = delete;
};
// A match result listener that forwards the explanation to a given
@@ -249,19 +198,40 @@ class StreamMatchResultListener : public MatchResultListener {
: MatchResultListener(os) {}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamMatchResultListener);
StreamMatchResultListener(const StreamMatchResultListener&) = delete;
StreamMatchResultListener& operator=(const StreamMatchResultListener&) =
delete;
};
struct SharedPayloadBase {
std::atomic<int> ref{1};
void Ref() { ref.fetch_add(1, std::memory_order_relaxed); }
bool Unref() { return ref.fetch_sub(1, std::memory_order_acq_rel) == 1; }
};
template <typename T>
struct SharedPayload : SharedPayloadBase {
explicit SharedPayload(const T& v) : value(v) {}
explicit SharedPayload(T&& v) : value(std::move(v)) {}
static void Destroy(SharedPayloadBase* shared) {
delete static_cast<SharedPayload*>(shared);
}
T value;
};
// An internal class for implementing Matcher<T>, which will derive
// from it. We put functionalities common to all Matcher<T>
// specializations here to avoid code duplication.
template <typename T>
class MatcherBase {
class MatcherBase : private MatcherDescriberInterface {
public:
// Returns true if and only if the matcher matches x; also explains the
// match result to 'listener'.
bool MatchAndExplain(const T& x, MatchResultListener* listener) const {
return impl_->MatchAndExplain(x, listener);
GTEST_CHECK_(vtable_ != nullptr);
return vtable_->match_and_explain(*this, x, listener);
}
// Returns true if and only if this matcher matches x.
@@ -271,11 +241,15 @@ class MatcherBase {
}
// Describes this matcher to an ostream.
void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); }
void DescribeTo(::std::ostream* os) const final {
GTEST_CHECK_(vtable_ != nullptr);
vtable_->describe(*this, os, false);
}
// Describes the negation of this matcher to an ostream.
void DescribeNegationTo(::std::ostream* os) const {
impl_->DescribeNegationTo(os);
void DescribeNegationTo(::std::ostream* os) const final {
GTEST_CHECK_(vtable_ != nullptr);
vtable_->describe(*this, os, true);
}
// Explains why x matches, or doesn't match, the matcher.
@@ -288,31 +262,195 @@ class MatcherBase {
// of the describer, which is only guaranteed to be alive when
// this matcher object is alive.
const MatcherDescriberInterface* GetDescriber() const {
return impl_.get();
if (vtable_ == nullptr) return nullptr;
return vtable_->get_describer(*this);
}
protected:
MatcherBase() {}
MatcherBase() : vtable_(nullptr), buffer_() {}
// Constructs a matcher from its implementation.
explicit MatcherBase(const MatcherInterface<const T&>* impl) : impl_(impl) {}
template <typename U>
explicit MatcherBase(
const MatcherInterface<U>* impl,
typename std::enable_if<!std::is_same<U, const U&>::value>::type* =
nullptr)
: impl_(new internal::MatcherInterfaceAdapter<U>(impl)) {}
explicit MatcherBase(const MatcherInterface<U>* impl)
: vtable_(nullptr), buffer_() {
Init(impl);
}
MatcherBase(const MatcherBase&) = default;
MatcherBase& operator=(const MatcherBase&) = default;
MatcherBase(MatcherBase&&) = default;
MatcherBase& operator=(MatcherBase&&) = default;
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
MatcherBase(M&& m) : vtable_(nullptr), buffer_() { // NOLINT
Init(std::forward<M>(m));
}
virtual ~MatcherBase() {}
MatcherBase(const MatcherBase& other)
: vtable_(other.vtable_), buffer_(other.buffer_) {
if (IsShared()) buffer_.shared->Ref();
}
MatcherBase& operator=(const MatcherBase& other) {
if (this == &other) return *this;
Destroy();
vtable_ = other.vtable_;
buffer_ = other.buffer_;
if (IsShared()) buffer_.shared->Ref();
return *this;
}
MatcherBase(MatcherBase&& other)
: vtable_(other.vtable_), buffer_(other.buffer_) {
other.vtable_ = nullptr;
}
MatcherBase& operator=(MatcherBase&& other) {
if (this == &other) return *this;
Destroy();
vtable_ = other.vtable_;
buffer_ = other.buffer_;
other.vtable_ = nullptr;
return *this;
}
~MatcherBase() override { Destroy(); }
private:
std::shared_ptr<const MatcherInterface<const T&>> impl_;
struct VTable {
bool (*match_and_explain)(const MatcherBase&, const T&,
MatchResultListener*);
void (*describe)(const MatcherBase&, std::ostream*, bool negation);
// Returns the captured object if it implements the interface, otherwise
// returns the MatcherBase itself.
const MatcherDescriberInterface* (*get_describer)(const MatcherBase&);
// Called on shared instances when the reference count reaches 0.
void (*shared_destroy)(SharedPayloadBase*);
};
bool IsShared() const {
return vtable_ != nullptr && vtable_->shared_destroy != nullptr;
}
// If the implementation uses a listener, call that.
template <typename P>
static auto MatchAndExplainImpl(const MatcherBase& m, const T& value,
MatchResultListener* listener)
-> decltype(P::Get(m).MatchAndExplain(value, listener->stream())) {
return P::Get(m).MatchAndExplain(value, listener->stream());
}
template <typename P>
static auto MatchAndExplainImpl(const MatcherBase& m, const T& value,
MatchResultListener* listener)
-> decltype(P::Get(m).MatchAndExplain(value, listener)) {
return P::Get(m).MatchAndExplain(value, listener);
}
template <typename P>
static void DescribeImpl(const MatcherBase& m, std::ostream* os,
bool negation) {
if (negation) {
P::Get(m).DescribeNegationTo(os);
} else {
P::Get(m).DescribeTo(os);
}
}
template <typename P>
static const MatcherDescriberInterface* GetDescriberImpl(
const MatcherBase& m) {
// If the impl is a MatcherDescriberInterface, then return it.
// Otherwise use MatcherBase itself.
// This allows us to implement the GetDescriber() function without support
// from the impl, but some users really want to get their impl back when
// they call GetDescriber().
// We use std::get on a tuple as a workaround of not having `if constexpr`.
return std::get<(
std::is_convertible<decltype(&P::Get(m)),
const MatcherDescriberInterface*>::value
? 1
: 0)>(std::make_tuple(&m, &P::Get(m)));
}
template <typename P>
const VTable* GetVTable() {
static constexpr VTable kVTable = {&MatchAndExplainImpl<P>,
&DescribeImpl<P>, &GetDescriberImpl<P>,
P::shared_destroy};
return &kVTable;
}
union Buffer {
// Add some types to give Buffer some common alignment/size use cases.
void* ptr;
double d;
int64_t i;
// And add one for the out-of-line cases.
SharedPayloadBase* shared;
};
void Destroy() {
if (IsShared() && buffer_.shared->Unref()) {
vtable_->shared_destroy(buffer_.shared);
}
}
template <typename M>
static constexpr bool IsInlined() {
return sizeof(M) <= sizeof(Buffer) && alignof(M) <= alignof(Buffer) &&
std::is_trivially_copy_constructible<M>::value &&
std::is_trivially_destructible<M>::value;
}
template <typename M, bool = MatcherBase::IsInlined<M>()>
struct ValuePolicy {
static const M& Get(const MatcherBase& m) {
// When inlined along with Init, need to be explicit to avoid violating
// strict aliasing rules.
const M* ptr =
static_cast<const M*>(static_cast<const void*>(&m.buffer_));
return *ptr;
}
static void Init(MatcherBase& m, M impl) {
::new (static_cast<void*>(&m.buffer_)) M(impl);
}
static constexpr auto shared_destroy = nullptr;
};
template <typename M>
struct ValuePolicy<M, false> {
using Shared = SharedPayload<M>;
static const M& Get(const MatcherBase& m) {
return static_cast<Shared*>(m.buffer_.shared)->value;
}
template <typename Arg>
static void Init(MatcherBase& m, Arg&& arg) {
m.buffer_.shared = new Shared(std::forward<Arg>(arg));
}
static constexpr auto shared_destroy = &Shared::Destroy;
};
template <typename U, bool B>
struct ValuePolicy<const MatcherInterface<U>*, B> {
using M = const MatcherInterface<U>;
using Shared = SharedPayload<std::unique_ptr<M>>;
static const M& Get(const MatcherBase& m) {
return *static_cast<Shared*>(m.buffer_.shared)->value;
}
static void Init(MatcherBase& m, M* impl) {
m.buffer_.shared = new Shared(std::unique_ptr<M>(impl));
}
static constexpr auto shared_destroy = &Shared::Destroy;
};
template <typename M>
void Init(M&& m) {
using MM = typename std::decay<M>::type;
using Policy = ValuePolicy<MM>;
vtable_ = GetVTable<Policy>();
Policy::Init(*this, std::forward<M>(m));
}
const VTable* vtable_;
Buffer buffer_;
};
} // namespace internal
@@ -340,6 +478,10 @@ class Matcher : public internal::MatcherBase<T> {
nullptr)
: internal::MatcherBase<T>(impl) {}
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
Matcher(M&& m) : internal::MatcherBase<T>(std::forward<M>(m)) {} // NOLINT
// Implicit constructor here allows people to write
// EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes
Matcher(T value); // NOLINT
@@ -352,11 +494,16 @@ template <>
class GTEST_API_ Matcher<const std::string&>
: public internal::MatcherBase<const std::string&> {
public:
Matcher() {}
Matcher() = default;
explicit Matcher(const MatcherInterface<const std::string&>* impl)
: internal::MatcherBase<const std::string&>(impl) {}
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
Matcher(M&& m) // NOLINT
: internal::MatcherBase<const std::string&>(std::forward<M>(m)) {}
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a std::string object.
Matcher(const std::string& s); // NOLINT
@@ -369,13 +516,18 @@ template <>
class GTEST_API_ Matcher<std::string>
: public internal::MatcherBase<std::string> {
public:
Matcher() {}
Matcher() = default;
explicit Matcher(const MatcherInterface<const std::string&>* impl)
: internal::MatcherBase<std::string>(impl) {}
explicit Matcher(const MatcherInterface<std::string>* impl)
: internal::MatcherBase<std::string>(impl) {}
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
Matcher(M&& m) // NOLINT
: internal::MatcherBase<std::string>(std::forward<M>(m)) {}
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a string object.
Matcher(const std::string& s); // NOLINT
@@ -392,11 +544,17 @@ template <>
class GTEST_API_ Matcher<const internal::StringView&>
: public internal::MatcherBase<const internal::StringView&> {
public:
Matcher() {}
Matcher() = default;
explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
: internal::MatcherBase<const internal::StringView&>(impl) {}
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
Matcher(M&& m) // NOLINT
: internal::MatcherBase<const internal::StringView&>(std::forward<M>(m)) {
}
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a std::string object.
Matcher(const std::string& s); // NOLINT
@@ -412,13 +570,18 @@ template <>
class GTEST_API_ Matcher<internal::StringView>
: public internal::MatcherBase<internal::StringView> {
public:
Matcher() {}
Matcher() = default;
explicit Matcher(const MatcherInterface<const internal::StringView&>* impl)
: internal::MatcherBase<internal::StringView>(impl) {}
explicit Matcher(const MatcherInterface<internal::StringView>* impl)
: internal::MatcherBase<internal::StringView>(impl) {}
template <typename M, typename = typename std::remove_reference<
M>::type::is_gtest_matcher>
Matcher(M&& m) // NOLINT
: internal::MatcherBase<internal::StringView>(std::forward<M>(m)) {}
// Allows the user to write str instead of Eq(str) sometimes, where
// str is a std::string object.
Matcher(const std::string& s); // NOLINT
@@ -529,89 +692,91 @@ template <typename D, typename Rhs, typename Op>
class ComparisonBase {
public:
explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {}
using is_gtest_matcher = void;
template <typename Lhs>
operator Matcher<Lhs>() const {
return Matcher<Lhs>(new Impl<const Lhs&>(rhs_));
bool MatchAndExplain(const Lhs& lhs, std::ostream*) const {
return Op()(lhs, Unwrap(rhs_));
}
void DescribeTo(std::ostream* os) const {
*os << D::Desc() << " ";
UniversalPrint(Unwrap(rhs_), os);
}
void DescribeNegationTo(std::ostream* os) const {
*os << D::NegatedDesc() << " ";
UniversalPrint(Unwrap(rhs_), os);
}
private:
template <typename T>
static const T& Unwrap(const T& v) { return v; }
static const T& Unwrap(const T& v) {
return v;
}
template <typename T>
static const T& Unwrap(std::reference_wrapper<T> v) { return v; }
static const T& Unwrap(std::reference_wrapper<T> v) {
return v;
}
template <typename Lhs, typename = Rhs>
class Impl : public MatcherInterface<Lhs> {
public:
explicit Impl(const Rhs& rhs) : rhs_(rhs) {}
bool MatchAndExplain(Lhs lhs,
MatchResultListener* /* listener */) const override {
return Op()(lhs, Unwrap(rhs_));
}
void DescribeTo(::std::ostream* os) const override {
*os << D::Desc() << " ";
UniversalPrint(Unwrap(rhs_), os);
}
void DescribeNegationTo(::std::ostream* os) const override {
*os << D::NegatedDesc() << " ";
UniversalPrint(Unwrap(rhs_), os);
}
private:
Rhs rhs_;
};
Rhs rhs_;
};
template <typename Rhs>
class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq> {
class EqMatcher : public ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>> {
public:
explicit EqMatcher(const Rhs& rhs)
: ComparisonBase<EqMatcher<Rhs>, Rhs, AnyEq>(rhs) { }
: ComparisonBase<EqMatcher<Rhs>, Rhs, std::equal_to<>>(rhs) {}
static const char* Desc() { return "is equal to"; }
static const char* NegatedDesc() { return "isn't equal to"; }
};
template <typename Rhs>
class NeMatcher : public ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe> {
class NeMatcher
: public ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>> {
public:
explicit NeMatcher(const Rhs& rhs)
: ComparisonBase<NeMatcher<Rhs>, Rhs, AnyNe>(rhs) { }
: ComparisonBase<NeMatcher<Rhs>, Rhs, std::not_equal_to<>>(rhs) {}
static const char* Desc() { return "isn't equal to"; }
static const char* NegatedDesc() { return "is equal to"; }
};
template <typename Rhs>
class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt> {
class LtMatcher : public ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>> {
public:
explicit LtMatcher(const Rhs& rhs)
: ComparisonBase<LtMatcher<Rhs>, Rhs, AnyLt>(rhs) { }
: ComparisonBase<LtMatcher<Rhs>, Rhs, std::less<>>(rhs) {}
static const char* Desc() { return "is <"; }
static const char* NegatedDesc() { return "isn't <"; }
};
template <typename Rhs>
class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt> {
class GtMatcher : public ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>> {
public:
explicit GtMatcher(const Rhs& rhs)
: ComparisonBase<GtMatcher<Rhs>, Rhs, AnyGt>(rhs) { }
: ComparisonBase<GtMatcher<Rhs>, Rhs, std::greater<>>(rhs) {}
static const char* Desc() { return "is >"; }
static const char* NegatedDesc() { return "isn't >"; }
};
template <typename Rhs>
class LeMatcher : public ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe> {
class LeMatcher
: public ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>> {
public:
explicit LeMatcher(const Rhs& rhs)
: ComparisonBase<LeMatcher<Rhs>, Rhs, AnyLe>(rhs) { }
: ComparisonBase<LeMatcher<Rhs>, Rhs, std::less_equal<>>(rhs) {}
static const char* Desc() { return "is <="; }
static const char* NegatedDesc() { return "isn't <="; }
};
template <typename Rhs>
class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> {
class GeMatcher
: public ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>> {
public:
explicit GeMatcher(const Rhs& rhs)
: ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe>(rhs) { }
: ComparisonBase<GeMatcher<Rhs>, Rhs, std::greater_equal<>>(rhs) {}
static const char* Desc() { return "is >="; }
static const char* NegatedDesc() { return "isn't >="; }
};
template <typename T, typename = typename std::enable_if<
std::is_constructible<std::string, T>::value>::type>
using StringLike = T;
// Implements polymorphic matchers MatchesRegex(regex) and
// ContainsRegex(regex), which can be used as a Matcher<T> as long as
// T can be converted to a string.
@@ -644,7 +809,7 @@ class MatchesRegexMatcher {
template <class MatcheeStringType>
bool MatchAndExplain(const MatcheeStringType& s,
MatchResultListener* /* listener */) const {
const std::string& s2(s);
const std::string s2(s);
return full_match_ ? RE::FullMatch(s2, *regex_)
: RE::PartialMatch(s2, *regex_);
}
@@ -672,9 +837,10 @@ inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
const internal::RE* regex) {
return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, true));
}
inline PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
const std::string& regex) {
return MatchesRegex(new internal::RE(regex));
template <typename T = std::string>
PolymorphicMatcher<internal::MatchesRegexMatcher> MatchesRegex(
const internal::StringLike<T>& regex) {
return MatchesRegex(new internal::RE(std::string(regex)));
}
// Matches a string that contains regular expression 'regex'.
@@ -683,21 +849,26 @@ inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
const internal::RE* regex) {
return MakePolymorphicMatcher(internal::MatchesRegexMatcher(regex, false));
}
inline PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
const std::string& regex) {
return ContainsRegex(new internal::RE(regex));
template <typename T = std::string>
PolymorphicMatcher<internal::MatchesRegexMatcher> ContainsRegex(
const internal::StringLike<T>& regex) {
return ContainsRegex(new internal::RE(std::string(regex)));
}
// Creates a polymorphic matcher that matches anything equal to x.
// Note: if the parameter of Eq() were declared as const T&, Eq("foo")
// wouldn't compile.
template <typename T>
inline internal::EqMatcher<T> Eq(T x) { return internal::EqMatcher<T>(x); }
inline internal::EqMatcher<T> Eq(T x) {
return internal::EqMatcher<T>(x);
}
// Constructs a Matcher<T> from a 'value' of type T. The constructed
// matcher matches any value that's equal to 'value'.
template <typename T>
Matcher<T>::Matcher(T value) { *this = Eq(value); }
Matcher<T>::Matcher(T value) {
*this = Eq(value);
}
// Creates a monomorphic matcher that matches anything with type Lhs
// and equal to rhs. A user may need to use this instead of Eq(...)
@@ -712,7 +883,9 @@ Matcher<T>::Matcher(T value) { *this = Eq(value); }
// can always write Matcher<T>(Lt(5)) to be explicit about the type,
// for example.
template <typename Lhs, typename Rhs>
inline Matcher<Lhs> TypedEq(const Rhs& rhs) { return Eq(rhs); }
inline Matcher<Lhs> TypedEq(const Rhs& rhs) {
return Eq(rhs);
}
// Creates a polymorphic matcher that matches anything >= x.
template <typename Rhs>
@@ -747,4 +920,4 @@ inline internal::NeMatcher<Rhs> Ne(Rhs x) {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046
#endif // GTEST_INCLUDE_GTEST_GTEST_MATCHERS_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_MATCHERS_H_

View File

@@ -27,7 +27,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The Google C++ Testing and Mocking Framework (Google Test)
//
// This header file defines the Message class.
@@ -42,17 +41,28 @@
// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user
// program!
// GOOGLETEST_CM0001 DO NOT DELETE
// IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#include <limits>
#include <memory>
#include <ostream>
#include <sstream>
#include <string>
#include "gtest/internal/gtest-port.h"
#ifdef GTEST_HAS_ABSL
#include <type_traits>
#include "absl/strings/has_absl_stringify.h"
#include "absl/strings/str_cat.h"
#endif // GTEST_HAS_ABSL
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
@@ -108,10 +118,19 @@ class GTEST_API_ Message {
*ss_ << str;
}
// Streams a non-pointer value to this object.
template <typename T>
inline Message& operator <<(const T& val) {
// Some libraries overload << for STL containers. These
// 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.
template <
typename T
#ifdef GTEST_HAS_ABSL
,
typename std::enable_if<!absl::HasAbslStringify<T>::value, // NOLINT
int>::type = 0
#endif // GTEST_HAS_ABSL
>
inline Message& operator<<(const T& val) {
// Some libraries overload << for STL containers. These
// overloads are defined in the global namespace instead of ::std.
//
// C++'s symbol lookup rule (i.e. Koenig lookup) says that these
@@ -125,11 +144,26 @@ class GTEST_API_ Message {
// from the global namespace. With this using declaration,
// overloads of << defined in the global namespace and those
// visible via Koenig lookup are both exposed in this function.
using ::operator <<;
using ::operator<<;
*ss_ << val;
return *this;
}
#ifdef GTEST_HAS_ABSL
// Streams a non-pointer value with an AbslStringify definition to this
// object.
template <typename T,
typename std::enable_if<absl::HasAbslStringify<T>::value, // NOLINT
int>::type = 0>
inline Message& operator<<(const T& val) {
// ::operator<< is needed here for a similar reason as with the non-Abseil
// version above
using ::operator<<;
*ss_ << absl::StrCat(val);
return *this;
}
#endif // GTEST_HAS_ABSL
// Streams a pointer value to this object.
//
// This function is an overload of the previous one. When you
@@ -144,7 +178,7 @@ class GTEST_API_ Message {
// ensure consistent result across compilers, we always treat NULL
// as "(null)".
template <typename T>
inline Message& operator <<(T* const& pointer) { // NOLINT
inline Message& operator<<(T* const& pointer) { // NOLINT
if (pointer == nullptr) {
*ss_ << "(null)";
} else {
@@ -159,25 +193,23 @@ 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) {
Message& operator<<(BasicNarrowIoManip val) {
*ss_ << val;
return *this;
}
// Instead of 1/0, we want to see true/false for bool values.
Message& operator <<(bool b) {
return *this << (b ? "true" : "false");
}
Message& operator<<(bool b) { return *this << (b ? "true" : "false"); }
// These two overloads allow streaming a wide C string to a Message
// using the UTF-8 encoding.
Message& operator <<(const wchar_t* wide_c_str);
Message& operator <<(wchar_t* wide_c_str);
Message& operator<<(const wchar_t* wide_c_str);
Message& operator<<(wchar_t* wide_c_str);
#if GTEST_HAS_STD_WSTRING
// Converts the given wide string to a narrow string using the UTF-8
// encoding, and streams the result to this Message object.
Message& operator <<(const ::std::wstring& wstr);
Message& operator<<(const ::std::wstring& wstr);
#endif // GTEST_HAS_STD_WSTRING
// Gets the text streamed to this object so far as an std::string.
@@ -196,7 +228,7 @@ class GTEST_API_ Message {
};
// Streams a Message to an ostream.
inline std::ostream& operator <<(std::ostream& os, const Message& sb) {
inline std::ostream& operator<<(std::ostream& os, const Message& sb) {
return os << sb.GetString();
}
@@ -216,4 +248,4 @@ std::string StreamableToString(const T& streamable) {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_MESSAGE_H_

View File

@@ -26,16 +26,16 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Macros and functions for implementing parameterized tests
// in Google C++ Testing and Mocking Framework (Google Test)
//
// This file is generated by a SCRIPT. DO NOT EDIT BY HAND!
//
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
// IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
// Value-parameterized tests allow you to test your code with different
// parameters without writing multiple copies of the same test.
@@ -174,11 +174,12 @@ TEST_P(DerivedTest, DoesBlah) {
#endif // 0
#include <functional>
#include <iterator>
#include <utility>
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-param-util.h"
#include "gtest/internal/gtest-param-util.h" // IWYU pragma: export
#include "gtest/internal/gtest-port.h"
namespace testing {
@@ -356,9 +357,7 @@ internal::ValueArray<T...> Values(T... v) {
// }
// INSTANTIATE_TEST_SUITE_P(BoolSequence, FlagDependentTest, Bool());
//
inline internal::ParamGenerator<bool> Bool() {
return Values(false, true);
}
inline internal::ParamGenerator<bool> Bool() { return Values(false, true); }
// Combine() allows the user to combine two or more sequences to produce
// values of a Cartesian product of those sequences' elements.
@@ -371,8 +370,6 @@ inline internal::ParamGenerator<bool> Bool() {
// std::tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types
// of elements from sequences produces by gen1, gen2, ..., genN.
//
// Combine can have up to 10 arguments.
//
// Example:
//
// This will instantiate tests in test suite AnimalTest each one with
@@ -411,9 +408,106 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
return internal::CartesianProductHolder<Generator...>(g...);
}
// ConvertGenerator() wraps a parameter generator in order to cast each produced
// value through a known type before supplying it to the test suite
//
// Synopsis:
// ConvertGenerator<T>(gen)
// - returns a generator producing the same elements as generated by gen, but
// each T-typed element is static_cast to a type deduced from the interface
// that accepts this generator, and then returned
//
// It is useful when using the Combine() function to get the generated
// parameters in a custom type instead of std::tuple
//
// Example:
//
// This will instantiate tests in test suite AnimalTest each one with
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
// tuple("dog", BLACK), and tuple("dog", WHITE):
//
// enum Color { BLACK, GRAY, WHITE };
// struct ParamType {
// using TupleT = std::tuple<const char*, Color>;
// std::string animal;
// Color color;
// ParamType(TupleT t) : animal(std::get<0>(t)), color(std::get<1>(t)) {}
// };
// class AnimalTest
// : public testing::TestWithParam<ParamType> {...};
//
// TEST_P(AnimalTest, AnimalLooksNice) {...}
//
// INSTANTIATE_TEST_SUITE_P(AnimalVariations, AnimalTest,
// ConvertGenerator<ParamType::TupleT>(
// Combine(Values("cat", "dog"),
// Values(BLACK, WHITE))));
//
template <typename RequestedT>
internal::ParamConverterGenerator<RequestedT> ConvertGenerator(
internal::ParamGenerator<RequestedT> gen) {
return internal::ParamConverterGenerator<RequestedT>(std::move(gen));
}
// As above, but takes a callable as a second argument. The callable converts
// the generated parameter to the test fixture's parameter type. This allows you
// to use a parameter type that does not have a converting constructor from the
// generated type.
//
// Example:
//
// This will instantiate tests in test suite AnimalTest each one with
// the parameter values tuple("cat", BLACK), tuple("cat", WHITE),
// tuple("dog", BLACK), and tuple("dog", WHITE):
//
// enum Color { BLACK, GRAY, WHITE };
// struct ParamType {
// std::string animal;
// Color color;
// };
// class AnimalTest
// : public testing::TestWithParam<ParamType> {...};
//
// TEST_P(AnimalTest, AnimalLooksNice) {...}
//
// INSTANTIATE_TEST_SUITE_P(
// AnimalVariations, AnimalTest,
// ConvertGenerator(Combine(Values("cat", "dog"), Values(BLACK, WHITE)),
// [](std::tuple<std::string, Color> t) {
// return ParamType{.animal = std::get<0>(t),
// .color = std::get<1>(t)};
// }));
//
template <typename T, int&... ExplicitArgumentBarrier, typename Gen,
typename Func,
typename StdFunction = decltype(std::function(std::declval<Func>()))>
internal::ParamConverterGenerator<T, StdFunction> ConvertGenerator(Gen&& gen,
Func&& f) {
return internal::ParamConverterGenerator<T, StdFunction>(
std::forward<Gen>(gen), std::forward<Func>(f));
}
// As above, but infers the T from the supplied std::function instead of
// having the caller specify it.
template <int&... ExplicitArgumentBarrier, typename Gen, typename Func,
typename StdFunction = decltype(std::function(std::declval<Func>()))>
auto ConvertGenerator(Gen&& gen, Func&& f) {
constexpr bool is_single_arg_std_function =
internal::IsSingleArgStdFunction<StdFunction>::value;
if constexpr (is_single_arg_std_function) {
return ConvertGenerator<
typename internal::FuncSingleParamType<StdFunction>::type>(
std::forward<Gen>(gen), std::forward<Func>(f));
} else {
static_assert(is_single_arg_std_function,
"The call signature must contain a single argument.");
}
}
#define TEST_P(test_suite_name, test_name) \
class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \
: public test_suite_name { \
: public test_suite_name, \
private ::testing::internal::GTestNonCopyable { \
public: \
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \
void TestBody() override; \
@@ -428,12 +522,11 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
->AddTestPattern( \
GTEST_STRINGIFY_(test_suite_name), GTEST_STRINGIFY_(test_name), \
new ::testing::internal::TestMetaFactory<GTEST_TEST_CLASS_NAME_( \
test_suite_name, test_name)>()); \
test_suite_name, test_name)>(), \
::testing::internal::CodeLocation(__FILE__, __LINE__)); \
return 0; \
} \
static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \
GTEST_DISALLOW_COPY_AND_ASSIGN_(GTEST_TEST_CLASS_NAME_(test_suite_name, \
test_name)); \
[[maybe_unused]] static int gtest_registering_dummy_; \
}; \
int GTEST_TEST_CLASS_NAME_(test_suite_name, \
test_name)::gtest_registering_dummy_ = \
@@ -478,22 +571,20 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
DUMMY_PARAM_))))(info); \
} \
static int gtest_##prefix##test_suite_name##_dummy_ \
GTEST_ATTRIBUTE_UNUSED_ = \
::testing::UnitTest::GetInstance() \
->parameterized_test_registry() \
.GetTestSuitePatternHolder<test_suite_name>( \
GTEST_STRINGIFY_(test_suite_name), \
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
->AddTestSuiteInstantiation( \
GTEST_STRINGIFY_(prefix), \
&gtest_##prefix##test_suite_name##_EvalGenerator_, \
&gtest_##prefix##test_suite_name##_EvalGenerateName_, \
__FILE__, __LINE__)
[[maybe_unused]] static int gtest_##prefix##test_suite_name##_dummy_ = \
::testing::UnitTest::GetInstance() \
->parameterized_test_registry() \
.GetTestSuitePatternHolder<test_suite_name>( \
GTEST_STRINGIFY_(test_suite_name), \
::testing::internal::CodeLocation(__FILE__, __LINE__)) \
->AddTestSuiteInstantiation( \
GTEST_STRINGIFY_(prefix), \
&gtest_##prefix##test_suite_name##_EvalGenerator_, \
&gtest_##prefix##test_suite_name##_EvalGenerateName_, __FILE__, \
__LINE__)
// Allow Marking a Parameterized test class as not needing to be instantiated.
#define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T) \
#define GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(T) \
namespace gtest_do_not_use_outside_namespace_scope {} \
static const ::testing::internal::MarkAsIgnored gtest_allow_ignore_##T( \
GTEST_STRINGIFY_(T))
@@ -508,4 +599,4 @@ internal::CartesianProductHolder<Generator...> Combine(const Generator&... g) {
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_

View File

@@ -27,7 +27,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Test - The Google C++ Testing and Mocking Framework
//
// This file implements a universal value printer that can print a
@@ -44,6 +43,9 @@
// 1. foo::PrintTo(const T&, ostream*)
// 2. operator<<(ostream&, const T&) defined in either foo or the
// global namespace.
// * Prefer AbslStringify(..) to operator<<(..), per https://abseil.io/tips/215.
// * Define foo::PrintTo(..) if the type already has AbslStringify(..), but an
// alternative presentation in test results is of interest.
//
// However if T is an STL-style container then it is printed element-wise
// unless foo::PrintTo(const T&, ostream*) is defined. Note that
@@ -95,27 +97,38 @@
// being defined as many user-defined container types don't have
// value_type.
// GOOGLETEST_CM0001 DO NOT DELETE
// IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#include <functional>
#include <memory>
#include <ostream> // NOLINT
#include <sstream>
#include <string>
#include <tuple>
#include <type_traits>
#include <typeinfo>
#include <utility>
#include <vector>
#ifdef GTEST_HAS_ABSL
#include "absl/strings/has_absl_stringify.h"
#include "absl/strings/str_cat.h"
#endif // GTEST_HAS_ABSL
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
#if GTEST_HAS_ABSL
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
#endif // GTEST_HAS_ABSL
#if GTEST_INTERNAL_HAS_STD_SPAN
#include <span> // NOLINT
#endif // GTEST_INTERNAL_HAS_STD_SPAN
#if GTEST_INTERNAL_HAS_COMPARE_LIB
#include <compare> // NOLINT
#endif // GTEST_INTERNAL_HAS_COMPARE_LIB
namespace testing {
@@ -126,13 +139,32 @@ namespace internal {
template <typename T>
void UniversalPrint(const T& value, ::std::ostream* os);
template <typename T>
struct IsStdSpan {
static constexpr bool value = false;
};
#if GTEST_INTERNAL_HAS_STD_SPAN
template <typename E>
struct IsStdSpan<std::span<E>> {
static constexpr bool value = true;
};
#endif // GTEST_INTERNAL_HAS_STD_SPAN
// Used to print an STL-style container when the user doesn't define
// a PrintTo() for it.
//
// NOTE: Since std::span does not have const_iterator until C++23, it would
// fail IsContainerTest before C++23. However, IsContainerTest only uses
// the presence of const_iterator to avoid treating iterators as containers
// because of iterator::iterator. Which means std::span satisfies the *intended*
// condition of IsContainerTest.
struct ContainerPrinter {
template <typename T,
typename = typename std::enable_if<
(sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
!IsRecursiveContainer<T>::value>::type>
((sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
!IsRecursiveContainer<T>::value) ||
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 << '{';
@@ -194,51 +226,44 @@ struct PointerPrinter {
}
};
namespace internal_stream {
namespace internal_stream_operator_without_lexical_name_lookup {
struct Sentinel;
template <typename Char, typename CharTraits, typename T>
Sentinel* operator<<(::std::basic_ostream<Char, CharTraits>& os, const T& x);
// Check if the user has a user-defined operator<< for their type.
//
// We put this in its own namespace to inject a custom operator<< that allows us
// to probe the type's operator.
//
// Note that this operator<< takes a generic std::basic_ostream<Char,
// CharTraits> type instead of the more restricted std::ostream. If
// we define it to take an std::ostream instead, we'll get an
// "ambiguous overloads" compiler error when trying to print a type
// Foo that supports streaming to std::basic_ostream<Char,
// CharTraits>, as the compiler cannot tell whether
// operator<<(std::ostream&, const T&) or
// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more
// specific.
template <typename T>
constexpr bool UseStreamOperator() {
return !std::is_same<decltype(std::declval<std::ostream&>()
<< std::declval<const T&>()),
Sentinel*>::value;
}
} // namespace internal_stream
// The presence of an operator<< here will terminate lexical scope lookup
// straight away (even though it cannot be a match because of its argument
// types). Thus, the two operator<< calls in StreamPrinter will find only ADL
// candidates.
struct LookupBlocker {};
void operator<<(LookupBlocker, LookupBlocker);
struct StreamPrinter {
template <typename T, typename = typename std::enable_if<
internal_stream::UseStreamOperator<T>()>::type>
static void PrintValue(const T& value, ::std::ostream* os) {
template <typename T,
// Don't accept member pointers here. We'd print them via implicit
// conversion to bool, which isn't useful.
typename = typename std::enable_if<
!std::is_member_pointer<T>::value>::type>
// Only accept types for which we can find a streaming operator via
// ADL (possibly involving implicit conversions).
// (Use SFINAE via return type, because it seems GCC < 12 doesn't handle name
// lookup properly when we do it in the template parameter list.)
static auto PrintValue(const T& value,
::std::ostream* os) -> decltype((void)(*os << value)) {
// Call streaming operator found by ADL, possibly with implicit conversions
// of the arguments.
*os << value;
}
};
} // namespace internal_stream_operator_without_lexical_name_lookup
struct ProtobufPrinter {
// We print a protobuf using its ShortDebugString() when the string
// doesn't exceed this many characters; otherwise we print it using
// DebugString() for better readability.
static const size_t kProtobufOneLinerMaxLength = 50;
template <typename T, typename = typename std::enable_if<
internal::IsAProtocolMessage<T>::value>::type>
template <typename T,
typename = typename std::enable_if<
internal::HasDebugStringAndShortDebugString<T>::value>::type>
static void PrintValue(const T& value, ::std::ostream* os) {
std::string pretty_str = value.ShortDebugString();
if (pretty_str.length() > kProtobufOneLinerMaxLength) {
@@ -269,22 +294,40 @@ struct ConvertibleToStringViewPrinter {
#endif
};
#ifdef GTEST_HAS_ABSL
struct ConvertibleToAbslStringifyPrinter {
template <typename T,
typename = typename std::enable_if<
absl::HasAbslStringify<T>::value>::type> // NOLINT
static void PrintValue(const T& value, ::std::ostream* os) {
*os << absl::StrCat(value);
}
};
#endif // GTEST_HAS_ABSL
// Prints the given number of bytes in the given object to the given
// ostream.
GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes,
size_t count,
::std::ostream* os);
struct FallbackPrinter {
template <typename T>
size_t count, ::std::ostream* os);
struct RawBytesPrinter {
// SFINAE on `sizeof` to make sure we have a complete type.
template <typename T, size_t = sizeof(T)>
static void PrintValue(const T& value, ::std::ostream* os) {
PrintBytesInObjectTo(
static_cast<const unsigned char*>(
// Load bearing cast to void* to support iOS
reinterpret_cast<const void*>(std::addressof(value))),
sizeof(value), os);
}
};
struct FallbackPrinter {
template <typename T>
static void PrintValue(const T&, ::std::ostream* os) {
*os << "(incomplete type)";
}
};
// Try every printer in order and return the first one that works.
template <typename T, typename E, typename Printer, typename... Printers>
struct FindFirstPrinter : FindFirstPrinter<T, E, Printers...> {};
@@ -300,8 +343,8 @@ struct FindFirstPrinter<
// - Print containers (they have begin/end/etc).
// - Print function pointers.
// - Print object pointers.
// - Use the stream operator, if available.
// - Print protocol buffers.
// - Use the stream operator, if available.
// - Print types convertible to BiggestInt.
// - Print types convertible to StringView, if available.
// - Fallback to printing the raw bytes of the object.
@@ -309,8 +352,13 @@ template <typename T>
void PrintWithFallback(const T& value, ::std::ostream* os) {
using Printer = typename FindFirstPrinter<
T, void, ContainerPrinter, FunctionPointerPrinter, PointerPrinter,
StreamPrinter, ProtobufPrinter, ConvertibleToIntegerPrinter,
ConvertibleToStringViewPrinter, FallbackPrinter>::type;
ProtobufPrinter,
#ifdef GTEST_HAS_ABSL
ConvertibleToAbslStringifyPrinter,
#endif // GTEST_HAS_ABSL
internal_stream_operator_without_lexical_name_lookup::StreamPrinter,
ConvertibleToIntegerPrinter, ConvertibleToStringViewPrinter,
RawBytesPrinter, FallbackPrinter>::type;
Printer::PrintValue(value, os);
}
@@ -362,6 +410,14 @@ GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(wchar_t);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
#ifdef __cpp_lib_char8_t
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char8_t);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char8_t);
#endif
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char16_t);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char16_t);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char32_t);
GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char32_t);
#undef GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_
@@ -369,16 +425,24 @@ GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t);
// to point to a NUL-terminated string, and thus can print it as a string.
#define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \
template <> \
class FormatForComparison<CharType*, OtherStringType> { \
public: \
static ::std::string Format(CharType* value) { \
return ::testing::PrintToString(value); \
} \
template <> \
class FormatForComparison<CharType*, OtherStringType> { \
public: \
static ::std::string Format(CharType* value) { \
return ::testing::PrintToString(value); \
} \
}
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string);
#ifdef __cpp_lib_char8_t
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char8_t, ::std::u8string);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char8_t, ::std::u8string);
#endif
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char16_t, ::std::u16string);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char16_t, ::std::u16string);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char32_t, ::std::u32string);
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char32_t, ::std::u32string);
#if GTEST_HAS_STD_WSTRING
GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(wchar_t, ::std::wstring);
@@ -396,8 +460,8 @@ GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring);
//
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
template <typename T1, typename T2>
std::string FormatForComparisonFailureMessage(
const T1& value, const T2& /* other_operand */) {
std::string FormatForComparisonFailureMessage(const T1& value,
const T2& /* other_operand */) {
return FormatForComparison<T1, T2>::Format(value);
}
@@ -455,6 +519,117 @@ inline void PrintTo(bool x, ::std::ostream* os) {
// is implemented as an unsigned type.
GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);
GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os);
inline void PrintTo(char16_t c, ::std::ostream* os) {
PrintTo(ImplicitCast_<char32_t>(c), os);
}
#ifdef __cpp_lib_char8_t
inline void PrintTo(char8_t c, ::std::ostream* os) {
PrintTo(ImplicitCast_<char32_t>(c), os);
}
#endif
// gcc/clang __{u,}int128_t
#if defined(__SIZEOF_INT128__)
GTEST_API_ void PrintTo(__uint128_t v, ::std::ostream* os);
GTEST_API_ void PrintTo(__int128_t v, ::std::ostream* os);
#endif // __SIZEOF_INT128__
// The default resolution used to print floating-point values uses only
// 6 digits, which can be confusing if a test compares two values whose
// difference lies in the 7th digit. So we'd like to print out numbers
// in full precision.
// However if the value is something simple like 1.1, full will print a
// long string like 1.100000001 due to floating-point numbers not using
// a base of 10. This routiune returns an appropriate resolution for a
// given floating-point number, that is, 6 if it will be accurate, or a
// max_digits10 value (full precision) if it won't, for values between
// 0.0001 and one million.
// It does this by computing what those digits would be (by multiplying
// by an appropriate power of 10), then dividing by that power again to
// see if gets the original value back.
// A similar algorithm applies for values larger than one million; note
// that for those values, we must divide to get a six-digit number, and
// then multiply to possibly get the original value again.
template <typename FloatType>
int AppropriateResolution(FloatType val) {
int full = std::numeric_limits<FloatType>::max_digits10;
if (val < 0) val = -val;
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
#endif
if (val < 1000000) {
FloatType mulfor6 = 1e10;
// Without these static casts, the template instantiation for float would
// fail to compile when -Wdouble-promotion is enabled, as the arithmetic and
// comparison logic would promote floats to doubles.
if (val >= static_cast<FloatType>(100000.0)) { // 100,000 to 999,999
mulfor6 = 1.0;
} else if (val >= static_cast<FloatType>(10000.0)) {
mulfor6 = 1e1;
} else if (val >= static_cast<FloatType>(1000.0)) {
mulfor6 = 1e2;
} else if (val >= static_cast<FloatType>(100.0)) {
mulfor6 = 1e3;
} else if (val >= static_cast<FloatType>(10.0)) {
mulfor6 = 1e4;
} else if (val >= static_cast<FloatType>(1.0)) {
mulfor6 = 1e5;
} else if (val >= static_cast<FloatType>(0.1)) {
mulfor6 = 1e6;
} else if (val >= static_cast<FloatType>(0.01)) {
mulfor6 = 1e7;
} else if (val >= static_cast<FloatType>(0.001)) {
mulfor6 = 1e8;
} else if (val >= static_cast<FloatType>(0.0001)) {
mulfor6 = 1e9;
}
if (static_cast<FloatType>(static_cast<int32_t>(
val * mulfor6 + (static_cast<FloatType>(0.5)))) /
mulfor6 ==
val)
return 6;
} else if (val < static_cast<FloatType>(1e10)) {
FloatType divfor6 = static_cast<FloatType>(1.0);
if (val >= static_cast<FloatType>(1e9)) { // 1,000,000,000 to 9,999,999,999
divfor6 = 10000;
} else if (val >=
static_cast<FloatType>(1e8)) { // 100,000,000 to 999,999,999
divfor6 = 1000;
} else if (val >=
static_cast<FloatType>(1e7)) { // 10,000,000 to 99,999,999
divfor6 = 100;
} else if (val >= static_cast<FloatType>(1e6)) { // 1,000,000 to 9,999,999
divfor6 = 10;
}
if (static_cast<FloatType>(static_cast<int32_t>(
val / divfor6 + (static_cast<FloatType>(0.5)))) *
divfor6 ==
val)
return 6;
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
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);
}
// Overloads for C strings.
GTEST_API_ void PrintTo(const char* s, ::std::ostream* os);
inline void PrintTo(char* s, ::std::ostream* os) {
@@ -475,6 +650,23 @@ inline void PrintTo(const unsigned char* s, ::std::ostream* os) {
inline void PrintTo(unsigned char* s, ::std::ostream* os) {
PrintTo(ImplicitCast_<const void*>(s), os);
}
#ifdef __cpp_lib_char8_t
// Overloads for u8 strings.
GTEST_API_ void PrintTo(const char8_t* s, ::std::ostream* os);
inline void PrintTo(char8_t* s, ::std::ostream* os) {
PrintTo(ImplicitCast_<const char8_t*>(s), os);
}
#endif
// Overloads for u16 strings.
GTEST_API_ void PrintTo(const char16_t* s, ::std::ostream* os);
inline void PrintTo(char16_t* s, ::std::ostream* os) {
PrintTo(ImplicitCast_<const char16_t*>(s), os);
}
// Overloads for u32 strings.
GTEST_API_ void PrintTo(const char32_t* s, ::std::ostream* os);
inline void PrintTo(char32_t* s, ::std::ostream* os) {
PrintTo(ImplicitCast_<const char32_t*>(s), os);
}
// MSVC can be configured to define wchar_t as a typedef of unsigned
// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native
@@ -504,14 +696,34 @@ void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) {
}
// Overloads for ::std::string.
GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os);
GTEST_API_ void PrintStringTo(const ::std::string& s, ::std::ostream* os);
inline void PrintTo(const ::std::string& s, ::std::ostream* os) {
PrintStringTo(s, os);
}
// Overloads for ::std::u8string
#ifdef __cpp_lib_char8_t
GTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os);
inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) {
PrintU8StringTo(s, os);
}
#endif
// Overloads for ::std::u16string
GTEST_API_ void PrintU16StringTo(const ::std::u16string& s, ::std::ostream* os);
inline void PrintTo(const ::std::u16string& s, ::std::ostream* os) {
PrintU16StringTo(s, os);
}
// Overloads for ::std::u32string
GTEST_API_ void PrintU32StringTo(const ::std::u32string& s, ::std::ostream* os);
inline void PrintTo(const ::std::u32string& s, ::std::ostream* os) {
PrintU32StringTo(s, os);
}
// Overloads for ::std::wstring.
#if GTEST_HAS_STD_WSTRING
GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os);
GTEST_API_ void PrintWideStringTo(const ::std::wstring& s, ::std::ostream* os);
inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) {
PrintWideStringTo(s, os);
}
@@ -526,11 +738,89 @@ inline void PrintTo(internal::StringView sp, ::std::ostream* os) {
inline void PrintTo(std::nullptr_t, ::std::ostream* os) { *os << "(nullptr)"; }
#if GTEST_HAS_RTTI
inline void PrintTo(const std::type_info& info, std::ostream* os) {
*os << internal::GetTypeName(info);
}
#endif // GTEST_HAS_RTTI
template <typename T>
void PrintTo(std::reference_wrapper<T> ref, ::std::ostream* os) {
UniversalPrinter<T&>::Print(ref.get(), os);
}
inline const void* VoidifyPointer(const void* p) { return p; }
inline const void* VoidifyPointer(volatile const void* p) {
return const_cast<const void*>(p);
}
template <typename T, typename Ptr>
void PrintSmartPointer(const Ptr& ptr, std::ostream* os, char) {
if (ptr == nullptr) {
*os << "(nullptr)";
} else {
// We can't print the value. Just print the pointer..
*os << "(" << (VoidifyPointer)(ptr.get()) << ")";
}
}
template <typename T, typename Ptr,
typename = typename std::enable_if<!std::is_void<T>::value &&
!std::is_array<T>::value>::type>
void PrintSmartPointer(const Ptr& ptr, std::ostream* os, int) {
if (ptr == nullptr) {
*os << "(nullptr)";
} else {
*os << "(ptr = " << (VoidifyPointer)(ptr.get()) << ", value = ";
UniversalPrinter<T>::Print(*ptr, os);
*os << ")";
}
}
template <typename T, typename D>
void PrintTo(const std::unique_ptr<T, D>& ptr, std::ostream* os) {
(PrintSmartPointer<T>)(ptr, os, 0);
}
template <typename T>
void PrintTo(const std::shared_ptr<T>& ptr, std::ostream* os) {
(PrintSmartPointer<T>)(ptr, os, 0);
}
#if GTEST_INTERNAL_HAS_COMPARE_LIB
template <typename T>
void PrintOrderingHelper(T ordering, std::ostream* os) {
if (ordering == T::less) {
*os << "(less)";
} else if (ordering == T::greater) {
*os << "(greater)";
} else if (ordering == T::equivalent) {
*os << "(equivalent)";
} else {
*os << "(unknown ordering)";
}
}
inline void PrintTo(std::strong_ordering ordering, std::ostream* os) {
if (ordering == std::strong_ordering::equal) {
*os << "(equal)";
} else {
PrintOrderingHelper(ordering, os);
}
}
inline void PrintTo(std::partial_ordering ordering, std::ostream* os) {
if (ordering == std::partial_ordering::unordered) {
*os << "(unordered)";
} else {
PrintOrderingHelper(ordering, os);
}
}
inline void PrintTo(std::weak_ordering ordering, std::ostream* os) {
PrintOrderingHelper(ordering, os);
}
#endif
// Helper function for printing a tuple. T must be instantiated with
// a tuple type.
template <typename T>
@@ -596,14 +886,46 @@ class UniversalPrinter {
GTEST_DISABLE_MSC_WARNINGS_POP_()
};
#if GTEST_HAS_ABSL
// Remove any const-qualifiers before passing a type to UniversalPrinter.
template <typename T>
class UniversalPrinter<const T> : public UniversalPrinter<T> {};
// Printer for absl::optional
#if GTEST_INTERNAL_HAS_ANY
// Printer for std::any / absl::any
template <>
class UniversalPrinter<Any> {
public:
static void Print(const Any& value, ::std::ostream* os) {
if (value.has_value()) {
*os << "value of type " << GetTypeName(value);
} else {
*os << "no value";
}
}
private:
static std::string GetTypeName(const Any& value) {
#if GTEST_HAS_RTTI
return internal::GetTypeName(value.type());
#else
static_cast<void>(value); // possibly unused
return "<unknown_type>";
#endif // GTEST_HAS_RTTI
}
};
#endif // GTEST_INTERNAL_HAS_ANY
#if GTEST_INTERNAL_HAS_OPTIONAL
// Printer for std::optional / absl::optional
template <typename T>
class UniversalPrinter<::absl::optional<T>> {
class UniversalPrinter<Optional<T>> {
public:
static void Print(const ::absl::optional<T>& value, ::std::ostream* os) {
static void Print(const Optional<T>& value, ::std::ostream* os) {
*os << '(';
if (!value) {
*os << "nullopt";
@@ -614,14 +936,30 @@ class UniversalPrinter<::absl::optional<T>> {
}
};
// Printer for absl::variant
template <>
class UniversalPrinter<decltype(Nullopt())> {
public:
static void Print(decltype(Nullopt()), ::std::ostream* os) {
*os << "(nullopt)";
}
};
#endif // GTEST_INTERNAL_HAS_OPTIONAL
#if GTEST_INTERNAL_HAS_VARIANT
// Printer for std::variant / absl::variant
template <typename... T>
class UniversalPrinter<::absl::variant<T...>> {
class UniversalPrinter<Variant<T...>> {
public:
static void Print(const ::absl::variant<T...>& value, ::std::ostream* os) {
static void Print(const Variant<T...>& value, ::std::ostream* os) {
*os << '(';
absl::visit(Visitor{os}, value);
#ifdef GTEST_HAS_ABSL
absl::visit(Visitor{os, value.index()}, value);
#else
std::visit(Visitor{os, value.index()}, value);
#endif // GTEST_HAS_ABSL
*os << ')';
}
@@ -629,14 +967,16 @@ class UniversalPrinter<::absl::variant<T...>> {
struct Visitor {
template <typename U>
void operator()(const U& u) const {
*os << "'" << GetTypeName<U>() << "' with value ";
*os << "'" << GetTypeName<U>() << "(index = " << index
<< ")' with value ";
UniversalPrint(u, os);
}
::std::ostream* os;
std::size_t index;
};
};
#endif // GTEST_HAS_ABSL
#endif // GTEST_INTERNAL_HAS_VARIANT
// UniversalPrintArray(begin, len, os) prints an array of 'len'
// elements, starting at address 'begin'.
@@ -662,12 +1002,26 @@ void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) {
}
}
// This overload prints a (const) char array compactly.
GTEST_API_ void UniversalPrintArray(
const char* begin, size_t len, ::std::ostream* os);
GTEST_API_ void UniversalPrintArray(const char* begin, size_t len,
::std::ostream* os);
#ifdef __cpp_lib_char8_t
// This overload prints a (const) char8_t array compactly.
GTEST_API_ void UniversalPrintArray(const char8_t* begin, size_t len,
::std::ostream* os);
#endif
// This overload prints a (const) char16_t array compactly.
GTEST_API_ void UniversalPrintArray(const char16_t* begin, size_t len,
::std::ostream* os);
// This overload prints a (const) char32_t array compactly.
GTEST_API_ void UniversalPrintArray(const char32_t* begin, size_t len,
::std::ostream* os);
// This overload prints a (const) wchar_t array compactly.
GTEST_API_ void UniversalPrintArray(
const wchar_t* begin, size_t len, ::std::ostream* os);
GTEST_API_ void UniversalPrintArray(const wchar_t* begin, size_t len,
::std::ostream* os);
// Implements printing an array type T[N].
template <typename T, size_t N>
@@ -718,6 +1072,13 @@ class UniversalTersePrinter<T&> {
UniversalPrint(value, os);
}
};
template <typename T>
class UniversalTersePrinter<std::reference_wrapper<T>> {
public:
static void Print(std::reference_wrapper<T> value, ::std::ostream* os) {
UniversalTersePrinter<T>::Print(value.get(), os);
}
};
template <typename T, size_t N>
class UniversalTersePrinter<T[N]> {
public:
@@ -737,12 +1098,55 @@ class UniversalTersePrinter<const char*> {
}
};
template <>
class UniversalTersePrinter<char*> {
class UniversalTersePrinter<char*> : public UniversalTersePrinter<const char*> {
};
#ifdef __cpp_lib_char8_t
template <>
class UniversalTersePrinter<const char8_t*> {
public:
static void Print(char* str, ::std::ostream* os) {
UniversalTersePrinter<const char*>::Print(str, os);
static void Print(const char8_t* str, ::std::ostream* os) {
if (str == nullptr) {
*os << "NULL";
} else {
UniversalPrint(::std::u8string(str), os);
}
}
};
template <>
class UniversalTersePrinter<char8_t*>
: public UniversalTersePrinter<const char8_t*> {};
#endif
template <>
class UniversalTersePrinter<const char16_t*> {
public:
static void Print(const char16_t* str, ::std::ostream* os) {
if (str == nullptr) {
*os << "NULL";
} else {
UniversalPrint(::std::u16string(str), os);
}
}
};
template <>
class UniversalTersePrinter<char16_t*>
: public UniversalTersePrinter<const char16_t*> {};
template <>
class UniversalTersePrinter<const char32_t*> {
public:
static void Print(const char32_t* str, ::std::ostream* os) {
if (str == nullptr) {
*os << "NULL";
} else {
UniversalPrint(::std::u32string(str), os);
}
}
};
template <>
class UniversalTersePrinter<char32_t*>
: public UniversalTersePrinter<const char32_t*> {};
#if GTEST_HAS_STD_WSTRING
template <>
@@ -783,10 +1187,10 @@ void UniversalPrint(const T& value, ::std::ostream* os) {
UniversalPrinter<T1>::Print(value, os);
}
typedef ::std::vector< ::std::string> Strings;
typedef ::std::vector<::std::string> Strings;
// Tersely prints the first N fields of a tuple to a string vector,
// one element for each field.
// Tersely prints the first N fields of a tuple to a string vector,
// one element for each field.
template <typename Tuple>
void TersePrintPrefixToStrings(const Tuple&, std::integral_constant<size_t, 0>,
Strings*) {}
@@ -829,4 +1233,4 @@ template <typename T>
// declarations from this file.
#include "gtest/internal/custom/gtest-printers.h"
#endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_

View File

@@ -27,14 +27,13 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Utilities for testing Google Test itself and code that uses Google Test
// (e.g. frameworks built on top of Google Test).
// GOOGLETEST_CM0004 DO NOT DELETE
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_
#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_
#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_
#include <string>
#include "gtest/gtest.h"
@@ -88,7 +87,10 @@ class GTEST_API_ ScopedFakeTestPartResultReporter
TestPartResultReporterInterface* old_reporter_;
TestPartResultArray* const result_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter);
ScopedFakeTestPartResultReporter(const ScopedFakeTestPartResultReporter&) =
delete;
ScopedFakeTestPartResultReporter& operator=(
const ScopedFakeTestPartResultReporter&) = delete;
};
namespace internal {
@@ -104,12 +106,14 @@ class GTEST_API_ SingleFailureChecker {
SingleFailureChecker(const TestPartResultArray* results,
TestPartResult::Type type, const std::string& substr);
~SingleFailureChecker();
private:
const TestPartResultArray* const results_;
const TestPartResult::Type type_;
const std::string substr_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker);
SingleFailureChecker(const SingleFailureChecker&) = delete;
SingleFailureChecker& operator=(const SingleFailureChecker&) = delete;
};
} // namespace internal
@@ -119,7 +123,8 @@ class GTEST_API_ SingleFailureChecker {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
// A set of macros for testing Google Test assertions or code that's expected
// to generate Google Test fatal failures. It verifies that the given
// to generate Google Test fatal failures (e.g. a failure from an ASSERT_EQ, but
// not a non-fatal failure, as from EXPECT_EQ). It verifies that the given
// statement will cause exactly one fatal Google Test failure with 'substr'
// being part of the failure message.
//
@@ -141,44 +146,46 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
// helper macro, due to some peculiarity in how the preprocessor
// works. The AcceptsMacroThatExpandsToUnprotectedComma test in
// gtest_unittest.cc will fail to compile if we do that.
#define EXPECT_FATAL_FAILURE(statement, substr) \
do { \
class GTestExpectFatalFailureHelper {\
public:\
static void Execute() { statement; }\
};\
::testing::TestPartResultArray gtest_failures;\
::testing::internal::SingleFailureChecker gtest_checker(\
&gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
{\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
::testing::ScopedFakeTestPartResultReporter:: \
INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
GTestExpectFatalFailureHelper::Execute();\
}\
#define EXPECT_FATAL_FAILURE(statement, substr) \
do { \
class GTestExpectFatalFailureHelper { \
public: \
static void Execute() { statement; } \
}; \
::testing::TestPartResultArray gtest_failures; \
::testing::internal::SingleFailureChecker gtest_checker( \
&gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \
{ \
::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
::testing::ScopedFakeTestPartResultReporter:: \
INTERCEPT_ONLY_CURRENT_THREAD, \
&gtest_failures); \
GTestExpectFatalFailureHelper::Execute(); \
} \
} while (::testing::internal::AlwaysFalse())
#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
do { \
class GTestExpectFatalFailureHelper {\
public:\
static void Execute() { statement; }\
};\
::testing::TestPartResultArray gtest_failures;\
::testing::internal::SingleFailureChecker gtest_checker(\
&gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr));\
{\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
::testing::ScopedFakeTestPartResultReporter:: \
INTERCEPT_ALL_THREADS, &gtest_failures);\
GTestExpectFatalFailureHelper::Execute();\
}\
#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
do { \
class GTestExpectFatalFailureHelper { \
public: \
static void Execute() { statement; } \
}; \
::testing::TestPartResultArray gtest_failures; \
::testing::internal::SingleFailureChecker gtest_checker( \
&gtest_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \
{ \
::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \
&gtest_failures); \
GTestExpectFatalFailureHelper::Execute(); \
} \
} while (::testing::internal::AlwaysFalse())
// A macro for testing Google Test assertions or code that's expected to
// generate Google Test non-fatal failures. It asserts that the given
// statement will cause exactly one non-fatal Google Test failure with 'substr'
// being part of the failure message.
// generate Google Test non-fatal failures (e.g. a failure from an EXPECT_EQ,
// but not from an ASSERT_EQ). It asserts that the given statement will cause
// exactly one non-fatal Google Test failure with 'substr' being part of the
// failure message.
//
// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only
// affects and considers failures generated in the current thread and
@@ -207,32 +214,37 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
// instead of
// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
// to avoid an MSVC warning on unreachable code.
#define EXPECT_NONFATAL_FAILURE(statement, substr) \
do {\
::testing::TestPartResultArray gtest_failures;\
::testing::internal::SingleFailureChecker gtest_checker(\
#define EXPECT_NONFATAL_FAILURE(statement, substr) \
do { \
::testing::TestPartResultArray gtest_failures; \
::testing::internal::SingleFailureChecker gtest_checker( \
&gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
(substr));\
{\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
::testing::ScopedFakeTestPartResultReporter:: \
INTERCEPT_ONLY_CURRENT_THREAD, &gtest_failures);\
if (::testing::internal::AlwaysTrue()) { statement; }\
}\
(substr)); \
{ \
::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
::testing::ScopedFakeTestPartResultReporter:: \
INTERCEPT_ONLY_CURRENT_THREAD, \
&gtest_failures); \
if (::testing::internal::AlwaysTrue()) { \
statement; \
} \
} \
} while (::testing::internal::AlwaysFalse())
#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
do {\
::testing::TestPartResultArray gtest_failures;\
::testing::internal::SingleFailureChecker gtest_checker(\
&gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
(substr));\
{\
::testing::ScopedFakeTestPartResultReporter gtest_reporter(\
#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \
do { \
::testing::TestPartResultArray gtest_failures; \
::testing::internal::SingleFailureChecker gtest_checker( \
&gtest_failures, ::testing::TestPartResult::kNonFatalFailure, \
(substr)); \
{ \
::testing::ScopedFakeTestPartResultReporter gtest_reporter( \
::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \
&gtest_failures);\
if (::testing::internal::AlwaysTrue()) { statement; }\
}\
&gtest_failures); \
if (::testing::internal::AlwaysTrue()) { \
statement; \
} \
} \
} while (::testing::internal::AlwaysFalse())
#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_

View File

@@ -26,14 +26,19 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
// IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#include <iosfwd>
#include <ostream>
#include <string>
#include <vector>
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-string.h"
@@ -128,7 +133,7 @@ std::ostream& operator<<(std::ostream& os, const TestPartResult& result);
// virtual.
class GTEST_API_ TestPartResultArray {
public:
TestPartResultArray() {}
TestPartResultArray() = default;
// Appends the given TestPartResult to the array.
void Append(const TestPartResult& result);
@@ -142,13 +147,14 @@ class GTEST_API_ TestPartResultArray {
private:
std::vector<TestPartResult> array_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray);
TestPartResultArray(const TestPartResultArray&) = delete;
TestPartResultArray& operator=(const TestPartResultArray&) = delete;
};
// This interface knows how to report a test part result.
class GTEST_API_ TestPartResultReporterInterface {
public:
virtual ~TestPartResultReporterInterface() {}
virtual ~TestPartResultReporterInterface() = default;
virtual void ReportTestPartResult(const TestPartResult& result) = 0;
};
@@ -168,11 +174,13 @@ class GTEST_API_ HasNewFatalFailureHelper
~HasNewFatalFailureHelper() override;
void ReportTestPartResult(const TestPartResult& result) override;
bool has_new_fatal_failure() const { return has_new_fatal_failure_; }
private:
bool has_new_fatal_failure_;
TestPartResultReporterInterface* original_reporter_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper);
HasNewFatalFailureHelper(const HasNewFatalFailureHelper&) = delete;
HasNewFatalFailureHelper& operator=(const HasNewFatalFailureHelper&) = delete;
};
} // namespace internal
@@ -181,4 +189,4 @@ class GTEST_API_ HasNewFatalFailureHelper
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_

View File

@@ -27,10 +27,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// GOOGLETEST_CM0001 DO NOT DELETE
// IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
// This header implements typed tests and type-parameterized tests.
@@ -175,8 +177,6 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
// Implements typed tests.
#if GTEST_HAS_TYPED_TEST
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Expands to the name of the typedef for the type parameters of the
@@ -192,7 +192,7 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
typedef ::testing::internal::GenerateTypeList<Types>::type \
GTEST_TYPE_PARAMS_(CaseName); \
typedef ::testing::internal::NameGeneratorSelector<__VA_ARGS__>::type \
GTEST_NAME_GENERATOR_(CaseName)
GTEST_NAME_GENERATOR_(CaseName)
#define TYPED_TEST(CaseName, TestName) \
static_assert(sizeof(GTEST_STRINGIFY_(TestName)) > 1, \
@@ -205,8 +205,8 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
typedef gtest_TypeParam_ TypeParam; \
void TestBody() override; \
}; \
static bool gtest_##CaseName##_##TestName##_registered_ \
GTEST_ATTRIBUTE_UNUSED_ = ::testing::internal::TypeParameterizedTest< \
[[maybe_unused]] static bool gtest_##CaseName##_##TestName##_registered_ = \
::testing::internal::TypeParameterizedTest< \
CaseName, \
::testing::internal::TemplateSel<GTEST_TEST_CLASS_NAME_(CaseName, \
TestName)>, \
@@ -230,12 +230,8 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
TYPED_TEST_SUITE
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
#endif // GTEST_HAS_TYPED_TEST
// Implements type-parameterized tests.
#if GTEST_HAS_TYPED_TEST_P
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Expands to the namespace name that the type-parameterized tests for
@@ -262,7 +258,7 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
// #included in multiple translation units linked together.
#define TYPED_TEST_SUITE_P(SuiteName) \
static ::testing::internal::TypedTestSuitePState \
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName)
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName)
// Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
@@ -271,31 +267,31 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
TYPED_TEST_SUITE_P
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
#define TYPED_TEST_P(SuiteName, TestName) \
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
template <typename gtest_TypeParam_> \
class TestName : public SuiteName<gtest_TypeParam_> { \
private: \
typedef SuiteName<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \
void TestBody() override; \
}; \
static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
GTEST_STRINGIFY_(TestName)); \
} \
template <typename gtest_TypeParam_> \
void GTEST_SUITE_NAMESPACE_( \
#define TYPED_TEST_P(SuiteName, TestName) \
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
template <typename gtest_TypeParam_> \
class TestName : public SuiteName<gtest_TypeParam_> { \
private: \
typedef SuiteName<gtest_TypeParam_> TestFixture; \
typedef gtest_TypeParam_ TypeParam; \
void TestBody() override; \
}; \
[[maybe_unused]] static bool gtest_##TestName##_defined_ = \
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
GTEST_STRINGIFY_(TestName)); \
} \
template <typename gtest_TypeParam_> \
void GTEST_SUITE_NAMESPACE_( \
SuiteName)::TestName<gtest_TypeParam_>::TestBody()
// Note: this won't work correctly if the trailing arguments are macros.
#define REGISTER_TYPED_TEST_SUITE_P(SuiteName, ...) \
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \
typedef ::testing::internal::Templates<__VA_ARGS__> gtest_AllTests_; \
} \
static const char* const GTEST_REGISTERED_TEST_NAMES_( \
SuiteName) GTEST_ATTRIBUTE_UNUSED_ = \
[[maybe_unused]] static const char* const GTEST_REGISTERED_TEST_NAMES_( \
SuiteName) = \
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).VerifyRegisteredTestNames( \
GTEST_STRINGIFY_(SuiteName), __FILE__, __LINE__, #__VA_ARGS__)
@@ -307,21 +303,21 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
REGISTER_TYPED_TEST_SUITE_P
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \
"test-suit-prefix must not be empty"); \
static bool gtest_##Prefix##_##SuiteName GTEST_ATTRIBUTE_UNUSED_ = \
::testing::internal::TypeParameterizedTestSuite< \
SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
::testing::internal::GenerateTypeList<Types>::type>:: \
Register(GTEST_STRINGIFY_(Prefix), \
::testing::internal::CodeLocation(__FILE__, __LINE__), \
&GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \
GTEST_STRINGIFY_(SuiteName), \
GTEST_REGISTERED_TEST_NAMES_(SuiteName), \
::testing::internal::GenerateNames< \
::testing::internal::NameGeneratorSelector< \
__VA_ARGS__>::type, \
#define INSTANTIATE_TYPED_TEST_SUITE_P(Prefix, SuiteName, Types, ...) \
static_assert(sizeof(GTEST_STRINGIFY_(Prefix)) > 1, \
"test-suit-prefix must not be empty"); \
[[maybe_unused]] static bool gtest_##Prefix##_##SuiteName = \
::testing::internal::TypeParameterizedTestSuite< \
SuiteName, GTEST_SUITE_NAMESPACE_(SuiteName)::gtest_AllTests_, \
::testing::internal::GenerateTypeList<Types>::type>:: \
Register(GTEST_STRINGIFY_(Prefix), \
::testing::internal::CodeLocation(__FILE__, __LINE__), \
&GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName), \
GTEST_STRINGIFY_(SuiteName), \
GTEST_REGISTERED_TEST_NAMES_(SuiteName), \
::testing::internal::GenerateNames< \
::testing::internal::NameGeneratorSelector< \
__VA_ARGS__>::type, \
::testing::internal::GenerateTypeList<Types>::type>())
// Legacy API is deprecated but still available
@@ -332,6 +328,4 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
INSTANTIATE_TYPED_TEST_SUITE_P
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
#endif // GTEST_HAS_TYPED_TEST_P
#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_

File diff suppressed because it is too large Load Diff

View File

@@ -26,17 +26,19 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file is AUTOMATICALLY GENERATED on 01/02/2019 by command
// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND!
//
// Implements a family of generic predicate assertion macros.
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
// IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#include "gtest/gtest.h"
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#include "gtest/gtest-assertion-result.h"
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
namespace testing {
@@ -72,22 +74,18 @@ namespace testing {
// GTEST_ASSERT_ is the basic statement to which all of the assertions
// in this file reduce. Don't use this in your code.
#define GTEST_ASSERT_(expression, on_failure) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
#define GTEST_ASSERT_(expression, on_failure) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (const ::testing::AssertionResult gtest_ar = (expression)) \
; \
else \
; \
else \
on_failure(gtest_ar.failure_message())
// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use
// this in your code.
template <typename Pred,
typename T1>
AssertionResult AssertPred1Helper(const char* pred_text,
const char* e1,
Pred pred,
const T1& v1) {
template <typename Pred, typename T1>
AssertionResult AssertPred1Helper(const char* pred_text, const char* e1,
Pred pred, const T1& v1) {
if (pred(v1)) return AssertionSuccess();
return AssertionFailure()
@@ -98,40 +96,27 @@ AssertionResult AssertPred1Helper(const char* pred_text,
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1.
// Don't use this in your code.
#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\
GTEST_ASSERT_(pred_format(#v1, v1), \
on_failure)
#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure) \
GTEST_ASSERT_(pred_format(#v1, v1), on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use
// this in your code.
#define GTEST_PRED1_(pred, v1, on_failure)\
GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \
#v1, \
pred, \
v1), on_failure)
#define GTEST_PRED1_(pred, v1, on_failure) \
GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, #v1, pred, v1), on_failure)
// Unary predicate assertion macros.
#define EXPECT_PRED_FORMAT1(pred_format, v1) \
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED1(pred, v1) \
GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)
#define EXPECT_PRED1(pred, v1) GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_)
#define ASSERT_PRED_FORMAT1(pred_format, v1) \
GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED1(pred, v1) \
GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)
#define ASSERT_PRED1(pred, v1) GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use
// this in your code.
template <typename Pred,
typename T1,
typename T2>
AssertionResult AssertPred2Helper(const char* pred_text,
const char* e1,
const char* e2,
Pred pred,
const T1& v1,
template <typename Pred, typename T1, typename T2>
AssertionResult AssertPred2Helper(const char* pred_text, const char* e1,
const char* e2, Pred pred, const T1& v1,
const T2& v2) {
if (pred(v1, v2)) return AssertionSuccess();
@@ -145,19 +130,14 @@ AssertionResult AssertPred2Helper(const char* pred_text,
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2.
// Don't use this in your code.
#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \
on_failure)
#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure) \
GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use
// this in your code.
#define GTEST_PRED2_(pred, v1, v2, on_failure)\
GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \
#v1, \
#v2, \
pred, \
v1, \
v2), on_failure)
#define GTEST_PRED2_(pred, v1, v2, on_failure) \
GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, #v1, #v2, pred, v1, v2), \
on_failure)
// Binary predicate assertion macros.
#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \
@@ -169,22 +149,12 @@ AssertionResult AssertPred2Helper(const char* pred_text,
#define ASSERT_PRED2(pred, v1, v2) \
GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use
// this in your code.
template <typename Pred,
typename T1,
typename T2,
typename T3>
AssertionResult AssertPred3Helper(const char* pred_text,
const char* e1,
const char* e2,
const char* e3,
Pred pred,
const T1& v1,
const T2& v2,
const T3& v3) {
template <typename Pred, typename T1, typename T2, typename T3>
AssertionResult AssertPred3Helper(const char* pred_text, const char* e1,
const char* e2, const char* e3, Pred pred,
const T1& v1, const T2& v2, const T3& v3) {
if (pred(v1, v2, v3)) return AssertionSuccess();
return AssertionFailure()
@@ -198,21 +168,15 @@ AssertionResult AssertPred3Helper(const char* pred_text,
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3.
// Don't use this in your code.
#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \
on_failure)
#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure) \
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use
// this in your code.
#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\
GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \
#v1, \
#v2, \
#v3, \
pred, \
v1, \
v2, \
v3), on_failure)
#define GTEST_PRED3_(pred, v1, v2, v3, on_failure) \
GTEST_ASSERT_( \
::testing::AssertPred3Helper(#pred, #v1, #v2, #v3, pred, v1, v2, v3), \
on_failure)
// Ternary predicate assertion macros.
#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \
@@ -224,25 +188,13 @@ AssertionResult AssertPred3Helper(const char* pred_text,
#define ASSERT_PRED3(pred, v1, v2, v3) \
GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use
// this in your code.
template <typename Pred,
typename T1,
typename T2,
typename T3,
typename T4>
AssertionResult AssertPred4Helper(const char* pred_text,
const char* e1,
const char* e2,
const char* e3,
const char* e4,
Pred pred,
const T1& v1,
const T2& v2,
const T3& v3,
const T4& v4) {
template <typename Pred, typename T1, typename T2, typename T3, typename T4>
AssertionResult AssertPred4Helper(const char* pred_text, const char* e1,
const char* e2, const char* e3,
const char* e4, Pred pred, const T1& v1,
const T2& v2, const T3& v3, const T4& v4) {
if (pred(v1, v2, v3, v4)) return AssertionSuccess();
return AssertionFailure()
@@ -257,23 +209,15 @@ AssertionResult AssertPred4Helper(const char* pred_text,
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4.
// Don't use this in your code.
#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \
on_failure)
#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure) \
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use
// this in your code.
#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\
GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \
#v1, \
#v2, \
#v3, \
#v4, \
pred, \
v1, \
v2, \
v3, \
v4), on_failure)
#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure) \
GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, #v1, #v2, #v3, #v4, pred, \
v1, v2, v3, v4), \
on_failure)
// 4-ary predicate assertion macros.
#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \
@@ -285,28 +229,15 @@ AssertionResult AssertPred4Helper(const char* pred_text,
#define ASSERT_PRED4(pred, v1, v2, v3, v4) \
GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_)
// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use
// this in your code.
template <typename Pred,
typename T1,
typename T2,
typename T3,
typename T4,
template <typename Pred, typename T1, typename T2, typename T3, typename T4,
typename T5>
AssertionResult AssertPred5Helper(const char* pred_text,
const char* e1,
const char* e2,
const char* e3,
const char* e4,
const char* e5,
Pred pred,
const T1& v1,
const T2& v2,
const T3& v3,
const T4& v4,
const T5& v5) {
AssertionResult AssertPred5Helper(const char* pred_text, const char* e1,
const char* e2, const char* e3,
const char* e4, const char* e5, Pred pred,
const T1& v1, const T2& v2, const T3& v3,
const T4& v4, const T5& v5) {
if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess();
return AssertionFailure()
@@ -322,25 +253,16 @@ AssertionResult AssertPred5Helper(const char* pred_text,
// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5.
// Don't use this in your code.
#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\
#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure) \
GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \
on_failure)
// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use
// this in your code.
#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\
GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \
#v1, \
#v2, \
#v3, \
#v4, \
#v5, \
pred, \
v1, \
v2, \
v3, \
v4, \
v5), on_failure)
#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure) \
GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, #v1, #v2, #v3, #v4, #v5, \
pred, v1, v2, v3, v4, v5), \
on_failure)
// 5-ary predicate assertion macros.
#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \
@@ -352,8 +274,6 @@ AssertionResult AssertPred5Helper(const char* pred_text,
#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \
GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_)
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_

View File

@@ -27,12 +27,11 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Google C++ Testing and Mocking Framework definitions useful in production code.
// GOOGLETEST_CM0003 DO NOT DELETE
// Google C++ Testing and Mocking Framework definitions useful in production
// code.
#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_
#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_
// When you need to test the private or protected members of a class,
// use the FRIEND_TEST macro to declare your tests as friends of the
@@ -55,7 +54,7 @@
// Note: The test class must be in the same namespace as the class being tested.
// For example, putting MyClassTest in an anonymous namespace will not work.
#define FRIEND_TEST(test_case_name, test_name)\
friend class test_case_name##_##test_name##_Test
#define FRIEND_TEST(test_case_name, test_name) \
friend class test_case_name##_##test_name##_Test
#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_
#endif // GOOGLETEST_INCLUDE_GTEST_GTEST_PROD_H_

View File

@@ -15,18 +15,6 @@ The custom directory is an injection point for custom user configurations.
The following macros can be defined:
### Flag related macros:
* `GTEST_FLAG(flag_name)`
* `GTEST_USE_OWN_FLAGFILE_FLAG_` - Define to 0 when the system provides its
own flagfile flag parsing.
* `GTEST_DECLARE_bool_(name)`
* `GTEST_DECLARE_int32_(name)`
* `GTEST_DECLARE_string_(name)`
* `GTEST_DEFINE_bool_(name, default_val, doc)`
* `GTEST_DEFINE_int32_(name, default_val, doc)`
* `GTEST_DEFINE_string_(name, default_val, doc)`
### Logging:
* `GTEST_LOG_(severity)`

View File

@@ -31,7 +31,7 @@
//
// ** Custom implementation starts here **
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_

View File

@@ -36,7 +36,7 @@
//
// ** Custom implementation starts here **
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_

View File

@@ -31,7 +31,7 @@
//
// ** Custom implementation starts here **
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_

View File

@@ -26,33 +26,59 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The Google C++ Testing and Mocking Framework (Google Test)
//
// This header file defines internal utilities needed for implementing
// death tests. They are subject to change without notice.
// GOOGLETEST_CM0001 DO NOT DELETE
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
// IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#include <stdio.h>
#include <memory>
#include <string>
#include "gtest/gtest-matchers.h"
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
#include <stdio.h>
#include <memory>
GTEST_DECLARE_string_(internal_run_death_test);
namespace testing {
namespace internal {
GTEST_DECLARE_string_(internal_run_death_test);
// Names of the flags (needed for parsing Google Test flags).
const char kDeathTestStyleFlag[] = "death_test_style";
const char kDeathTestUseFork[] = "death_test_use_fork";
// Name of the flag (needed for parsing Google Test flag).
const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
#if GTEST_HAS_DEATH_TEST
// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads
// and interpreted as a regex (rather than an Eq matcher) for legacy
// compatibility.
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
::testing::internal::RE regex) {
return ContainsRegex(regex.pattern());
}
inline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {
return ContainsRegex(regex);
}
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
const ::std::string& regex) {
return ContainsRegex(regex);
}
// If a Matcher<const ::std::string&> is passed to EXPECT_DEATH (etc.), it's
// used directly.
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
Matcher<const ::std::string&> matcher) {
return matcher;
}
#ifdef GTEST_HAS_DEATH_TEST
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
@@ -68,7 +94,7 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
//
// exit status: The integer exit information in the format specified
// by wait(2)
// exit code: The integer code passed to exit(3), _exit(2), or
// exit code: The integer code passed to exit(3), _Exit(2), or
// returned from main()
class GTEST_API_ DeathTest {
public:
@@ -83,17 +109,19 @@ class GTEST_API_ DeathTest {
static bool Create(const char* statement, Matcher<const std::string&> matcher,
const char* file, int line, DeathTest** test);
DeathTest();
virtual ~DeathTest() { }
virtual ~DeathTest() = default;
// A helper class that aborts a death test when it's deleted.
class ReturnSentinel {
public:
explicit ReturnSentinel(DeathTest* test) : test_(test) { }
explicit ReturnSentinel(DeathTest* test) : test_(test) {}
~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
private:
DeathTest* const test_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel);
} GTEST_ATTRIBUTE_UNUSED_;
ReturnSentinel(const ReturnSentinel&) = delete;
ReturnSentinel& operator=(const ReturnSentinel&) = delete;
};
// An enumeration of possible roles that may be taken when a death
// test is encountered. EXECUTE means that the death test logic should
@@ -137,7 +165,8 @@ class GTEST_API_ DeathTest {
// A string containing a description of the outcome of the last death test.
static std::string last_death_test_message_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);
DeathTest(const DeathTest&) = delete;
DeathTest& operator=(const DeathTest&) = delete;
};
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
@@ -145,7 +174,7 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
// Factory interface for death tests. May be mocked out for testing.
class DeathTestFactory {
public:
virtual ~DeathTestFactory() { }
virtual ~DeathTestFactory() = default;
virtual bool Create(const char* statement,
Matcher<const std::string&> matcher, const char* file,
int line, DeathTest** test) = 0;
@@ -162,52 +191,30 @@ class DefaultDeathTestFactory : public DeathTestFactory {
// by a signal, or exited normally with a nonzero exit code.
GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads
// and interpreted as a regex (rather than an Eq matcher) for legacy
// compatibility.
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
::testing::internal::RE regex) {
return ContainsRegex(regex.pattern());
}
inline Matcher<const ::std::string&> MakeDeathTestMatcher(const char* regex) {
return ContainsRegex(regex);
}
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
const ::std::string& regex) {
return ContainsRegex(regex);
}
// If a Matcher<const ::std::string&> is passed to EXPECT_DEATH (etc.), it's
// used directly.
inline Matcher<const ::std::string&> MakeDeathTestMatcher(
Matcher<const ::std::string&> matcher) {
return matcher;
}
// Traps C++ exceptions escaping statement and reports them as test
// failures. Note that trapping SEH exceptions is not implemented here.
# if GTEST_HAS_EXCEPTIONS
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} catch (const ::std::exception& gtest_exception) { \
fprintf(\
stderr, \
"\n%s: Caught std::exception-derived exception escaping the " \
"death test statement. Exception message: %s\n", \
#if GTEST_HAS_EXCEPTIONS
#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} catch (const ::std::exception& gtest_exception) { \
fprintf( \
stderr, \
"\n%s: Caught std::exception-derived exception escaping the " \
"death test statement. Exception message: %s\n", \
::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \
gtest_exception.what()); \
fflush(stderr); \
gtest_exception.what()); \
fflush(stderr); \
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
} catch (...) { \
} catch (...) { \
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
}
# else
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
#else
#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
# endif
#endif
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
// ASSERT_EXIT*, and EXPECT_EXIT*.
@@ -230,14 +237,12 @@ inline Matcher<const ::std::string&> MakeDeathTestMatcher(
} \
break; \
case ::testing::internal::DeathTest::EXECUTE_TEST: { \
::testing::internal::DeathTest::ReturnSentinel gtest_sentinel( \
const ::testing::internal::DeathTest::ReturnSentinel gtest_sentinel( \
gtest_dt); \
GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
break; \
} \
default: \
break; \
} \
} \
} else \
@@ -265,16 +270,12 @@ inline Matcher<const ::std::string&> MakeDeathTestMatcher(
// RUN_ALL_TESTS was called.
class InternalRunDeathTestFlag {
public:
InternalRunDeathTestFlag(const std::string& a_file,
int a_line,
int an_index,
InternalRunDeathTestFlag(const std::string& a_file, int a_line, int an_index,
int a_write_fd)
: file_(a_file), line_(a_line), index_(an_index),
write_fd_(a_write_fd) {}
: file_(a_file), line_(a_line), index_(an_index), write_fd_(a_write_fd) {}
~InternalRunDeathTestFlag() {
if (write_fd_ >= 0)
posix::Close(write_fd_);
if (write_fd_ >= 0) posix::Close(write_fd_);
}
const std::string& file() const { return file_; }
@@ -288,7 +289,8 @@ class InternalRunDeathTestFlag {
int index_;
int write_fd_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
InternalRunDeathTestFlag(const InternalRunDeathTestFlag&) = delete;
InternalRunDeathTestFlag& operator=(const InternalRunDeathTestFlag&) = delete;
};
// Returns a newly created InternalRunDeathTestFlag object with fields
@@ -301,4 +303,4 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_

View File

@@ -26,7 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Google Test filepath utilities
//
// This header file declares classes and functions used internally by
@@ -35,16 +35,24 @@
// This file is #included in gtest/internal/gtest-internal.h.
// Do not include this header file separately!
// GOOGLETEST_CM0001 DO NOT DELETE
// IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#include <string>
#include <utility>
#include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-string.h"
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
#if GTEST_HAS_FILE_SYSTEM
namespace testing {
namespace internal {
@@ -61,10 +69,11 @@ namespace internal {
class GTEST_API_ FilePath {
public:
FilePath() : pathname_("") { }
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { }
FilePath() : pathname_("") {}
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {}
FilePath(FilePath&& rhs) noexcept : pathname_(std::move(rhs.pathname_)) {}
explicit FilePath(const std::string& pathname) : pathname_(pathname) {
explicit FilePath(std::string pathname) : pathname_(std::move(pathname)) {
Normalize();
}
@@ -72,11 +81,13 @@ class GTEST_API_ FilePath {
Set(rhs);
return *this;
}
void Set(const FilePath& rhs) {
pathname_ = rhs.pathname_;
FilePath& operator=(FilePath&& rhs) noexcept {
pathname_ = std::move(rhs.pathname_);
return *this;
}
void Set(const FilePath& rhs) { pathname_ = rhs.pathname_; }
const std::string& string() const { return pathname_; }
const char* c_str() const { return pathname_.c_str(); }
@@ -88,8 +99,7 @@ class GTEST_API_ FilePath {
// than zero (e.g., 12), returns "dir/test_12.xml".
// On Windows platform, uses \ as the separator rather than /.
static FilePath MakeFileName(const FilePath& directory,
const FilePath& base_name,
int number,
const FilePath& base_name, int number,
const char* extension);
// Given directory = "dir", relative_path = "test.xml",
@@ -195,11 +205,21 @@ class GTEST_API_ FilePath {
void Normalize();
// Returns a pointer to the last occurence of a valid path separator in
// Returns a pointer to the last occurrence of a valid path separator in
// the FilePath. On Windows, for example, both '/' and '\' are valid path
// separators. Returns NULL if no path separator was found.
const char* FindLastPathSeparator() const;
// Returns the length of the path root, including the directory separator at
// the end of the prefix. Returns zero by definition if the path is relative.
// Examples:
// - [Windows] "..\Sibling" => 0
// - [Windows] "\Windows" => 1
// - [Windows] "C:/Windows\Notepad.exe" => 3
// - [Windows] "\\Host\Share\C$/Windows" => 13
// - [UNIX] "/bin" => 1
size_t CalculateRootLength() const;
std::string pathname_;
}; // class FilePath
@@ -208,4 +228,6 @@ class GTEST_API_ FilePath {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_
#endif // GTEST_HAS_FILE_SYSTEM
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_

File diff suppressed because it is too large Load Diff

View File

@@ -27,38 +27,43 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Type and function utilities for implementing parameterized tests.
// GOOGLETEST_CM0001 DO NOT DELETE
// IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#include <ctype.h>
#include <cassert>
#include <functional>
#include <iterator>
#include <map>
#include <memory>
#include <ostream>
#include <set>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <utility>
#include <vector>
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
#include "gtest/gtest-printers.h"
#include "gtest/gtest-test-part.h"
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
namespace testing {
// Input to a parameterized test name generator, describing a test parameter.
// Consists of the parameter value and the integer parameter index.
template <class ParamType>
struct TestParamInfo {
TestParamInfo(const ParamType& a_param, size_t an_index) :
param(a_param),
index(an_index) {}
TestParamInfo(const ParamType& a_param, size_t an_index)
: param(a_param), index(an_index) {}
ParamType param;
size_t index;
};
@@ -82,17 +87,19 @@ namespace internal {
// TEST_P macro is used to define two tests with the same name
// but in different namespaces.
GTEST_API_ void ReportInvalidTestSuiteType(const char* test_suite_name,
CodeLocation code_location);
const CodeLocation& code_location);
template <typename> class ParamGeneratorInterface;
template <typename> class ParamGenerator;
template <typename>
class ParamGeneratorInterface;
template <typename>
class ParamGenerator;
// Interface for iterating over elements provided by an implementation
// of ParamGeneratorInterface<T>.
template <typename T>
class ParamIteratorInterface {
public:
virtual ~ParamIteratorInterface() {}
virtual ~ParamIteratorInterface() = default;
// A pointer to the base generator instance.
// Used only for the purposes of iterator comparison
// to make sure that two iterators belong to the same generator.
@@ -129,8 +136,7 @@ class ParamIterator {
// ParamIterator assumes ownership of the impl_ pointer.
ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {}
ParamIterator& operator=(const ParamIterator& other) {
if (this != &other)
impl_.reset(other.impl_->Clone());
if (this != &other) impl_.reset(other.impl_->Clone());
return *this;
}
@@ -157,7 +163,7 @@ class ParamIterator {
private:
friend class ParamGenerator<T>;
explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {}
std::unique_ptr<ParamIteratorInterface<T> > impl_;
std::unique_ptr<ParamIteratorInterface<T>> impl_;
};
// ParamGeneratorInterface<T> is the binary interface to access generators
@@ -167,7 +173,7 @@ class ParamGeneratorInterface {
public:
typedef T ParamType;
virtual ~ParamGeneratorInterface() {}
virtual ~ParamGeneratorInterface() = default;
// Generator interface definition
virtual ParamIteratorInterface<T>* Begin() const = 0;
@@ -179,7 +185,7 @@ class ParamGeneratorInterface {
// This class implements copy initialization semantics and the contained
// ParamGeneratorInterface<T> instance is shared among all copies
// of the original object. This is possible because that instance is immutable.
template<typename T>
template <typename T>
class ParamGenerator {
public:
typedef ParamIterator<T> iterator;
@@ -196,7 +202,7 @@ class ParamGenerator {
iterator end() const { return iterator(impl_->End()); }
private:
std::shared_ptr<const ParamGeneratorInterface<T> > impl_;
std::shared_ptr<const ParamGeneratorInterface<T>> impl_;
};
// Generates values from a range of two comparable values. Can be used to
@@ -207,9 +213,11 @@ template <typename T, typename IncrementT>
class RangeGenerator : public ParamGeneratorInterface<T> {
public:
RangeGenerator(T begin, T end, IncrementT step)
: begin_(begin), end_(end),
step_(step), end_index_(CalculateEndIndex(begin, end, step)) {}
~RangeGenerator() override {}
: begin_(begin),
end_(end),
step_(step),
end_index_(CalculateEndIndex(begin, end, step)) {}
~RangeGenerator() override = default;
ParamIteratorInterface<T>* Begin() const override {
return new Iterator(this, begin_, 0, step_);
@@ -224,7 +232,7 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
Iterator(const ParamGeneratorInterface<T>* base, T value, int index,
IncrementT step)
: base_(base), value_(value), index_(index), step_(step) {}
~Iterator() override {}
~Iterator() override = default;
const ParamGeneratorInterface<T>* BaseGenerator() const override {
return base_;
@@ -251,7 +259,9 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
private:
Iterator(const Iterator& other)
: ParamIteratorInterface<T>(),
base_(other.base_), value_(other.value_), index_(other.index_),
base_(other.base_),
value_(other.value_),
index_(other.index_),
step_(other.step_) {}
// No implementation - assignment is unsupported.
@@ -263,12 +273,10 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
const IncrementT step_;
}; // class RangeGenerator::Iterator
static int CalculateEndIndex(const T& begin,
const T& end,
static int CalculateEndIndex(const T& begin, const T& end,
const IncrementT& step) {
int end_index = 0;
for (T i = begin; i < end; i = static_cast<T>(i + step))
end_index++;
for (T i = begin; i < end; i = static_cast<T>(i + step)) end_index++;
return end_index;
}
@@ -283,7 +291,6 @@ class RangeGenerator : public ParamGeneratorInterface<T> {
const int end_index_;
}; // class RangeGenerator
// Generates values from a pair of STL-style iterators. Used in the
// ValuesIn() function. The elements are copied from the source range
// since the source can be located on the stack, and the generator
@@ -294,7 +301,7 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
template <typename ForwardIterator>
ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end)
: container_(begin, end) {}
~ValuesInIteratorRangeGenerator() override {}
~ValuesInIteratorRangeGenerator() override = default;
ParamIteratorInterface<T>* Begin() const override {
return new Iterator(this, container_.begin());
@@ -311,7 +318,7 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
Iterator(const ParamGeneratorInterface<T>* base,
typename ContainerType::const_iterator iterator)
: base_(base), iterator_(iterator) {}
~Iterator() override {}
~Iterator() override = default;
const ParamGeneratorInterface<T>* BaseGenerator() const override {
return base_;
@@ -341,13 +348,13 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
<< "The program attempted to compare iterators "
<< "from different generators." << std::endl;
return iterator_ ==
CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
CheckedDowncastToActualType<const Iterator>(&other)->iterator_;
}
private:
Iterator(const Iterator& other)
// The explicit constructor call suppresses a false warning
// emitted by gcc when supplied with the -Wextra option.
// The explicit constructor call suppresses a false warning
// emitted by gcc when supplied with the -Wextra option.
: ParamIteratorInterface<T>(),
base_(other.base_),
iterator_(other.iterator_) {}
@@ -374,9 +381,7 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> {
// integer test parameter index.
template <class ParamType>
std::string DefaultParamName(const TestParamInfo<ParamType>& info) {
Message name_stream;
name_stream << info.index;
return name_stream.GetString();
return std::to_string(info.index);
}
template <typename T = int>
@@ -394,8 +399,8 @@ template <class TestClass>
class ParameterizedTestFactory : public TestFactoryBase {
public:
typedef typename TestClass::ParamType ParamType;
explicit ParameterizedTestFactory(ParamType parameter) :
parameter_(parameter) {}
explicit ParameterizedTestFactory(ParamType parameter)
: parameter_(parameter) {}
Test* CreateTest() override {
TestClass::SetParam(&parameter_);
return new TestClass();
@@ -404,7 +409,8 @@ class ParameterizedTestFactory : public TestFactoryBase {
private:
const ParamType parameter_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory);
ParameterizedTestFactory(const ParameterizedTestFactory&) = delete;
ParameterizedTestFactory& operator=(const ParameterizedTestFactory&) = delete;
};
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
@@ -414,7 +420,7 @@ class ParameterizedTestFactory : public TestFactoryBase {
template <class ParamType>
class TestMetaFactoryBase {
public:
virtual ~TestMetaFactoryBase() {}
virtual ~TestMetaFactoryBase() = default;
virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0;
};
@@ -433,14 +439,15 @@ class TestMetaFactory
public:
using ParamType = typename TestSuite::ParamType;
TestMetaFactory() {}
TestMetaFactory() = default;
TestFactoryBase* CreateTestFactory(ParamType parameter) override {
return new ParameterizedTestFactory<TestSuite>(parameter);
}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory);
TestMetaFactory(const TestMetaFactory&) = delete;
TestMetaFactory& operator=(const TestMetaFactory&) = delete;
};
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
@@ -455,11 +462,11 @@ class TestMetaFactory
// and calls RegisterTests() on each of them when asked.
class ParameterizedTestSuiteInfoBase {
public:
virtual ~ParameterizedTestSuiteInfoBase() {}
virtual ~ParameterizedTestSuiteInfoBase() = default;
// Base part of test suite name for display purposes.
virtual const std::string& GetTestSuiteName() const = 0;
// Test case id to verify identity.
// Test suite id to verify identity.
virtual TypeId GetTestSuiteTypeId() const = 0;
// UnitTest class invokes this method to register tests in this
// test suite right before running them in RUN_ALL_TESTS macro.
@@ -471,14 +478,17 @@ class ParameterizedTestSuiteInfoBase {
ParameterizedTestSuiteInfoBase() {}
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfoBase);
ParameterizedTestSuiteInfoBase(const ParameterizedTestSuiteInfoBase&) =
delete;
ParameterizedTestSuiteInfoBase& operator=(
const ParameterizedTestSuiteInfoBase&) = delete;
};
// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE.
//
// Report a the name of a test_suit as safe to ignore
// as the side effect of construction of this type.
struct MarkAsIgnored {
struct GTEST_API_ MarkAsIgnored {
explicit MarkAsIgnored(const char* test_suite);
};
@@ -503,15 +513,16 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
typedef ParamGenerator<ParamType>(GeneratorCreationFunc)();
using ParamNameGeneratorFunc = std::string(const TestParamInfo<ParamType>&);
explicit ParameterizedTestSuiteInfo(const char* name,
explicit ParameterizedTestSuiteInfo(std::string name,
CodeLocation code_location)
: test_suite_name_(name), code_location_(code_location) {}
: test_suite_name_(std::move(name)),
code_location_(std::move(code_location)) {}
// Test case base name for display purposes.
// Test suite base name for display purposes.
const std::string& GetTestSuiteName() const override {
return test_suite_name_;
}
// Test case id to verify identity.
// Test suite id to verify identity.
TypeId GetTestSuiteTypeId() const override { return GetTypeId<TestSuite>(); }
// TEST_P macro uses AddTestPattern() to record information
// about a single test in a LocalTestInfo structure.
@@ -519,19 +530,20 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
// prefix). test_base_name is the name of an individual test without
// parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is
// test suite base name and DoBar is test base name.
void AddTestPattern(const char* test_suite_name, const char* test_base_name,
TestMetaFactoryBase<ParamType>* meta_factory) {
tests_.push_back(std::shared_ptr<TestInfo>(
new TestInfo(test_suite_name, test_base_name, meta_factory)));
void AddTestPattern(const char*, const char* test_base_name,
TestMetaFactoryBase<ParamType>* meta_factory,
CodeLocation code_location) {
tests_.emplace_back(
new TestInfo(test_base_name, meta_factory, std::move(code_location)));
}
// INSTANTIATE_TEST_SUITE_P macro uses AddGenerator() to record information
// about a generator.
int AddTestSuiteInstantiation(const std::string& instantiation_name,
int AddTestSuiteInstantiation(std::string instantiation_name,
GeneratorCreationFunc* func,
ParamNameGeneratorFunc* name_func,
const char* file, int line) {
instantiations_.push_back(
InstantiationInfo(instantiation_name, func, name_func, file, line));
instantiations_.emplace_back(std::move(instantiation_name), func, name_func,
file, line);
return 0; // Return value used only to run this method in namespace scope.
}
// UnitTest class invokes this method to register tests in this test suite
@@ -542,116 +554,113 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
void RegisterTests() override {
bool generated_instantiations = false;
for (typename TestInfoContainer::iterator test_it = tests_.begin();
test_it != tests_.end(); ++test_it) {
std::shared_ptr<TestInfo> test_info = *test_it;
for (typename InstantiationContainer::iterator gen_it =
instantiations_.begin(); gen_it != instantiations_.end();
++gen_it) {
const std::string& instantiation_name = gen_it->name;
ParamGenerator<ParamType> generator((*gen_it->generator)());
ParamNameGeneratorFunc* name_func = gen_it->name_func;
const char* file = gen_it->file;
int line = gen_it->line;
std::string test_suite_name;
std::string test_name;
for (const std::shared_ptr<TestInfo>& test_info : tests_) {
for (const InstantiationInfo& instantiation : instantiations_) {
const std::string& instantiation_name = instantiation.name;
ParamGenerator<ParamType> generator((*instantiation.generator)());
ParamNameGeneratorFunc* name_func = instantiation.name_func;
const char* file = instantiation.file;
int line = instantiation.line;
std::string test_suite_name;
if ( !instantiation_name.empty() )
if (!instantiation_name.empty())
test_suite_name = instantiation_name + "/";
test_suite_name += test_info->test_suite_base_name;
else
test_suite_name.clear();
test_suite_name += test_suite_name_;
size_t i = 0;
std::set<std::string> test_param_names;
for (typename ParamGenerator<ParamType>::iterator param_it =
generator.begin();
param_it != generator.end(); ++param_it, ++i) {
for (const auto& param : generator) {
generated_instantiations = true;
Message test_name_stream;
test_name.clear();
std::string param_name = name_func(
TestParamInfo<ParamType>(*param_it, i));
std::string param_name =
name_func(TestParamInfo<ParamType>(param, i));
GTEST_CHECK_(IsValidParamName(param_name))
<< "Parameterized test name '" << param_name
<< "' is invalid, in " << file
<< " line " << line << std::endl;
<< "' is invalid (contains spaces, dashes, or any "
"non-alphanumeric characters other than underscores), in "
<< file << " line " << line << "" << std::endl;
GTEST_CHECK_(test_param_names.count(param_name) == 0)
<< "Duplicate parameterized test name '" << param_name
<< "', in " << file << " line " << line << std::endl;
test_param_names.insert(param_name);
<< "Duplicate parameterized test name '" << param_name << "', in "
<< file << " line " << line << std::endl;
if (!test_info->test_base_name.empty()) {
test_name_stream << test_info->test_base_name << "/";
test_name.append(test_info->test_base_name).append("/");
}
test_name_stream << param_name;
test_name += param_name;
test_param_names.insert(std::move(param_name));
MakeAndRegisterTestInfo(
test_suite_name.c_str(), test_name_stream.GetString().c_str(),
test_suite_name, test_name.c_str(),
nullptr, // No type parameter.
PrintToString(*param_it).c_str(), code_location_,
PrintToString(param).c_str(), test_info->code_location,
GetTestSuiteTypeId(),
SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
SuiteApiResolver<TestSuite>::GetTearDownCaseOrSuite(file, line),
test_info->test_meta_factory->CreateTestFactory(*param_it));
} // for param_it
} // for gen_it
} // for test_it
test_info->test_meta_factory->CreateTestFactory(param));
++i;
} // for param
} // for instantiation
} // for test_info
if (!generated_instantiations) {
// There are no generaotrs, or they all generate nothing ...
InsertSyntheticTestCase(GetTestSuiteName(), code_location_,
!tests_.empty());
}
} // RegisterTests
} // RegisterTests
private:
// LocalTestInfo structure keeps information about a single test registered
// with TEST_P macro.
struct TestInfo {
TestInfo(const char* a_test_suite_base_name, const char* a_test_base_name,
TestMetaFactoryBase<ParamType>* a_test_meta_factory)
: test_suite_base_name(a_test_suite_base_name),
test_base_name(a_test_base_name),
test_meta_factory(a_test_meta_factory) {}
TestInfo(const char* a_test_base_name,
TestMetaFactoryBase<ParamType>* a_test_meta_factory,
CodeLocation a_code_location)
: test_base_name(a_test_base_name),
test_meta_factory(a_test_meta_factory),
code_location(std::move(a_code_location)) {}
const std::string test_suite_base_name;
const std::string test_base_name;
const std::unique_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory;
const std::unique_ptr<TestMetaFactoryBase<ParamType>> test_meta_factory;
const CodeLocation code_location;
};
using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo> >;
using TestInfoContainer = ::std::vector<std::shared_ptr<TestInfo>>;
// Records data received from INSTANTIATE_TEST_SUITE_P macros:
// <Instantiation name, Sequence generator creation function,
// Name generator function, Source file, Source line>
struct InstantiationInfo {
InstantiationInfo(const std::string &name_in,
GeneratorCreationFunc* generator_in,
ParamNameGeneratorFunc* name_func_in,
const char* file_in,
int line_in)
: name(name_in),
generator(generator_in),
name_func(name_func_in),
file(file_in),
line(line_in) {}
InstantiationInfo(std::string name_in, GeneratorCreationFunc* generator_in,
ParamNameGeneratorFunc* name_func_in, const char* file_in,
int line_in)
: name(std::move(name_in)),
generator(generator_in),
name_func(name_func_in),
file(file_in),
line(line_in) {}
std::string name;
GeneratorCreationFunc* generator;
ParamNameGeneratorFunc* name_func;
const char* file;
int line;
std::string name;
GeneratorCreationFunc* generator;
ParamNameGeneratorFunc* name_func;
const char* file;
int line;
};
typedef ::std::vector<InstantiationInfo> InstantiationContainer;
static bool IsValidParamName(const std::string& name) {
// Check for empty string
if (name.empty())
return false;
if (name.empty()) return false;
// Check for invalid characters
for (std::string::size_type index = 0; index < name.size(); ++index) {
if (!isalnum(name[index]) && name[index] != '_')
return false;
if (!IsAlNum(name[index]) && name[index] != '_') return false;
}
return true;
@@ -662,7 +671,9 @@ class ParameterizedTestSuiteInfo : public ParameterizedTestSuiteInfoBase {
TestInfoContainer tests_;
InstantiationContainer instantiations_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteInfo);
ParameterizedTestSuiteInfo(const ParameterizedTestSuiteInfo&) = delete;
ParameterizedTestSuiteInfo& operator=(const ParameterizedTestSuiteInfo&) =
delete;
}; // class ParameterizedTestSuiteInfo
// Legacy API is deprecated but still available
@@ -679,7 +690,7 @@ using ParameterizedTestCaseInfo = ParameterizedTestSuiteInfo<TestCase>;
// ParameterizedTestSuiteInfo descriptors.
class ParameterizedTestSuiteRegistry {
public:
ParameterizedTestSuiteRegistry() {}
ParameterizedTestSuiteRegistry() = default;
~ParameterizedTestSuiteRegistry() {
for (auto& test_suite_info : test_suite_infos_) {
delete test_suite_info;
@@ -690,29 +701,32 @@ class ParameterizedTestSuiteRegistry {
// tests and instantiations of a particular test suite.
template <class TestSuite>
ParameterizedTestSuiteInfo<TestSuite>* GetTestSuitePatternHolder(
const char* test_suite_name, CodeLocation code_location) {
std::string test_suite_name, CodeLocation code_location) {
ParameterizedTestSuiteInfo<TestSuite>* typed_test_info = nullptr;
for (auto& test_suite_info : test_suite_infos_) {
if (test_suite_info->GetTestSuiteName() == test_suite_name) {
if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
// Complain about incorrect usage of Google Test facilities
// and terminate the program since we cannot guaranty correct
// test suite setup and tear-down in this case.
ReportInvalidTestSuiteType(test_suite_name, code_location);
posix::Abort();
} else {
// At this point we are sure that the object we found is of the same
// type we are looking for, so we downcast it to that type
// without further checks.
typed_test_info = CheckedDowncastToActualType<
ParameterizedTestSuiteInfo<TestSuite> >(test_suite_info);
}
break;
auto item_it = suite_name_to_info_index_.find(test_suite_name);
if (item_it != suite_name_to_info_index_.end()) {
auto* test_suite_info = test_suite_infos_[item_it->second];
if (test_suite_info->GetTestSuiteTypeId() != GetTypeId<TestSuite>()) {
// Complain about incorrect usage of Google Test facilities
// and terminate the program since we cannot guaranty correct
// test suite setup and tear-down in this case.
ReportInvalidTestSuiteType(test_suite_name.c_str(), code_location);
posix::Abort();
} else {
// At this point we are sure that the object we found is of the same
// type we are looking for, so we downcast it to that type
// without further checks.
typed_test_info =
CheckedDowncastToActualType<ParameterizedTestSuiteInfo<TestSuite>>(
test_suite_info);
}
}
if (typed_test_info == nullptr) {
typed_test_info = new ParameterizedTestSuiteInfo<TestSuite>(
test_suite_name, code_location);
test_suite_name, std::move(code_location));
suite_name_to_info_index_.emplace(std::move(test_suite_name),
test_suite_infos_.size());
test_suite_infos_.push_back(typed_test_info);
}
return typed_test_info;
@@ -726,8 +740,9 @@ class ParameterizedTestSuiteRegistry {
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
template <class TestCase>
ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder(
const char* test_case_name, CodeLocation code_location) {
return GetTestSuitePatternHolder<TestCase>(test_case_name, code_location);
std::string test_case_name, CodeLocation code_location) {
return GetTestSuitePatternHolder<TestCase>(std::move(test_case_name),
std::move(code_location));
}
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
@@ -736,8 +751,12 @@ class ParameterizedTestSuiteRegistry {
using TestSuiteInfoContainer = ::std::vector<ParameterizedTestSuiteInfoBase*>;
TestSuiteInfoContainer test_suite_infos_;
::std::unordered_map<std::string, size_t> suite_name_to_info_index_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestSuiteRegistry);
ParameterizedTestSuiteRegistry(const ParameterizedTestSuiteRegistry&) =
delete;
ParameterizedTestSuiteRegistry& operator=(
const ParameterizedTestSuiteRegistry&) = delete;
};
// Keep track of what type-parameterized test suite are defined and
@@ -759,7 +778,7 @@ class TypeParameterizedTestSuiteRegistry {
private:
struct TypeParameterizedTestSuiteInfo {
explicit TypeParameterizedTestSuiteInfo(CodeLocation c)
: code_location(c), instantiated(false) {}
: code_location(std::move(c)), instantiated(false) {}
CodeLocation code_location;
bool instantiated;
@@ -779,25 +798,29 @@ internal::ParamGenerator<typename Container::value_type> ValuesIn(
namespace internal {
// Used in the Values() function to provide polymorphic capabilities.
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
template <typename... Ts>
class ValueArray {
public:
ValueArray(Ts... v) : v_{std::move(v)...} {}
explicit ValueArray(Ts... v) : v_(FlatTupleConstructTag{}, std::move(v)...) {}
template <typename T>
operator ParamGenerator<T>() const { // NOLINT
return ValuesIn(MakeVector<T>(MakeIndexSequence<sizeof...(Ts)>()));
return ValuesIn(MakeVector<T>(std::make_index_sequence<sizeof...(Ts)>()));
}
private:
template <typename T, size_t... I>
std::vector<T> MakeVector(IndexSequence<I...>) const {
std::vector<T> MakeVector(std::index_sequence<I...>) const {
return std::vector<T>{static_cast<T>(v_.template Get<I>())...};
}
FlatTuple<Ts...> v_;
};
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100
template <typename... T>
class CartesianProductGenerator
: public ParamGeneratorInterface<::std::tuple<T...>> {
@@ -806,7 +829,7 @@ class CartesianProductGenerator
CartesianProductGenerator(const std::tuple<ParamGenerator<T>...>& g)
: generators_(g) {}
~CartesianProductGenerator() override {}
~CartesianProductGenerator() override = default;
ParamIteratorInterface<ParamType>* Begin() const override {
return new Iterator(this, generators_, false);
@@ -819,18 +842,19 @@ class CartesianProductGenerator
template <class I>
class IteratorImpl;
template <size_t... I>
class IteratorImpl<IndexSequence<I...>>
class IteratorImpl<std::index_sequence<I...>>
: public ParamIteratorInterface<ParamType> {
public:
IteratorImpl(const ParamGeneratorInterface<ParamType>* base,
const std::tuple<ParamGenerator<T>...>& generators, bool is_end)
const std::tuple<ParamGenerator<T>...>& generators,
bool is_end)
: base_(base),
begin_(std::get<I>(generators).begin()...),
end_(std::get<I>(generators).end()...),
current_(is_end ? end_ : begin_) {
ComputeCurrentValue();
}
~IteratorImpl() override {}
~IteratorImpl() override = default;
const ParamGeneratorInterface<ParamType>* BaseGenerator() const override {
return base_;
@@ -909,7 +933,7 @@ class CartesianProductGenerator
std::shared_ptr<ParamType> current_value_;
};
using Iterator = IteratorImpl<typename MakeIndexSequence<sizeof...(T)>::type>;
using Iterator = IteratorImpl<std::make_index_sequence<sizeof...(T)>>;
std::tuple<ParamGenerator<T>...> generators_;
};
@@ -928,7 +952,113 @@ class CartesianProductHolder {
std::tuple<Gen...> generators_;
};
template <typename From, typename To, typename Func>
class ParamGeneratorConverter : public ParamGeneratorInterface<To> {
public:
ParamGeneratorConverter(ParamGenerator<From> gen, Func converter) // NOLINT
: generator_(std::move(gen)), converter_(std::move(converter)) {}
ParamIteratorInterface<To>* Begin() const override {
return new Iterator(this, generator_.begin(), generator_.end());
}
ParamIteratorInterface<To>* End() const override {
return new Iterator(this, generator_.end(), generator_.end());
}
// Returns the std::function wrapping the user-supplied converter callable. It
// is used by the iterator (see class Iterator below) to convert the object
// (of type FROM) returned by the ParamGenerator to an object of a type that
// can be static_cast to type TO.
const Func& TypeConverter() const { return converter_; }
private:
class Iterator : public ParamIteratorInterface<To> {
public:
Iterator(const ParamGeneratorConverter* base, ParamIterator<From> it,
ParamIterator<From> end)
: base_(base), it_(it), end_(end) {
if (it_ != end_)
value_ =
std::make_shared<To>(static_cast<To>(base->TypeConverter()(*it_)));
}
~Iterator() override = default;
const ParamGeneratorInterface<To>* BaseGenerator() const override {
return base_;
}
void Advance() override {
++it_;
if (it_ != end_)
value_ =
std::make_shared<To>(static_cast<To>(base_->TypeConverter()(*it_)));
}
ParamIteratorInterface<To>* Clone() const override {
return new Iterator(*this);
}
const To* Current() const override { return value_.get(); }
bool Equals(const ParamIteratorInterface<To>& other) const override {
// Having the same base generator guarantees that the other
// 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;
const ParamIterator<From> other_it =
CheckedDowncastToActualType<const Iterator>(&other)->it_;
return it_ == other_it;
}
private:
Iterator(const Iterator& other) = default;
const ParamGeneratorConverter* const base_;
ParamIterator<From> it_;
ParamIterator<From> end_;
std::shared_ptr<To> value_;
}; // class ParamGeneratorConverter::Iterator
ParamGenerator<From> generator_;
Func converter_;
}; // class ParamGeneratorConverter
template <class GeneratedT,
typename StdFunction =
std::function<const GeneratedT&(const GeneratedT&)>>
class ParamConverterGenerator {
public:
ParamConverterGenerator(ParamGenerator<GeneratedT> g) // NOLINT
: generator_(std::move(g)), converter_(Identity) {}
ParamConverterGenerator(ParamGenerator<GeneratedT> g, StdFunction converter)
: generator_(std::move(g)), converter_(std::move(converter)) {}
template <typename T>
operator ParamGenerator<T>() const { // NOLINT
return ParamGenerator<T>(
new ParamGeneratorConverter<GeneratedT, T, StdFunction>(generator_,
converter_));
}
private:
static const GeneratedT& Identity(const GeneratedT& v) { return v; }
ParamGenerator<GeneratedT> generator_;
StdFunction converter_;
};
// Template to determine the param type of a single-param std::function.
template <typename T>
struct FuncSingleParamType;
template <typename R, typename P>
struct FuncSingleParamType<std::function<R(P)>> {
using type = std::remove_cv_t<std::remove_reference_t<P>>;
};
template <typename T>
struct IsSingleArgStdFunction : public std::false_type {};
template <typename R, typename P>
struct IsSingleArgStdFunction<std::function<R(P)>> : public std::true_type {};
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_

View File

@@ -26,86 +26,99 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The Google C++ Testing and Mocking Framework (Google Test)
//
// This header file defines the GTEST_OS_* macro.
// It is separate from gtest-port.h so that custom/gtest-port.h can include it.
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
// Determines the platform on which Google Test is compiled.
#ifdef __CYGWIN__
# define GTEST_OS_CYGWIN 1
# elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)
# define GTEST_OS_WINDOWS_MINGW 1
# define GTEST_OS_WINDOWS 1
#define GTEST_OS_CYGWIN 1
#elif defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)
#define GTEST_OS_WINDOWS_MINGW 1
#define GTEST_OS_WINDOWS 1
#elif defined _WIN32
# define GTEST_OS_WINDOWS 1
# ifdef _WIN32_WCE
# define GTEST_OS_WINDOWS_MOBILE 1
# elif defined(WINAPI_FAMILY)
# include <winapifamily.h>
# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
# define GTEST_OS_WINDOWS_DESKTOP 1
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
# define GTEST_OS_WINDOWS_PHONE 1
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
# define GTEST_OS_WINDOWS_RT 1
# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)
# define GTEST_OS_WINDOWS_PHONE 1
# define GTEST_OS_WINDOWS_TV_TITLE 1
# else
// WINAPI_FAMILY defined but no known partition matched.
// Default to desktop.
# define GTEST_OS_WINDOWS_DESKTOP 1
# endif
# else
# define GTEST_OS_WINDOWS_DESKTOP 1
# endif // _WIN32_WCE
#define GTEST_OS_WINDOWS 1
#ifdef _WIN32_WCE
#define GTEST_OS_WINDOWS_MOBILE 1
#elif defined(WINAPI_FAMILY)
#include <winapifamily.h>
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#define GTEST_OS_WINDOWS_DESKTOP 1
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
#define GTEST_OS_WINDOWS_PHONE 1
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
#define GTEST_OS_WINDOWS_RT 1
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_TV_TITLE)
#define GTEST_OS_WINDOWS_PHONE 1
#define GTEST_OS_WINDOWS_TV_TITLE 1
#elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_GAMES)
#define GTEST_OS_WINDOWS_GAMES 1
#else
// WINAPI_FAMILY defined but no known partition matched.
// Default to desktop.
#define GTEST_OS_WINDOWS_DESKTOP 1
#endif
#else
#define GTEST_OS_WINDOWS_DESKTOP 1
#endif // _WIN32_WCE
#elif defined __OS2__
# define GTEST_OS_OS2 1
#define GTEST_OS_OS2 1
#elif defined __APPLE__
# define GTEST_OS_MAC 1
# if TARGET_OS_IPHONE
# define GTEST_OS_IOS 1
# endif
#define GTEST_OS_MAC 1
#include <TargetConditionals.h>
#if TARGET_OS_IPHONE
#define GTEST_OS_IOS 1
#endif
#elif defined __DragonFly__
# define GTEST_OS_DRAGONFLY 1
#define GTEST_OS_DRAGONFLY 1
#elif defined __FreeBSD__
# define GTEST_OS_FREEBSD 1
#define GTEST_OS_FREEBSD 1
#elif defined __Fuchsia__
# define GTEST_OS_FUCHSIA 1
#define GTEST_OS_FUCHSIA 1
#elif defined(__GNU__)
#define GTEST_OS_GNU_HURD 1
#elif defined(__GLIBC__) && defined(__FreeBSD_kernel__)
# define GTEST_OS_GNU_KFREEBSD 1
#define GTEST_OS_GNU_KFREEBSD 1
#elif defined __linux__
# define GTEST_OS_LINUX 1
# if defined __ANDROID__
# define GTEST_OS_LINUX_ANDROID 1
# endif
#define GTEST_OS_LINUX 1
#if defined __ANDROID__
#define GTEST_OS_LINUX_ANDROID 1
#endif
#elif defined __MVS__
# define GTEST_OS_ZOS 1
#define GTEST_OS_ZOS 1
#elif defined(__sun) && defined(__SVR4)
# define GTEST_OS_SOLARIS 1
#define GTEST_OS_SOLARIS 1
#elif defined(_AIX)
# define GTEST_OS_AIX 1
#define GTEST_OS_AIX 1
#elif defined(__hpux)
# define GTEST_OS_HPUX 1
#define GTEST_OS_HPUX 1
#elif defined __native_client__
# define GTEST_OS_NACL 1
#define GTEST_OS_NACL 1
#elif defined __NetBSD__
# define GTEST_OS_NETBSD 1
#define GTEST_OS_NETBSD 1
#elif defined __OpenBSD__
# define GTEST_OS_OPENBSD 1
#define GTEST_OS_OPENBSD 1
#elif defined __QNX__
# define GTEST_OS_QNX 1
#define GTEST_OS_QNX 1
#elif defined(__HAIKU__)
#define GTEST_OS_HAIKU 1
#elif defined ESP8266
#define GTEST_OS_ESP8266 1
#elif defined ESP32
#define GTEST_OS_ESP32 1
#elif defined(__XTENSA__)
#define GTEST_OS_XTENSA 1
#elif defined(__hexagon__)
#define GTEST_OS_QURT 1
#elif defined(CPU_QN9090) || defined(CPU_QN9090HN)
#define GTEST_OS_NXP_QN9090 1
#elif defined(NRF52)
#define GTEST_OS_NRF52 1
#endif // __CYGWIN__
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_

File diff suppressed because it is too large Load Diff

View File

@@ -26,7 +26,7 @@
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// The Google C++ Testing and Mocking Framework (Google Test)
//
// This header file declares the String class and functions used internally by
@@ -36,18 +36,22 @@
// This header file is #included by gtest-internal.h.
// It should not be #included by other files.
// GOOGLETEST_CM0001 DO NOT DELETE
// IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#ifdef __BORLANDC__
// string.h is not guaranteed to provide strcpy on C++ Builder.
# include <mem.h>
#include <mem.h>
#endif
#include <string.h>
#include <cstdint>
#include <sstream>
#include <string>
#include "gtest/internal/gtest-port.h"
@@ -69,7 +73,7 @@ class GTEST_API_ String {
// memory using malloc().
static const char* CloneCString(const char* c_str);
#if GTEST_OS_WINDOWS_MOBILE
#ifdef GTEST_OS_WINDOWS_MOBILE
// Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
// able to pass strings to Win32 APIs on CE we need to convert them
// to 'Unicode', UTF-16.
@@ -123,8 +127,7 @@ class GTEST_API_ String {
// Unlike strcasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL C string,
// including the empty string.
static bool CaseInsensitiveCStringEquals(const char* lhs,
const char* rhs);
static bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs);
// Compares two wide C strings, ignoring case. Returns true if and only if
// they have the same content.
@@ -143,12 +146,15 @@ class GTEST_API_ String {
// Returns true if and only if the given string ends with the given suffix,
// ignoring case. Any string is considered to end with an empty suffix.
static bool EndsWithCaseInsensitive(
const std::string& str, const std::string& suffix);
static bool EndsWithCaseInsensitive(const std::string& str,
const std::string& suffix);
// Formats an int value as "%02d".
static std::string FormatIntWidth2(int value); // "%02d" for width == 2
// Formats an int value to given width with leading zeros.
static std::string FormatIntWidthN(int value, int width);
// Formats an int value as "%X".
static std::string FormatHexInt(int value);
@@ -160,7 +166,7 @@ class GTEST_API_ String {
private:
String(); // Not meant to be instantiated.
}; // class String
}; // class String
// Gets the content of the stringstream's buffer as an std::string. Each '\0'
// character in the buffer is replaced with "\\0".
@@ -169,4 +175,4 @@ GTEST_API_ std::string StringStreamToString(::std::stringstream* stream);
} // namespace internal
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_

View File

@@ -30,20 +30,26 @@
// Type utilities needed for implementing typed and type-parameterized
// tests.
// GOOGLETEST_CM0001 DO NOT DELETE
// IWYU pragma: private, include "gtest/gtest.h"
// IWYU pragma: friend gtest/.*
// IWYU pragma: friend gmock/.*
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#include <string>
#include <type_traits>
#include <typeinfo>
#include "gtest/internal/gtest-port.h"
// #ifdef __GNUC__ is too general here. It is possible to use gcc without using
// libstdc++ (which is where cxxabi.h comes from).
# if GTEST_HAS_CXXABI_H_
# include <cxxabi.h>
# elif defined(__HP_aCC)
# include <acxx_demangle.h>
# endif // GTEST_HASH_CXXABI_H_
#if GTEST_HAS_CXXABI_H_
#include <cxxabi.h>
#elif defined(__HP_aCC)
#include <acxx_demangle.h>
#endif // GTEST_HASH_CXXABI_H_
namespace testing {
namespace internal {
@@ -61,45 +67,79 @@ inline std::string CanonicalizeForStdLibVersioning(std::string s) {
s.erase(strlen("std"), end - strlen("std"));
}
}
// Strip redundant spaces in typename to match MSVC
// For example, std::pair<int, bool> -> std::pair<int,bool>
static const char to_search[] = ", ";
const char replace_char = ',';
size_t pos = 0;
while (true) {
// Get the next occurrence from the current position
pos = s.find(to_search, pos);
if (pos == std::string::npos) {
break;
}
// Replace this occurrence of substring
s.replace(pos, strlen(to_search), 1, replace_char);
++pos;
}
return s;
}
// GetTypeName<T>() returns a human-readable name of type T.
// NB: This function is also used in Google Mock, so don't move it inside of
// the typed-test-only section below.
template <typename T>
std::string GetTypeName() {
# if GTEST_HAS_RTTI
const char* const name = typeid(T).name();
# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)
#if GTEST_HAS_RTTI
// GetTypeName(const std::type_info&) returns a human-readable name of type T.
inline std::string GetTypeName(const std::type_info& type) {
const char* const name = type.name();
#if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)
int status = 0;
// gcc's implementation of typeid(T).name() mangles the type name,
// so we have to demangle it.
# if GTEST_HAS_CXXABI_H_
#if GTEST_HAS_CXXABI_H_
using abi::__cxa_demangle;
# endif // GTEST_HAS_CXXABI_H_
#endif // GTEST_HAS_CXXABI_H_
char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status);
const std::string name_str(status == 0 ? readable_name : name);
free(readable_name);
return CanonicalizeForStdLibVersioning(name_str);
# else
#elif defined(_MSC_VER)
// Strip struct and class due to differences between
// MSVC and other compilers. std::pair<int,bool> is printed as
// "struct std::pair<int,bool>" when using MSVC vs "std::pair<int, bool>" with
// other compilers.
std::string s = name;
// Only strip the leading "struct " and "class ", so uses rfind == 0 to
// ensure that
if (s.rfind("struct ", 0) == 0) {
s = s.substr(strlen("struct "));
} else if (s.rfind("class ", 0) == 0) {
s = s.substr(strlen("class "));
}
return s;
#else
return name;
# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC
# else
return "<type>";
# endif // GTEST_HAS_RTTI
#endif // GTEST_HAS_CXXABI_H_ || __HP_aCC
}
#endif // GTEST_HAS_RTTI
#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
// GetTypeName<T>() returns a human-readable name of type T if and only if
// RTTI is enabled, otherwise it returns a dummy type name.
// NB: This function is also used in Google Mock, so don't move it inside of
// the typed-test-only section below.
template <typename T>
std::string GetTypeName() {
#if GTEST_HAS_RTTI
return GetTypeName(typeid(T));
#else
return "<type>";
#endif // GTEST_HAS_RTTI
}
// A unique type indicating an empty node
struct None {};
# define GTEST_TEMPLATE_ template <typename T> class
#define GTEST_TEMPLATE_ \
template <typename T> \
class
// The template "selector" struct TemplateSel<Tmpl> is used to
// represent Tmpl, which must be a class template with one type
@@ -117,8 +157,7 @@ struct TemplateSel {
};
};
# define GTEST_BIND_(TmplSel, T) \
TmplSel::template Bind<T>::type
#define GTEST_BIND_(TmplSel, T) TmplSel::template Bind<T>::type
template <GTEST_TEMPLATE_ Head_, GTEST_TEMPLATE_... Tail_>
struct Templates {
@@ -171,8 +210,6 @@ struct GenerateTypeList {
using type = typename proxy::type;
};
#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P
} // namespace internal
template <typename... Ts>
@@ -180,4 +217,4 @@ using Types = internal::ProxyTypeList<Ts...>;
} // namespace testing
#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_

View File

@@ -38,7 +38,7 @@
#include "gtest/gtest.h"
// The following lines pull in the real gtest *.cc files.
#include "src/gtest.cc"
#include "src/gtest-assertion-result.cc"
#include "src/gtest-death-test.cc"
#include "src/gtest-filepath.cc"
#include "src/gtest-matchers.cc"
@@ -46,3 +46,4 @@
#include "src/gtest-printers.cc"
#include "src/gtest-test-part.cc"
#include "src/gtest-typed-test.cc"
#include "src/gtest.cc"

View File

@@ -0,0 +1,77 @@
// Copyright 2005, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// The Google C++ Testing and Mocking Framework (Google Test)
//
// This file defines the AssertionResult type.
#include "gtest/gtest-assertion-result.h"
#include <string>
#include <utility>
#include "gtest/gtest-message.h"
namespace testing {
// AssertionResult constructors.
// Used in EXPECT_TRUE/FALSE(assertion_result).
AssertionResult::AssertionResult(const AssertionResult& other)
: success_(other.success_),
message_(other.message_ != nullptr
? new ::std::string(*other.message_)
: static_cast< ::std::string*>(nullptr)) {}
// Swaps two AssertionResults.
void AssertionResult::swap(AssertionResult& other) {
using std::swap;
swap(success_, other.success_);
swap(message_, other.message_);
}
// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE.
AssertionResult AssertionResult::operator!() const {
AssertionResult negation(!success_);
if (message_ != nullptr) negation << *message_;
return negation;
}
// Makes a successful assertion result.
AssertionResult AssertionSuccess() { return AssertionResult(true); }
// Makes a failed assertion result.
AssertionResult AssertionFailure() { return AssertionResult(false); }
// Makes a failed assertion result with the given failure message.
// Deprecated; use AssertionFailure() << message.
AssertionResult AssertionFailure(const Message& message) {
return AssertionFailure() << message;
}
} // namespace testing

File diff suppressed because it is too large Load Diff

View File

@@ -30,35 +30,42 @@
#include "gtest/internal/gtest-filepath.h"
#include <stdlib.h>
#include "gtest/internal/gtest-port.h"
#include "gtest/gtest-message.h"
#if GTEST_OS_WINDOWS_MOBILE
# include <windows.h>
#elif GTEST_OS_WINDOWS
# include <direct.h>
# include <io.h>
#include <iterator>
#include <string>
#include "gtest/gtest-message.h"
#include "gtest/internal/gtest-port.h"
#ifdef GTEST_OS_WINDOWS_MOBILE
#include <windows.h>
#elif defined(GTEST_OS_WINDOWS)
#include <direct.h>
#include <io.h>
#else
# include <limits.h>
# include <climits> // Some Linux distributions define PATH_MAX here.
#endif // GTEST_OS_WINDOWS_MOBILE
#include <limits.h>
#include <climits> // Some Linux distributions define PATH_MAX here.
#endif // GTEST_OS_WINDOWS_MOBILE
#include "gtest/internal/gtest-string.h"
#if GTEST_OS_WINDOWS
# define GTEST_PATH_MAX_ _MAX_PATH
#ifdef GTEST_OS_WINDOWS
#define GTEST_PATH_MAX_ _MAX_PATH
#elif defined(PATH_MAX)
# define GTEST_PATH_MAX_ PATH_MAX
#define GTEST_PATH_MAX_ PATH_MAX
#elif defined(_XOPEN_PATH_MAX)
# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
#define GTEST_PATH_MAX_ _XOPEN_PATH_MAX
#else
# define GTEST_PATH_MAX_ _POSIX_PATH_MAX
#define GTEST_PATH_MAX_ _POSIX_PATH_MAX
#endif // GTEST_OS_WINDOWS
#if GTEST_HAS_FILE_SYSTEM
namespace testing {
namespace internal {
#if GTEST_OS_WINDOWS
#ifdef GTEST_OS_WINDOWS
// On Windows, '\\' is the standard path separator, but many tools and the
// Windows API also accept '/' as an alternate path separator. Unless otherwise
// noted, a file path can contain either kind of path separators, or a mixture
@@ -66,16 +73,16 @@ namespace internal {
const char kPathSeparator = '\\';
const char kAlternatePathSeparator = '/';
const char kAlternatePathSeparatorString[] = "/";
# if GTEST_OS_WINDOWS_MOBILE
#ifdef GTEST_OS_WINDOWS_MOBILE
// Windows CE doesn't have a current directory. You should not use
// the current directory in tests on Windows CE, but this at least
// provides a reasonable fallback.
const char kCurrentDirectoryString[] = "\\";
// Windows CE doesn't define INVALID_FILE_ATTRIBUTES
const DWORD kInvalidFileAttributes = 0xffffffff;
# else
#else
const char kCurrentDirectoryString[] = ".\\";
# endif // GTEST_OS_WINDOWS_MOBILE
#endif // GTEST_OS_WINDOWS_MOBILE
#else
const char kPathSeparator = '/';
const char kCurrentDirectoryString[] = "./";
@@ -92,23 +99,26 @@ static bool IsPathSeparator(char c) {
// Returns the current working directory, or "" if unsuccessful.
FilePath FilePath::GetCurrentDir() {
#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \
GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_ESP32
#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_WINDOWS_PHONE) || \
defined(GTEST_OS_WINDOWS_RT) || defined(GTEST_OS_ESP8266) || \
defined(GTEST_OS_ESP32) || defined(GTEST_OS_XTENSA) || \
defined(GTEST_OS_QURT) || defined(GTEST_OS_NXP_QN9090) || \
defined(GTEST_OS_NRF52)
// These platforms do not have a current directory, so we just return
// something reasonable.
return FilePath(kCurrentDirectoryString);
#elif GTEST_OS_WINDOWS
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
#elif defined(GTEST_OS_WINDOWS)
char cwd[GTEST_PATH_MAX_ + 1] = {'\0'};
return FilePath(_getcwd(cwd, sizeof(cwd)) == nullptr ? "" : cwd);
#else
char cwd[GTEST_PATH_MAX_ + 1] = { '\0' };
char cwd[GTEST_PATH_MAX_ + 1] = {'\0'};
char* result = getcwd(cwd, sizeof(cwd));
# if GTEST_OS_NACL
#ifdef GTEST_OS_NACL
// getcwd will likely fail in NaCl due to the sandbox, so return something
// reasonable. The user may have provided a shim implementation for getcwd,
// however, so fallback only when failure is detected.
return FilePath(result == nullptr ? kCurrentDirectoryString : cwd);
# endif // GTEST_OS_NACL
#endif // GTEST_OS_NACL
return FilePath(result == nullptr ? "" : cwd);
#endif // GTEST_OS_WINDOWS_MOBILE
}
@@ -120,8 +130,8 @@ FilePath FilePath::GetCurrentDir() {
FilePath FilePath::RemoveExtension(const char* extension) const {
const std::string dot_extension = std::string(".") + extension;
if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) {
return FilePath(pathname_.substr(
0, pathname_.length() - dot_extension.length()));
return FilePath(
pathname_.substr(0, pathname_.length() - dot_extension.length()));
}
return *this;
}
@@ -142,6 +152,44 @@ const char* FilePath::FindLastPathSeparator() const {
return last_sep;
}
size_t FilePath::CalculateRootLength() const {
const auto& path = pathname_;
auto s = path.begin();
auto end = path.end();
#ifdef GTEST_OS_WINDOWS
if (end - s >= 2 && s[1] == ':' && (end - s == 2 || IsPathSeparator(s[2])) &&
(('A' <= s[0] && s[0] <= 'Z') || ('a' <= s[0] && s[0] <= 'z'))) {
// A typical absolute path like "C:\Windows" or "D:"
s += 2;
if (s != end) {
++s;
}
} else if (end - s >= 3 && IsPathSeparator(*s) && IsPathSeparator(*(s + 1)) &&
!IsPathSeparator(*(s + 2))) {
// Move past the "\\" prefix in a UNC path like "\\Server\Share\Folder"
s += 2;
// Skip 2 components and their following separators ("Server\" and "Share\")
for (int i = 0; i < 2; ++i) {
while (s != end) {
bool stop = IsPathSeparator(*s);
++s;
if (stop) {
break;
}
}
}
} else if (s != end && IsPathSeparator(*s)) {
// A drive-rooted path like "\Windows"
++s;
}
#else
if (s != end && IsPathSeparator(*s)) {
++s;
}
#endif
return static_cast<size_t>(s - path.begin());
}
// Returns a copy of the FilePath with the directory part removed.
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
@@ -177,15 +225,14 @@ FilePath FilePath::RemoveFileName() const {
// than zero (e.g., 12), returns "dir/test_12.xml".
// On Windows platform, uses \ as the separator rather than /.
FilePath FilePath::MakeFileName(const FilePath& directory,
const FilePath& base_name,
int number,
const FilePath& base_name, int number,
const char* extension) {
std::string file;
if (number == 0) {
file = base_name.string() + "." + extension;
} else {
file = base_name.string() + "_" + StreamableToString(number)
+ "." + extension;
file =
base_name.string() + "_" + StreamableToString(number) + "." + extension;
}
return ConcatPaths(directory, FilePath(file));
}
@@ -194,8 +241,7 @@ FilePath FilePath::MakeFileName(const FilePath& directory,
// On Windows, uses \ as the separator rather than /.
FilePath FilePath::ConcatPaths(const FilePath& directory,
const FilePath& relative_path) {
if (directory.IsEmpty())
return relative_path;
if (directory.IsEmpty()) return relative_path;
const FilePath dir(directory.RemoveTrailingPathSeparator());
return FilePath(dir.string() + kPathSeparator + relative_path.string());
}
@@ -203,13 +249,13 @@ FilePath FilePath::ConcatPaths(const FilePath& directory,
// Returns true if pathname describes something findable in the file-system,
// either a file, directory, or whatever.
bool FilePath::FileOrDirectoryExists() const {
#if GTEST_OS_WINDOWS_MOBILE
#ifdef GTEST_OS_WINDOWS_MOBILE
LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str());
const DWORD attributes = GetFileAttributes(unicode);
delete [] unicode;
delete[] unicode;
return attributes != kInvalidFileAttributes;
#else
posix::StatStruct file_stat;
posix::StatStruct file_stat{};
return posix::Stat(pathname_.c_str(), &file_stat) == 0;
#endif // GTEST_OS_WINDOWS_MOBILE
}
@@ -218,55 +264,42 @@ bool FilePath::FileOrDirectoryExists() const {
// that exists.
bool FilePath::DirectoryExists() const {
bool result = false;
#if GTEST_OS_WINDOWS
#ifdef GTEST_OS_WINDOWS
// Don't strip off trailing separator if path is a root directory on
// Windows (like "C:\\").
const FilePath& path(IsRootDirectory() ? *this :
RemoveTrailingPathSeparator());
const FilePath& path(IsRootDirectory() ? *this
: RemoveTrailingPathSeparator());
#else
const FilePath& path(*this);
#endif
#if GTEST_OS_WINDOWS_MOBILE
#ifdef GTEST_OS_WINDOWS_MOBILE
LPCWSTR unicode = String::AnsiToUtf16(path.c_str());
const DWORD attributes = GetFileAttributes(unicode);
delete [] unicode;
delete[] unicode;
if ((attributes != kInvalidFileAttributes) &&
(attributes & FILE_ATTRIBUTE_DIRECTORY)) {
result = true;
}
#else
posix::StatStruct file_stat;
result = posix::Stat(path.c_str(), &file_stat) == 0 &&
posix::IsDir(file_stat);
posix::StatStruct file_stat{};
result =
posix::Stat(path.c_str(), &file_stat) == 0 && posix::IsDir(file_stat);
#endif // GTEST_OS_WINDOWS_MOBILE
return result;
}
// Returns true if pathname describes a root directory. (Windows has one
// root directory per disk drive.)
// root directory per disk drive. UNC share roots are also included.)
bool FilePath::IsRootDirectory() const {
#if GTEST_OS_WINDOWS
return pathname_.length() == 3 && IsAbsolutePath();
#else
return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]);
#endif
size_t root_length = CalculateRootLength();
return root_length > 0 && root_length == pathname_.size() &&
IsPathSeparator(pathname_[root_length - 1]);
}
// Returns true if pathname describes an absolute path.
bool FilePath::IsAbsolutePath() const {
const char* const name = pathname_.c_str();
#if GTEST_OS_WINDOWS
return pathname_.length() >= 3 &&
((name[0] >= 'a' && name[0] <= 'z') ||
(name[0] >= 'A' && name[0] <= 'Z')) &&
name[1] == ':' &&
IsPathSeparator(name[2]);
#else
return IsPathSeparator(name[0]);
#endif
}
bool FilePath::IsAbsolutePath() const { return CalculateRootLength() > 0; }
// Returns a pathname for a file that does not currently exist. The pathname
// will be directory/base_name.extension or
@@ -303,7 +336,7 @@ bool FilePath::CreateDirectoriesRecursively() const {
return false;
}
if (pathname_.length() == 0 || this->DirectoryExists()) {
if (pathname_.empty() || this->DirectoryExists()) {
return true;
}
@@ -316,14 +349,16 @@ bool FilePath::CreateDirectoriesRecursively() const {
// directory for any reason, including if the parent directory does not
// exist. Not named "CreateDirectory" because that's a macro on Windows.
bool FilePath::CreateFolder() const {
#if GTEST_OS_WINDOWS_MOBILE
#ifdef GTEST_OS_WINDOWS_MOBILE
FilePath removed_sep(this->RemoveTrailingPathSeparator());
LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str());
int result = CreateDirectory(unicode, nullptr) ? 0 : -1;
delete [] unicode;
#elif GTEST_OS_WINDOWS
delete[] unicode;
#elif defined(GTEST_OS_WINDOWS)
int result = _mkdir(pathname_.c_str());
#elif GTEST_OS_ESP8266
#elif defined(GTEST_OS_ESP8266) || defined(GTEST_OS_XTENSA) || \
defined(GTEST_OS_QURT) || defined(GTEST_OS_NXP_QN9090) || \
defined(GTEST_OS_NRF52)
// do nothing
int result = 0;
#else
@@ -340,43 +375,40 @@ bool FilePath::CreateFolder() const {
// name, otherwise return the name string unmodified.
// On Windows platform, uses \ as the separator, other platforms use /.
FilePath FilePath::RemoveTrailingPathSeparator() const {
return IsDirectory()
? FilePath(pathname_.substr(0, pathname_.length() - 1))
: *this;
return IsDirectory() ? FilePath(pathname_.substr(0, pathname_.length() - 1))
: *this;
}
// Removes any redundant separators that might be in the pathname.
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
// redundancies that might be in a pathname involving "." or "..".
// Note that "\\Host\Share" does not contain a redundancy on Windows!
void FilePath::Normalize() {
if (pathname_.c_str() == nullptr) {
pathname_ = "";
return;
}
const char* src = pathname_.c_str();
char* const dest = new char[pathname_.length() + 1];
char* dest_ptr = dest;
memset(dest_ptr, 0, pathname_.length() + 1);
auto out = pathname_.begin();
while (*src != '\0') {
*dest_ptr = *src;
if (!IsPathSeparator(*src)) {
src++;
} else {
#if GTEST_HAS_ALT_PATH_SEP_
if (*dest_ptr == kAlternatePathSeparator) {
*dest_ptr = kPathSeparator;
}
#endif
while (IsPathSeparator(*src))
src++;
}
dest_ptr++;
auto i = pathname_.cbegin();
#ifdef GTEST_OS_WINDOWS
// UNC paths are treated specially
if (pathname_.end() - i >= 3 && IsPathSeparator(*i) &&
IsPathSeparator(*(i + 1)) && !IsPathSeparator(*(i + 2))) {
*(out++) = kPathSeparator;
*(out++) = kPathSeparator;
}
*dest_ptr = '\0';
pathname_ = dest;
delete[] dest;
#endif
while (i != pathname_.end()) {
const char character = *i;
if (!IsPathSeparator(character)) {
*(out++) = character;
} else if (out == pathname_.begin() || *std::prev(out) != kPathSeparator) {
*(out++) = kPathSeparator;
}
++i;
}
pathname_.erase(out, pathname_.end());
}
} // namespace internal
} // namespace testing
#endif // GTEST_HAS_FILE_SYSTEM

View File

@@ -31,11 +31,11 @@
// This file contains purely Google Test's internal implementation. Please
// DO NOT #INCLUDE IT IN A USER PROGRAM.
#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_
#define GTEST_SRC_GTEST_INTERNAL_INL_H_
#ifndef GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_
#define GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_
#ifndef _WIN32_WCE
# include <errno.h>
#include <errno.h>
#endif // !_WIN32_WCE
#include <stddef.h>
#include <stdlib.h> // For strtoll/_strtoul64/malloc/free.
@@ -44,28 +44,28 @@
#include <algorithm>
#include <cstdint>
#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>
#include "gtest/internal/gtest-port.h"
#if GTEST_CAN_STREAM_RESULTS_
# include <arpa/inet.h> // NOLINT
# include <netdb.h> // NOLINT
#include <arpa/inet.h> // NOLINT
#include <netdb.h> // NOLINT
#endif
#if GTEST_OS_WINDOWS
# include <windows.h> // NOLINT
#endif // GTEST_OS_WINDOWS
#ifdef GTEST_OS_WINDOWS
#include <windows.h> // NOLINT
#endif // GTEST_OS_WINDOWS
#include "gtest/gtest.h"
#include "gtest/gtest-spi.h"
#include "gtest/gtest.h"
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */)
namespace testing {
// Declares the flags.
//
// We don't want the users to modify this flag in the code, but want
@@ -73,30 +73,13 @@ namespace testing {
// declare it here as opposed to in gtest.h.
GTEST_DECLARE_bool_(death_test_use_fork);
namespace testing {
namespace internal {
// The value of GetTestTypeId() as seen from within the Google Test
// library. This is solely for testing GetTestTypeId().
GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest;
// Names of the flags (needed for parsing Google Test flags).
const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests";
const char kBreakOnFailureFlag[] = "break_on_failure";
const char kCatchExceptionsFlag[] = "catch_exceptions";
const char kColorFlag[] = "color";
const char kFilterFlag[] = "filter";
const char kListTestsFlag[] = "list_tests";
const char kOutputFlag[] = "output";
const char kPrintTimeFlag[] = "print_time";
const char kPrintUTF8Flag[] = "print_utf8";
const char kRandomSeedFlag[] = "random_seed";
const char kRepeatFlag[] = "repeat";
const char kShuffleFlag[] = "shuffle";
const char kStackTraceDepthFlag[] = "stack_trace_depth";
const char kStreamResultToFlag[] = "stream_result_to";
const char kThrowOnFailureFlag[] = "throw_on_failure";
const char kFlagfileFlag[] = "flagfile";
// A valid random seed must be in [1, kMaxRandomSeed].
const int kMaxRandomSeed = 99999;
@@ -110,7 +93,8 @@ GTEST_API_ TimeInMillis GetTimeInMillis();
// Returns true if and only if Google Test should use colors in the output.
GTEST_API_ bool ShouldUseColor(bool stdout_is_tty);
// Formats the given time in milliseconds as seconds.
// Formats the given time in milliseconds as seconds. If the input is an exact N
// seconds, the output has a trailing decimal point (e.g., "N." instead of "N").
GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms);
// Converts the given time in milliseconds to a date string in the ISO 8601
@@ -123,21 +107,21 @@ GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms);
//
// On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value.
GTEST_API_ bool ParseInt32Flag(
const char* str, const char* flag, int32_t* value);
GTEST_API_ bool ParseFlag(const char* str, const char* flag, int32_t* value);
// Returns a random seed in range [1, kMaxRandomSeed] based on the
// given --gtest_random_seed flag value.
inline int GetRandomSeedFromFlag(int32_t random_seed_flag) {
const unsigned int raw_seed = (random_seed_flag == 0) ?
static_cast<unsigned int>(GetTimeInMillis()) :
static_cast<unsigned int>(random_seed_flag);
const unsigned int raw_seed =
(random_seed_flag == 0) ? static_cast<unsigned int>(GetTimeInMillis())
: static_cast<unsigned int>(random_seed_flag);
// Normalizes the actual seed to range [1, kMaxRandomSeed] such that
// it's easy to type.
const int normalized_seed =
static_cast<int>((raw_seed - 1U) %
static_cast<unsigned int>(kMaxRandomSeed)) + 1;
static_cast<unsigned int>(kMaxRandomSeed)) +
1;
return normalized_seed;
}
@@ -158,46 +142,54 @@ class GTestFlagSaver {
public:
// The c'tor.
GTestFlagSaver() {
also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests);
break_on_failure_ = GTEST_FLAG(break_on_failure);
catch_exceptions_ = GTEST_FLAG(catch_exceptions);
color_ = GTEST_FLAG(color);
death_test_style_ = GTEST_FLAG(death_test_style);
death_test_use_fork_ = GTEST_FLAG(death_test_use_fork);
filter_ = GTEST_FLAG(filter);
internal_run_death_test_ = GTEST_FLAG(internal_run_death_test);
list_tests_ = GTEST_FLAG(list_tests);
output_ = GTEST_FLAG(output);
print_time_ = GTEST_FLAG(print_time);
print_utf8_ = GTEST_FLAG(print_utf8);
random_seed_ = GTEST_FLAG(random_seed);
repeat_ = GTEST_FLAG(repeat);
shuffle_ = GTEST_FLAG(shuffle);
stack_trace_depth_ = GTEST_FLAG(stack_trace_depth);
stream_result_to_ = GTEST_FLAG(stream_result_to);
throw_on_failure_ = GTEST_FLAG(throw_on_failure);
also_run_disabled_tests_ = GTEST_FLAG_GET(also_run_disabled_tests);
break_on_failure_ = GTEST_FLAG_GET(break_on_failure);
catch_exceptions_ = GTEST_FLAG_GET(catch_exceptions);
color_ = GTEST_FLAG_GET(color);
death_test_style_ = GTEST_FLAG_GET(death_test_style);
death_test_use_fork_ = GTEST_FLAG_GET(death_test_use_fork);
fail_fast_ = GTEST_FLAG_GET(fail_fast);
filter_ = GTEST_FLAG_GET(filter);
internal_run_death_test_ = GTEST_FLAG_GET(internal_run_death_test);
list_tests_ = GTEST_FLAG_GET(list_tests);
output_ = GTEST_FLAG_GET(output);
brief_ = GTEST_FLAG_GET(brief);
print_time_ = GTEST_FLAG_GET(print_time);
print_utf8_ = GTEST_FLAG_GET(print_utf8);
random_seed_ = GTEST_FLAG_GET(random_seed);
repeat_ = GTEST_FLAG_GET(repeat);
recreate_environments_when_repeating_ =
GTEST_FLAG_GET(recreate_environments_when_repeating);
shuffle_ = GTEST_FLAG_GET(shuffle);
stack_trace_depth_ = GTEST_FLAG_GET(stack_trace_depth);
stream_result_to_ = GTEST_FLAG_GET(stream_result_to);
throw_on_failure_ = GTEST_FLAG_GET(throw_on_failure);
}
// The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS.
~GTestFlagSaver() {
GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_;
GTEST_FLAG(break_on_failure) = break_on_failure_;
GTEST_FLAG(catch_exceptions) = catch_exceptions_;
GTEST_FLAG(color) = color_;
GTEST_FLAG(death_test_style) = death_test_style_;
GTEST_FLAG(death_test_use_fork) = death_test_use_fork_;
GTEST_FLAG(filter) = filter_;
GTEST_FLAG(internal_run_death_test) = internal_run_death_test_;
GTEST_FLAG(list_tests) = list_tests_;
GTEST_FLAG(output) = output_;
GTEST_FLAG(print_time) = print_time_;
GTEST_FLAG(print_utf8) = print_utf8_;
GTEST_FLAG(random_seed) = random_seed_;
GTEST_FLAG(repeat) = repeat_;
GTEST_FLAG(shuffle) = shuffle_;
GTEST_FLAG(stack_trace_depth) = stack_trace_depth_;
GTEST_FLAG(stream_result_to) = stream_result_to_;
GTEST_FLAG(throw_on_failure) = throw_on_failure_;
GTEST_FLAG_SET(also_run_disabled_tests, also_run_disabled_tests_);
GTEST_FLAG_SET(break_on_failure, break_on_failure_);
GTEST_FLAG_SET(catch_exceptions, catch_exceptions_);
GTEST_FLAG_SET(color, color_);
GTEST_FLAG_SET(death_test_style, death_test_style_);
GTEST_FLAG_SET(death_test_use_fork, death_test_use_fork_);
GTEST_FLAG_SET(filter, filter_);
GTEST_FLAG_SET(fail_fast, fail_fast_);
GTEST_FLAG_SET(internal_run_death_test, internal_run_death_test_);
GTEST_FLAG_SET(list_tests, list_tests_);
GTEST_FLAG_SET(output, output_);
GTEST_FLAG_SET(brief, brief_);
GTEST_FLAG_SET(print_time, print_time_);
GTEST_FLAG_SET(print_utf8, print_utf8_);
GTEST_FLAG_SET(random_seed, random_seed_);
GTEST_FLAG_SET(repeat, repeat_);
GTEST_FLAG_SET(recreate_environments_when_repeating,
recreate_environments_when_repeating_);
GTEST_FLAG_SET(shuffle, shuffle_);
GTEST_FLAG_SET(stack_trace_depth, stack_trace_depth_);
GTEST_FLAG_SET(stream_result_to, stream_result_to_);
GTEST_FLAG_SET(throw_on_failure, throw_on_failure_);
}
private:
@@ -208,19 +200,22 @@ class GTestFlagSaver {
std::string color_;
std::string death_test_style_;
bool death_test_use_fork_;
bool fail_fast_;
std::string filter_;
std::string internal_run_death_test_;
bool list_tests_;
std::string output_;
bool brief_;
bool print_time_;
bool print_utf8_;
int32_t random_seed_;
int32_t repeat_;
bool recreate_environments_when_repeating_;
bool shuffle_;
int32_t stack_trace_depth_;
std::string stream_result_to_;
bool throw_on_failure_;
} GTEST_ATTRIBUTE_UNUSED_;
};
// Converts a Unicode code point to a narrow string in UTF-8 encoding.
// code_point parameter is of type UInt32 because wchar_t may not be
@@ -270,8 +265,8 @@ GTEST_API_ int32_t Int32FromEnvOrDie(const char* env_var, int32_t default_val);
// returns true if and only if the test should be run on this shard. The test id
// is some arbitrary but unique non-negative integer assigned to each test
// method. Assumes that 0 <= shard_index < total_shards.
GTEST_API_ bool ShouldRunTestOnShard(
int total_shards, int shard_index, int test_id);
GTEST_API_ bool ShouldRunTestOnShard(int total_shards, int shard_index,
int test_id);
// STL container utilities.
@@ -282,9 +277,8 @@ inline int CountIf(const Container& c, Predicate predicate) {
// Implemented as an explicit loop since std::count_if() in libCstd on
// Solaris has a non-standard signature.
int count = 0;
for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) {
if (predicate(*it))
++count;
for (auto it = c.begin(); it != c.end(); ++it) {
if (predicate(*it)) ++count;
}
return count;
}
@@ -319,7 +313,7 @@ void ShuffleRange(internal::Random* random, int begin, int end,
<< begin << ", " << size << "].";
// Fisher-Yates shuffle, from
// http://en.wikipedia.org/wiki/Fisher-Yates_shuffle
// https://en.wikipedia.org/wiki/Fisher-Yates_shuffle
for (int range_width = end - begin; range_width >= 2; range_width--) {
const int last_in_range = begin + range_width - 1;
const int selected =
@@ -386,25 +380,18 @@ class GTEST_API_ UnitTestOptions {
// Functions for processing the gtest_filter flag.
// Returns true if and only if the wildcard pattern matches the string.
// The first ':' or '\0' character in pattern marks the end of it.
//
// This recursive algorithm isn't very efficient, but is clear and
// works well enough for matching test names, which are short.
static bool PatternMatchesString(const char *pattern, const char *str);
// Returns true if and only if the user-specified filter matches the test
// suite name and the test name.
static bool FilterMatchesTest(const std::string& test_suite_name,
const std::string& test_name);
#if GTEST_OS_WINDOWS
#ifdef GTEST_OS_WINDOWS
// Function for supporting the gtest_catch_exception flag.
// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the
// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise.
// Returns EXCEPTION_EXECUTE_HANDLER if given SEH exception was handled, or
// EXCEPTION_CONTINUE_SEARCH otherwise.
// This function is useful as an __except condition.
static int GTestShouldProcessSEH(DWORD exception_code);
static int GTestProcessSEH(DWORD seh_code, const char* location);
#endif // GTEST_OS_WINDOWS
// Returns true if "name" matches the ':' separated list of glob-style
@@ -412,15 +399,17 @@ class GTEST_API_ UnitTestOptions {
static bool MatchesFilter(const std::string& name, const char* filter);
};
#if GTEST_HAS_FILE_SYSTEM
// Returns the current application's name, removing directory path if that
// is present. Used by UnitTestOptions::GetOutputFile.
GTEST_API_ FilePath GetCurrentExecutableName();
#endif // GTEST_HAS_FILE_SYSTEM
// The role interface for getting the OS stack trace as a string.
class OsStackTraceGetterInterface {
public:
OsStackTraceGetterInterface() {}
virtual ~OsStackTraceGetterInterface() {}
OsStackTraceGetterInterface() = default;
virtual ~OsStackTraceGetterInterface() = default;
// Returns the current OS stack trace as an std::string. Parameters:
//
@@ -440,19 +429,21 @@ class OsStackTraceGetterInterface {
static const char* const kElidedFramesMarker;
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface);
OsStackTraceGetterInterface(const OsStackTraceGetterInterface&) = delete;
OsStackTraceGetterInterface& operator=(const OsStackTraceGetterInterface&) =
delete;
};
// A working implementation of the OsStackTraceGetterInterface interface.
class OsStackTraceGetter : public OsStackTraceGetterInterface {
public:
OsStackTraceGetter() {}
OsStackTraceGetter() = default;
std::string CurrentStackTrace(int max_depth, int skip_count) override;
void UponLeavingGTest() override;
private:
#if GTEST_HAS_ABSL
#ifdef GTEST_HAS_ABSL
Mutex mutex_; // Protects all internal state.
// We save the stack frame below the frame that calls user code.
@@ -462,7 +453,8 @@ class OsStackTraceGetter : public OsStackTraceGetterInterface {
void* caller_frame_ = nullptr;
#endif // GTEST_HAS_ABSL
GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter);
OsStackTraceGetter(const OsStackTraceGetter&) = delete;
OsStackTraceGetter& operator=(const OsStackTraceGetter&) = delete;
};
// Information about a Google Test trace point.
@@ -475,7 +467,7 @@ struct TraceInfo {
// This is the default global test part result reporter used in UnitTestImpl.
// This class should only be used by UnitTestImpl.
class DefaultGlobalTestPartResultReporter
: public TestPartResultReporterInterface {
: public TestPartResultReporterInterface {
public:
explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test);
// Implements the TestPartResultReporterInterface. Reports the test part
@@ -485,7 +477,10 @@ class DefaultGlobalTestPartResultReporter
private:
UnitTestImpl* const unit_test_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter);
DefaultGlobalTestPartResultReporter(
const DefaultGlobalTestPartResultReporter&) = delete;
DefaultGlobalTestPartResultReporter& operator=(
const DefaultGlobalTestPartResultReporter&) = delete;
};
// This is the default per thread test part result reporter used in
@@ -501,7 +496,10 @@ class DefaultPerThreadTestPartResultReporter
private:
UnitTestImpl* const unit_test_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter);
DefaultPerThreadTestPartResultReporter(
const DefaultPerThreadTestPartResultReporter&) = delete;
DefaultPerThreadTestPartResultReporter& operator=(
const DefaultPerThreadTestPartResultReporter&) = delete;
};
// The private implementation of the UnitTest class. We don't protect
@@ -514,9 +512,9 @@ class GTEST_API_ UnitTestImpl {
virtual ~UnitTestImpl();
// There are two different ways to register your own TestPartResultReporter.
// You can register your own repoter to listen either only for test results
// You can register your own reporter to listen either only for test results
// from the current thread or for results from all threads.
// By default, each per-thread test result repoter just passes a new
// By default, each per-thread test result reporter just passes a new
// TestPartResult to the global test result reporter, which registers the
// test part result for the currently running test.
@@ -639,7 +637,8 @@ class GTEST_API_ UnitTestImpl {
// For example, if Foo() calls Bar(), which in turn calls
// CurrentOsStackTraceExceptTop(1), Foo() will be included in the
// trace but Bar() and CurrentOsStackTraceExceptTop() won't.
std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_;
std::string CurrentOsStackTraceExceptTop(int skip_count)
GTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_;
// Finds and returns a TestSuite with the given name. If one doesn't
// exist, creates one and returns it.
@@ -647,17 +646,19 @@ class GTEST_API_ UnitTestImpl {
// Arguments:
//
// test_suite_name: name of the test suite
// type_param: the name of the test's type parameter, or NULL if
// this is not a typed or a type-parameterized test.
// set_up_tc: pointer to the function that sets up the test suite
// tear_down_tc: pointer to the function that tears down the test suite
TestSuite* GetTestSuite(const char* test_suite_name, const char* type_param,
// type_param: the name of the test's type parameter, or NULL if
// this is not a typed or a type-parameterized test.
// set_up_tc: pointer to the function that sets up the test suite
// tear_down_tc: pointer to the function that tears down the test suite
TestSuite* GetTestSuite(const std::string& test_suite_name,
const char* type_param,
internal::SetUpTestSuiteFunc set_up_tc,
internal::TearDownTestSuiteFunc tear_down_tc);
// Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
TestCase* GetTestCase(const char* test_case_name, const char* type_param,
TestCase* GetTestCase(const std::string& test_case_name,
const char* type_param,
internal::SetUpTestSuiteFunc set_up_tc,
internal::TearDownTestSuiteFunc tear_down_tc) {
return GetTestSuite(test_case_name, type_param, set_up_tc, tear_down_tc);
@@ -674,6 +675,7 @@ class GTEST_API_ UnitTestImpl {
void AddTestInfo(internal::SetUpTestSuiteFunc set_up_tc,
internal::TearDownTestSuiteFunc tear_down_tc,
TestInfo* test_info) {
#if GTEST_HAS_FILE_SYSTEM
// In order to support thread-safe death tests, we need to
// remember the original working directory when the test program
// was first invoked. We cannot do this in RUN_ALL_TESTS(), as
@@ -682,12 +684,13 @@ class GTEST_API_ UnitTestImpl {
// AddTestInfo(), which is called to register a TEST or TEST_F
// before main() is reached.
if (original_working_dir_.IsEmpty()) {
original_working_dir_.Set(FilePath::GetCurrentDir());
original_working_dir_ = FilePath::GetCurrentDir();
GTEST_CHECK_(!original_working_dir_.IsEmpty())
<< "Failed to get the current working directory.";
}
#endif // GTEST_HAS_FILE_SYSTEM
GetTestSuite(test_info->test_suite_name(), test_info->type_param(),
GetTestSuite(test_info->test_suite_name_, test_info->type_param(),
set_up_tc, tear_down_tc)
->AddTestInfo(test_info);
}
@@ -709,18 +712,6 @@ class GTEST_API_ UnitTestImpl {
return type_parameterized_test_registry_;
}
// Sets the TestSuite object for the test that's currently running.
void set_current_test_suite(TestSuite* a_current_test_suite) {
current_test_suite_ = a_current_test_suite;
}
// Sets the TestInfo object for the test that's currently running. If
// current_test_info is NULL, the assertion results will be stored in
// ad_hoc_test_result_.
void set_current_test_info(TestInfo* a_current_test_info) {
current_test_info_ = a_current_test_info;
}
// Registers all parameterized tests defined using TEST_P and
// INSTANTIATE_TEST_SUITE_P, creating regular tests for each test/parameter
// combination. This method can be called more then once; it has guards
@@ -741,9 +732,7 @@ class GTEST_API_ UnitTestImpl {
}
// Clears the results of ad-hoc test assertions.
void ClearAdHocTestResult() {
ad_hoc_test_result_.Clear();
}
void ClearAdHocTestResult() { ad_hoc_test_result_.Clear(); }
// Adds a TestProperty to the current TestResult object when invoked in a
// context of a test or a test suite, or to the global property set. If the
@@ -751,10 +740,7 @@ class GTEST_API_ UnitTestImpl {
// updated.
void RecordProperty(const TestProperty& test_property);
enum ReactionToSharding {
HONOR_SHARDING_PROTOCOL,
IGNORE_SHARDING_PROTOCOL
};
enum ReactionToSharding { HONOR_SHARDING_PROTOCOL, IGNORE_SHARDING_PROTOCOL };
// Matches the full name of each test against the user-specified
// filter to decide whether the test should run, then records the
@@ -783,7 +769,7 @@ class GTEST_API_ UnitTestImpl {
return gtest_trace_stack_.get();
}
#if GTEST_HAS_DEATH_TEST
#ifdef GTEST_HAS_DEATH_TEST
void InitDeathTestSubprocessControlInfo() {
internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag());
}
@@ -840,18 +826,42 @@ class GTEST_API_ UnitTestImpl {
bool catch_exceptions() const { return catch_exceptions_; }
private:
// Returns true if a warning should be issued if no tests match the test
// filter flag.
bool ShouldWarnIfNoTestsMatchFilter() const;
struct CompareTestSuitesByPointer {
bool operator()(const TestSuite* lhs, const TestSuite* rhs) const {
return lhs->name_ < rhs->name_;
}
};
friend class ::testing::UnitTest;
// Used by UnitTest::Run() to capture the state of
// GTEST_FLAG(catch_exceptions) at the moment it starts.
void set_catch_exceptions(bool value) { catch_exceptions_ = value; }
// Sets the TestSuite object for the test that's currently running.
void set_current_test_suite(TestSuite* a_current_test_suite) {
current_test_suite_ = a_current_test_suite;
}
// Sets the TestInfo object for the test that's currently running. If
// current_test_info is NULL, the assertion results will be stored in
// ad_hoc_test_result_.
void set_current_test_info(TestInfo* a_current_test_info) {
current_test_info_ = a_current_test_info;
}
// The UnitTest object that owns this implementation object.
UnitTest* const parent_;
#if GTEST_HAS_FILE_SYSTEM
// The working directory when the first TEST() or TEST_F() was
// executed.
internal::FilePath original_working_dir_;
#endif // GTEST_HAS_FILE_SYSTEM
// The default test part result reporters.
DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_;
@@ -859,7 +869,7 @@ class GTEST_API_ UnitTestImpl {
default_per_thread_test_part_result_reporter_;
// Points to (but doesn't own) the global test part result reporter.
TestPartResultReporterInterface* global_test_part_result_repoter_;
TestPartResultReporterInterface* global_test_part_result_reporter_;
// Protects read and write access to global_test_part_result_reporter_.
internal::Mutex global_test_part_result_reporter_mutex_;
@@ -876,6 +886,9 @@ class GTEST_API_ UnitTestImpl {
// elements in the vector.
std::vector<TestSuite*> test_suites_;
// The set of TestSuites by name.
std::unordered_map<std::string, TestSuite*> test_suites_by_name_;
// Provides a level of indirection for the test suite list to allow
// easy shuffling and restoring the test suite order. The i-th
// element of this vector is the index of the i-th test suite in the
@@ -946,7 +959,7 @@ class GTEST_API_ UnitTestImpl {
// How long the test took to run, in milliseconds.
TimeInMillis elapsed_time_;
#if GTEST_HAS_DEATH_TEST
#ifdef GTEST_HAS_DEATH_TEST
// The decomposed components of the gtest_internal_run_death_test flag,
// parsed when RUN_ALL_TESTS is called.
std::unique_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_;
@@ -960,7 +973,8 @@ class GTEST_API_ UnitTestImpl {
// starts.
bool catch_exceptions_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl);
UnitTestImpl(const UnitTestImpl&) = delete;
UnitTestImpl& operator=(const UnitTestImpl&) = delete;
}; // class UnitTestImpl
// Convenience function for accessing the global UnitTest
@@ -969,7 +983,7 @@ inline UnitTestImpl* GetUnitTestImpl() {
return UnitTest::GetInstance()->impl();
}
#if GTEST_USES_SIMPLE_RE
#ifdef GTEST_USES_SIMPLE_RE
// Internal helper functions for implementing the simple regular
// expression matcher.
@@ -983,8 +997,9 @@ GTEST_API_ bool IsValidEscape(char ch);
GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch);
GTEST_API_ bool ValidateRegex(const char* regex);
GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str);
GTEST_API_ bool MatchRepetitionAndRegexAtHead(
bool escaped, char ch, char repeat, const char* regex, const char* str);
GTEST_API_ bool MatchRepetitionAndRegexAtHead(bool escaped, char ch,
char repeat, const char* regex,
const char* str);
GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str);
#endif // GTEST_USES_SIMPLE_RE
@@ -994,7 +1009,7 @@ GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str);
GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv);
GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv);
#if GTEST_HAS_DEATH_TEST
#ifdef GTEST_HAS_DEATH_TEST
// Returns the message describing the last system error, regardless of the
// platform.
@@ -1065,7 +1080,7 @@ class StreamingListener : public EmptyTestEventListener {
// Abstract base class for writing strings to a socket.
class AbstractSocketWriter {
public:
virtual ~AbstractSocketWriter() {}
virtual ~AbstractSocketWriter() = default;
// Sends a string to the socket.
virtual void Send(const std::string& message) = 0;
@@ -1086,8 +1101,7 @@ class StreamingListener : public EmptyTestEventListener {
}
~SocketWriter() override {
if (sockfd_ != -1)
CloseConnection();
if (sockfd_ != -1) CloseConnection();
}
// Sends a string to the socket.
@@ -1097,9 +1111,8 @@ class StreamingListener : public EmptyTestEventListener {
const auto len = static_cast<size_t>(message.length());
if (write(sockfd_, message.c_str(), len) != static_cast<ssize_t>(len)) {
GTEST_LOG_(WARNING)
<< "stream_result_to: failed to stream to "
<< host_name_ << ":" << port_num_;
GTEST_LOG_(WARNING) << "stream_result_to: failed to stream to "
<< host_name_ << ":" << port_num_;
}
}
@@ -1120,7 +1133,8 @@ class StreamingListener : public EmptyTestEventListener {
const std::string host_name_;
const std::string port_num_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter);
SocketWriter(const SocketWriter&) = delete;
SocketWriter& operator=(const SocketWriter&) = delete;
}; // class SocketWriter
// Escapes '=', '&', '%', and '\n' characters in str as "%xx".
@@ -1132,7 +1146,9 @@ class StreamingListener : public EmptyTestEventListener {
}
explicit StreamingListener(AbstractSocketWriter* socket_writer)
: socket_writer_(socket_writer) { Start(); }
: socket_writer_(socket_writer) {
Start();
}
void OnTestProgramStart(const UnitTest& /* unit_test */) override {
SendLn("event=TestProgramStart");
@@ -1155,22 +1171,22 @@ class StreamingListener : public EmptyTestEventListener {
void OnTestIterationEnd(const UnitTest& unit_test,
int /* iteration */) override {
SendLn("event=TestIterationEnd&passed=" +
FormatBool(unit_test.Passed()) + "&elapsed_time=" +
StreamableToString(unit_test.elapsed_time()) + "ms");
SendLn("event=TestIterationEnd&passed=" + FormatBool(unit_test.Passed()) +
"&elapsed_time=" + StreamableToString(unit_test.elapsed_time()) +
"ms");
}
// Note that "event=TestCaseStart" is a wire format and has to remain
// "case" for compatibilty
void OnTestCaseStart(const TestCase& test_case) override {
SendLn(std::string("event=TestCaseStart&name=") + test_case.name());
// "case" for compatibility
void OnTestSuiteStart(const TestSuite& test_suite) override {
SendLn(std::string("event=TestCaseStart&name=") + test_suite.name());
}
// Note that "event=TestCaseEnd" is a wire format and has to remain
// "case" for compatibilty
void OnTestCaseEnd(const TestCase& test_case) override {
SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) +
"&elapsed_time=" + StreamableToString(test_case.elapsed_time()) +
// "case" for compatibility
void OnTestSuiteEnd(const TestSuite& test_suite) override {
SendLn("event=TestCaseEnd&passed=" + FormatBool(test_suite.Passed()) +
"&elapsed_time=" + StreamableToString(test_suite.elapsed_time()) +
"ms");
}
@@ -1180,8 +1196,7 @@ class StreamingListener : public EmptyTestEventListener {
void OnTestEnd(const TestInfo& test_info) override {
SendLn("event=TestEnd&passed=" +
FormatBool((test_info.result())->Passed()) +
"&elapsed_time=" +
FormatBool((test_info.result())->Passed()) + "&elapsed_time=" +
StreamableToString((test_info.result())->elapsed_time()) + "ms");
}
@@ -1205,7 +1220,8 @@ class StreamingListener : public EmptyTestEventListener {
const std::unique_ptr<AbstractSocketWriter> socket_writer_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener);
StreamingListener(const StreamingListener&) = delete;
StreamingListener& operator=(const StreamingListener&) = delete;
}; // class StreamingListener
#endif // GTEST_CAN_STREAM_RESULTS_
@@ -1215,4 +1231,4 @@ class StreamingListener : public EmptyTestEventListener {
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_
#endif // GOOGLETEST_SRC_GTEST_INTERNAL_INL_H_

View File

@@ -32,12 +32,13 @@
// This file implements just enough of the matcher interface to allow
// EXPECT_DEATH and friends to accept a matcher argument.
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
#include "gtest/gtest-matchers.h"
#include <string>
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
namespace testing {
// Constructs a matcher that matches a const std::string& whose value is

File diff suppressed because it is too large Load Diff

View File

@@ -27,7 +27,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Test - The Google C++ Testing and Mocking Framework
//
// This file implements a universal value printer that can print a
@@ -42,11 +41,18 @@
// defines Foo.
#include "gtest/gtest-printers.h"
#include <stdio.h>
#include <cctype>
#include <cstdint>
#include <cwchar>
#include <iomanip>
#include <ios>
#include <ostream> // NOLINT
#include <string>
#include <type_traits>
#include "gtest/internal/gtest-port.h"
#include "src/gtest-internal-inl.h"
@@ -96,12 +102,22 @@ void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os);
*os << " ... ";
// Rounds up to 2-byte boundary.
const size_t resume_pos = (count - kChunkSize + 1)/2*2;
const size_t resume_pos = (count - kChunkSize + 1) / 2 * 2;
PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os);
}
*os << ">";
}
// Helpers for widening a character to char32_t. Since the standard does not
// specify if char / wchar_t is signed or unsigned, it is important to first
// convert it to the unsigned type of the same width before widening it to
// char32_t.
template <typename CharType>
char32_t ToChar32(CharType in) {
return static_cast<char32_t>(
static_cast<typename std::make_unsigned<CharType>::type>(in));
}
} // namespace
namespace internal {
@@ -121,27 +137,20 @@ void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
// - as is if it's a printable ASCII (e.g. 'a', '2', ' '),
// - as a hexadecimal escape sequence (e.g. '\x7F'), or
// - as a special escape sequence (e.g. '\r', '\n').
enum CharFormat {
kAsIs,
kHexEscape,
kSpecialEscape
};
enum CharFormat { kAsIs, kHexEscape, kSpecialEscape };
// Returns true if c is a printable ASCII character. We test the
// value of c directly instead of calling isprint(), which is buggy on
// Windows Mobile.
inline bool IsPrintableAscii(wchar_t c) {
return 0x20 <= c && c <= 0x7E;
}
inline bool IsPrintableAscii(char32_t c) { return 0x20 <= c && c <= 0x7E; }
// Prints a wide or narrow char c as a character literal without the
// quotes, escaping it when necessary; returns how c was formatted.
// The template argument UnsignedChar is the unsigned version of Char,
// which is the type of c.
template <typename UnsignedChar, typename Char>
// Prints c (of type char, char8_t, char16_t, char32_t, or wchar_t) as a
// character literal without the quotes, escaping it when necessary; returns how
// c was formatted.
template <typename Char>
static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
wchar_t w_c = static_cast<wchar_t>(c);
switch (w_c) {
const char32_t u_c = ToChar32(c);
switch (u_c) {
case L'\0':
*os << "\\0";
break;
@@ -173,13 +182,12 @@ static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
*os << "\\v";
break;
default:
if (IsPrintableAscii(w_c)) {
if (IsPrintableAscii(u_c)) {
*os << static_cast<char>(c);
return kAsIs;
} else {
ostream::fmtflags flags = os->flags();
*os << "\\x" << std::hex << std::uppercase
<< static_cast<int>(static_cast<UnsignedChar>(c));
*os << "\\x" << std::hex << std::uppercase << static_cast<int>(u_c);
os->flags(flags);
return kHexEscape;
}
@@ -187,9 +195,9 @@ static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) {
return kSpecialEscape;
}
// Prints a wchar_t c as if it's part of a string literal, escaping it when
// Prints a char32_t c as if it's part of a string literal, escaping it when
// necessary; returns how c was formatted.
static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {
static CharFormat PrintAsStringLiteralTo(char32_t c, ostream* os) {
switch (c) {
case L'\'':
*os << "'";
@@ -198,33 +206,60 @@ static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {
*os << "\\\"";
return kSpecialEscape;
default:
return PrintAsCharLiteralTo<wchar_t>(c, os);
return PrintAsCharLiteralTo(c, os);
}
}
static const char* GetCharWidthPrefix(char) { return ""; }
static const char* GetCharWidthPrefix(signed char) { return ""; }
static const char* GetCharWidthPrefix(unsigned char) { return ""; }
#ifdef __cpp_lib_char8_t
static const char* GetCharWidthPrefix(char8_t) { return "u8"; }
#endif
static const char* GetCharWidthPrefix(char16_t) { return "u"; }
static const char* GetCharWidthPrefix(char32_t) { return "U"; }
static const char* GetCharWidthPrefix(wchar_t) { return "L"; }
// Prints a char c as if it's part of a string literal, escaping it when
// necessary; returns how c was formatted.
static CharFormat PrintAsStringLiteralTo(char c, ostream* os) {
return PrintAsStringLiteralTo(
static_cast<wchar_t>(static_cast<unsigned char>(c)), os);
return PrintAsStringLiteralTo(ToChar32(c), os);
}
// Prints a wide or narrow character c and its code. '\0' is printed
// as "'\\0'", other unprintable characters are also properly escaped
// using the standard C++ escape sequence. The template argument
// UnsignedChar is the unsigned version of Char, which is the type of c.
template <typename UnsignedChar, typename Char>
#ifdef __cpp_lib_char8_t
static CharFormat PrintAsStringLiteralTo(char8_t c, ostream* os) {
return PrintAsStringLiteralTo(ToChar32(c), os);
}
#endif
static CharFormat PrintAsStringLiteralTo(char16_t c, ostream* os) {
return PrintAsStringLiteralTo(ToChar32(c), os);
}
static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) {
return PrintAsStringLiteralTo(ToChar32(c), os);
}
// Prints a character c (of type char, char8_t, char16_t, char32_t, or wchar_t)
// and its code. '\0' is printed as "'\\0'", other unprintable characters are
// also properly escaped using the standard C++ escape sequence.
template <typename Char>
void PrintCharAndCodeTo(Char c, ostream* os) {
// First, print c as a literal in the most readable form we can find.
*os << ((sizeof(c) > 1) ? "L'" : "'");
const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os);
*os << GetCharWidthPrefix(c) << "'";
const CharFormat format = PrintAsCharLiteralTo(c, os);
*os << "'";
// To aid user debugging, we also print c's code in decimal, unless
// it's 0 (in which case c was printed as '\\0', making the code
// obvious).
if (c == 0)
return;
if (c == 0) return;
*os << " (" << static_cast<int>(c);
// For more convenience, we print c's code again in hexadecimal,
@@ -238,32 +273,75 @@ void PrintCharAndCodeTo(Char c, ostream* os) {
*os << ")";
}
void PrintTo(unsigned char c, ::std::ostream* os) {
PrintCharAndCodeTo<unsigned char>(c, os);
}
void PrintTo(signed char c, ::std::ostream* os) {
PrintCharAndCodeTo<unsigned char>(c, os);
}
void PrintTo(unsigned char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); }
void PrintTo(signed char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); }
// Prints a wchar_t as a symbol if it is printable or as its internal
// code otherwise and also as its code. L'\0' is printed as "L'\\0'".
void PrintTo(wchar_t wc, ostream* os) {
PrintCharAndCodeTo<wchar_t>(wc, os);
void PrintTo(wchar_t wc, ostream* os) { PrintCharAndCodeTo(wc, os); }
// TODO(dcheng): Consider making this delegate to PrintCharAndCodeTo() as well.
void PrintTo(char32_t c, ::std::ostream* os) {
*os << std::hex << "U+" << std::uppercase << std::setfill('0') << std::setw(4)
<< static_cast<uint32_t>(c);
}
// gcc/clang __{u,}int128_t
#if defined(__SIZEOF_INT128__)
void PrintTo(__uint128_t v, ::std::ostream* os) {
if (v == 0) {
*os << "0";
return;
}
// Buffer large enough for ceil(log10(2^128))==39 and the null terminator
char buf[40];
char* p = buf + sizeof(buf);
// Some configurations have a __uint128_t, but no support for built in
// division. Do manual long division instead.
uint64_t high = static_cast<uint64_t>(v >> 64);
uint64_t low = static_cast<uint64_t>(v);
*--p = 0;
while (high != 0 || low != 0) {
uint64_t high_mod = high % 10;
high = high / 10;
// This is the long division algorithm specialized for a divisor of 10 and
// only two elements.
// Notable values:
// 2^64 / 10 == 1844674407370955161
// 2^64 % 10 == 6
const uint64_t carry = 6 * high_mod + low % 10;
low = low / 10 + high_mod * 1844674407370955161 + carry / 10;
char digit = static_cast<char>(carry % 10);
*--p = static_cast<char>('0' + digit);
}
*os << p;
}
void PrintTo(__int128_t v, ::std::ostream* os) {
__uint128_t uv = static_cast<__uint128_t>(v);
if (v < 0) {
*os << "-";
uv = -uv;
}
PrintTo(uv, os);
}
#endif // __SIZEOF_INT128__
// Prints the given array of characters to the ostream. CharType must be either
// char or wchar_t.
// char, char8_t, char16_t, char32_t, or wchar_t.
// The array starts at begin, the length is len, it may include '\0' characters
// and may not be NUL-terminated.
template <typename CharType>
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
static CharFormat PrintCharsAsStringTo(
const CharType* begin, size_t len, ostream* os) {
const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\"";
*os << kQuoteBegin;
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static CharFormat
PrintCharsAsStringTo(const CharType* begin, size_t len, ostream* os) {
const char* const quote_prefix = GetCharWidthPrefix(*begin);
*os << quote_prefix << "\"";
bool is_previous_hex = false;
CharFormat print_format = kAsIs;
for (size_t index = 0; index < len; ++index) {
@@ -272,7 +350,7 @@ static CharFormat PrintCharsAsStringTo(
// Previous character is of '\x..' form and this character can be
// interpreted as another hexadecimal digit in its number. Break string to
// disambiguate.
*os << "\" " << kQuoteBegin;
*os << "\" " << quote_prefix << "\"";
}
is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape;
// Remember if any characters required hex escaping.
@@ -287,12 +365,11 @@ static CharFormat PrintCharsAsStringTo(
// Prints a (const) char/wchar_t array of 'len' elements, starting at address
// 'begin'. CharType must be either char or wchar_t.
template <typename CharType>
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_
GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_
static void UniversalPrintCharArray(
const CharType* begin, size_t len, ostream* os) {
GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_
GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static void
UniversalPrintCharArray(const CharType* begin, size_t len,
ostream* os) {
// The code
// const char kFoo[] = "foo";
// generates an array of 4, not 3, elements, with the last one being '\0'.
@@ -318,22 +395,57 @@ void UniversalPrintArray(const char* begin, size_t len, ostream* os) {
UniversalPrintCharArray(begin, len, os);
}
#ifdef __cpp_lib_char8_t
// Prints a (const) char8_t array of 'len' elements, starting at address
// 'begin'.
void UniversalPrintArray(const char8_t* begin, size_t len, ostream* os) {
UniversalPrintCharArray(begin, len, os);
}
#endif
// Prints a (const) char16_t array of 'len' elements, starting at address
// 'begin'.
void UniversalPrintArray(const char16_t* begin, size_t len, ostream* os) {
UniversalPrintCharArray(begin, len, os);
}
// Prints a (const) char32_t array of 'len' elements, starting at address
// 'begin'.
void UniversalPrintArray(const char32_t* begin, size_t len, ostream* os) {
UniversalPrintCharArray(begin, len, os);
}
// Prints a (const) wchar_t array of 'len' elements, starting at address
// 'begin'.
void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {
UniversalPrintCharArray(begin, len, os);
}
// Prints the given C string to the ostream.
void PrintTo(const char* s, ostream* os) {
namespace {
// Prints a null-terminated C-style string to the ostream.
template <typename Char>
void PrintCStringTo(const Char* s, ostream* os) {
if (s == nullptr) {
*os << "NULL";
} else {
*os << ImplicitCast_<const void*>(s) << " pointing to ";
PrintCharsAsStringTo(s, strlen(s), os);
PrintCharsAsStringTo(s, std::char_traits<Char>::length(s), os);
}
}
} // anonymous namespace
void PrintTo(const char* s, ostream* os) { PrintCStringTo(s, os); }
#ifdef __cpp_lib_char8_t
void PrintTo(const char8_t* s, ostream* os) { PrintCStringTo(s, os); }
#endif
void PrintTo(const char16_t* s, ostream* os) { PrintCStringTo(s, os); }
void PrintTo(const char32_t* s, ostream* os) { PrintCStringTo(s, os); }
// MSVC compiler can be configured to define whar_t as a typedef
// of unsigned short. Defining an overload for const wchar_t* in that case
// would cause pointers to unsigned shorts be printed as wide strings,
@@ -342,41 +454,34 @@ void PrintTo(const char* s, ostream* os) {
// wchar_t is implemented as a native type.
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
// Prints the given wide C string to the ostream.
void PrintTo(const wchar_t* s, ostream* os) {
if (s == nullptr) {
*os << "NULL";
} else {
*os << ImplicitCast_<const void*>(s) << " pointing to ";
PrintCharsAsStringTo(s, wcslen(s), os);
}
}
void PrintTo(const wchar_t* s, ostream* os) { PrintCStringTo(s, os); }
#endif // wchar_t is native
namespace {
bool ContainsUnprintableControlCodes(const char* str, size_t length) {
const unsigned char *s = reinterpret_cast<const unsigned char *>(str);
const unsigned char* s = reinterpret_cast<const unsigned char*>(str);
for (size_t i = 0; i < length; i++) {
unsigned char ch = *s++;
if (std::iscntrl(ch)) {
switch (ch) {
switch (ch) {
case '\t':
case '\n':
case '\r':
break;
default:
return true;
}
}
}
}
return false;
}
bool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t<= 0xbf; }
bool IsUTF8TrailByte(unsigned char t) { return 0x80 <= t && t <= 0xbf; }
bool IsValidUTF8(const char* str, size_t length) {
const unsigned char *s = reinterpret_cast<const unsigned char *>(str);
const unsigned char* s = reinterpret_cast<const unsigned char*>(str);
for (size_t i = 0; i < length;) {
unsigned char lead = s[i++];
@@ -389,15 +494,13 @@ bool IsValidUTF8(const char* str, size_t length) {
} else if (lead <= 0xdf && (i + 1) <= length && IsUTF8TrailByte(s[i])) {
++i; // 2-byte character
} else if (0xe0 <= lead && lead <= 0xef && (i + 2) <= length &&
IsUTF8TrailByte(s[i]) &&
IsUTF8TrailByte(s[i + 1]) &&
IsUTF8TrailByte(s[i]) && IsUTF8TrailByte(s[i + 1]) &&
// check for non-shortest form and surrogate
(lead != 0xe0 || s[i] >= 0xa0) &&
(lead != 0xed || s[i] < 0xa0)) {
i += 2; // 3-byte character
} else if (0xf0 <= lead && lead <= 0xf4 && (i + 3) <= length &&
IsUTF8TrailByte(s[i]) &&
IsUTF8TrailByte(s[i + 1]) &&
IsUTF8TrailByte(s[i]) && IsUTF8TrailByte(s[i + 1]) &&
IsUTF8TrailByte(s[i + 2]) &&
// check for non-shortest form
(lead != 0xf0 || s[i] >= 0x90) &&
@@ -421,12 +524,26 @@ void ConditionalPrintAsText(const char* str, size_t length, ostream* os) {
void PrintStringTo(const ::std::string& s, ostream* os) {
if (PrintCharsAsStringTo(s.data(), s.size(), os) == kHexEscape) {
if (GTEST_FLAG(print_utf8)) {
if (GTEST_FLAG_GET(print_utf8)) {
ConditionalPrintAsText(s.data(), s.size(), os);
}
}
}
#ifdef __cpp_lib_char8_t
void PrintU8StringTo(const ::std::u8string& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
}
#endif
void PrintU16StringTo(const ::std::u16string& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
}
void PrintU32StringTo(const ::std::u32string& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);
}
#if GTEST_HAS_STD_WSTRING
void PrintWideStringTo(const ::std::wstring& s, ostream* os) {
PrintCharsAsStringTo(s.data(), s.size(), os);

View File

@@ -32,13 +32,14 @@
#include "gtest/gtest-test-part.h"
#include <ostream>
#include <string>
#include "gtest/internal/gtest-port.h"
#include "src/gtest-internal-inl.h"
namespace testing {
using internal::GetUnitTestImpl;
// Gets the summary of the failure message by omitting the stack trace
// in it.
std::string TestPartResult::ExtractSummary(const char* message) {
@@ -51,13 +52,11 @@ std::ostream& operator<<(std::ostream& os, const TestPartResult& result) {
return os << internal::FormatFileLocation(result.file_name(),
result.line_number())
<< " "
<< (result.type() == TestPartResult::kSuccess
? "Success"
: result.type() == TestPartResult::kSkip
? "Skipped"
: result.type() == TestPartResult::kFatalFailure
? "Fatal failure"
: "Non-fatal failure")
<< (result.type() == TestPartResult::kSuccess ? "Success"
: result.type() == TestPartResult::kSkip ? "Skipped"
: result.type() == TestPartResult::kFatalFailure
? "Fatal failure"
: "Non-fatal failure")
<< ":\n"
<< result.message() << std::endl;
}
@@ -86,8 +85,8 @@ namespace internal {
HasNewFatalFailureHelper::HasNewFatalFailureHelper()
: has_new_fatal_failure_(false),
original_reporter_(GetUnitTestImpl()->
GetTestPartResultReporterForCurrentThread()) {
original_reporter_(
GetUnitTestImpl()->GetTestPartResultReporterForCurrentThread()) {
GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this);
}
@@ -98,8 +97,7 @@ HasNewFatalFailureHelper::~HasNewFatalFailureHelper() {
void HasNewFatalFailureHelper::ReportTestPartResult(
const TestPartResult& result) {
if (result.fatally_failed())
has_new_fatal_failure_ = true;
if (result.fatally_failed()) has_new_fatal_failure_ = true;
original_reporter_->ReportTestPartResult(result);
}

View File

@@ -27,21 +27,21 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "gtest/gtest-typed-test.h"
#include <set>
#include <string>
#include <vector>
#include "gtest/gtest.h"
namespace testing {
namespace internal {
#if GTEST_HAS_TYPED_TEST_P
// Skips to the first non-space char in str. Returns an empty string if str
// contains only whitespace characters.
static const char* SkipSpaces(const char* str) {
while (IsSpace(*str))
str++;
while (IsSpace(*str)) str++;
return str;
}
@@ -78,17 +78,7 @@ const char* TypedTestSuitePState::VerifyRegisteredTestNames(
continue;
}
bool found = false;
for (RegisteredTestIter it = registered_tests_.begin();
it != registered_tests_.end();
++it) {
if (name == it->first) {
found = true;
break;
}
}
if (found) {
if (registered_tests_.count(name) != 0) {
tests.insert(name);
} else {
errors << "No test named " << name
@@ -97,15 +87,14 @@ const char* TypedTestSuitePState::VerifyRegisteredTestNames(
}
for (RegisteredTestIter it = registered_tests_.begin();
it != registered_tests_.end();
++it) {
it != registered_tests_.end(); ++it) {
if (tests.count(it->first) == 0) {
errors << "You forgot to list test " << it->first << ".\n";
}
}
const std::string& errors_str = errors.GetString();
if (errors_str != "") {
if (!errors_str.empty()) {
fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(),
errors_str.c_str());
fflush(stderr);
@@ -115,7 +104,5 @@ const char* TypedTestSuitePState::VerifyRegisteredTestNames(
return registered_tests;
}
#endif // GTEST_HAS_TYPED_TEST_P
} // namespace internal
} // namespace testing

File diff suppressed because it is too large Load Diff

View File

@@ -28,23 +28,35 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <cstdio>
#include "gtest/gtest.h"
#if GTEST_OS_ESP8266 || GTEST_OS_ESP32
#if GTEST_OS_ESP8266
#if defined(GTEST_OS_ESP8266) || defined(GTEST_OS_ESP32) || \
(defined(GTEST_OS_NRF52) && defined(ARDUINO))
// Arduino-like platforms: program entry points are setup/loop instead of main.
#ifdef GTEST_OS_ESP8266
extern "C" {
#endif
void setup() {
testing::InitGoogleTest();
}
void setup() { testing::InitGoogleTest(); }
void loop() { RUN_ALL_TESTS(); }
#if GTEST_OS_ESP8266
#ifdef GTEST_OS_ESP8266
}
#endif
#elif defined(GTEST_OS_QURT)
// QuRT: program entry point is main, but argc/argv are unusable.
GTEST_API_ int main() {
printf("Running main() from %s\n", __FILE__);
testing::InitGoogleTest();
return RUN_ALL_TESTS();
}
#else
// Normal platforms: program entry point is main, argc/argv are initialized.
GTEST_API_ int main(int argc, char **argv) {
printf("Running main() from %s\n", __FILE__);