Compare commits

..

1 Commits

Author SHA1 Message Date
Abseil Team
94f756749c Export Test - Do Not Merge
Remove the CMAKE_CXX_STANDARD from GoogleTest's CMakeLists.txt

This causes ABI issues since it can create a mixed-mode build.  The
value should be inherited from the top-level build if it needs to be
set.

PiperOrigin-RevId: 294730724
2020-02-13 12:05:32 -05:00
24 changed files with 464 additions and 1259 deletions

View File

@ -10,7 +10,7 @@ endif (POLICY CMP0048)
project(googletest-distribution) project(googletest-distribution)
set(GOOGLETEST_VERSION 1.10.0) set(GOOGLETEST_VERSION 1.10.0)
if (CMAKE_VERSION VERSION_GREATER "3.0.2") if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.1")
if(NOT CYGWIN AND NOT MSYS) if(NOT CYGWIN AND NOT MSYS)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
endif() endif()

View File

@ -421,7 +421,7 @@ sadly they are side effects of C++'s limitations):
`NiceMock<StrictMock<MockFoo> >`) is **not** supported. `NiceMock<StrictMock<MockFoo> >`) is **not** supported.
2. `NiceMock<MockFoo>` and `StrictMock<MockFoo>` may not work correctly if the 2. `NiceMock<MockFoo>` and `StrictMock<MockFoo>` may not work correctly if the
destructor of `MockFoo` is not virtual. We would like to fix this, but it destructor of `MockFoo` is not virtual. We would like to fix this, but it
requires cleaning up existing tests. requires cleaning up existing tests. http://b/28934720 tracks the issue.
3. During the constructor or destructor of `MockFoo`, the mock object is *not* 3. During the constructor or destructor of `MockFoo`, the mock object is *not*
nice or strict. This may cause surprises if the constructor or destructor nice or strict. This may cause surprises if the constructor or destructor
calls a mock method on `this` object. (This behavior, however, is consistent calls a mock method on `this` object. (This behavior, however, is consistent
@ -2174,7 +2174,7 @@ own precedence order distinct from the `ON_CALL` precedence order.
### Using Functions/Methods/Functors/Lambdas as Actions {#FunctionsAsActions} ### Using Functions/Methods/Functors/Lambdas as Actions {#FunctionsAsActions}
If the built-in actions don't suit you, you can use an existing callable If the built-in actions don't suit you, you can use an existing callable
(function, `std::function`, method, functor, lambda) as an action. (function, `std::function`, method, functor, lambda as an action.
<!-- GOOGLETEST_CM0024 DO NOT DELETE --> <!-- GOOGLETEST_CM0024 DO NOT DELETE -->
@ -2203,7 +2203,6 @@ class Helper {
.WillRepeatedly(Invoke(NewPermanentCallback(Sum3, 1))); .WillRepeatedly(Invoke(NewPermanentCallback(Sum3, 1)));
EXPECT_CALL(foo, ComplexJob(_)) EXPECT_CALL(foo, ComplexJob(_))
.WillOnce(Invoke(&helper, &Helper::ComplexJob)) .WillOnce(Invoke(&helper, &Helper::ComplexJob))
.WillOnce([] { return true; })
.WillRepeatedly([](int x) { return x > 0; }); .WillRepeatedly([](int x) { return x > 0; });
foo.Sum(5, 6); // Invokes CalculateSum(5, 6). foo.Sum(5, 6); // Invokes CalculateSum(5, 6).
@ -2213,11 +2212,11 @@ class Helper {
``` ```
The only requirement is that the type of the function, etc must be *compatible* The only requirement is that the type of the function, etc must be *compatible*
with the signature of the mock function, meaning that the latter's arguments (if with the signature of the mock function, meaning that the latter's arguments can
it takes any) can be implicitly converted to the corresponding arguments of the be implicitly converted to the corresponding arguments of the former, and the
former, and the former's return type can be implicitly converted to that of the former's return type can be implicitly converted to that of the latter. So, you
latter. So, you can invoke something whose type is *not* exactly the same as the can invoke something whose type is *not* exactly the same as the mock function,
mock function, as long as it's safe to do so - nice, huh? as long as it's safe to do so - nice, huh?
**`Note:`{.escaped}** **`Note:`{.escaped}**
@ -2268,20 +2267,19 @@ TEST_F(FooTest, Test) {
### Invoking a Function/Method/Functor/Lambda/Callback Without Arguments ### Invoking a Function/Method/Functor/Lambda/Callback Without Arguments
`Invoke()` passes the mock function's arguments to the function, etc being `Invoke()` is very useful for doing actions that are more complex. It passes the
invoked such that the callee has the full context of the call to work with. If mock function's arguments to the function, etc being invoked such that the
the invoked function is not interested in some or all of the arguments, it can callee has the full context of the call to work with. If the invoked function is
simply ignore them. not interested in some or all of the arguments, it can simply ignore them.
Yet, a common pattern is that a test author wants to invoke a function without Yet, a common pattern is that a test author wants to invoke a function without
the arguments of the mock function. She could do that using a wrapper function the arguments of the mock function. `Invoke()` allows her to do that using a
that throws away the arguments before invoking an underlining nullary function. wrapper function that throws away the arguments before invoking an underlining
Needless to say, this can be tedious and obscures the intent of the test. nullary function. Needless to say, this can be tedious and obscures the intent
of the test.
There are two solutions to this problem. First, you can pass any callable of `InvokeWithoutArgs()` solves this problem. It's like `Invoke()` except that it
zero args as an action. Alternatively, use `InvokeWithoutArgs()`, which is like doesn't pass the mock function's arguments to the callee. Here's an example:
`Invoke()` except that it doesn't pass the mock function's arguments to the
callee. Here's an example of each:
```cpp ```cpp
using ::testing::_; using ::testing::_;
@ -2298,7 +2296,7 @@ bool Job2(int n, char c) { ... }
... ...
MockFoo foo; MockFoo foo;
EXPECT_CALL(foo, ComplexJob(_)) EXPECT_CALL(foo, ComplexJob(_))
.WillOnce([] { Job1(); }); .WillOnce(InvokeWithoutArgs(Job1))
.WillOnce(InvokeWithoutArgs(NewPermanentCallback(Job2, 5, 'a'))); .WillOnce(InvokeWithoutArgs(NewPermanentCallback(Job2, 5, 'a')));
foo.ComplexJob(10); // Invokes Job1(). foo.ComplexJob(10); // Invokes Job1().

View File

@ -374,7 +374,7 @@ convenient way of saying "any value".
In the above examples, `100` and `50` are also matchers; implicitly, they are In the above examples, `100` and `50` are also matchers; implicitly, they are
the same as `Eq(100)` and `Eq(50)`, which specify that the argument must be the same as `Eq(100)` and `Eq(50)`, which specify that the argument must be
equal (using `operator==`) to the matcher argument. There are many equal (using `operator==`) to the matcher argument. There are many
[built-in matchers](cheat_sheet.md#MatcherList) for common types (as well as [built-in matchers](#MatcherList) for common types (as well as
[custom matchers](cook_book.md#NewMatchers)); for example: [custom matchers](cook_book.md#NewMatchers)); for example:
```cpp ```cpp

View File

@ -263,10 +263,6 @@ GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0);
#undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_ #undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_
// Simple two-arg form of std::disjunction.
template <typename P, typename Q>
using disjunction = typename ::std::conditional<P::value, P, Q>::type;
} // namespace internal } // namespace internal
// When an unexpected function call is encountered, Google Mock will // When an unexpected function call is encountered, Google Mock will
@ -460,15 +456,9 @@ class Action {
// This cannot take std::function directly, because then Action would not be // This cannot take std::function directly, because then Action would not be
// directly constructible from lambda (it would require two conversions). // directly constructible from lambda (it would require two conversions).
template <typename G, template <typename G,
typename IsCompatibleFunctor = typename = typename ::std::enable_if<
::std::is_constructible<::std::function<F>, G>, ::std::is_constructible<::std::function<F>, G>::value>::type>
typename IsNoArgsFunctor = Action(G&& fun) : fun_(::std::forward<G>(fun)) {} // NOLINT
::std::is_constructible<::std::function<Result()>, G>,
typename = typename ::std::enable_if<internal::disjunction<
IsCompatibleFunctor, IsNoArgsFunctor>::value>::type>
Action(G&& fun) { // NOLINT
Init(::std::forward<G>(fun), IsCompatibleFunctor());
}
// Constructs an Action from its implementation. // Constructs an Action from its implementation.
explicit Action(ActionInterface<F>* impl) explicit Action(ActionInterface<F>* impl)
@ -500,26 +490,6 @@ class Action {
template <typename G> template <typename G>
friend class Action; friend class Action;
template <typename G>
void Init(G&& g, ::std::true_type) {
fun_ = ::std::forward<G>(g);
}
template <typename G>
void Init(G&& g, ::std::false_type) {
fun_ = IgnoreArgs<typename ::std::decay<G>::type>{::std::forward<G>(g)};
}
template <typename FunctionImpl>
struct IgnoreArgs {
template <typename... Args>
Result operator()(const Args&...) const {
return function_impl();
}
FunctionImpl function_impl;
};
// fun_ is an empty function if and only if this is the DoDefault() action. // fun_ is an empty function if and only if this is the DoDefault() action.
::std::function<F> fun_; ::std::function<F> fun_;
}; };

View File

@ -424,14 +424,7 @@ class MatcherCastImpl<T, Matcher<U> > {
!std::is_base_of<FromType, ToType>::value, !std::is_base_of<FromType, ToType>::value,
"Can't implicitly convert from <base> to <derived>"); "Can't implicitly convert from <base> to <derived>");
// Do the cast to `U` explicitly if necessary. return source_matcher_.MatchAndExplain(static_cast<U>(x), listener);
// Otherwise, let implicit conversions do the trick.
using CastType =
typename std::conditional<std::is_convertible<T&, const U&>::value,
T&, U>::type;
return source_matcher_.MatchAndExplain(static_cast<CastType>(x),
listener);
} }
void DescribeTo(::std::ostream* os) const override { void DescribeTo(::std::ostream* os) const override {
@ -531,8 +524,8 @@ inline Matcher<T> SafeMatcherCast(const M& polymorphic_matcher_or_value) {
template <typename T, typename U> template <typename T, typename U>
inline Matcher<T> SafeMatcherCast(const Matcher<U>& matcher) { inline Matcher<T> SafeMatcherCast(const Matcher<U>& matcher) {
// Enforce that T can be implicitly converted to U. // Enforce that T can be implicitly converted to U.
static_assert(std::is_convertible<const T&, const U&>::value, GTEST_COMPILE_ASSERT_((std::is_convertible<T, U>::value),
"T must be implicitly convertible to U"); "T must be implicitly convertible to U");
// Enforce that we are not converting a non-reference type T to a reference // Enforce that we are not converting a non-reference type T to a reference
// type U. // type U.
GTEST_COMPILE_ASSERT_( GTEST_COMPILE_ASSERT_(

View File

@ -1786,79 +1786,10 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg);
} // namespace internal } // namespace internal
namespace internal { // A MockFunction<F> class has one mock method whose type is F. It is
// useful when you just want your test code to emit some messages and
template <typename F> // have Google Mock verify the right messages are sent (and perhaps at
class MockFunction; // the right times). For example, if you are exercising code:
template <typename R, typename... Args>
class MockFunction<R(Args...)> {
public:
MockFunction(const MockFunction&) = delete;
MockFunction& operator=(const MockFunction&) = delete;
std::function<R(Args...)> AsStdFunction() {
return [this](Args... args) -> R {
return this->Call(std::forward<Args>(args)...);
};
}
// Implementation detail: the expansion of the MOCK_METHOD macro.
R Call(Args... args) {
mock_.SetOwnerAndName(this, "Call");
return mock_.Invoke(std::forward<Args>(args)...);
}
MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) {
mock_.RegisterOwner(this);
return mock_.With(std::move(m)...);
}
MockSpec<R(Args...)> gmock_Call(const WithoutMatchers&, R (*)(Args...)) {
return this->gmock_Call(::testing::A<Args>()...);
}
protected:
MockFunction() = default;
~MockFunction() = default;
private:
FunctionMocker<R(Args...)> mock_;
};
/*
The SignatureOf<F> struct is a meta-function returning function signature
corresponding to the provided F argument.
It makes use of MockFunction easier by allowing it to accept more F arguments
than just function signatures.
Specializations provided here cover only a signature type itself and
std::function. However, if need be it can be easily extended to cover also other
types (like for example boost::function).
*/
template <typename F>
struct SignatureOf;
template <typename R, typename... Args>
struct SignatureOf<R(Args...)> {
using type = R(Args...);
};
template <typename F>
struct SignatureOf<std::function<F>> : SignatureOf<F> {};
template <typename F>
using SignatureOfT = typename SignatureOf<F>::type;
} // namespace internal
// A MockFunction<F> type has one mock method whose type is
// internal::SignatureOfT<F>. It is useful when you just want your
// test code to emit some messages and have Google Mock verify the
// right messages are sent (and perhaps at the right times). For
// example, if you are exercising code:
// //
// Foo(1); // Foo(1);
// Foo(2); // Foo(2);
@ -1892,34 +1823,49 @@ using SignatureOfT = typename SignatureOf<F>::type;
// Bar("a") is called by which call to Foo(). // Bar("a") is called by which call to Foo().
// //
// MockFunction<F> can also be used to exercise code that accepts // MockFunction<F> can also be used to exercise code that accepts
// std::function<internal::SignatureOfT<F>> callbacks. To do so, use // std::function<F> callbacks. To do so, use AsStdFunction() method
// AsStdFunction() method to create std::function proxy forwarding to // to create std::function proxy forwarding to original object's Call.
// original object's Call. Example: // Example:
// //
// TEST(FooTest, RunsCallbackWithBarArgument) { // TEST(FooTest, RunsCallbackWithBarArgument) {
// MockFunction<int(string)> callback; // MockFunction<int(string)> callback;
// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1)); // EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1));
// Foo(callback.AsStdFunction()); // Foo(callback.AsStdFunction());
// } // }
//
// The internal::SignatureOfT<F> indirection allows to use other types
// than just function signature type. This is typically useful when
// providing a mock for a predefined std::function type. Example:
//
// using FilterPredicate = std::function<bool(string)>;
// void MyFilterAlgorithm(FilterPredicate predicate);
//
// TEST(FooTest, FilterPredicateAlwaysAccepts) {
// MockFunction<FilterPredicate> predicateMock;
// EXPECT_CALL(predicateMock, Call(_)).WillRepeatedly(Return(true));
// MyFilterAlgorithm(predicateMock.AsStdFunction());
// }
template <typename F> template <typename F>
class MockFunction : public internal::MockFunction<internal::SignatureOfT<F>> { class MockFunction;
using Base = internal::MockFunction<internal::SignatureOfT<F>>;
template <typename R, typename... Args>
class MockFunction<R(Args...)> {
public: public:
using Base::Base; MockFunction() {}
MockFunction(const MockFunction&) = delete;
MockFunction& operator=(const MockFunction&) = delete;
std::function<R(Args...)> AsStdFunction() {
return [this](Args... args) -> R {
return this->Call(std::forward<Args>(args)...);
};
}
// Implementation detail: the expansion of the MOCK_METHOD macro.
R Call(Args... args) {
mock_.SetOwnerAndName(this, "Call");
return mock_.Invoke(std::forward<Args>(args)...);
}
internal::MockSpec<R(Args...)> gmock_Call(Matcher<Args>... m) {
mock_.RegisterOwner(this);
return mock_.With(std::move(m)...);
}
internal::MockSpec<R(Args...)> gmock_Call(const internal::WithoutMatchers&,
R (*)(Args...)) {
return this->gmock_Call(::testing::A<Args>()...);
}
private:
internal::FunctionMocker<R(Args...)> mock_;
}; };
// The style guide prohibits "using" statements in a namespace scope // The style guide prohibits "using" statements in a namespace scope

View File

@ -28,6 +28,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# #
# Author: misterg@google.com (Gennadiy Civil)
#
# Bazel Build for Google C++ Testing Framework(Google Test)-googlemock # Bazel Build for Google C++ Testing Framework(Google Test)-googlemock
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test") load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test")

View File

@ -1470,19 +1470,8 @@ TEST(FunctorActionTest, TypeConversion) {
EXPECT_EQ(1, s2.Perform(std::make_tuple("hello"))); EXPECT_EQ(1, s2.Perform(std::make_tuple("hello")));
// Also between the lambda and the action itself. // Also between the lambda and the action itself.
const Action<bool(std::string)> x1 = [](Unused) { return 42; }; const Action<bool(std::string)> x = [](Unused) { return 42; };
const Action<bool(std::string)> x2 = [] { return 42; }; EXPECT_TRUE(x.Perform(std::make_tuple("hello")));
EXPECT_TRUE(x1.Perform(std::make_tuple("hello")));
EXPECT_TRUE(x2.Perform(std::make_tuple("hello")));
// Ensure decay occurs where required.
std::function<int()> f = [] { return 7; };
Action<int(int)> d = f;
f = nullptr;
EXPECT_EQ(7, d.Perform(std::make_tuple(1)));
// Ensure creation of an empty action succeeds.
Action<void(int)>(nullptr);
} }
TEST(FunctorActionTest, UnusedArguments) { TEST(FunctorActionTest, UnusedArguments) {

View File

@ -40,7 +40,6 @@
# include <objbase.h> # include <objbase.h>
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
#include <functional>
#include <map> #include <map>
#include <string> #include <string>
#include <type_traits> #include <type_traits>
@ -779,56 +778,6 @@ TEST(MockMethodMockFunctionTest, AsStdFunctionWithReferenceParameter) {
EXPECT_EQ(-1, call(foo.AsStdFunction(), i)); EXPECT_EQ(-1, call(foo.AsStdFunction(), i));
} }
namespace {
template <typename Expected, typename F>
static constexpr bool IsMockFunctionTemplateArgumentDeducedTo(
const MockFunction<F>&) {
return std::is_same<F, Expected>::value;
}
} // namespace
template <typename F>
class MockMethodMockFunctionSignatureTest : public Test {};
using MockMethodMockFunctionSignatureTypes =
Types<void(), int(), void(int), int(int), int(bool, int),
int(bool, char, int, int, int, int, int, char, int, bool)>;
TYPED_TEST_SUITE(MockMethodMockFunctionSignatureTest,
MockMethodMockFunctionSignatureTypes);
TYPED_TEST(MockMethodMockFunctionSignatureTest,
IsMockFunctionTemplateArgumentDeducedForRawSignature) {
using Argument = TypeParam;
MockFunction<Argument> foo;
EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<Argument>(foo));
}
TYPED_TEST(MockMethodMockFunctionSignatureTest,
IsMockFunctionTemplateArgumentDeducedForStdFunction) {
using Argument = std::function<TypeParam>;
MockFunction<Argument> foo;
EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo<Argument>(foo));
}
TYPED_TEST(
MockMethodMockFunctionSignatureTest,
IsMockFunctionCallMethodSignatureTheSameForRawSignatureAndStdFunction) {
using ForRawSignature = decltype(&MockFunction<TypeParam>::Call);
using ForStdFunction =
decltype(&MockFunction<std::function<TypeParam>>::Call);
EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value));
}
TYPED_TEST(
MockMethodMockFunctionSignatureTest,
IsMockFunctionAsStdFunctionMethodSignatureTheSameForRawSignatureAndStdFunction) {
using ForRawSignature = decltype(&MockFunction<TypeParam>::AsStdFunction);
using ForStdFunction =
decltype(&MockFunction<std::function<TypeParam>>::AsStdFunction);
EXPECT_TRUE((std::is_same<ForRawSignature, ForStdFunction>::value));
}
struct MockMethodSizes0 { struct MockMethodSizes0 {
MOCK_METHOD(void, func, ()); MOCK_METHOD(void, func, ());

View File

@ -765,11 +765,10 @@ TEST(SafeMatcherCastTest, FromConstReferenceToReference) {
// Tests that MatcherCast<const T&>(m) works when m is a Matcher<T>. // Tests that MatcherCast<const T&>(m) works when m is a Matcher<T>.
TEST(SafeMatcherCastTest, FromNonReferenceToConstReference) { TEST(SafeMatcherCastTest, FromNonReferenceToConstReference) {
Matcher<std::unique_ptr<int>> m1 = IsNull(); Matcher<int> m1 = Eq(0);
Matcher<const std::unique_ptr<int>&> m2 = Matcher<const int&> m2 = SafeMatcherCast<const int&>(m1);
SafeMatcherCast<const std::unique_ptr<int>&>(m1); EXPECT_TRUE(m2.Matches(0));
EXPECT_TRUE(m2.Matches(std::unique_ptr<int>())); EXPECT_FALSE(m2.Matches(1));
EXPECT_FALSE(m2.Matches(std::unique_ptr<int>(new int)));
} }
// Tests that SafeMatcherCast<T&>(m) works when m is a Matcher<T>. // Tests that SafeMatcherCast<T&>(m) works when m is a Matcher<T>.
@ -4726,18 +4725,20 @@ TEST(SizeIsTest, ExplainsResult) {
Matcher<vector<int> > m1 = SizeIs(2); Matcher<vector<int> > m1 = SizeIs(2);
Matcher<vector<int> > m2 = SizeIs(Lt(2u)); Matcher<vector<int> > m2 = SizeIs(Lt(2u));
Matcher<vector<int> > m3 = SizeIs(AnyOf(0, 3)); Matcher<vector<int> > m3 = SizeIs(AnyOf(0, 3));
Matcher<vector<int> > m4 = SizeIs(Gt(1u)); Matcher<vector<int> > m4 = SizeIs(GreaterThan(1));
vector<int> container; vector<int> container;
EXPECT_EQ("whose size 0 doesn't match", Explain(m1, container)); EXPECT_EQ("whose size 0 doesn't match", Explain(m1, container));
EXPECT_EQ("whose size 0 matches", Explain(m2, container)); EXPECT_EQ("whose size 0 matches", Explain(m2, container));
EXPECT_EQ("whose size 0 matches", Explain(m3, container)); EXPECT_EQ("whose size 0 matches", Explain(m3, container));
EXPECT_EQ("whose size 0 doesn't match", Explain(m4, container)); EXPECT_EQ("whose size 0 doesn't match, which is 1 less than 1",
Explain(m4, container));
container.push_back(0); container.push_back(0);
container.push_back(0); container.push_back(0);
EXPECT_EQ("whose size 2 matches", Explain(m1, container)); EXPECT_EQ("whose size 2 matches", Explain(m1, container));
EXPECT_EQ("whose size 2 doesn't match", Explain(m2, container)); EXPECT_EQ("whose size 2 doesn't match", Explain(m2, container));
EXPECT_EQ("whose size 2 doesn't match", Explain(m3, container)); EXPECT_EQ("whose size 2 doesn't match", Explain(m3, container));
EXPECT_EQ("whose size 2 matches", Explain(m4, container)); EXPECT_EQ("whose size 2 matches, which is 1 more than 1",
Explain(m4, container));
} }
#if GTEST_HAS_TYPED_TEST #if GTEST_HAS_TYPED_TEST

View File

@ -189,9 +189,9 @@ or
When Google Test uses pthread, you may need to add flags to your compiler and/or When Google Test uses pthread, you may need to add flags to your compiler and/or
linker to select the pthread library, or you'll get link errors. If you use the linker to select the pthread library, or you'll get link errors. If you use the
CMake script, this is taken care of for you. If you use your own build script, CMake script or the deprecated Autotools script, this is taken care of for you.
you'll need to read your compiler and linker's manual to figure out what flags If you use your own build script, you'll need to read your compiler and linker's
to add. manual to figure out what flags to add.
### As a Shared Library (DLL) ### As a Shared Library (DLL)

View File

@ -2116,15 +2116,6 @@ For example:
everything in test suite `FooTest` except `FooTest.Bar` and everything in everything in test suite `FooTest` except `FooTest.Bar` and everything in
test suite `BarTest` except `BarTest.Foo`. test suite `BarTest` except `BarTest.Foo`.
#### Stop test execution upon first failure
By default, a googletest program runs all tests the user has defined. In some
cases (e.g. iterative test development & execution) it may be desirable stop
test execution upon first failure (trading improved latency for completeness).
If `GTEST_FAIL_FAST` environment variable or `--gtest_fail_fast` flag is set,
the test runner will stop execution as soon as the first test failure is
found.
#### Temporarily Disabling Tests #### Temporarily Disabling Tests
If you have a broken test that you cannot fix right away, you can add the If you have a broken test that you cannot fix right away, you can add the

View File

@ -119,91 +119,106 @@
namespace testing { namespace testing {
// Definitions in the internal* namespaces are subject to change without notice. // Definitions in the 'internal' and 'internal2' name spaces are
// DO NOT USE THEM IN USER CODE! // subject to change without notice. DO NOT USE THEM IN USER CODE!
namespace internal { namespace internal2 {
// 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);
// For selecting which printer to use when a given type has neither <<
// nor PrintTo().
enum TypeKind {
kProtobuf, // a protobuf type
kConvertibleToInteger, // a type implicitly convertible to BiggestInt
// (e.g. a named or unnamed enum type)
#if GTEST_INTERNAL_HAS_STRING_VIEW
kConvertibleToStringView, // a type implicitly convertible to
// absl::string_view or std::string_view
#endif
kOtherType // anything else
};
// TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called
// by the universal printer to print a value of type T when neither
// operator<< nor PrintTo() is defined for T, where kTypeKind is the
// "kind" of T as defined by enum TypeKind.
template <typename T, TypeKind kTypeKind>
class TypeWithoutFormatter {
public:
// This default version is called when kTypeKind is kOtherType.
static void PrintValue(const T& value, ::std::ostream* os) {
PrintBytesInObjectTo(
static_cast<const unsigned char*>(
reinterpret_cast<const void*>(std::addressof(value))),
sizeof(value), os);
}
};
// 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.
const size_t kProtobufOneLinerMaxLength = 50;
template <typename T> template <typename T>
void UniversalPrint(const T& value, ::std::ostream* os); class TypeWithoutFormatter<T, kProtobuf> {
public:
// Used to print an STL-style container when the user doesn't define static void PrintValue(const T& value, ::std::ostream* os) {
// a PrintTo() for it. std::string pretty_str = value.ShortDebugString();
struct ContainerPrinter { if (pretty_str.length() > kProtobufOneLinerMaxLength) {
template <typename T, pretty_str = "\n" + value.DebugString();
typename = typename std::enable_if<
(sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
!IsRecursiveContainer<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 << '{';
size_t count = 0;
for (auto&& elem : container) {
if (count > 0) {
*os << ',';
if (count == kMaxCount) { // Enough has been printed.
*os << " ...";
break;
}
}
*os << ' ';
// We cannot call PrintTo(elem, os) here as PrintTo() doesn't
// handle `elem` being a native array.
internal::UniversalPrint(elem, os);
++count;
} }
*os << ("<" + pretty_str + ">");
if (count > 0) {
*os << ' ';
}
*os << '}';
} }
}; };
// Used to print a pointer that is neither a char pointer nor a member template <typename T>
// pointer, when the user doesn't define PrintTo() for it. (A member class TypeWithoutFormatter<T, kConvertibleToInteger> {
// variable pointer or member function pointer doesn't really point to public:
// a location in the address space. Their representation is // Since T has no << operator or PrintTo() but can be implicitly
// implementation-defined. Therefore they will be printed as raw // converted to BiggestInt, we print it as a BiggestInt.
// bytes.) //
struct FunctionPointerPrinter { // Most likely T is an enum type (either named or unnamed), in which
template <typename T, typename = typename std::enable_if< // case printing it as an integer is the desired behavior. In case
std::is_function<T>::value>::type> // T is not an enum, printing it as an integer is the best we can do
static void PrintValue(T* p, ::std::ostream* os) { // given that it has no user-defined printer.
if (p == nullptr) { static void PrintValue(const T& value, ::std::ostream* os) {
*os << "NULL"; const internal::BiggestInt kBigInt = value;
} else { *os << kBigInt;
// T is a function type, so '*os << p' doesn't do what we want
// (it just prints p as bool). We want to print p as a const
// void*.
*os << reinterpret_cast<const void*>(p);
}
} }
}; };
struct PointerPrinter { #if GTEST_INTERNAL_HAS_STRING_VIEW
template <typename T> template <typename T>
static void PrintValue(T* p, ::std::ostream* os) { class TypeWithoutFormatter<T, kConvertibleToStringView> {
if (p == nullptr) { public:
*os << "NULL"; // Since T has neither operator<< nor PrintTo() but can be implicitly
} else { // converted to absl::string_view, we print it as a absl::string_view
// T is not a function type. We just call << to print p, // (or std::string_view).
// relying on ADL to pick up user-defined << for their pointer //
// types, if any. // Note: the implementation is further below, as it depends on
*os << p; // internal::PrintTo symbol which is defined later in the file.
} static void PrintValue(const T& value, ::std::ostream* os);
}
}; };
#endif
namespace internal_stream { // Prints the given value to the given ostream. If the value is a
// protocol message, its debug string is printed; if it's an enum or
struct Sentinel; // of a type implicitly convertible to BiggestInt, it's printed as an
template <typename Char, typename CharTraits, typename T> // integer; otherwise the bytes in the value are printed. This is
Sentinel* operator<<(::std::basic_ostream<Char, CharTraits>& os, const T& x); // what UniversalPrinter<T>::Print() does when it knows nothing about
// type T and T has neither << operator nor PrintTo().
// 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 // A user can override this behavior for a class type Foo by defining
// to probe the type's operator. // a << operator in the namespace where Foo is defined.
//
// We put this operator in namespace 'internal2' instead of 'internal'
// to simplify the implementation, as much code in 'internal' needs to
// use << in STL, which would conflict with our own << were it defined
// in 'internal'.
// //
// Note that this operator<< takes a generic std::basic_ostream<Char, // Note that this operator<< takes a generic std::basic_ostream<Char,
// CharTraits> type instead of the more restricted std::ostream. If // CharTraits> type instead of the more restricted std::ostream. If
@ -214,106 +229,68 @@ Sentinel* operator<<(::std::basic_ostream<Char, CharTraits>& os, const T& x);
// operator<<(std::ostream&, const T&) or // operator<<(std::ostream&, const T&) or
// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more // operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more
// specific. // specific.
template <typename T> template <typename Char, typename CharTraits, typename T>
constexpr bool UseStreamOperator() { ::std::basic_ostream<Char, CharTraits>& operator<<(
return !std::is_same<decltype(std::declval<std::ostream&>() ::std::basic_ostream<Char, CharTraits>& os, const T& x) {
<< std::declval<const T&>()), TypeWithoutFormatter<T, (internal::IsAProtocolMessage<T>::value
Sentinel*>::value; ? kProtobuf
} : std::is_convertible<
const T&, internal::BiggestInt>::value
} // namespace internal_stream ? kConvertibleToInteger
:
struct StreamPrinter {
template <typename T, typename = typename std::enable_if<
internal_stream::UseStreamOperator<T>()>::type>
static void PrintValue(const T& value, ::std::ostream* os) {
*os << value;
}
};
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>
static void PrintValue(const T& value, ::std::ostream* os) {
std::string pretty_str = value.ShortDebugString();
if (pretty_str.length() > kProtobufOneLinerMaxLength) {
pretty_str = "\n" + value.DebugString();
}
*os << ("<" + pretty_str + ">");
}
};
struct ConvertibleToIntegerPrinter {
// Since T has no << operator or PrintTo() but can be implicitly
// converted to BiggestInt, we print it as a BiggestInt.
//
// Most likely T is an enum type (either named or unnamed), in which
// case printing it as an integer is the desired behavior. In case
// T is not an enum, printing it as an integer is the best we can do
// given that it has no user-defined printer.
static void PrintValue(internal::BiggestInt value, ::std::ostream* os) {
*os << value;
}
};
struct ConvertibleToStringViewPrinter {
#if GTEST_INTERNAL_HAS_STRING_VIEW #if GTEST_INTERNAL_HAS_STRING_VIEW
static void PrintValue(internal::StringView value, ::std::ostream* os) { std::is_convertible<
internal::UniversalPrint(value, os); const T&, internal::StringView>::value
} ? kConvertibleToStringView
:
#endif #endif
}; kOtherType)>::PrintValue(x, &os);
return os;
// 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>
static void PrintValue(const T& value, ::std::ostream* os) {
PrintBytesInObjectTo(
static_cast<const unsigned char*>(
reinterpret_cast<const void*>(std::addressof(value))),
sizeof(value), os);
}
};
// 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...> {};
template <typename T, typename Printer, typename... Printers>
struct FindFirstPrinter<
T, decltype(Printer::PrintValue(std::declval<const T&>(), nullptr)),
Printer, Printers...> {
using type = Printer;
};
// Select the best printer in the following order:
// - Print containers (they have begin/end/etc).
// - Print function pointers.
// - Print object pointers.
// - Use the stream operator, if available.
// - Print protocol buffers.
// - Print types convertible to BiggestInt.
// - Print types convertible to StringView, if available.
// - Fallback to printing the raw bytes of the object.
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;
Printer::PrintValue(value, os);
} }
} // namespace internal2
} // namespace testing
// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up
// magic needed for implementing UniversalPrinter won't work.
namespace testing_internal {
// Used to print a value that is not an STL-style container when the
// user doesn't define PrintTo() for it.
template <typename T>
void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) {
// With the following statement, during unqualified name lookup,
// testing::internal2::operator<< appears as if it was declared in
// the nearest enclosing namespace that contains both
// ::testing_internal and ::testing::internal2, i.e. the global
// namespace. For more details, refer to the C++ Standard section
// 7.3.4-1 [namespace.udir]. This allows us to fall back onto
// testing::internal2::operator<< in case T doesn't come with a <<
// operator.
using ::testing::internal2::operator<<;
// Assuming T is defined in namespace foo, in the next statement,
// the compiler will consider all of:
//
// 1. foo::operator<< (thanks to Koenig look-up),
// 2. ::operator<< (as the current namespace is enclosed in ::),
// 3. testing::internal2::operator<< (thanks to the using statement above).
//
// The operator<< whose type matches T best will be picked.
//
// We deliberately allow #2 to be a candidate, as sometimes it's
// impossible to define #1 (e.g. when foo is ::std, defining
// anything in it is undefined behavior unless you are a compiler
// vendor.).
*os << value;
}
} // namespace testing_internal
namespace testing {
namespace internal {
// FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a // FormatForComparison<ToPrint, OtherOperand>::Format(value) formats a
// value of type ToPrint that is an operand of a comparison assertion // value of type ToPrint that is an operand of a comparison assertion
// (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in // (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in
@ -411,6 +388,85 @@ std::string FormatForComparisonFailureMessage(
template <typename T> template <typename T>
class UniversalPrinter; class UniversalPrinter;
template <typename T>
void UniversalPrint(const T& value, ::std::ostream* os);
enum DefaultPrinterType {
kPrintContainer,
kPrintPointer,
kPrintFunctionPointer,
kPrintOther,
};
template <DefaultPrinterType type> struct WrapPrinterType {};
// Used to print an STL-style container when the user doesn't define
// a PrintTo() for it.
template <typename C>
void DefaultPrintTo(WrapPrinterType<kPrintContainer> /* dummy */,
const C& container, ::std::ostream* os) {
const size_t kMaxCount = 32; // The maximum number of elements to print.
*os << '{';
size_t count = 0;
for (typename C::const_iterator it = container.begin();
it != container.end(); ++it, ++count) {
if (count > 0) {
*os << ',';
if (count == kMaxCount) { // Enough has been printed.
*os << " ...";
break;
}
}
*os << ' ';
// We cannot call PrintTo(*it, os) here as PrintTo() doesn't
// handle *it being a native array.
internal::UniversalPrint(*it, os);
}
if (count > 0) {
*os << ' ';
}
*os << '}';
}
// Used to print a pointer that is neither a char pointer nor a member
// pointer, when the user doesn't define PrintTo() for it. (A member
// variable pointer or member function pointer doesn't really point to
// a location in the address space. Their representation is
// implementation-defined. Therefore they will be printed as raw
// bytes.)
template <typename T>
void DefaultPrintTo(WrapPrinterType<kPrintPointer> /* dummy */,
T* p, ::std::ostream* os) {
if (p == nullptr) {
*os << "NULL";
} else {
// T is not a function type. We just call << to print p,
// relying on ADL to pick up user-defined << for their pointer
// types, if any.
*os << p;
}
}
template <typename T>
void DefaultPrintTo(WrapPrinterType<kPrintFunctionPointer> /* dummy */,
T* p, ::std::ostream* os) {
if (p == nullptr) {
*os << "NULL";
} else {
// T is a function type, so '*os << p' doesn't do what we want
// (it just prints p as bool). We want to print p as a const
// void*.
*os << reinterpret_cast<const void*>(p);
}
}
// Used to print a non-container, non-pointer value when the user
// doesn't define PrintTo() for it.
template <typename T>
void DefaultPrintTo(WrapPrinterType<kPrintOther> /* dummy */,
const T& value, ::std::ostream* os) {
::testing_internal::DefaultPrintNonContainerTo(value, os);
}
// Prints the given value using the << operator if it has one; // Prints the given value using the << operator if it has one;
// otherwise prints the bytes in it. This is what // otherwise prints the bytes in it. This is what
// UniversalPrinter<T>::Print() does when PrintTo() is not specialized // UniversalPrinter<T>::Print() does when PrintTo() is not specialized
@ -424,7 +480,36 @@ class UniversalPrinter;
// wants). // wants).
template <typename T> template <typename T>
void PrintTo(const T& value, ::std::ostream* os) { void PrintTo(const T& value, ::std::ostream* os) {
internal::PrintWithFallback(value, os); // DefaultPrintTo() is overloaded. The type of its first argument
// determines which version will be picked.
//
// Note that we check for container types here, prior to we check
// for protocol message types in our operator<<. The rationale is:
//
// For protocol messages, we want to give people a chance to
// override Google Mock's format by defining a PrintTo() or
// operator<<. For STL containers, other formats can be
// incompatible with Google Mock's format for the container
// elements; therefore we check for container types here to ensure
// that our format is used.
//
// Note that MSVC and clang-cl do allow an implicit conversion from
// pointer-to-function to pointer-to-object, but clang-cl warns on it.
// So don't use ImplicitlyConvertible if it can be helped since it will
// cause this warning, and use a separate overload of DefaultPrintTo for
// function pointers so that the `*os << p` in the object pointer overload
// doesn't cause that warning either.
DefaultPrintTo(
WrapPrinterType <
(sizeof(IsContainerTest<T>(0)) == sizeof(IsContainer)) &&
!IsRecursiveContainer<T>::value
? kPrintContainer
: !std::is_pointer<T>::value
? kPrintOther
: std::is_function<typename std::remove_pointer<T>::type>::value
? kPrintFunctionPointer
: kPrintPointer > (),
value, os);
} }
// The following list of PrintTo() overloads tells // The following list of PrintTo() overloads tells
@ -815,6 +900,16 @@ Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) {
} // namespace internal } // namespace internal
#if GTEST_INTERNAL_HAS_STRING_VIEW
namespace internal2 {
template <typename T>
void TypeWithoutFormatter<T, kConvertibleToStringView>::PrintValue(
const T& value, ::std::ostream* os) {
internal::PrintTo(internal::StringView(value), os);
}
} // namespace internal2
#endif
template <typename T> template <typename T>
::std::string PrintToString(const T& value) { ::std::string PrintToString(const T& value) {
::std::stringstream ss; ::std::stringstream ss;

View File

@ -101,10 +101,6 @@ GTEST_DECLARE_bool_(catch_exceptions);
// to let Google Test decide. // to let Google Test decide.
GTEST_DECLARE_string_(color); GTEST_DECLARE_string_(color);
// This flag controls whether the test runner should continue execution past
// first failure.
GTEST_DECLARE_bool_(fail_fast);
// This flag sets up the filter to select by name using a glob pattern // This flag sets up the filter to select by name using a glob pattern
// the tests to run. If the filter is not given all tests are executed. // the tests to run. If the filter is not given all tests are executed.
GTEST_DECLARE_string_(filter); GTEST_DECLARE_string_(filter);
@ -799,9 +795,6 @@ class GTEST_API_ TestInfo {
// deletes it. // deletes it.
void Run(); void Run();
// Skip and records the test result for this object.
void Skip();
static void ClearTestResult(TestInfo* test_info) { static void ClearTestResult(TestInfo* test_info) {
test_info->result_.Clear(); test_info->result_.Clear();
} }
@ -950,9 +943,6 @@ class GTEST_API_ TestSuite {
// Runs every test in this TestSuite. // Runs every test in this TestSuite.
void Run(); void Run();
// Skips the execution of tests under this TestSuite
void Skip();
// Runs SetUpTestSuite() for this TestSuite. This wrapper is needed // Runs SetUpTestSuite() for this TestSuite. This wrapper is needed
// for catching exceptions thrown from SetUpTestSuite(). // for catching exceptions thrown from SetUpTestSuite().
void RunSetUpTestSuite() { void RunSetUpTestSuite() {
@ -1817,6 +1807,12 @@ class GTEST_API_ AssertHelper {
GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper);
}; };
enum GTestColor { COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW };
GTEST_API_ GTEST_ATTRIBUTE_PRINTF_(2, 3) void ColoredPrintf(GTestColor color,
const char* fmt,
...);
} // namespace internal } // namespace internal
// The pure interface class that all value-parameterized tests inherit from. // The pure interface class that all value-parameterized tests inherit from.

View File

@ -252,8 +252,6 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <cerrno>
#include <cstdint> #include <cstdint>
#include <limits> #include <limits>
#include <type_traits> #include <type_traits>
@ -1962,16 +1960,16 @@ namespace posix {
typedef struct _stat StatStruct; typedef struct _stat StatStruct;
# ifdef __BORLANDC__ # ifdef __BORLANDC__
inline int DoIsATTY(int fd) { return isatty(fd); } inline int IsATTY(int fd) { return isatty(fd); }
inline int StrCaseCmp(const char* s1, const char* s2) { inline int StrCaseCmp(const char* s1, const char* s2) {
return stricmp(s1, s2); return stricmp(s1, s2);
} }
inline char* StrDup(const char* src) { return strdup(src); } inline char* StrDup(const char* src) { return strdup(src); }
# else // !__BORLANDC__ # else // !__BORLANDC__
# if GTEST_OS_WINDOWS_MOBILE # if GTEST_OS_WINDOWS_MOBILE
inline int DoIsATTY(int /* fd */) { return 0; } inline int IsATTY(int /* fd */) { return 0; }
# else # else
inline int DoIsATTY(int fd) { return _isatty(fd); } inline int IsATTY(int fd) { return _isatty(fd); }
# endif // GTEST_OS_WINDOWS_MOBILE # endif // GTEST_OS_WINDOWS_MOBILE
inline int StrCaseCmp(const char* s1, const char* s2) { inline int StrCaseCmp(const char* s1, const char* s2) {
return _stricmp(s1, s2); return _stricmp(s1, s2);
@ -1996,7 +1994,7 @@ inline bool IsDir(const StatStruct& st) {
typedef struct stat StatStruct; typedef struct stat StatStruct;
inline int FileNo(FILE* file) { return fileno(file); } inline int FileNo(FILE* file) { return fileno(file); }
inline int DoIsATTY(int fd) { return isatty(fd); } inline int IsATTY(int fd) { return isatty(fd); }
inline int Stat(const char* path, StatStruct* buf) { inline int Stat(const char* path, StatStruct* buf) {
// stat function not implemented on ESP8266 // stat function not implemented on ESP8266
return 0; return 0;
@ -2013,7 +2011,7 @@ inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
typedef struct stat StatStruct; typedef struct stat StatStruct;
inline int FileNo(FILE* file) { return fileno(file); } inline int FileNo(FILE* file) { return fileno(file); }
inline int DoIsATTY(int fd) { return isatty(fd); } inline int IsATTY(int fd) { return isatty(fd); }
inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); }
inline int StrCaseCmp(const char* s1, const char* s2) { inline int StrCaseCmp(const char* s1, const char* s2) {
return strcasecmp(s1, s2); return strcasecmp(s1, s2);
@ -2024,17 +2022,6 @@ inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
inline int IsATTY(int fd) {
// DoIsATTY might change errno (for example ENOTTY in case you redirect stdout
// to a file on Linux), which is unexpected, so save the previous value, and
// restore it after the call.
int savedErrno = errno;
int isAttyValue = DoIsATTY(fd);
errno = savedErrno;
return isAttyValue;
}
// Functions deprecated by MSVC 8.0. // Functions deprecated by MSVC 8.0.
GTEST_DISABLE_MSC_DEPRECATED_PUSH_() GTEST_DISABLE_MSC_DEPRECATED_PUSH_()

View File

@ -84,7 +84,6 @@ const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests";
const char kBreakOnFailureFlag[] = "break_on_failure"; const char kBreakOnFailureFlag[] = "break_on_failure";
const char kCatchExceptionsFlag[] = "catch_exceptions"; const char kCatchExceptionsFlag[] = "catch_exceptions";
const char kColorFlag[] = "color"; const char kColorFlag[] = "color";
const char kFailFast[] = "fail_fast";
const char kFilterFlag[] = "filter"; const char kFilterFlag[] = "filter";
const char kListTestsFlag[] = "list_tests"; const char kListTestsFlag[] = "list_tests";
const char kOutputFlag[] = "output"; const char kOutputFlag[] = "output";
@ -165,7 +164,6 @@ class GTestFlagSaver {
color_ = GTEST_FLAG(color); color_ = GTEST_FLAG(color);
death_test_style_ = GTEST_FLAG(death_test_style); death_test_style_ = GTEST_FLAG(death_test_style);
death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); death_test_use_fork_ = GTEST_FLAG(death_test_use_fork);
fail_fast_ = GTEST_FLAG(fail_fast);
filter_ = GTEST_FLAG(filter); filter_ = GTEST_FLAG(filter);
internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); internal_run_death_test_ = GTEST_FLAG(internal_run_death_test);
list_tests_ = GTEST_FLAG(list_tests); list_tests_ = GTEST_FLAG(list_tests);
@ -189,7 +187,6 @@ class GTestFlagSaver {
GTEST_FLAG(death_test_style) = death_test_style_; GTEST_FLAG(death_test_style) = death_test_style_;
GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; GTEST_FLAG(death_test_use_fork) = death_test_use_fork_;
GTEST_FLAG(filter) = filter_; GTEST_FLAG(filter) = filter_;
GTEST_FLAG(fail_fast) = fail_fast_;
GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; GTEST_FLAG(internal_run_death_test) = internal_run_death_test_;
GTEST_FLAG(list_tests) = list_tests_; GTEST_FLAG(list_tests) = list_tests_;
GTEST_FLAG(output) = output_; GTEST_FLAG(output) = output_;
@ -211,7 +208,6 @@ class GTestFlagSaver {
std::string color_; std::string color_;
std::string death_test_style_; std::string death_test_style_;
bool death_test_use_fork_; bool death_test_use_fork_;
bool fail_fast_;
std::string filter_; std::string filter_;
std::string internal_run_death_test_; std::string internal_run_death_test_;
bool list_tests_; bool list_tests_;

View File

@ -104,7 +104,7 @@ void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count,
} // namespace } // namespace
namespace internal { namespace internal2 {
// Delegates to PrintBytesInObjectToImpl() to print the bytes in the // Delegates to PrintBytesInObjectToImpl() to print the bytes in the
// given object. The delegation simplifies the implementation, which // given object. The delegation simplifies the implementation, which
@ -116,6 +116,10 @@ void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count,
PrintBytesInObjectToImpl(obj_bytes, count, os); PrintBytesInObjectToImpl(obj_bytes, count, os);
} }
} // namespace internal2
namespace internal {
// Depending on the value of a char (or wchar_t), we print it in one // Depending on the value of a char (or wchar_t), we print it in one
// of three formats: // of three formats:
// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), // - as is if it's a printable ASCII (e.g. 'a', '2', ' '),

View File

@ -213,21 +213,6 @@ static const char* GetDefaultFilter() {
return kUniversalFilter; return kUniversalFilter;
} }
// Bazel passes in the argument to '--test_runner_fail_fast' via the
// TESTBRIDGE_TEST_RUNNER_FAIL_FAST environment variable.
static bool GetDefaultFailFast() {
const char* const testbridge_test_runner_fail_fast =
internal::posix::GetEnv("TESTBRIDGE_TEST_RUNNER_FAIL_FAST");
if (testbridge_test_runner_fail_fast != nullptr) {
return strcmp(testbridge_test_runner_fail_fast, "1") == 0;
}
return false;
}
GTEST_DEFINE_bool_(
fail_fast, internal::BoolFromGTestEnv("fail_fast", GetDefaultFailFast()),
"True if and only if a test failure should stop further test execution.");
GTEST_DEFINE_bool_( GTEST_DEFINE_bool_(
also_run_disabled_tests, also_run_disabled_tests,
internal::BoolFromGTestEnv("also_run_disabled_tests", false), internal::BoolFromGTestEnv("also_run_disabled_tests", false),
@ -2283,7 +2268,7 @@ static const char* const kReservedOutputTestCaseAttributes[] = {
"classname", "name", "status", "time", "type_param", "classname", "name", "status", "time", "type_param",
"value_param", "file", "line", "result", "timestamp"}; "value_param", "file", "line", "result", "timestamp"};
template <size_t kSize> template <int kSize>
std::vector<std::string> ArrayAsVector(const char* const (&array)[kSize]) { std::vector<std::string> ArrayAsVector(const char* const (&array)[kSize]) {
return std::vector<std::string>(array, array + kSize); return std::vector<std::string>(array, array + kSize);
} }
@ -2878,28 +2863,6 @@ void TestInfo::Run() {
impl->set_current_test_info(nullptr); impl->set_current_test_info(nullptr);
} }
// Skip and records a skipped test result for this object.
void TestInfo::Skip() {
if (!should_run_) return;
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
impl->set_current_test_info(this);
TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
// Notifies the unit test event listeners that a test is about to start.
repeater->OnTestStart(*this);
const TestPartResult test_part_result =
TestPartResult(TestPartResult::kSkip, this->file(), this->line(), "");
impl->GetTestPartResultReporterForCurrentThread()->ReportTestPartResult(
test_part_result);
// Notifies the unit test event listener that a test has just finished.
repeater->OnTestEnd(*this);
impl->set_current_test_info(nullptr);
}
// class TestSuite // class TestSuite
// Gets the number of successful tests in this test suite. // Gets the number of successful tests in this test suite.
@ -3012,12 +2975,6 @@ void TestSuite::Run() {
start_timestamp_ = internal::GetTimeInMillis(); start_timestamp_ = internal::GetTimeInMillis();
for (int i = 0; i < total_test_count(); i++) { for (int i = 0; i < total_test_count(); i++) {
GetMutableTestInfo(i)->Run(); GetMutableTestInfo(i)->Run();
if (GTEST_FLAG(fail_fast) && GetMutableTestInfo(i)->result()->Failed()) {
for (int j = i + 1; j < total_test_count(); j++) {
GetMutableTestInfo(j)->Skip();
}
break;
}
} }
elapsed_time_ = internal::GetTimeInMillis() - start_timestamp_; elapsed_time_ = internal::GetTimeInMillis() - start_timestamp_;
@ -3035,36 +2992,6 @@ void TestSuite::Run() {
impl->set_current_test_suite(nullptr); impl->set_current_test_suite(nullptr);
} }
// Skips all tests under this TestSuite.
void TestSuite::Skip() {
if (!should_run_) return;
internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
impl->set_current_test_suite(this);
TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater();
// Call both legacy and the new API
repeater->OnTestSuiteStart(*this);
// Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI
repeater->OnTestCaseStart(*this);
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI
for (int i = 0; i < total_test_count(); i++) {
GetMutableTestInfo(i)->Skip();
}
// Call both legacy and the new API
repeater->OnTestSuiteEnd(*this);
// Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI
repeater->OnTestCaseEnd(*this);
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI
impl->set_current_test_suite(nullptr);
}
// Clears the results of all tests in this test suite. // Clears the results of all tests in this test suite.
void TestSuite::ClearResult() { void TestSuite::ClearResult() {
ad_hoc_test_result_.Clear(); ad_hoc_test_result_.Clear();
@ -3129,9 +3056,6 @@ static const char * TestPartResultTypeToString(TestPartResult::Type type) {
} }
namespace internal { namespace internal {
namespace {
enum class GTestColor { kDefault, kRed, kGreen, kYellow };
} // namespace
// Prints a TestPartResult to an std::string. // Prints a TestPartResult to an std::string.
static std::string PrintTestPartResultToString( static std::string PrintTestPartResultToString(
@ -3169,12 +3093,9 @@ static void PrintTestPartResult(const TestPartResult& test_part_result) {
// Returns the character attribute for the given color. // Returns the character attribute for the given color.
static WORD GetColorAttribute(GTestColor color) { static WORD GetColorAttribute(GTestColor color) {
switch (color) { switch (color) {
case GTestColor::kRed: case COLOR_RED: return FOREGROUND_RED;
return FOREGROUND_RED; case COLOR_GREEN: return FOREGROUND_GREEN;
case GTestColor::kGreen: case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN;
return FOREGROUND_GREEN;
case GTestColor::kYellow:
return FOREGROUND_RED | FOREGROUND_GREEN;
default: return 0; default: return 0;
} }
} }
@ -3212,16 +3133,13 @@ static WORD GetNewColor(GTestColor color, WORD old_color_attrs) {
#else #else
// Returns the ANSI color code for the given color. GTestColor::kDefault is // Returns the ANSI color code for the given color. COLOR_DEFAULT is
// an invalid input. // an invalid input.
static const char* GetAnsiColorCode(GTestColor color) { static const char* GetAnsiColorCode(GTestColor color) {
switch (color) { switch (color) {
case GTestColor::kRed: case COLOR_RED: return "1";
return "1"; case COLOR_GREEN: return "2";
case GTestColor::kGreen: case COLOR_YELLOW: return "3";
return "2";
case GTestColor::kYellow:
return "3";
default: default:
return nullptr; return nullptr;
} }
@ -3270,7 +3188,6 @@ bool ShouldUseColor(bool stdout_is_tty) {
// cannot simply emit special characters and have the terminal change colors. // cannot simply emit special characters and have the terminal change colors.
// This routine must actually emit the characters rather than return a string // This routine must actually emit the characters rather than return a string
// that would be colored when printed, as can be done on Linux. // that would be colored when printed, as can be done on Linux.
void ColoredPrintf(GTestColor color, const char* fmt, ...) { void ColoredPrintf(GTestColor color, const char* fmt, ...) {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
@ -3281,7 +3198,7 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) {
#else #else
static const bool in_color_mode = static const bool in_color_mode =
ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0);
const bool use_color = in_color_mode && (color != GTestColor::kDefault); const bool use_color = in_color_mode && (color != COLOR_DEFAULT);
#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS #endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS
if (!use_color) { if (!use_color) {
@ -3393,24 +3310,25 @@ void PrettyUnitTestResultPrinter::OnTestIterationStart(
// Prints the filter if it's not *. This reminds the user that some // Prints the filter if it's not *. This reminds the user that some
// tests may be skipped. // tests may be skipped.
if (!String::CStringEquals(filter, kUniversalFilter)) { if (!String::CStringEquals(filter, kUniversalFilter)) {
ColoredPrintf(GTestColor::kYellow, "Note: %s filter = %s\n", GTEST_NAME_, ColoredPrintf(COLOR_YELLOW,
filter); "Note: %s filter = %s\n", GTEST_NAME_, filter);
} }
if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) {
const int32_t shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); const int32_t shard_index = Int32FromEnvOrDie(kTestShardIndex, -1);
ColoredPrintf(GTestColor::kYellow, "Note: This is test shard %d of %s.\n", ColoredPrintf(COLOR_YELLOW,
"Note: This is test shard %d of %s.\n",
static_cast<int>(shard_index) + 1, static_cast<int>(shard_index) + 1,
internal::posix::GetEnv(kTestTotalShards)); internal::posix::GetEnv(kTestTotalShards));
} }
if (GTEST_FLAG(shuffle)) { if (GTEST_FLAG(shuffle)) {
ColoredPrintf(GTestColor::kYellow, ColoredPrintf(COLOR_YELLOW,
"Note: Randomizing tests' orders with a seed of %d .\n", "Note: Randomizing tests' orders with a seed of %d .\n",
unit_test.random_seed()); unit_test.random_seed());
} }
ColoredPrintf(GTestColor::kGreen, "[==========] "); ColoredPrintf(COLOR_GREEN, "[==========] ");
printf("Running %s from %s.\n", printf("Running %s from %s.\n",
FormatTestCount(unit_test.test_to_run_count()).c_str(), FormatTestCount(unit_test.test_to_run_count()).c_str(),
FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str()); FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());
@ -3419,7 +3337,7 @@ void PrettyUnitTestResultPrinter::OnTestIterationStart(
void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart(
const UnitTest& /*unit_test*/) { const UnitTest& /*unit_test*/) {
ColoredPrintf(GTestColor::kGreen, "[----------] "); ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("Global test environment set-up.\n"); printf("Global test environment set-up.\n");
fflush(stdout); fflush(stdout);
} }
@ -3428,7 +3346,7 @@ void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart(
void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) {
const std::string counts = const std::string counts =
FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
ColoredPrintf(GTestColor::kGreen, "[----------] "); ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("%s from %s", counts.c_str(), test_case.name()); printf("%s from %s", counts.c_str(), test_case.name());
if (test_case.type_param() == nullptr) { if (test_case.type_param() == nullptr) {
printf("\n"); printf("\n");
@ -3442,7 +3360,7 @@ void PrettyUnitTestResultPrinter::OnTestSuiteStart(
const TestSuite& test_suite) { const TestSuite& test_suite) {
const std::string counts = const std::string counts =
FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests"); FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests");
ColoredPrintf(GTestColor::kGreen, "[----------] "); ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("%s from %s", counts.c_str(), test_suite.name()); printf("%s from %s", counts.c_str(), test_suite.name());
if (test_suite.type_param() == nullptr) { if (test_suite.type_param() == nullptr) {
printf("\n"); printf("\n");
@ -3454,7 +3372,7 @@ void PrettyUnitTestResultPrinter::OnTestSuiteStart(
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) {
ColoredPrintf(GTestColor::kGreen, "[ RUN ] "); ColoredPrintf(COLOR_GREEN, "[ RUN ] ");
PrintTestName(test_info.test_suite_name(), test_info.name()); PrintTestName(test_info.test_suite_name(), test_info.name());
printf("\n"); printf("\n");
fflush(stdout); fflush(stdout);
@ -3477,11 +3395,11 @@ void PrettyUnitTestResultPrinter::OnTestPartResult(
void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) {
if (test_info.result()->Passed()) { if (test_info.result()->Passed()) {
ColoredPrintf(GTestColor::kGreen, "[ OK ] "); ColoredPrintf(COLOR_GREEN, "[ OK ] ");
} else if (test_info.result()->Skipped()) { } else if (test_info.result()->Skipped()) {
ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] "); ColoredPrintf(COLOR_GREEN, "[ SKIPPED ] ");
} else { } else {
ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); ColoredPrintf(COLOR_RED, "[ FAILED ] ");
} }
PrintTestName(test_info.test_suite_name(), test_info.name()); PrintTestName(test_info.test_suite_name(), test_info.name());
if (test_info.result()->Failed()) if (test_info.result()->Failed())
@ -3502,7 +3420,7 @@ void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) {
const std::string counts = const std::string counts =
FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); FormatCountableNoun(test_case.test_to_run_count(), "test", "tests");
ColoredPrintf(GTestColor::kGreen, "[----------] "); ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_case.name(), printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_case.name(),
internal::StreamableToString(test_case.elapsed_time()).c_str()); internal::StreamableToString(test_case.elapsed_time()).c_str());
fflush(stdout); fflush(stdout);
@ -3513,7 +3431,7 @@ void PrettyUnitTestResultPrinter::OnTestSuiteEnd(const TestSuite& test_suite) {
const std::string counts = const std::string counts =
FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests"); FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests");
ColoredPrintf(GTestColor::kGreen, "[----------] "); ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_suite.name(), printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_suite.name(),
internal::StreamableToString(test_suite.elapsed_time()).c_str()); internal::StreamableToString(test_suite.elapsed_time()).c_str());
fflush(stdout); fflush(stdout);
@ -3522,7 +3440,7 @@ void PrettyUnitTestResultPrinter::OnTestSuiteEnd(const TestSuite& test_suite) {
void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart(
const UnitTest& /*unit_test*/) { const UnitTest& /*unit_test*/) {
ColoredPrintf(GTestColor::kGreen, "[----------] "); ColoredPrintf(COLOR_GREEN, "[----------] ");
printf("Global test environment tear-down\n"); printf("Global test environment tear-down\n");
fflush(stdout); fflush(stdout);
} }
@ -3530,7 +3448,7 @@ void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart(
// Internal helper for printing the list of failed tests. // Internal helper for printing the list of failed tests.
void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) {
const int failed_test_count = unit_test.failed_test_count(); const int failed_test_count = unit_test.failed_test_count();
ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); ColoredPrintf(COLOR_RED, "[ FAILED ] ");
printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str());
for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { for (int i = 0; i < unit_test.total_test_suite_count(); ++i) {
@ -3543,7 +3461,7 @@ void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) {
if (!test_info.should_run() || !test_info.result()->Failed()) { if (!test_info.should_run() || !test_info.result()->Failed()) {
continue; continue;
} }
ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); ColoredPrintf(COLOR_RED, "[ FAILED ] ");
printf("%s.%s", test_suite.name(), test_info.name()); printf("%s.%s", test_suite.name(), test_info.name());
PrintFullTestCommentIfPresent(test_info); PrintFullTestCommentIfPresent(test_info);
printf("\n"); printf("\n");
@ -3564,7 +3482,7 @@ void PrettyUnitTestResultPrinter::PrintFailedTestSuites(
continue; continue;
} }
if (test_suite.ad_hoc_test_result().Failed()) { if (test_suite.ad_hoc_test_result().Failed()) {
ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); ColoredPrintf(COLOR_RED, "[ FAILED ] ");
printf("%s: SetUpTestSuite or TearDownTestSuite\n", test_suite.name()); printf("%s: SetUpTestSuite or TearDownTestSuite\n", test_suite.name());
++suite_failure_count; ++suite_failure_count;
} }
@ -3592,7 +3510,7 @@ void PrettyUnitTestResultPrinter::PrintSkippedTests(const UnitTest& unit_test) {
if (!test_info.should_run() || !test_info.result()->Skipped()) { if (!test_info.should_run() || !test_info.result()->Skipped()) {
continue; continue;
} }
ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] "); ColoredPrintf(COLOR_GREEN, "[ SKIPPED ] ");
printf("%s.%s", test_suite.name(), test_info.name()); printf("%s.%s", test_suite.name(), test_info.name());
printf("\n"); printf("\n");
} }
@ -3601,7 +3519,7 @@ void PrettyUnitTestResultPrinter::PrintSkippedTests(const UnitTest& unit_test) {
void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
int /*iteration*/) { int /*iteration*/) {
ColoredPrintf(GTestColor::kGreen, "[==========] "); ColoredPrintf(COLOR_GREEN, "[==========] ");
printf("%s from %s ran.", printf("%s from %s ran.",
FormatTestCount(unit_test.test_to_run_count()).c_str(), FormatTestCount(unit_test.test_to_run_count()).c_str(),
FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str()); FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str());
@ -3610,12 +3528,12 @@ void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
internal::StreamableToString(unit_test.elapsed_time()).c_str()); internal::StreamableToString(unit_test.elapsed_time()).c_str());
} }
printf("\n"); printf("\n");
ColoredPrintf(GTestColor::kGreen, "[ PASSED ] "); ColoredPrintf(COLOR_GREEN, "[ PASSED ] ");
printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str());
const int skipped_test_count = unit_test.skipped_test_count(); const int skipped_test_count = unit_test.skipped_test_count();
if (skipped_test_count > 0) { if (skipped_test_count > 0) {
ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] "); ColoredPrintf(COLOR_GREEN, "[ SKIPPED ] ");
printf("%s, listed below:\n", FormatTestCount(skipped_test_count).c_str()); printf("%s, listed below:\n", FormatTestCount(skipped_test_count).c_str());
PrintSkippedTests(unit_test); PrintSkippedTests(unit_test);
} }
@ -3630,8 +3548,10 @@ void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test,
if (unit_test.Passed()) { if (unit_test.Passed()) {
printf("\n"); // Add a spacer if no FAILURE banner is displayed. printf("\n"); // Add a spacer if no FAILURE banner is displayed.
} }
ColoredPrintf(GTestColor::kYellow, " YOU HAVE %d DISABLED %s\n\n", ColoredPrintf(COLOR_YELLOW,
num_disabled, num_disabled == 1 ? "TEST" : "TESTS"); " YOU HAVE %d DISABLED %s\n\n",
num_disabled,
num_disabled == 1 ? "TEST" : "TESTS");
} }
// Ensure that Google Test output is printed before, e.g., heapchecker output. // Ensure that Google Test output is printed before, e.g., heapchecker output.
fflush(stdout); fflush(stdout);
@ -5596,13 +5516,6 @@ bool UnitTestImpl::RunAllTests() {
for (int test_index = 0; test_index < total_test_suite_count(); for (int test_index = 0; test_index < total_test_suite_count();
test_index++) { test_index++) {
GetMutableSuiteCase(test_index)->Run(); GetMutableSuiteCase(test_index)->Run();
if (GTEST_FLAG(fail_fast) &&
GetMutableSuiteCase(test_index)->Failed()) {
for (int j = test_index + 1; j < total_test_suite_count(); j++) {
GetMutableSuiteCase(j)->Skip();
}
break;
}
} }
} }
@ -5641,14 +5554,14 @@ bool UnitTestImpl::RunAllTests() {
if (!gtest_is_initialized_before_run_all_tests) { if (!gtest_is_initialized_before_run_all_tests) {
ColoredPrintf( ColoredPrintf(
GTestColor::kRed, COLOR_RED,
"\nIMPORTANT NOTICE - DO NOT IGNORE:\n" "\nIMPORTANT NOTICE - DO NOT IGNORE:\n"
"This test program did NOT call " GTEST_INIT_GOOGLE_TEST_NAME_ "This test program did NOT call " GTEST_INIT_GOOGLE_TEST_NAME_
"() before calling RUN_ALL_TESTS(). This is INVALID. Soon " GTEST_NAME_ "() before calling RUN_ALL_TESTS(). This is INVALID. Soon " GTEST_NAME_
" will start to enforce the valid usage. " " will start to enforce the valid usage. "
"Please fix it ASAP, or IT WILL START TO FAIL.\n"); // NOLINT "Please fix it ASAP, or IT WILL START TO FAIL.\n"); // NOLINT
#if GTEST_FOR_GOOGLE_ #if GTEST_FOR_GOOGLE_
ColoredPrintf(GTestColor::kRed, ColoredPrintf(COLOR_RED,
"For more details, see http://wiki/Main/ValidGUnitMain.\n"); "For more details, see http://wiki/Main/ValidGUnitMain.\n");
#endif // GTEST_FOR_GOOGLE_ #endif // GTEST_FOR_GOOGLE_
} }
@ -5665,7 +5578,7 @@ void WriteToShardStatusFileIfNeeded() {
if (test_shard_file != nullptr) { if (test_shard_file != nullptr) {
FILE* const file = posix::FOpen(test_shard_file, "w"); FILE* const file = posix::FOpen(test_shard_file, "w");
if (file == nullptr) { if (file == nullptr) {
ColoredPrintf(GTestColor::kRed, ColoredPrintf(COLOR_RED,
"Could not write to the test shard status file \"%s\" " "Could not write to the test shard status file \"%s\" "
"specified by the %s environment variable.\n", "specified by the %s environment variable.\n",
test_shard_file, kTestShardStatusFile); test_shard_file, kTestShardStatusFile);
@ -5699,7 +5612,7 @@ bool ShouldShard(const char* total_shards_env,
<< "Invalid environment variables: you have " << "Invalid environment variables: you have "
<< kTestShardIndex << " = " << shard_index << kTestShardIndex << " = " << shard_index
<< ", but have left " << kTestTotalShards << " unset.\n"; << ", but have left " << kTestTotalShards << " unset.\n";
ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str());
fflush(stdout); fflush(stdout);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} else if (total_shards != -1 && shard_index == -1) { } else if (total_shards != -1 && shard_index == -1) {
@ -5707,7 +5620,7 @@ bool ShouldShard(const char* total_shards_env,
<< "Invalid environment variables: you have " << "Invalid environment variables: you have "
<< kTestTotalShards << " = " << total_shards << kTestTotalShards << " = " << total_shards
<< ", but have left " << kTestShardIndex << " unset.\n"; << ", but have left " << kTestShardIndex << " unset.\n";
ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str());
fflush(stdout); fflush(stdout);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} else if (shard_index < 0 || shard_index >= total_shards) { } else if (shard_index < 0 || shard_index >= total_shards) {
@ -5716,7 +5629,7 @@ bool ShouldShard(const char* total_shards_env,
<< kTestShardIndex << " < " << kTestTotalShards << kTestShardIndex << " < " << kTestTotalShards
<< ", but you have " << kTestShardIndex << "=" << shard_index << ", but you have " << kTestShardIndex << "=" << shard_index
<< ", " << kTestTotalShards << "=" << total_shards << ".\n"; << ", " << kTestTotalShards << "=" << total_shards << ".\n";
ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str());
fflush(stdout); fflush(stdout);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
@ -6106,7 +6019,7 @@ static bool HasGoogleTestFlagPrefix(const char* str) {
// @D changes to the default terminal text color. // @D changes to the default terminal text color.
// //
static void PrintColorEncoded(const char* str) { static void PrintColorEncoded(const char* str) {
GTestColor color = GTestColor::kDefault; // The current color. GTestColor color = COLOR_DEFAULT; // The current color.
// Conceptually, we split the string into segments divided by escape // Conceptually, we split the string into segments divided by escape
// sequences. Then we print one segment at a time. At the end of // sequences. Then we print one segment at a time. At the end of
@ -6126,13 +6039,13 @@ static void PrintColorEncoded(const char* str) {
if (ch == '@') { if (ch == '@') {
ColoredPrintf(color, "@"); ColoredPrintf(color, "@");
} else if (ch == 'D') { } else if (ch == 'D') {
color = GTestColor::kDefault; color = COLOR_DEFAULT;
} else if (ch == 'R') { } else if (ch == 'R') {
color = GTestColor::kRed; color = COLOR_RED;
} else if (ch == 'G') { } else if (ch == 'G') {
color = GTestColor::kGreen; color = COLOR_GREEN;
} else if (ch == 'Y') { } else if (ch == 'Y') {
color = GTestColor::kYellow; color = COLOR_YELLOW;
} else { } else {
--str; --str;
} }
@ -6207,31 +6120,31 @@ static const char kColorEncodedHelpMessage[] =
static bool ParseGoogleTestFlag(const char* const arg) { static bool ParseGoogleTestFlag(const char* const arg) {
return ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, return ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag,
&GTEST_FLAG(also_run_disabled_tests)) || &GTEST_FLAG(also_run_disabled_tests)) ||
ParseBoolFlag(arg, kBreakOnFailureFlag, ParseBoolFlag(arg, kBreakOnFailureFlag,
&GTEST_FLAG(break_on_failure)) || &GTEST_FLAG(break_on_failure)) ||
ParseBoolFlag(arg, kCatchExceptionsFlag, ParseBoolFlag(arg, kCatchExceptionsFlag,
&GTEST_FLAG(catch_exceptions)) || &GTEST_FLAG(catch_exceptions)) ||
ParseStringFlag(arg, kColorFlag, &GTEST_FLAG(color)) || ParseStringFlag(arg, kColorFlag, &GTEST_FLAG(color)) ||
ParseStringFlag(arg, kDeathTestStyleFlag, ParseStringFlag(arg, kDeathTestStyleFlag,
&GTEST_FLAG(death_test_style)) || &GTEST_FLAG(death_test_style)) ||
ParseBoolFlag(arg, kDeathTestUseFork, ParseBoolFlag(arg, kDeathTestUseFork,
&GTEST_FLAG(death_test_use_fork)) || &GTEST_FLAG(death_test_use_fork)) ||
ParseBoolFlag(arg, kFailFast, &GTEST_FLAG(fail_fast)) || ParseStringFlag(arg, kFilterFlag, &GTEST_FLAG(filter)) ||
ParseStringFlag(arg, kFilterFlag, &GTEST_FLAG(filter)) || ParseStringFlag(arg, kInternalRunDeathTestFlag,
ParseStringFlag(arg, kInternalRunDeathTestFlag, &GTEST_FLAG(internal_run_death_test)) ||
&GTEST_FLAG(internal_run_death_test)) || ParseBoolFlag(arg, kListTestsFlag, &GTEST_FLAG(list_tests)) ||
ParseBoolFlag(arg, kListTestsFlag, &GTEST_FLAG(list_tests)) || ParseStringFlag(arg, kOutputFlag, &GTEST_FLAG(output)) ||
ParseStringFlag(arg, kOutputFlag, &GTEST_FLAG(output)) || ParseBoolFlag(arg, kPrintTimeFlag, &GTEST_FLAG(print_time)) ||
ParseBoolFlag(arg, kPrintTimeFlag, &GTEST_FLAG(print_time)) || ParseBoolFlag(arg, kPrintUTF8Flag, &GTEST_FLAG(print_utf8)) ||
ParseBoolFlag(arg, kPrintUTF8Flag, &GTEST_FLAG(print_utf8)) || ParseInt32Flag(arg, kRandomSeedFlag, &GTEST_FLAG(random_seed)) ||
ParseInt32Flag(arg, kRandomSeedFlag, &GTEST_FLAG(random_seed)) || ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat)) ||
ParseInt32Flag(arg, kRepeatFlag, &GTEST_FLAG(repeat)) || ParseBoolFlag(arg, kShuffleFlag, &GTEST_FLAG(shuffle)) ||
ParseBoolFlag(arg, kShuffleFlag, &GTEST_FLAG(shuffle)) || ParseInt32Flag(arg, kStackTraceDepthFlag,
ParseInt32Flag(arg, kStackTraceDepthFlag, &GTEST_FLAG(stack_trace_depth)) ||
&GTEST_FLAG(stack_trace_depth)) || ParseStringFlag(arg, kStreamResultToFlag,
ParseStringFlag(arg, kStreamResultToFlag, &GTEST_FLAG(stream_result_to)) ||
&GTEST_FLAG(stream_result_to)) || ParseBoolFlag(arg, kThrowOnFailureFlag,
ParseBoolFlag(arg, kThrowOnFailureFlag, &GTEST_FLAG(throw_on_failure)); &GTEST_FLAG(throw_on_failure));
} }
#if GTEST_USE_OWN_FLAGFILE_FLAG_ #if GTEST_USE_OWN_FLAGFILE_FLAG_

View File

@ -28,6 +28,8 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# #
# Author: misterg@google.com (Gennadiy Civil)
#
# Bazel BUILD for The Google C++ Testing Framework (Google Test) # Bazel BUILD for The Google C++ Testing Framework (Google Test)
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test") load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test")
@ -58,7 +60,6 @@ cc_test(
"googletest-catch-exceptions-test_.cc", "googletest-catch-exceptions-test_.cc",
"googletest-color-test_.cc", "googletest-color-test_.cc",
"googletest-env-var-test_.cc", "googletest-env-var-test_.cc",
"googletest-failfast-unittest_.cc",
"googletest-filter-unittest_.cc", "googletest-filter-unittest_.cc",
"googletest-break-on-failure-unittest_.cc", "googletest-break-on-failure-unittest_.cc",
"googletest-listener-test.cc", "googletest-listener-test.cc",
@ -223,21 +224,6 @@ py_test(
deps = [":gtest_test_utils"], deps = [":gtest_test_utils"],
) )
cc_binary(
name = "googletest-failfast-unittest_",
testonly = 1,
srcs = ["googletest-failfast-unittest_.cc"],
deps = ["//:gtest"],
)
py_test(
name = "googletest-failfast-unittest",
size = "medium",
srcs = ["googletest-failfast-unittest.py"],
data = [":googletest-failfast-unittest_"],
deps = [":gtest_test_utils"],
)
cc_binary( cc_binary(
name = "googletest-filter-unittest_", name = "googletest-filter-unittest_",
testonly = 1, testonly = 1,

View File

@ -85,8 +85,6 @@ class GTestEnvVarTest(gtest_test_utils.TestCase):
TestFlag('break_on_failure', '1', '0') TestFlag('break_on_failure', '1', '0')
TestFlag('color', 'yes', 'auto') TestFlag('color', 'yes', 'auto')
SetEnvVar('TESTBRIDGE_TEST_RUNNER_FAIL_FAST', None) # For 'fail_fast' test
TestFlag('fail_fast', '1', '0')
TestFlag('filter', 'FooTest.Bar', '*') TestFlag('filter', 'FooTest.Bar', '*')
SetEnvVar('XML_OUTPUT_FILE', None) # For 'output' test SetEnvVar('XML_OUTPUT_FILE', None) # For 'output' test
TestFlag('output', 'xml:tmp/foo.xml', '') TestFlag('output', 'xml:tmp/foo.xml', '')

View File

@ -72,11 +72,6 @@ void PrintFlag(const char* flag) {
return; return;
} }
if (strcmp(flag, "fail_fast") == 0) {
cout << GTEST_FLAG(fail_fast);
return;
}
if (strcmp(flag, "filter") == 0) { if (strcmp(flag, "filter") == 0) {
cout << GTEST_FLAG(filter); cout << GTEST_FLAG(filter);
return; return;

View File

@ -1,410 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2020 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.
"""Unit test for Google Test fail_fast.
A user can specify if a Google Test program should continue test execution
after a test failure via the GTEST_FAIL_FAST environment variable or the
--gtest_fail_fast flag. The default value of the flag can also be changed
by Bazel fail fast environment variable TESTBRIDGE_TEST_RUNNER_FAIL_FAST.
This script tests such functionality by invoking googletest-failfast-unittest_
(a program written with Google Test) with different environments and command
line flags.
"""
import os
import gtest_test_utils
# Constants.
# Bazel testbridge environment variable for fail fast
BAZEL_FAIL_FAST_ENV_VAR = 'TESTBRIDGE_TEST_RUNNER_FAIL_FAST'
# The environment variable for specifying fail fast.
FAIL_FAST_ENV_VAR = 'GTEST_FAIL_FAST'
# The command line flag for specifying fail fast.
FAIL_FAST_FLAG = 'gtest_fail_fast'
# The command line flag to run disabled tests.
RUN_DISABLED_FLAG = 'gtest_also_run_disabled_tests'
# The command line flag for specifying a filter.
FILTER_FLAG = 'gtest_filter'
# Command to run the googletest-failfast-unittest_ program.
COMMAND = gtest_test_utils.GetTestExecutablePath(
'googletest-failfast-unittest_')
# The command line flag to tell Google Test to output the list of tests it
# will run.
LIST_TESTS_FLAG = '--gtest_list_tests'
# Indicates whether Google Test supports death tests.
SUPPORTS_DEATH_TESTS = 'HasDeathTest' in gtest_test_utils.Subprocess(
[COMMAND, LIST_TESTS_FLAG]).output
# Utilities.
environ = os.environ.copy()
def SetEnvVar(env_var, value):
"""Sets the env variable to 'value'; unsets it when 'value' is None."""
if value is not None:
environ[env_var] = value
elif env_var in environ:
del environ[env_var]
def RunAndReturnOutput(test_suite=None, fail_fast=None, run_disabled=False):
"""Runs the test program and returns its output."""
args = []
xml_path = os.path.join(gtest_test_utils.GetTempDir(),
'.GTestFailFastUnitTest.xml')
args += ['--gtest_output=xml:' + xml_path]
if fail_fast is not None:
if isinstance(fail_fast, str):
args += ['--%s=%s' % (FAIL_FAST_FLAG, fail_fast)]
elif fail_fast:
args += ['--%s' % FAIL_FAST_FLAG]
else:
args += ['--no%s' % FAIL_FAST_FLAG]
if test_suite:
args += ['--%s=%s.*' % (FILTER_FLAG, test_suite)]
if run_disabled:
args += ['--%s' % RUN_DISABLED_FLAG]
txt_out = gtest_test_utils.Subprocess([COMMAND] + args, env=environ).output
with open(xml_path) as xml_file:
return txt_out, xml_file.read()
# The unit test.
class GTestFailFastUnitTest(gtest_test_utils.TestCase):
"""Tests the env variable or the command line flag for fail_fast."""
def testDefaultBehavior(self):
"""Tests the behavior of not specifying the fail_fast."""
txt, _ = RunAndReturnOutput()
self.assertIn('22 FAILED TEST', txt)
def testGoogletestFlag(self):
txt, _ = RunAndReturnOutput(test_suite='HasSimpleTest', fail_fast=True)
self.assertIn('1 FAILED TEST', txt)
self.assertIn('[ SKIPPED ] 3 tests', txt)
txt, _ = RunAndReturnOutput(test_suite='HasSimpleTest', fail_fast=False)
self.assertIn('4 FAILED TEST', txt)
self.assertNotIn('[ SKIPPED ]', txt)
def testGoogletestEnvVar(self):
"""Tests the behavior of specifying fail_fast via Googletest env var."""
try:
SetEnvVar(FAIL_FAST_ENV_VAR, '1')
txt, _ = RunAndReturnOutput('HasSimpleTest')
self.assertIn('1 FAILED TEST', txt)
self.assertIn('[ SKIPPED ] 3 tests', txt)
SetEnvVar(FAIL_FAST_ENV_VAR, '0')
txt, _ = RunAndReturnOutput('HasSimpleTest')
self.assertIn('4 FAILED TEST', txt)
self.assertNotIn('[ SKIPPED ]', txt)
finally:
SetEnvVar(FAIL_FAST_ENV_VAR, None)
def testBazelEnvVar(self):
"""Tests the behavior of specifying fail_fast via Bazel testbridge."""
try:
SetEnvVar(BAZEL_FAIL_FAST_ENV_VAR, '1')
txt, _ = RunAndReturnOutput('HasSimpleTest')
self.assertIn('1 FAILED TEST', txt)
self.assertIn('[ SKIPPED ] 3 tests', txt)
SetEnvVar(BAZEL_FAIL_FAST_ENV_VAR, '0')
txt, _ = RunAndReturnOutput('HasSimpleTest')
self.assertIn('4 FAILED TEST', txt)
self.assertNotIn('[ SKIPPED ]', txt)
finally:
SetEnvVar(BAZEL_FAIL_FAST_ENV_VAR, None)
def testFlagOverridesEnvVar(self):
"""Tests precedence of flag over env var."""
try:
SetEnvVar(FAIL_FAST_ENV_VAR, '0')
txt, _ = RunAndReturnOutput('HasSimpleTest', True)
self.assertIn('1 FAILED TEST', txt)
self.assertIn('[ SKIPPED ] 3 tests', txt)
finally:
SetEnvVar(FAIL_FAST_ENV_VAR, None)
def testGoogletestEnvVarOverridesBazelEnvVar(self):
"""Tests that the Googletest native env var over Bazel testbridge."""
try:
SetEnvVar(BAZEL_FAIL_FAST_ENV_VAR, '0')
SetEnvVar(FAIL_FAST_ENV_VAR, '1')
txt, _ = RunAndReturnOutput('HasSimpleTest')
self.assertIn('1 FAILED TEST', txt)
self.assertIn('[ SKIPPED ] 3 tests', txt)
finally:
SetEnvVar(FAIL_FAST_ENV_VAR, None)
SetEnvVar(BAZEL_FAIL_FAST_ENV_VAR, None)
def testEventListener(self):
txt, _ = RunAndReturnOutput(test_suite='HasSkipTest', fail_fast=True)
self.assertIn('1 FAILED TEST', txt)
self.assertIn('[ SKIPPED ] 3 tests', txt)
for expected_count, callback in [(1, 'OnTestSuiteStart'),
(5, 'OnTestStart'),
(5, 'OnTestEnd'),
(5, 'OnTestPartResult'),
(1, 'OnTestSuiteEnd')]:
self.assertEqual(
expected_count, txt.count(callback),
'Expected %d calls to callback %s match count on output: %s ' %
(expected_count, callback, txt))
txt, _ = RunAndReturnOutput(test_suite='HasSkipTest', fail_fast=False)
self.assertIn('3 FAILED TEST', txt)
self.assertIn('[ SKIPPED ] 1 test', txt)
for expected_count, callback in [(1, 'OnTestSuiteStart'),
(5, 'OnTestStart'),
(5, 'OnTestEnd'),
(5, 'OnTestPartResult'),
(1, 'OnTestSuiteEnd')]:
self.assertEqual(
expected_count, txt.count(callback),
'Expected %d calls to callback %s match count on output: %s ' %
(expected_count, callback, txt))
def assertXmlResultCount(self, result, count, xml):
self.assertEqual(
count, xml.count('result="%s"' % result),
'Expected \'result="%s"\' match count of %s: %s ' %
(result, count, xml))
def assertXmlStatusCount(self, status, count, xml):
self.assertEqual(
count, xml.count('status="%s"' % status),
'Expected \'status="%s"\' match count of %s: %s ' %
(status, count, xml))
def assertFailFastXmlAndTxtOutput(self,
fail_fast,
test_suite,
passed_count,
failure_count,
skipped_count,
suppressed_count,
run_disabled=False):
"""Assert XML and text output of a test execution."""
txt, xml = RunAndReturnOutput(test_suite, fail_fast, run_disabled)
if failure_count > 0:
self.assertIn('%s FAILED TEST' % failure_count, txt)
if suppressed_count > 0:
self.assertIn('%s DISABLED TEST' % suppressed_count, txt)
if skipped_count > 0:
self.assertIn('[ SKIPPED ] %s tests' % skipped_count, txt)
self.assertXmlStatusCount('run',
passed_count + failure_count + skipped_count, xml)
self.assertXmlStatusCount('notrun', suppressed_count, xml)
self.assertXmlResultCount('completed', passed_count + failure_count, xml)
self.assertXmlResultCount('skipped', skipped_count, xml)
self.assertXmlResultCount('suppressed', suppressed_count, xml)
def assertFailFastBehavior(self,
test_suite,
passed_count,
failure_count,
skipped_count,
suppressed_count,
run_disabled=False):
"""Assert --fail_fast via flag."""
for fail_fast in ('true', '1', 't', True):
self.assertFailFastXmlAndTxtOutput(fail_fast, test_suite, passed_count,
failure_count, skipped_count,
suppressed_count, run_disabled)
def assertNotFailFastBehavior(self,
test_suite,
passed_count,
failure_count,
skipped_count,
suppressed_count,
run_disabled=False):
"""Assert --nofail_fast via flag."""
for fail_fast in ('false', '0', 'f', False):
self.assertFailFastXmlAndTxtOutput(fail_fast, test_suite, passed_count,
failure_count, skipped_count,
suppressed_count, run_disabled)
def testFlag_HasFixtureTest(self):
"""Tests the behavior of fail_fast and TEST_F."""
self.assertFailFastBehavior(
test_suite='HasFixtureTest',
passed_count=1,
failure_count=1,
skipped_count=3,
suppressed_count=0)
self.assertNotFailFastBehavior(
test_suite='HasFixtureTest',
passed_count=1,
failure_count=4,
skipped_count=0,
suppressed_count=0)
def testFlag_HasSimpleTest(self):
"""Tests the behavior of fail_fast and TEST."""
self.assertFailFastBehavior(
test_suite='HasSimpleTest',
passed_count=1,
failure_count=1,
skipped_count=3,
suppressed_count=0)
self.assertNotFailFastBehavior(
test_suite='HasSimpleTest',
passed_count=1,
failure_count=4,
skipped_count=0,
suppressed_count=0)
def testFlag_HasParametersTest(self):
"""Tests the behavior of fail_fast and TEST_P."""
self.assertFailFastBehavior(
test_suite='HasParametersSuite/HasParametersTest',
passed_count=0,
failure_count=1,
skipped_count=3,
suppressed_count=0)
self.assertNotFailFastBehavior(
test_suite='HasParametersSuite/HasParametersTest',
passed_count=0,
failure_count=4,
skipped_count=0,
suppressed_count=0)
def testFlag_HasDisabledTest(self):
"""Tests the behavior of fail_fast and Disabled test cases."""
self.assertFailFastBehavior(
test_suite='HasDisabledTest',
passed_count=1,
failure_count=1,
skipped_count=2,
suppressed_count=1,
run_disabled=False)
self.assertNotFailFastBehavior(
test_suite='HasDisabledTest',
passed_count=1,
failure_count=3,
skipped_count=0,
suppressed_count=1,
run_disabled=False)
def testFlag_HasDisabledRunDisabledTest(self):
"""Tests the behavior of fail_fast and Disabled test cases enabled."""
self.assertFailFastBehavior(
test_suite='HasDisabledTest',
passed_count=1,
failure_count=1,
skipped_count=3,
suppressed_count=0,
run_disabled=True)
self.assertNotFailFastBehavior(
test_suite='HasDisabledTest',
passed_count=1,
failure_count=4,
skipped_count=0,
suppressed_count=0,
run_disabled=True)
def testFlag_HasDisabledSuiteTest(self):
"""Tests the behavior of fail_fast and Disabled test suites."""
self.assertFailFastBehavior(
test_suite='DISABLED_HasDisabledSuite',
passed_count=0,
failure_count=0,
skipped_count=0,
suppressed_count=5,
run_disabled=False)
self.assertNotFailFastBehavior(
test_suite='DISABLED_HasDisabledSuite',
passed_count=0,
failure_count=0,
skipped_count=0,
suppressed_count=5,
run_disabled=False)
def testFlag_HasDisabledSuiteRunDisabledTest(self):
"""Tests the behavior of fail_fast and Disabled test suites enabled."""
self.assertFailFastBehavior(
test_suite='DISABLED_HasDisabledSuite',
passed_count=1,
failure_count=1,
skipped_count=3,
suppressed_count=0,
run_disabled=True)
self.assertNotFailFastBehavior(
test_suite='DISABLED_HasDisabledSuite',
passed_count=1,
failure_count=4,
skipped_count=0,
suppressed_count=0,
run_disabled=True)
if SUPPORTS_DEATH_TESTS:
def testFlag_HasDeathTest(self):
"""Tests the behavior of fail_fast and death tests."""
self.assertFailFastBehavior(
test_suite='HasDeathTest',
passed_count=1,
failure_count=1,
skipped_count=3,
suppressed_count=0)
self.assertNotFailFastBehavior(
test_suite='HasDeathTest',
passed_count=1,
failure_count=4,
skipped_count=0,
suppressed_count=0)
if __name__ == '__main__':
gtest_test_utils.Main()

View File

@ -1,167 +0,0 @@
// 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.
// Unit test for Google Test test filters.
//
// A user can specify which test(s) in a Google Test program to run via
// either the GTEST_FILTER environment variable or the --gtest_filter
// flag. This is used for testing such functionality.
//
// The program will be invoked from a Python unit test. Don't run it
// directly.
#include "gtest/gtest.h"
namespace {
// Test HasFixtureTest.
class HasFixtureTest : public testing::Test {};
TEST_F(HasFixtureTest, Test0) {}
TEST_F(HasFixtureTest, Test1) { FAIL() << "Expected failure."; }
TEST_F(HasFixtureTest, Test2) { FAIL() << "Expected failure."; }
TEST_F(HasFixtureTest, Test3) { FAIL() << "Expected failure."; }
TEST_F(HasFixtureTest, Test4) { FAIL() << "Expected failure."; }
// Test HasSimpleTest.
TEST(HasSimpleTest, Test0) {}
TEST(HasSimpleTest, Test1) { FAIL() << "Expected failure."; }
TEST(HasSimpleTest, Test2) { FAIL() << "Expected failure."; }
TEST(HasSimpleTest, Test3) { FAIL() << "Expected failure."; }
TEST(HasSimpleTest, Test4) { FAIL() << "Expected failure."; }
// Test HasDisabledTest.
TEST(HasDisabledTest, Test0) {}
TEST(HasDisabledTest, DISABLED_Test1) { FAIL() << "Expected failure."; }
TEST(HasDisabledTest, Test2) { FAIL() << "Expected failure."; }
TEST(HasDisabledTest, Test3) { FAIL() << "Expected failure."; }
TEST(HasDisabledTest, Test4) { FAIL() << "Expected failure."; }
// Test HasDeathTest
TEST(HasDeathTest, Test0) { EXPECT_DEATH_IF_SUPPORTED(exit(1), ".*"); }
TEST(HasDeathTest, Test1) {
EXPECT_DEATH_IF_SUPPORTED(FAIL() << "Expected failure.", ".*");
}
TEST(HasDeathTest, Test2) {
EXPECT_DEATH_IF_SUPPORTED(FAIL() << "Expected failure.", ".*");
}
TEST(HasDeathTest, Test3) {
EXPECT_DEATH_IF_SUPPORTED(FAIL() << "Expected failure.", ".*");
}
TEST(HasDeathTest, Test4) {
EXPECT_DEATH_IF_SUPPORTED(FAIL() << "Expected failure.", ".*");
}
// Test DISABLED_HasDisabledSuite
TEST(DISABLED_HasDisabledSuite, Test0) {}
TEST(DISABLED_HasDisabledSuite, Test1) { FAIL() << "Expected failure."; }
TEST(DISABLED_HasDisabledSuite, Test2) { FAIL() << "Expected failure."; }
TEST(DISABLED_HasDisabledSuite, Test3) { FAIL() << "Expected failure."; }
TEST(DISABLED_HasDisabledSuite, Test4) { FAIL() << "Expected failure."; }
// Test HasParametersTest
class HasParametersTest : public testing::TestWithParam<int> {};
TEST_P(HasParametersTest, Test1) { FAIL() << "Expected failure."; }
TEST_P(HasParametersTest, Test2) { FAIL() << "Expected failure."; }
INSTANTIATE_TEST_SUITE_P(HasParametersSuite, HasParametersTest,
testing::Values(1, 2));
class MyTestListener : public ::testing::EmptyTestEventListener {
void OnTestSuiteStart(const ::testing::TestSuite& test_suite) override {
printf("We are in OnTestSuiteStart of %s.\n", test_suite.name());
}
void OnTestStart(const ::testing::TestInfo& test_info) override {
printf("We are in OnTestStart of %s.%s.\n", test_info.test_suite_name(),
test_info.name());
}
void OnTestPartResult(
const ::testing::TestPartResult& test_part_result) override {
printf("We are in OnTestPartResult %s:%d.\n", test_part_result.file_name(),
test_part_result.line_number());
}
void OnTestEnd(const ::testing::TestInfo& test_info) override {
printf("We are in OnTestEnd of %s.%s.\n", test_info.test_suite_name(),
test_info.name());
}
void OnTestSuiteEnd(const ::testing::TestSuite& test_suite) override {
printf("We are in OnTestSuiteEnd of %s.\n", test_suite.name());
}
};
TEST(HasSkipTest, Test0) { SUCCEED() << "Expected success."; }
TEST(HasSkipTest, Test1) { GTEST_SKIP() << "Expected skip."; }
TEST(HasSkipTest, Test2) { FAIL() << "Expected failure."; }
TEST(HasSkipTest, Test3) { FAIL() << "Expected failure."; }
TEST(HasSkipTest, Test4) { FAIL() << "Expected failure."; }
} // namespace
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
::testing::UnitTest::GetInstance()->listeners().Append(new MyTestListener());
return RUN_ALL_TESTS();
}

View File

@ -37,22 +37,21 @@
// code once "gtest.h" has been #included. // code once "gtest.h" has been #included.
// Do not move it after other gtest #includes. // Do not move it after other gtest #includes.
TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) {
bool dummy = testing::GTEST_FLAG(also_run_disabled_tests) || bool dummy = testing::GTEST_FLAG(also_run_disabled_tests)
testing::GTEST_FLAG(break_on_failure) || || testing::GTEST_FLAG(break_on_failure)
testing::GTEST_FLAG(catch_exceptions) || || testing::GTEST_FLAG(catch_exceptions)
testing::GTEST_FLAG(color) != "unknown" || || testing::GTEST_FLAG(color) != "unknown"
testing::GTEST_FLAG(fail_fast) || || testing::GTEST_FLAG(filter) != "unknown"
testing::GTEST_FLAG(filter) != "unknown" || || testing::GTEST_FLAG(list_tests)
testing::GTEST_FLAG(list_tests) || || testing::GTEST_FLAG(output) != "unknown"
testing::GTEST_FLAG(output) != "unknown" || || testing::GTEST_FLAG(print_time)
testing::GTEST_FLAG(print_time) || || testing::GTEST_FLAG(random_seed)
testing::GTEST_FLAG(random_seed) || || testing::GTEST_FLAG(repeat) > 0
testing::GTEST_FLAG(repeat) > 0 || || testing::GTEST_FLAG(show_internal_stack_frames)
testing::GTEST_FLAG(show_internal_stack_frames) || || testing::GTEST_FLAG(shuffle)
testing::GTEST_FLAG(shuffle) || || testing::GTEST_FLAG(stack_trace_depth) > 0
testing::GTEST_FLAG(stack_trace_depth) > 0 || || testing::GTEST_FLAG(stream_result_to) != "unknown"
testing::GTEST_FLAG(stream_result_to) != "unknown" || || testing::GTEST_FLAG(throw_on_failure);
testing::GTEST_FLAG(throw_on_failure);
EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused. EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused.
} }
@ -203,7 +202,6 @@ using testing::GTEST_FLAG(break_on_failure);
using testing::GTEST_FLAG(catch_exceptions); using testing::GTEST_FLAG(catch_exceptions);
using testing::GTEST_FLAG(color); using testing::GTEST_FLAG(color);
using testing::GTEST_FLAG(death_test_use_fork); using testing::GTEST_FLAG(death_test_use_fork);
using testing::GTEST_FLAG(fail_fast);
using testing::GTEST_FLAG(filter); using testing::GTEST_FLAG(filter);
using testing::GTEST_FLAG(list_tests); using testing::GTEST_FLAG(list_tests);
using testing::GTEST_FLAG(output); using testing::GTEST_FLAG(output);
@ -1600,7 +1598,6 @@ class GTestFlagSaverTest : public Test {
GTEST_FLAG(catch_exceptions) = false; GTEST_FLAG(catch_exceptions) = false;
GTEST_FLAG(death_test_use_fork) = false; GTEST_FLAG(death_test_use_fork) = false;
GTEST_FLAG(color) = "auto"; GTEST_FLAG(color) = "auto";
GTEST_FLAG(fail_fast) = false;
GTEST_FLAG(filter) = ""; GTEST_FLAG(filter) = "";
GTEST_FLAG(list_tests) = false; GTEST_FLAG(list_tests) = false;
GTEST_FLAG(output) = ""; GTEST_FLAG(output) = "";
@ -1628,7 +1625,6 @@ class GTestFlagSaverTest : public Test {
EXPECT_FALSE(GTEST_FLAG(catch_exceptions)); EXPECT_FALSE(GTEST_FLAG(catch_exceptions));
EXPECT_STREQ("auto", GTEST_FLAG(color).c_str()); EXPECT_STREQ("auto", GTEST_FLAG(color).c_str());
EXPECT_FALSE(GTEST_FLAG(death_test_use_fork)); EXPECT_FALSE(GTEST_FLAG(death_test_use_fork));
EXPECT_FALSE(GTEST_FLAG(fail_fast));
EXPECT_STREQ("", GTEST_FLAG(filter).c_str()); EXPECT_STREQ("", GTEST_FLAG(filter).c_str());
EXPECT_FALSE(GTEST_FLAG(list_tests)); EXPECT_FALSE(GTEST_FLAG(list_tests));
EXPECT_STREQ("", GTEST_FLAG(output).c_str()); EXPECT_STREQ("", GTEST_FLAG(output).c_str());
@ -1645,7 +1641,6 @@ class GTestFlagSaverTest : public Test {
GTEST_FLAG(catch_exceptions) = true; GTEST_FLAG(catch_exceptions) = true;
GTEST_FLAG(color) = "no"; GTEST_FLAG(color) = "no";
GTEST_FLAG(death_test_use_fork) = true; GTEST_FLAG(death_test_use_fork) = true;
GTEST_FLAG(fail_fast) = true;
GTEST_FLAG(filter) = "abc"; GTEST_FLAG(filter) = "abc";
GTEST_FLAG(list_tests) = true; GTEST_FLAG(list_tests) = true;
GTEST_FLAG(output) = "xml:foo.xml"; GTEST_FLAG(output) = "xml:foo.xml";
@ -5500,22 +5495,20 @@ TEST_F(SetUpTestSuiteTest, TestSetupTestSuite2) {
// The Flags struct stores a copy of all Google Test flags. // The Flags struct stores a copy of all Google Test flags.
struct Flags { struct Flags {
// Constructs a Flags struct where each flag has its default value. // Constructs a Flags struct where each flag has its default value.
Flags() Flags() : also_run_disabled_tests(false),
: also_run_disabled_tests(false), break_on_failure(false),
break_on_failure(false), catch_exceptions(false),
catch_exceptions(false), death_test_use_fork(false),
death_test_use_fork(false), filter(""),
fail_fast(false), list_tests(false),
filter(""), output(""),
list_tests(false), print_time(true),
output(""), random_seed(0),
print_time(true), repeat(1),
random_seed(0), shuffle(false),
repeat(1), stack_trace_depth(kMaxStackTraceDepth),
shuffle(false), stream_result_to(""),
stack_trace_depth(kMaxStackTraceDepth), throw_on_failure(false) {}
stream_result_to(""),
throw_on_failure(false) {}
// Factory methods. // Factory methods.
@ -5551,14 +5544,6 @@ struct Flags {
return flags; return flags;
} }
// Creates a Flags struct where the gtest_fail_fast flag has
// the given value.
static Flags FailFast(bool fail_fast) {
Flags flags;
flags.fail_fast = fail_fast;
return flags;
}
// Creates a Flags struct where the gtest_filter flag has the given // Creates a Flags struct where the gtest_filter flag has the given
// value. // value.
static Flags Filter(const char* filter) { static Flags Filter(const char* filter) {
@ -5644,7 +5629,6 @@ struct Flags {
bool break_on_failure; bool break_on_failure;
bool catch_exceptions; bool catch_exceptions;
bool death_test_use_fork; bool death_test_use_fork;
bool fail_fast;
const char* filter; const char* filter;
bool list_tests; bool list_tests;
const char* output; const char* output;
@ -5666,7 +5650,6 @@ class ParseFlagsTest : public Test {
GTEST_FLAG(break_on_failure) = false; GTEST_FLAG(break_on_failure) = false;
GTEST_FLAG(catch_exceptions) = false; GTEST_FLAG(catch_exceptions) = false;
GTEST_FLAG(death_test_use_fork) = false; GTEST_FLAG(death_test_use_fork) = false;
GTEST_FLAG(fail_fast) = false;
GTEST_FLAG(filter) = ""; GTEST_FLAG(filter) = "";
GTEST_FLAG(list_tests) = false; GTEST_FLAG(list_tests) = false;
GTEST_FLAG(output) = ""; GTEST_FLAG(output) = "";
@ -5697,7 +5680,6 @@ class ParseFlagsTest : public Test {
EXPECT_EQ(expected.break_on_failure, GTEST_FLAG(break_on_failure)); EXPECT_EQ(expected.break_on_failure, GTEST_FLAG(break_on_failure));
EXPECT_EQ(expected.catch_exceptions, GTEST_FLAG(catch_exceptions)); EXPECT_EQ(expected.catch_exceptions, GTEST_FLAG(catch_exceptions));
EXPECT_EQ(expected.death_test_use_fork, GTEST_FLAG(death_test_use_fork)); EXPECT_EQ(expected.death_test_use_fork, GTEST_FLAG(death_test_use_fork));
EXPECT_EQ(expected.fail_fast, GTEST_FLAG(fail_fast));
EXPECT_STREQ(expected.filter, GTEST_FLAG(filter).c_str()); EXPECT_STREQ(expected.filter, GTEST_FLAG(filter).c_str());
EXPECT_EQ(expected.list_tests, GTEST_FLAG(list_tests)); EXPECT_EQ(expected.list_tests, GTEST_FLAG(list_tests));
EXPECT_STREQ(expected.output, GTEST_FLAG(output).c_str()); EXPECT_STREQ(expected.output, GTEST_FLAG(output).c_str());
@ -5784,15 +5766,6 @@ TEST_F(ParseFlagsTest, NoFlag) {
GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false); GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags(), false);
} }
// Tests parsing --gtest_fail_fast.
TEST_F(ParseFlagsTest, FailFast) {
const char* argv[] = {"foo.exe", "--gtest_fail_fast", nullptr};
const char* argv2[] = {"foo.exe", nullptr};
GTEST_TEST_PARSING_FLAGS_(argv, argv2, Flags::FailFast(true), false);
}
// Tests parsing a bad --gtest_filter flag. // Tests parsing a bad --gtest_filter flag.
TEST_F(ParseFlagsTest, FilterBad) { TEST_F(ParseFlagsTest, FilterBad) {
const char* argv[] = {"foo.exe", "--gtest_filter", nullptr}; const char* argv[] = {"foo.exe", "--gtest_filter", nullptr};