From dee725b05332ca59a679c7b7dde5297c502d34b4 Mon Sep 17 00:00:00 2001 From: Krystian Kuzniarek Date: Mon, 11 Nov 2019 17:17:52 +0100 Subject: add documentation for the premature-exit-file protocol --- googletest/docs/advanced.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/googletest/docs/advanced.md b/googletest/docs/advanced.md index ce8644e..217d527 100644 --- a/googletest/docs/advanced.md +++ b/googletest/docs/advanced.md @@ -2541,6 +2541,18 @@ IMPORTANT: The exact format of the JSON document is subject to change. ### Controlling How Failures Are Reported +#### Detecting Test Premature Exit + +Google Test implements the _premature-exit-file_ protocol for test runners +to catch any kind of unexpected exits of test programs. Upon start, +Google Test creates the file which will be automatically deleted after +all work has been finished. Then, the test runner can check if this file +exists. In case the file remains undeleted, the inspected test has exited +prematurely. + +This feature is enabled only if the `TEST_PREMATURE_EXIT_FILE` environment +variable has been set. + #### Turning Assertion Failures into Break-Points When running test programs under a debugger, it's very convenient if the -- cgit v0.12 From c378d7eb93080e3b5ca322b1767bfb5cadf9c942 Mon Sep 17 00:00:00 2001 From: Krystian Kuzniarek Date: Wed, 29 Jan 2020 11:42:59 +0100 Subject: remove a dead reference to the Autotools script --- googletest/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/googletest/README.md b/googletest/README.md index 904048f..8520549 100644 --- a/googletest/README.md +++ b/googletest/README.md @@ -189,9 +189,9 @@ 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 -CMake script or the deprecated Autotools script, this is taken care of for you. -If you use your own build script, you'll need to read your compiler and linker's -manual to figure out what flags to add. +CMake script, this is taken care of for you. If you use your own build script, +you'll need to read your compiler and linker's manual to figure out what flags +to add. ### As a Shared Library (DLL) -- cgit v0.12 From 04e52ebe78166f0eb602dfc35817f91cc575cbfb Mon Sep 17 00:00:00 2001 From: Johan Mabille Date: Fri, 21 Feb 2020 11:55:07 +0100 Subject: Fixed warnings --- googletest/src/gtest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index a5b4e5a..69f25e6 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -2108,7 +2108,7 @@ static const char* const kReservedOutputTestCaseAttributes[] = { "classname", "name", "status", "time", "type_param", "value_param", "file", "line", "result", "timestamp"}; -template +template std::vector ArrayAsVector(const char* const (&array)[kSize]) { return std::vector(array, array + kSize); } -- cgit v0.12 From fd538161f484c202e68512ca37aaa73f2e06f606 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 19 Feb 2020 23:05:01 -0500 Subject: Googletest export Allow construction of an Action from a callable of zero args Action already allows construction from a callable with the same args as the mocked function, without needing to wrap the callable in Invoke. However, if you don't care about the arguments to the mocked function you need to either accept all of them or wrap your callable in InvokeWithoutArgs. This change makes both of those unnecessary, since it allows you to pass a no-args callable to Action directly. PiperOrigin-RevId: 296117034 --- googlemock/docs/cook_book.md | 36 +++++++++++++++++--------------- googlemock/include/gmock/gmock-actions.h | 36 +++++++++++++++++++++++++++++--- googlemock/test/gmock-actions_test.cc | 15 +++++++++++-- 3 files changed, 65 insertions(+), 22 deletions(-) diff --git a/googlemock/docs/cook_book.md b/googlemock/docs/cook_book.md index a493521..7209ea0 100644 --- a/googlemock/docs/cook_book.md +++ b/googlemock/docs/cook_book.md @@ -2174,7 +2174,7 @@ own precedence order distinct from the `ON_CALL` precedence order. ### Using Functions/Methods/Functors/Lambdas as Actions {#FunctionsAsActions} 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. @@ -2203,6 +2203,7 @@ class Helper { .WillRepeatedly(Invoke(NewPermanentCallback(Sum3, 1))); EXPECT_CALL(foo, ComplexJob(_)) .WillOnce(Invoke(&helper, &Helper::ComplexJob)) + .WillOnce([] { return true; }) .WillRepeatedly([](int x) { return x > 0; }); foo.Sum(5, 6); // Invokes CalculateSum(5, 6). @@ -2212,11 +2213,11 @@ class Helper { ``` 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 can -be implicitly converted to the corresponding arguments of the former, and the -former's return type can be implicitly converted to that of the latter. So, you -can invoke something whose type is *not* exactly the same as the mock function, -as long as it's safe to do so - nice, huh? +with the signature of the mock function, meaning that the latter's arguments (if +it takes any) can be implicitly converted to the corresponding arguments of the +former, and the former's return type can be implicitly converted to that of the +latter. So, you can invoke something whose type is *not* exactly the same as the +mock function, as long as it's safe to do so - nice, huh? **`Note:`{.escaped}** @@ -2267,19 +2268,20 @@ TEST_F(FooTest, Test) { ### Invoking a Function/Method/Functor/Lambda/Callback Without Arguments -`Invoke()` is very useful for doing actions that are more complex. It passes the -mock function's arguments to the function, etc being invoked such that the -callee has the full context of the call to work with. If the invoked function is -not interested in some or all of the arguments, it can simply ignore them. +`Invoke()` passes the mock function's arguments to the function, etc being +invoked such that the callee has the full context of the call to work with. If +the invoked function is 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 -the arguments of the mock function. `Invoke()` allows her to do that using a -wrapper function that throws away the arguments before invoking an underlining -nullary function. Needless to say, this can be tedious and obscures the intent -of the test. +the arguments of the mock function. She could do that using a wrapper function +that throws away the arguments before invoking an underlining nullary function. +Needless to say, this can be tedious and obscures the intent of the test. -`InvokeWithoutArgs()` solves this problem. It's like `Invoke()` except that it -doesn't pass the mock function's arguments to the callee. Here's an example: +There are two solutions to this problem. First, you can pass any callable of +zero args as an action. Alternatively, use `InvokeWithoutArgs()`, which is like +`Invoke()` except that it doesn't pass the mock function's arguments to the +callee. Here's an example of each: ```cpp using ::testing::_; @@ -2296,7 +2298,7 @@ bool Job2(int n, char c) { ... } ... MockFoo foo; EXPECT_CALL(foo, ComplexJob(_)) - .WillOnce(InvokeWithoutArgs(Job1)) + .WillOnce([] { Job1(); }); .WillOnce(InvokeWithoutArgs(NewPermanentCallback(Job2, 5, 'a'))); foo.ComplexJob(10); // Invokes Job1(). diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index e46bcaa..b4127e9 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -263,6 +263,10 @@ GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0); #undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_ +// Simple two-arg form of std::disjunction. +template +using disjunction = typename ::std::conditional::type; + } // namespace internal // When an unexpected function call is encountered, Google Mock will @@ -456,9 +460,15 @@ class Action { // This cannot take std::function directly, because then Action would not be // directly constructible from lambda (it would require two conversions). template , G>::value>::type> - Action(G&& fun) : fun_(::std::forward(fun)) {} // NOLINT + typename IsCompatibleFunctor = + ::std::is_constructible<::std::function, G>, + typename IsNoArgsFunctor = + ::std::is_constructible<::std::function, G>, + typename = typename ::std::enable_if::value>::type> + Action(G&& fun) { // NOLINT + Init(::std::forward(fun), IsCompatibleFunctor()); + } // Constructs an Action from its implementation. explicit Action(ActionInterface* impl) @@ -490,6 +500,26 @@ class Action { template friend class Action; + template + void Init(G&& g, ::std::true_type) { + fun_ = ::std::forward(g); + } + + template + void Init(G&& g, ::std::false_type) { + fun_ = IgnoreArgs::type>{::std::forward(g)}; + } + + template + struct IgnoreArgs { + template + 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. ::std::function fun_; }; diff --git a/googlemock/test/gmock-actions_test.cc b/googlemock/test/gmock-actions_test.cc index 58a2d35..d1229ac 100644 --- a/googlemock/test/gmock-actions_test.cc +++ b/googlemock/test/gmock-actions_test.cc @@ -1470,8 +1470,19 @@ TEST(FunctorActionTest, TypeConversion) { EXPECT_EQ(1, s2.Perform(std::make_tuple("hello"))); // Also between the lambda and the action itself. - const Action x = [](Unused) { return 42; }; - EXPECT_TRUE(x.Perform(std::make_tuple("hello"))); + const Action x1 = [](Unused) { return 42; }; + const Action x2 = [] { return 42; }; + EXPECT_TRUE(x1.Perform(std::make_tuple("hello"))); + EXPECT_TRUE(x2.Perform(std::make_tuple("hello"))); + + // Ensure decay occurs where required. + std::function f = [] { return 7; }; + Action d = f; + f = nullptr; + EXPECT_EQ(7, d.Perform(std::make_tuple(1))); + + // Ensure creation of an empty action succeeds. + Action(nullptr); } TEST(FunctorActionTest, UnusedArguments) { -- cgit v0.12 From 909b1ccfcacc9d6f920aa79e3f643c1a4e806eb2 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 25 Feb 2020 10:52:53 -0500 Subject: Googletest export Relax the implementation of MatcherCast to allow conversion of `Matcher` to `Matcher`. They have the same match signature. PiperOrigin-RevId: 297115843 --- googlemock/include/gmock/gmock-matchers.h | 13 ++++++++++--- googlemock/test/gmock-matchers_test.cc | 9 +++++---- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index 4b6ac56..fe88a7c 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -424,7 +424,14 @@ class MatcherCastImpl > { !std::is_base_of::value, "Can't implicitly convert from to "); - return source_matcher_.MatchAndExplain(static_cast(x), listener); + // Do the cast to `U` explicitly if necessary. + // Otherwise, let implicit conversions do the trick. + using CastType = + typename std::conditional::value, + T&, U>::type; + + return source_matcher_.MatchAndExplain(static_cast(x), + listener); } void DescribeTo(::std::ostream* os) const override { @@ -524,8 +531,8 @@ inline Matcher SafeMatcherCast(const M& polymorphic_matcher_or_value) { template inline Matcher SafeMatcherCast(const Matcher& matcher) { // Enforce that T can be implicitly converted to U. - GTEST_COMPILE_ASSERT_((std::is_convertible::value), - "T must be implicitly convertible to U"); + static_assert(std::is_convertible::value, + "T must be implicitly convertible to U"); // Enforce that we are not converting a non-reference type T to a reference // type U. GTEST_COMPILE_ASSERT_( diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc index c1949e6..3619959 100644 --- a/googlemock/test/gmock-matchers_test.cc +++ b/googlemock/test/gmock-matchers_test.cc @@ -765,10 +765,11 @@ TEST(SafeMatcherCastTest, FromConstReferenceToReference) { // Tests that MatcherCast(m) works when m is a Matcher. TEST(SafeMatcherCastTest, FromNonReferenceToConstReference) { - Matcher m1 = Eq(0); - Matcher m2 = SafeMatcherCast(m1); - EXPECT_TRUE(m2.Matches(0)); - EXPECT_FALSE(m2.Matches(1)); + Matcher> m1 = IsNull(); + Matcher&> m2 = + SafeMatcherCast&>(m1); + EXPECT_TRUE(m2.Matches(std::unique_ptr())); + EXPECT_FALSE(m2.Matches(std::unique_ptr(new int))); } // Tests that SafeMatcherCast(m) works when m is a Matcher. -- cgit v0.12 From e588eb1ff9ff6598666279b737b27f983156ad85 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 27 Feb 2020 14:02:17 -0500 Subject: Googletest export Rename internal color enumerators to avoid conflicts with curses.h macro definitions. Fixes #2685 PiperOrigin-RevId: 297639382 --- googletest/include/gtest/gtest.h | 2 +- googletest/src/gtest.cc | 95 +++++++++++++++++++++------------------- 2 files changed, 50 insertions(+), 47 deletions(-) diff --git a/googletest/include/gtest/gtest.h b/googletest/include/gtest/gtest.h index 39cff08..8871207 100644 --- a/googletest/include/gtest/gtest.h +++ b/googletest/include/gtest/gtest.h @@ -1807,7 +1807,7 @@ class GTEST_API_ AssertHelper { GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); }; -enum GTestColor { COLOR_DEFAULT, COLOR_RED, COLOR_GREEN, COLOR_YELLOW }; +enum class GTestColor { kDefault, kRed, kGreen, kYellow }; GTEST_API_ GTEST_ATTRIBUTE_PRINTF_(2, 3) void ColoredPrintf(GTestColor color, const char* fmt, diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 095778e..2259260 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -3093,9 +3093,12 @@ static void PrintTestPartResult(const TestPartResult& test_part_result) { // Returns the character attribute for the given color. static WORD GetColorAttribute(GTestColor color) { switch (color) { - case COLOR_RED: return FOREGROUND_RED; - case COLOR_GREEN: return FOREGROUND_GREEN; - case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; + case GTestColor::kRed: + return FOREGROUND_RED; + case GTestColor::kGreen: + return FOREGROUND_GREEN; + case GTestColor::kYellow: + return FOREGROUND_RED | FOREGROUND_GREEN; default: return 0; } } @@ -3133,13 +3136,16 @@ static WORD GetNewColor(GTestColor color, WORD old_color_attrs) { #else -// Returns the ANSI color code for the given color. COLOR_DEFAULT is +// Returns the ANSI color code for the given color. GTestColor::kDefault is // an invalid input. static const char* GetAnsiColorCode(GTestColor color) { switch (color) { - case COLOR_RED: return "1"; - case COLOR_GREEN: return "2"; - case COLOR_YELLOW: return "3"; + case GTestColor::kRed: + return "1"; + case GTestColor::kGreen: + return "2"; + case GTestColor::kYellow: + return "3"; default: return nullptr; } @@ -3198,7 +3204,7 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) { #else static const bool in_color_mode = ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); - const bool use_color = in_color_mode && (color != COLOR_DEFAULT); + const bool use_color = in_color_mode && (color != GTestColor::kDefault); #endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_ZOS if (!use_color) { @@ -3310,25 +3316,24 @@ void PrettyUnitTestResultPrinter::OnTestIterationStart( // Prints the filter if it's not *. This reminds the user that some // tests may be skipped. if (!String::CStringEquals(filter, kUniversalFilter)) { - ColoredPrintf(COLOR_YELLOW, - "Note: %s filter = %s\n", GTEST_NAME_, filter); + ColoredPrintf(GTestColor::kYellow, "Note: %s filter = %s\n", GTEST_NAME_, + filter); } if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { const int32_t shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); - ColoredPrintf(COLOR_YELLOW, - "Note: This is test shard %d of %s.\n", + ColoredPrintf(GTestColor::kYellow, "Note: This is test shard %d of %s.\n", static_cast(shard_index) + 1, internal::posix::GetEnv(kTestTotalShards)); } if (GTEST_FLAG(shuffle)) { - ColoredPrintf(COLOR_YELLOW, + ColoredPrintf(GTestColor::kYellow, "Note: Randomizing tests' orders with a seed of %d .\n", unit_test.random_seed()); } - ColoredPrintf(COLOR_GREEN, "[==========] "); + ColoredPrintf(GTestColor::kGreen, "[==========] "); printf("Running %s from %s.\n", FormatTestCount(unit_test.test_to_run_count()).c_str(), FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str()); @@ -3337,7 +3342,7 @@ void PrettyUnitTestResultPrinter::OnTestIterationStart( void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( const UnitTest& /*unit_test*/) { - ColoredPrintf(COLOR_GREEN, "[----------] "); + ColoredPrintf(GTestColor::kGreen, "[----------] "); printf("Global test environment set-up.\n"); fflush(stdout); } @@ -3346,7 +3351,7 @@ void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { const std::string counts = FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); - ColoredPrintf(COLOR_GREEN, "[----------] "); + ColoredPrintf(GTestColor::kGreen, "[----------] "); printf("%s from %s", counts.c_str(), test_case.name()); if (test_case.type_param() == nullptr) { printf("\n"); @@ -3360,7 +3365,7 @@ void PrettyUnitTestResultPrinter::OnTestSuiteStart( const TestSuite& test_suite) { const std::string counts = FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests"); - ColoredPrintf(COLOR_GREEN, "[----------] "); + ColoredPrintf(GTestColor::kGreen, "[----------] "); printf("%s from %s", counts.c_str(), test_suite.name()); if (test_suite.type_param() == nullptr) { printf("\n"); @@ -3372,7 +3377,7 @@ void PrettyUnitTestResultPrinter::OnTestSuiteStart( #endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_ void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { - ColoredPrintf(COLOR_GREEN, "[ RUN ] "); + ColoredPrintf(GTestColor::kGreen, "[ RUN ] "); PrintTestName(test_info.test_suite_name(), test_info.name()); printf("\n"); fflush(stdout); @@ -3395,11 +3400,11 @@ void PrettyUnitTestResultPrinter::OnTestPartResult( void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { if (test_info.result()->Passed()) { - ColoredPrintf(COLOR_GREEN, "[ OK ] "); + ColoredPrintf(GTestColor::kGreen, "[ OK ] "); } else if (test_info.result()->Skipped()) { - ColoredPrintf(COLOR_GREEN, "[ SKIPPED ] "); + ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] "); } else { - ColoredPrintf(COLOR_RED, "[ FAILED ] "); + ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); } PrintTestName(test_info.test_suite_name(), test_info.name()); if (test_info.result()->Failed()) @@ -3420,7 +3425,7 @@ void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { const std::string counts = FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); - ColoredPrintf(COLOR_GREEN, "[----------] "); + ColoredPrintf(GTestColor::kGreen, "[----------] "); printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_case.name(), internal::StreamableToString(test_case.elapsed_time()).c_str()); fflush(stdout); @@ -3431,7 +3436,7 @@ void PrettyUnitTestResultPrinter::OnTestSuiteEnd(const TestSuite& test_suite) { const std::string counts = FormatCountableNoun(test_suite.test_to_run_count(), "test", "tests"); - ColoredPrintf(COLOR_GREEN, "[----------] "); + ColoredPrintf(GTestColor::kGreen, "[----------] "); printf("%s from %s (%s ms total)\n\n", counts.c_str(), test_suite.name(), internal::StreamableToString(test_suite.elapsed_time()).c_str()); fflush(stdout); @@ -3440,7 +3445,7 @@ void PrettyUnitTestResultPrinter::OnTestSuiteEnd(const TestSuite& test_suite) { void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( const UnitTest& /*unit_test*/) { - ColoredPrintf(COLOR_GREEN, "[----------] "); + ColoredPrintf(GTestColor::kGreen, "[----------] "); printf("Global test environment tear-down\n"); fflush(stdout); } @@ -3448,7 +3453,7 @@ void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( // Internal helper for printing the list of failed tests. void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { const int failed_test_count = unit_test.failed_test_count(); - ColoredPrintf(COLOR_RED, "[ FAILED ] "); + ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); for (int i = 0; i < unit_test.total_test_suite_count(); ++i) { @@ -3461,7 +3466,7 @@ void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { if (!test_info.should_run() || !test_info.result()->Failed()) { continue; } - ColoredPrintf(COLOR_RED, "[ FAILED ] "); + ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); printf("%s.%s", test_suite.name(), test_info.name()); PrintFullTestCommentIfPresent(test_info); printf("\n"); @@ -3482,7 +3487,7 @@ void PrettyUnitTestResultPrinter::PrintFailedTestSuites( continue; } if (test_suite.ad_hoc_test_result().Failed()) { - ColoredPrintf(COLOR_RED, "[ FAILED ] "); + ColoredPrintf(GTestColor::kRed, "[ FAILED ] "); printf("%s: SetUpTestSuite or TearDownTestSuite\n", test_suite.name()); ++suite_failure_count; } @@ -3510,7 +3515,7 @@ void PrettyUnitTestResultPrinter::PrintSkippedTests(const UnitTest& unit_test) { if (!test_info.should_run() || !test_info.result()->Skipped()) { continue; } - ColoredPrintf(COLOR_GREEN, "[ SKIPPED ] "); + ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] "); printf("%s.%s", test_suite.name(), test_info.name()); printf("\n"); } @@ -3519,7 +3524,7 @@ void PrettyUnitTestResultPrinter::PrintSkippedTests(const UnitTest& unit_test) { void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, int /*iteration*/) { - ColoredPrintf(COLOR_GREEN, "[==========] "); + ColoredPrintf(GTestColor::kGreen, "[==========] "); printf("%s from %s ran.", FormatTestCount(unit_test.test_to_run_count()).c_str(), FormatTestSuiteCount(unit_test.test_suite_to_run_count()).c_str()); @@ -3528,12 +3533,12 @@ void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, internal::StreamableToString(unit_test.elapsed_time()).c_str()); } printf("\n"); - ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); + ColoredPrintf(GTestColor::kGreen, "[ PASSED ] "); printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); const int skipped_test_count = unit_test.skipped_test_count(); if (skipped_test_count > 0) { - ColoredPrintf(COLOR_GREEN, "[ SKIPPED ] "); + ColoredPrintf(GTestColor::kGreen, "[ SKIPPED ] "); printf("%s, listed below:\n", FormatTestCount(skipped_test_count).c_str()); PrintSkippedTests(unit_test); } @@ -3548,10 +3553,8 @@ void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, if (unit_test.Passed()) { printf("\n"); // Add a spacer if no FAILURE banner is displayed. } - ColoredPrintf(COLOR_YELLOW, - " YOU HAVE %d DISABLED %s\n\n", - num_disabled, - num_disabled == 1 ? "TEST" : "TESTS"); + ColoredPrintf(GTestColor::kYellow, " 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. fflush(stdout); @@ -5554,14 +5557,14 @@ bool UnitTestImpl::RunAllTests() { if (!gtest_is_initialized_before_run_all_tests) { ColoredPrintf( - COLOR_RED, + GTestColor::kRed, "\nIMPORTANT NOTICE - DO NOT IGNORE:\n" "This test program did NOT call " GTEST_INIT_GOOGLE_TEST_NAME_ "() before calling RUN_ALL_TESTS(). This is INVALID. Soon " GTEST_NAME_ " will start to enforce the valid usage. " "Please fix it ASAP, or IT WILL START TO FAIL.\n"); // NOLINT #if GTEST_FOR_GOOGLE_ - ColoredPrintf(COLOR_RED, + ColoredPrintf(GTestColor::kRed, "For more details, see http://wiki/Main/ValidGUnitMain.\n"); #endif // GTEST_FOR_GOOGLE_ } @@ -5578,7 +5581,7 @@ void WriteToShardStatusFileIfNeeded() { if (test_shard_file != nullptr) { FILE* const file = posix::FOpen(test_shard_file, "w"); if (file == nullptr) { - ColoredPrintf(COLOR_RED, + ColoredPrintf(GTestColor::kRed, "Could not write to the test shard status file \"%s\" " "specified by the %s environment variable.\n", test_shard_file, kTestShardStatusFile); @@ -5612,7 +5615,7 @@ bool ShouldShard(const char* total_shards_env, << "Invalid environment variables: you have " << kTestShardIndex << " = " << shard_index << ", but have left " << kTestTotalShards << " unset.\n"; - ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str()); + ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } else if (total_shards != -1 && shard_index == -1) { @@ -5620,7 +5623,7 @@ bool ShouldShard(const char* total_shards_env, << "Invalid environment variables: you have " << kTestTotalShards << " = " << total_shards << ", but have left " << kTestShardIndex << " unset.\n"; - ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str()); + ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } else if (shard_index < 0 || shard_index >= total_shards) { @@ -5629,7 +5632,7 @@ bool ShouldShard(const char* total_shards_env, << kTestShardIndex << " < " << kTestTotalShards << ", but you have " << kTestShardIndex << "=" << shard_index << ", " << kTestTotalShards << "=" << total_shards << ".\n"; - ColoredPrintf(COLOR_RED, "%s", msg.GetString().c_str()); + ColoredPrintf(GTestColor::kRed, "%s", msg.GetString().c_str()); fflush(stdout); exit(EXIT_FAILURE); } @@ -6019,7 +6022,7 @@ static bool HasGoogleTestFlagPrefix(const char* str) { // @D changes to the default terminal text color. // static void PrintColorEncoded(const char* str) { - GTestColor color = COLOR_DEFAULT; // The current color. + GTestColor color = GTestColor::kDefault; // The current color. // Conceptually, we split the string into segments divided by escape // sequences. Then we print one segment at a time. At the end of @@ -6039,13 +6042,13 @@ static void PrintColorEncoded(const char* str) { if (ch == '@') { ColoredPrintf(color, "@"); } else if (ch == 'D') { - color = COLOR_DEFAULT; + color = GTestColor::kDefault; } else if (ch == 'R') { - color = COLOR_RED; + color = GTestColor::kRed; } else if (ch == 'G') { - color = COLOR_GREEN; + color = GTestColor::kGreen; } else if (ch == 'Y') { - color = COLOR_YELLOW; + color = GTestColor::kYellow; } else { --str; } -- cgit v0.12 From a1b0173df92bbbad69254f929e341f8dbf1cc708 Mon Sep 17 00:00:00 2001 From: Romain Geissler Date: Wed, 11 Mar 2020 22:30:20 +0000 Subject: Make sure IsATTY does not clobber errno. Exposition of the problem: > cat main.cpp TEST(errnoTest, errnoTest) { ASSERT_EQ(errno, 0); } int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } Compiled with gcc 10 like this: > g++ -pthread -o runtest main.cpp -Wl,-Bstatic -lgtest -Wl,-Bdynamic Before patch: > ./runtest [==========] Running 1 test from 1 test suite. [----------] Global test environment set-up. [----------] 1 test from errnoTest [ RUN ] errnoTest.errnoTest [ OK ] errnoTest.errnoTest (0 ms) [----------] 1 test from errnoTest (0 ms total) [----------] Global test environment tear-down [==========] 1 test from 1 test suite ran. (0 ms total) [ PASSED ] 1 test. (output is colored, I run this inside an interactive terminal). > ./runtest | cat [==========] Running 1 test from 1 test suite. [----------] Global test environment set-up. [----------] 1 test from errnoTest [ RUN ] errnoTest.errnoTest main.cpp:5: Failure Expected equality of these values: (*__errno_location ()) Which is: 25 0 [ FAILED ] errnoTest.errnoTest (0 ms) [----------] 1 test from errnoTest (0 ms total) [----------] Global test environment tear-down [==========] 1 test from 1 test suite ran. (0 ms total) [ PASSED ] 0 tests. [ FAILED ] 1 test, listed below: [ FAILED ] errnoTest.errnoTest 1 FAILED TEST (output is not colored, since IsTTY return false, because of the pipe, however it also clobbered errno for the tests). After the patch, both cases are working fine: > ./runtest [==========] Running 1 test from 1 test suite. [----------] Global test environment set-up. [----------] 1 test from errnoTest [ RUN ] errnoTest.errnoTest [ OK ] errnoTest.errnoTest (0 ms) [----------] 1 test from errnoTest (0 ms total) [----------] Global test environment tear-down [==========] 1 test from 1 test suite ran. (0 ms total) [ PASSED ] 1 test. > ./runtest | cat [==========] Running 1 test from 1 test suite. [----------] Global test environment set-up. [----------] 1 test from errnoTest [ RUN ] errnoTest.errnoTest [ OK ] errnoTest.errnoTest (0 ms) [----------] 1 test from errnoTest (0 ms total) [----------] Global test environment tear-down [==========] 1 test from 1 test suite ran. (0 ms total) [ PASSED ] 1 test. --- googletest/include/gtest/internal/gtest-port.h | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index 60ff471..c7c79ae 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -252,6 +252,7 @@ #include #include #include +#include #include #include #include @@ -1960,16 +1961,16 @@ namespace posix { typedef struct _stat StatStruct; # ifdef __BORLANDC__ -inline int IsATTY(int fd) { return isatty(fd); } +inline int DoIsATTY(int fd) { return isatty(fd); } inline int StrCaseCmp(const char* s1, const char* s2) { return stricmp(s1, s2); } inline char* StrDup(const char* src) { return strdup(src); } # else // !__BORLANDC__ # if GTEST_OS_WINDOWS_MOBILE -inline int IsATTY(int /* fd */) { return 0; } +inline int DoIsATTY(int /* fd */) { return 0; } # else -inline int IsATTY(int fd) { return _isatty(fd); } +inline int DoIsATTY(int fd) { return _isatty(fd); } # endif // GTEST_OS_WINDOWS_MOBILE inline int StrCaseCmp(const char* s1, const char* s2) { return _stricmp(s1, s2); @@ -1994,7 +1995,7 @@ inline bool IsDir(const StatStruct& st) { typedef struct stat StatStruct; inline int FileNo(FILE* file) { return fileno(file); } -inline int IsATTY(int fd) { return isatty(fd); } +inline int DoIsATTY(int fd) { return isatty(fd); } inline int Stat(const char* path, StatStruct* buf) { // stat function not implemented on ESP8266 return 0; @@ -2011,7 +2012,7 @@ inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } typedef struct stat StatStruct; inline int FileNo(FILE* file) { return fileno(file); } -inline int IsATTY(int fd) { return isatty(fd); } +inline int DoIsATTY(int fd) { return isatty(fd); } inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } inline int StrCaseCmp(const char* s1, const char* s2) { return strcasecmp(s1, s2); @@ -2022,6 +2023,18 @@ inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } #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. GTEST_DISABLE_MSC_DEPRECATED_PUSH_() -- cgit v0.12 From cfb5ef4e7dc032c71e3e3323b45962839331e399 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 3 Mar 2020 10:08:02 -0500 Subject: Googletest export Remove public buganizer reference from googletest cookbook. It also seems that this bug is obsolete. PiperOrigin-RevId: 298598298 --- googlemock/docs/cook_book.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/googlemock/docs/cook_book.md b/googlemock/docs/cook_book.md index 7209ea0..51eb94a 100644 --- a/googlemock/docs/cook_book.md +++ b/googlemock/docs/cook_book.md @@ -421,7 +421,7 @@ sadly they are side effects of C++'s limitations): `NiceMock >`) is **not** supported. 2. `NiceMock` and `StrictMock` may not work correctly if the destructor of `MockFoo` is not virtual. We would like to fix this, but it - requires cleaning up existing tests. http://b/28934720 tracks the issue. + requires cleaning up existing tests. 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 calls a mock method on `this` object. (This behavior, however, is consistent -- cgit v0.12 From 0bf8ea3065f791289f383afee43d8464638a5075 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 3 Mar 2020 12:17:35 -0500 Subject: Googletest export Simplify the fallback printing logic to have a single sequence of trial printers. PiperOrigin-RevId: 298621376 --- googletest/include/gtest/gtest-printers.h | 413 ++++++++++++------------------ googletest/src/gtest-printers.cc | 6 +- 2 files changed, 160 insertions(+), 259 deletions(-) diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h index 407d1f1..75e4422 100644 --- a/googletest/include/gtest/gtest-printers.h +++ b/googletest/include/gtest/gtest-printers.h @@ -119,53 +119,126 @@ namespace testing { -// Definitions in the 'internal' and 'internal2' name spaces are -// subject to change without notice. DO NOT USE THEM IN USER CODE! -namespace internal2 { +// Definitions in the internal* namespaces are subject to change without notice. +// DO NOT USE THEM IN USER CODE! +namespace internal { -// 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); +template +void UniversalPrint(const T& value, ::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 +// Used to print an STL-style container when the user doesn't define +// a PrintTo() for it. +struct ContainerPrinter { + template (0)) == sizeof(IsContainer)) && + !IsRecursiveContainer::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; + } + + if (count > 0) { + *os << ' '; + } + *os << '}'; + } }; -// TypeWithoutFormatter::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 -class TypeWithoutFormatter { - public: - // This default version is called when kTypeKind is kOtherType. - static void PrintValue(const T& value, ::std::ostream* os) { - PrintBytesInObjectTo( - static_cast( - reinterpret_cast(std::addressof(value))), - sizeof(value), 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.) +struct FunctionPointerPrinter { + template ::value>::type> + static void PrintValue(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(p); + } } }; -// 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; +struct PointerPrinter { + template + static void PrintValue(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; + } + } +}; +namespace internal_stream { + +struct Sentinel; +template +Sentinel* operator<<(::std::basic_ostream& os, const T& x); + +// Check if the user has a user-defined operator<< for their type. +// +// We put this in its own namespace to inject a custom operator<< that allows us +// to probe the type's operator. +// +// Note that this operator<< takes a generic std::basic_ostream type instead of the more restricted std::ostream. If +// we define it to take an std::ostream instead, we'll get an +// "ambiguous overloads" compiler error when trying to print a type +// Foo that supports streaming to std::basic_ostream, as the compiler cannot tell whether +// operator<<(std::ostream&, const T&) or +// operator<<(std::basic_stream, const Foo&) is more +// specific. template -class TypeWithoutFormatter { - public: +constexpr bool UseStreamOperator() { + return !std::is_same() + << std::declval()), + Sentinel*>::value; +} + +} // namespace internal_stream + +struct StreamPrinter { + template ()>::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 ::value>::type> static void PrintValue(const T& value, ::std::ostream* os) { std::string pretty_str = value.ShortDebugString(); if (pretty_str.length() > kProtobufOneLinerMaxLength) { @@ -175,9 +248,7 @@ class TypeWithoutFormatter { } }; -template -class TypeWithoutFormatter { - public: +struct ConvertibleToIntegerPrinter { // Since T has no << operator or PrintTo() but can be implicitly // converted to BiggestInt, we print it as a BiggestInt. // @@ -185,112 +256,64 @@ class TypeWithoutFormatter { // 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(const T& value, ::std::ostream* os) { - const internal::BiggestInt kBigInt = value; - *os << kBigInt; + static void PrintValue(internal::BiggestInt value, ::std::ostream* os) { + *os << value; } }; +struct ConvertibleToStringViewPrinter { #if GTEST_INTERNAL_HAS_STRING_VIEW -template -class TypeWithoutFormatter { - public: - // Since T has neither operator<< nor PrintTo() but can be implicitly - // converted to absl::string_view, we print it as a absl::string_view - // (or std::string_view). - // - // Note: the implementation is further below, as it depends on - // internal::PrintTo symbol which is defined later in the file. - static void PrintValue(const T& value, ::std::ostream* os); -}; + static void PrintValue(internal::StringView value, ::std::ostream* os) { + internal::UniversalPrint(value, os); + } #endif +}; -// 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 -// of a type implicitly convertible to BiggestInt, it's printed as an -// integer; otherwise the bytes in the value are printed. This is -// what UniversalPrinter::Print() does when it knows nothing about -// type T and T has neither << operator nor PrintTo(). -// -// A user can override this behavior for a class type Foo by defining -// 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 type instead of the more restricted std::ostream. If -// we define it to take an std::ostream instead, we'll get an -// "ambiguous overloads" compiler error when trying to print a type -// Foo that supports streaming to std::basic_ostream, as the compiler cannot tell whether -// operator<<(std::ostream&, const T&) or -// operator<<(std::basic_stream, const Foo&) is more -// specific. -template -::std::basic_ostream& operator<<( - ::std::basic_ostream& os, const T& x) { - TypeWithoutFormatter::value - ? kProtobuf - : std::is_convertible< - const T&, internal::BiggestInt>::value - ? kConvertibleToInteger - : -#if GTEST_INTERNAL_HAS_STRING_VIEW - std::is_convertible< - const T&, internal::StringView>::value - ? kConvertibleToStringView - : -#endif - kOtherType)>::PrintValue(x, &os); - return os; -} -} // namespace internal2 -} // namespace testing +// 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 + static void PrintValue(const T& value, ::std::ostream* os) { + PrintBytesInObjectTo( + static_cast( + reinterpret_cast(std::addressof(value))), + sizeof(value), os); + } +}; + +// Try every printer in order and return the first one that works. +template +struct FindFirstPrinter : FindFirstPrinter {}; -// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up -// magic needed for implementing UniversalPrinter won't work. -namespace testing_internal { +template +struct FindFirstPrinter< + T, decltype(Printer::PrintValue(std::declval(), nullptr)), + Printer, Printers...> { + using type = Printer; +}; -// Used to print a value that is not an STL-style container when the -// user doesn't define PrintTo() for it. +// 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 -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; +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 testing_internal - -namespace testing { -namespace internal { - // FormatForComparison::Format(value) formats a // 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 @@ -388,85 +411,6 @@ std::string FormatForComparisonFailureMessage( template class UniversalPrinter; -template -void UniversalPrint(const T& value, ::std::ostream* os); - -enum DefaultPrinterType { - kPrintContainer, - kPrintPointer, - kPrintFunctionPointer, - kPrintOther, -}; -template struct WrapPrinterType {}; - -// Used to print an STL-style container when the user doesn't define -// a PrintTo() for it. -template -void DefaultPrintTo(WrapPrinterType /* 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 -void DefaultPrintTo(WrapPrinterType /* 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 -void DefaultPrintTo(WrapPrinterType /* 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(p); - } -} - -// Used to print a non-container, non-pointer value when the user -// doesn't define PrintTo() for it. -template -void DefaultPrintTo(WrapPrinterType /* dummy */, - const T& value, ::std::ostream* os) { - ::testing_internal::DefaultPrintNonContainerTo(value, os); -} - // Prints the given value using the << operator if it has one; // otherwise prints the bytes in it. This is what // UniversalPrinter::Print() does when PrintTo() is not specialized @@ -480,36 +424,7 @@ void DefaultPrintTo(WrapPrinterType /* dummy */, // wants). template void PrintTo(const T& value, ::std::ostream* 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(0)) == sizeof(IsContainer)) && - !IsRecursiveContainer::value - ? kPrintContainer - : !std::is_pointer::value - ? kPrintOther - : std::is_function::type>::value - ? kPrintFunctionPointer - : kPrintPointer > (), - value, os); + internal::PrintWithFallback(value, os); } // The following list of PrintTo() overloads tells @@ -900,16 +815,6 @@ Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { } // namespace internal -#if GTEST_INTERNAL_HAS_STRING_VIEW -namespace internal2 { -template -void TypeWithoutFormatter::PrintValue( - const T& value, ::std::ostream* os) { - internal::PrintTo(internal::StringView(value), os); -} -} // namespace internal2 -#endif - template ::std::string PrintToString(const T& value) { ::std::stringstream ss; diff --git a/googletest/src/gtest-printers.cc b/googletest/src/gtest-printers.cc index 3337be3..4e1ccad 100644 --- a/googletest/src/gtest-printers.cc +++ b/googletest/src/gtest-printers.cc @@ -104,7 +104,7 @@ void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, } // namespace -namespace internal2 { +namespace internal { // Delegates to PrintBytesInObjectToImpl() to print the bytes in the // given object. The delegation simplifies the implementation, which @@ -116,10 +116,6 @@ void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, PrintBytesInObjectToImpl(obj_bytes, count, os); } -} // namespace internal2 - -namespace internal { - // Depending on the value of a char (or wchar_t), we print it in one // of three formats: // - as is if it's a printable ASCII (e.g. 'a', '2', ' '), -- cgit v0.12 From 230afdb24e0ffb740f5af00c994442200ed59ae0 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Fri, 6 Mar 2020 09:50:02 -0500 Subject: Googletest export Internal change PiperOrigin-RevId: 299345492 --- googlemock/test/BUILD.bazel | 2 -- googletest/test/BUILD.bazel | 2 -- 2 files changed, 4 deletions(-) diff --git a/googlemock/test/BUILD.bazel b/googlemock/test/BUILD.bazel index da95ed5..4aa9a75 100644 --- a/googlemock/test/BUILD.bazel +++ b/googlemock/test/BUILD.bazel @@ -28,8 +28,6 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -# Author: misterg@google.com (Gennadiy Civil) -# # Bazel Build for Google C++ Testing Framework(Google Test)-googlemock load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test") diff --git a/googletest/test/BUILD.bazel b/googletest/test/BUILD.bazel index 456cc6f..dbbb5c0 100644 --- a/googletest/test/BUILD.bazel +++ b/googletest/test/BUILD.bazel @@ -28,8 +28,6 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -# Author: misterg@google.com (Gennadiy Civil) -# # Bazel BUILD for The Google C++ Testing Framework (Google Test) load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_test") -- cgit v0.12 From 227faf41db5eec00fa2b316098a49771b2fb4ad8 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Fri, 13 Mar 2020 16:36:27 -0400 Subject: Googletest export Fix Compilation against CMake < 3.7 (Fix #2711) `VERSION_GREATER_EQUAL` was introduced in CMake 3.7 ref: https://cmake.org/cmake/help/v3.7/release/3.7.html#commands PiperOrigin-RevId: 300817917 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d883409..37e7b61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ endif (POLICY CMP0048) project(googletest-distribution) set(GOOGLETEST_VERSION 1.10.0) -if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.1") +if (CMAKE_VERSION VERSION_GREATER "3.0.2") if(NOT CYGWIN AND NOT MSYS) set(CMAKE_CXX_EXTENSIONS OFF) endif() -- cgit v0.12 From c43f7100f084db17197c34c2d776ad2973dbf539 Mon Sep 17 00:00:00 2001 From: dmauro Date: Mon, 16 Mar 2020 11:35:02 -0400 Subject: Googletest export Use a polymorphic matcher instead of the GreaterThan test matcher to fix the sign-comparison warning on MSVC. PiperOrigin-RevId: 301163657 --- googlemock/test/gmock-matchers_test.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc index 3619959..186d8aa 100644 --- a/googlemock/test/gmock-matchers_test.cc +++ b/googlemock/test/gmock-matchers_test.cc @@ -4726,20 +4726,18 @@ TEST(SizeIsTest, ExplainsResult) { Matcher > m1 = SizeIs(2); Matcher > m2 = SizeIs(Lt(2u)); Matcher > m3 = SizeIs(AnyOf(0, 3)); - Matcher > m4 = SizeIs(GreaterThan(1)); + Matcher > m4 = SizeIs(Gt(1u)); vector 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(m3, container)); - EXPECT_EQ("whose size 0 doesn't match, which is 1 less than 1", - Explain(m4, container)); + EXPECT_EQ("whose size 0 doesn't match", Explain(m4, container)); container.push_back(0); container.push_back(0); 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(m3, container)); - EXPECT_EQ("whose size 2 matches, which is 1 more than 1", - Explain(m4, container)); + EXPECT_EQ("whose size 2 matches", Explain(m4, container)); } #if GTEST_HAS_TYPED_TEST -- cgit v0.12 From 482ac6ee63429af2aa9c44f4e6427873fb68fb1f Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Tue, 17 Mar 2020 16:58:55 -0400 Subject: Googletest export Move internal function out of header because Hyrum's law always wins. PiperOrigin-RevId: 301446904 --- googletest/include/gtest/gtest.h | 6 ------ googletest/src/gtest.cc | 4 ++++ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/googletest/include/gtest/gtest.h b/googletest/include/gtest/gtest.h index 8871207..0139fcc 100644 --- a/googletest/include/gtest/gtest.h +++ b/googletest/include/gtest/gtest.h @@ -1807,12 +1807,6 @@ class GTEST_API_ AssertHelper { GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); }; -enum class GTestColor { kDefault, kRed, kGreen, kYellow }; - -GTEST_API_ GTEST_ATTRIBUTE_PRINTF_(2, 3) void ColoredPrintf(GTestColor color, - const char* fmt, - ...); - } // namespace internal // The pure interface class that all value-parameterized tests inherit from. diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 6911ad6..2eb2ecb 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -3056,6 +3056,9 @@ static const char * TestPartResultTypeToString(TestPartResult::Type type) { } namespace internal { +namespace { +enum class GTestColor { kDefault, kRed, kGreen, kYellow }; +} // namespace // Prints a TestPartResult to an std::string. static std::string PrintTestPartResultToString( @@ -3194,6 +3197,7 @@ bool ShouldUseColor(bool stdout_is_tty) { // cannot simply emit special characters and have the terminal change colors. // This routine must actually emit the characters rather than return a string // that would be colored when printed, as can be done on Linux. + void ColoredPrintf(GTestColor color, const char* fmt, ...) { va_list args; va_start(args, fmt); -- cgit v0.12 From e41f31f2af3a713e8652d1e091a13bed22781ec3 Mon Sep 17 00:00:00 2001 From: Adam Badura Date: Thu, 26 Dec 2019 01:32:37 +0100 Subject: Add tests for MockFunction deduction (#2277) Add tests checking that ::testing::MockFunction template argument can be deduced in a function call context. This is a property raised in the review, however, not checked before by any tests. --- googlemock/test/gmock-function-mocker_test.cc | 30 +++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/googlemock/test/gmock-function-mocker_test.cc b/googlemock/test/gmock-function-mocker_test.cc index 019e3cb..164c6b4 100644 --- a/googlemock/test/gmock-function-mocker_test.cc +++ b/googlemock/test/gmock-function-mocker_test.cc @@ -779,6 +779,36 @@ TEST(MockMethodMockFunctionTest, AsStdFunctionWithReferenceParameter) { } +namespace { + +template +static constexpr bool IsMockFunctionTemplateArgumentDeducedTo(const MockFunction&) { + return std::is_same::value; +} + +} // namespace + +template +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, IsMockFunctionTemplateArgumentDeduced) { + using Argument = TypeParam; + MockFunction foo; + EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo(foo)); +} + + struct MockMethodSizes0 { MOCK_METHOD(void, func, ()); }; -- cgit v0.12 From 53740ebc21d54f537f42fc565b0501e690c90dc4 Mon Sep 17 00:00:00 2001 From: Adam Badura Date: Thu, 11 Jul 2019 10:20:21 +0200 Subject: Add support for std::function in MockFunction (#2277) --- googlemock/include/gmock/gmock-spec-builders.h | 132 +++++++++++++++++-------- googlemock/test/gmock-function-mocker_test.cc | 21 +++- 2 files changed, 113 insertions(+), 40 deletions(-) diff --git a/googlemock/include/gmock/gmock-spec-builders.h b/googlemock/include/gmock/gmock-spec-builders.h index 718c948..30a75ce 100644 --- a/googlemock/include/gmock/gmock-spec-builders.h +++ b/googlemock/include/gmock/gmock-spec-builders.h @@ -1786,10 +1786,80 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg); } // namespace internal -// A MockFunction class has one mock method whose type is 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: +namespace internal { + +template +class MockFunction; + +template +class MockFunction { + public: + MockFunction(const MockFunction&) = delete; + MockFunction& operator=(const MockFunction&) = delete; + + std::function AsStdFunction() { + return [this](Args... args) -> R { + return this->Call(std::forward(args)...); + }; + } + + // Implementation detail: the expansion of the MOCK_METHOD macro. + R Call(Args... args) { + mock_.SetOwnerAndName(this, "Call"); + return mock_.Invoke(std::forward(args)...); + } + + MockSpec gmock_Call(Matcher... m) { + mock_.RegisterOwner(this); + return mock_.With(std::move(m)...); + } + + MockSpec gmock_Call(const WithoutMatchers&, + R (*)(Args...)) { + return this->gmock_Call(::testing::A()...); + } + + protected: + MockFunction() = default; + ~MockFunction() = default; + + private: + FunctionMocker mock_; +}; + +/* +The SignatureOf 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 +struct SignatureOf; + +template +struct SignatureOf { + using type = R(Args...); +}; + +template +struct SignatureOf> : SignatureOf {}; + +template +using SignatureOfT = typename SignatureOf::type; + +} // namespace internal + +// A MockFunction type has one mock method whose type is +// internal::SignatureOfT. 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(2); @@ -1823,49 +1893,33 @@ void ReportUninterestingCall(CallReaction reaction, const std::string& msg); // Bar("a") is called by which call to Foo(). // // MockFunction can also be used to exercise code that accepts -// std::function callbacks. To do so, use AsStdFunction() method -// to create std::function proxy forwarding to original object's Call. -// Example: +// std::function> callbacks. To do so, use +// AsStdFunction() method to create std::function proxy forwarding to +// original object's Call. Example: // // TEST(FooTest, RunsCallbackWithBarArgument) { // MockFunction callback; // EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1)); // Foo(callback.AsStdFunction()); // } +// +// The internal::SignatureOfT 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; +// void MyFilterAlgorithm(FilterPredicate predicate); +// +// TEST(FooTest, FilterPredicateAlwaysAccepts) { +// MockFunction predicateMock; +// EXPECT_CALL(predicateMock, Call(_)).WillRepeatedly(Return(true)); +// MyFilterAlgorithm(predicateMock.AsStdFunction()); +// } template -class MockFunction; - -template -class MockFunction { +class MockFunction : public internal::MockFunction> { + using Base = internal::MockFunction>; public: - MockFunction() {} - MockFunction(const MockFunction&) = delete; - MockFunction& operator=(const MockFunction&) = delete; - - std::function AsStdFunction() { - return [this](Args... args) -> R { - return this->Call(std::forward(args)...); - }; - } - - // Implementation detail: the expansion of the MOCK_METHOD macro. - R Call(Args... args) { - mock_.SetOwnerAndName(this, "Call"); - return mock_.Invoke(std::forward(args)...); - } - - internal::MockSpec gmock_Call(Matcher... m) { - mock_.RegisterOwner(this); - return mock_.With(std::move(m)...); - } - - internal::MockSpec gmock_Call(const internal::WithoutMatchers&, - R (*)(Args...)) { - return this->gmock_Call(::testing::A()...); - } - - private: - internal::FunctionMocker mock_; + using Base::Base; }; // The style guide prohibits "using" statements in a namespace scope diff --git a/googlemock/test/gmock-function-mocker_test.cc b/googlemock/test/gmock-function-mocker_test.cc index 164c6b4..920b097 100644 --- a/googlemock/test/gmock-function-mocker_test.cc +++ b/googlemock/test/gmock-function-mocker_test.cc @@ -40,6 +40,7 @@ # include #endif // GTEST_OS_WINDOWS +#include #include #include #include @@ -802,12 +803,30 @@ using MockMethodMockFunctionSignatureTypes = Types< >; TYPED_TEST_SUITE(MockMethodMockFunctionSignatureTest, MockMethodMockFunctionSignatureTypes); -TYPED_TEST(MockMethodMockFunctionSignatureTest, IsMockFunctionTemplateArgumentDeduced) { +TYPED_TEST(MockMethodMockFunctionSignatureTest, IsMockFunctionTemplateArgumentDeducedForRawSignature) { using Argument = TypeParam; MockFunction foo; EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo(foo)); } +TYPED_TEST(MockMethodMockFunctionSignatureTest, IsMockFunctionTemplateArgumentDeducedForStdFunction) { + using Argument = std::function; + MockFunction foo; + EXPECT_TRUE(IsMockFunctionTemplateArgumentDeducedTo(foo)); +} + +TYPED_TEST(MockMethodMockFunctionSignatureTest, IsMockFunctionCallMethodSignatureTheSameForRawSignatureAndStdFunction) { + using ForRawSignature = decltype(&MockFunction::Call); + using ForStdFunction = decltype(&MockFunction>::Call); + EXPECT_TRUE((std::is_same::value)); +} + +TYPED_TEST(MockMethodMockFunctionSignatureTest, IsMockFunctionAsStdFunctionMethodSignatureTheSameForRawSignatureAndStdFunction) { + using ForRawSignature = decltype(&MockFunction::AsStdFunction); + using ForStdFunction = decltype(&MockFunction>::AsStdFunction); + EXPECT_TRUE((std::is_same::value)); +} + struct MockMethodSizes0 { MOCK_METHOD(void, func, ()); -- cgit v0.12 From 749148f1accc346d94825358a9a745b852961a11 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Fri, 20 Mar 2020 13:01:40 -0400 Subject: Googletest export Internal change PiperOrigin-RevId: 302048013 --- googlemock/docs/for_dummies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/googlemock/docs/for_dummies.md b/googlemock/docs/for_dummies.md index 93cf06f..327e6cc 100644 --- a/googlemock/docs/for_dummies.md +++ b/googlemock/docs/for_dummies.md @@ -374,7 +374,7 @@ convenient way of saying "any value". 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 equal (using `operator==`) to the matcher argument. There are many -[built-in matchers](#MatcherList) for common types (as well as +[built-in matchers](cheat_sheet.md#MatcherList) for common types (as well as [custom matchers](cook_book.md#NewMatchers)); for example: ```cpp -- cgit v0.12 From 08347d7a16044ea636465a2bbe13a5d15522e238 Mon Sep 17 00:00:00 2001 From: Przemek Kryger Date: Tue, 24 Mar 2020 10:08:42 +0000 Subject: Swap settimer and sigaction calls to avoid SIGPROF Fixes #2760. --- googletest/test/googletest-death-test-test.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/googletest/test/googletest-death-test-test.cc b/googletest/test/googletest-death-test-test.cc index cba906c..b0dda27 100644 --- a/googletest/test/googletest-death-test-test.cc +++ b/googletest/test/googletest-death-test-test.cc @@ -391,17 +391,19 @@ void SigprofAction(int, siginfo_t*, void*) { /* no op */ } // Sets SIGPROF action and ITIMER_PROF timer (interval: 1ms). void SetSigprofActionAndTimer() { - struct itimerval timer; - timer.it_interval.tv_sec = 0; - timer.it_interval.tv_usec = 1; - timer.it_value = timer.it_interval; - ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, nullptr)); struct sigaction signal_action; memset(&signal_action, 0, sizeof(signal_action)); sigemptyset(&signal_action.sa_mask); signal_action.sa_sigaction = SigprofAction; signal_action.sa_flags = SA_RESTART | SA_SIGINFO; ASSERT_EQ(0, sigaction(SIGPROF, &signal_action, nullptr)); + // timer comes second, to avoid SIGPROF premature delivery, as suggested at + // https://www.gnu.org/software/libc/manual/html_node/Setting-an-Alarm.html + struct itimerval timer; + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = 1; + timer.it_value = timer.it_interval; + ASSERT_EQ(0, setitimer(ITIMER_PROF, &timer, nullptr)); } // Disables ITIMER_PROF timer and ignores SIGPROF signal. -- cgit v0.12 From 82e5767f7812d7725a4920b98f1013409ac798d8 Mon Sep 17 00:00:00 2001 From: Krystian Kuzniarek Date: Tue, 24 Mar 2020 15:18:30 +0100 Subject: remove dead code in googletest-output-test --- googletest/test/googletest-output-test_.cc | 57 ------------------------------ 1 file changed, 57 deletions(-) diff --git a/googletest/test/googletest-output-test_.cc b/googletest/test/googletest-output-test_.cc index 76af5bc..b32b8f3 100644 --- a/googletest/test/googletest-output-test_.cc +++ b/googletest/test/googletest-output-test_.cc @@ -476,63 +476,6 @@ TEST(GtestFailAtTest, MessageContainsSpecifiedFileAndLineNumber) { GTEST_FAIL_AT("foo.cc", 42) << "Expected fatal failure in foo.cc"; } -#if GTEST_IS_THREADSAFE - -// A unary function that may die. -void DieIf(bool should_die) { - GTEST_CHECK_(!should_die) << " - death inside DieIf()."; -} - -// Tests running death tests in a multi-threaded context. - -// Used for coordination between the main and the spawn thread. -struct SpawnThreadNotifications { - SpawnThreadNotifications() {} - - Notification spawn_thread_started; - Notification spawn_thread_ok_to_terminate; - - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(SpawnThreadNotifications); -}; - -// The function to be executed in the thread spawn by the -// MultipleThreads test (below). -static void ThreadRoutine(SpawnThreadNotifications* notifications) { - // Signals the main thread that this thread has started. - notifications->spawn_thread_started.Notify(); - - // Waits for permission to finish from the main thread. - notifications->spawn_thread_ok_to_terminate.WaitForNotification(); -} - -// This is a death-test test, but it's not named with a DeathTest -// suffix. It starts threads which might interfere with later -// death tests, so it must run after all other death tests. -class DeathTestAndMultiThreadsTest : public testing::Test { - protected: - // Starts a thread and waits for it to begin. - void SetUp() override { - thread_.reset(new ThreadWithParam( - &ThreadRoutine, ¬ifications_, nullptr)); - notifications_.spawn_thread_started.WaitForNotification(); - } - // Tells the thread to finish, and reaps it. - // Depending on the version of the thread library in use, - // a manager thread might still be left running that will interfere - // with later death tests. This is unfortunate, but this class - // cleans up after itself as best it can. - void TearDown() override { - notifications_.spawn_thread_ok_to_terminate.Notify(); - } - - private: - SpawnThreadNotifications notifications_; - std::unique_ptr > thread_; -}; - -#endif // GTEST_IS_THREADSAFE - // The MixedUpTestSuiteTest test case verifies that Google Test will fail a // test if it uses a different fixture class than what other tests in // the same test case use. It deliberately contains two fixture -- cgit v0.12 From acabdf65fba14304af01d4734343964e0d5ef970 Mon Sep 17 00:00:00 2001 From: Krystian Kuzniarek Date: Tue, 24 Mar 2020 15:37:34 +0100 Subject: remove chapters on Autotools, Meson and plain Makefiles --- googletest/docs/pkgconfig.md | 71 -------------------------------------------- 1 file changed, 71 deletions(-) diff --git a/googletest/docs/pkgconfig.md b/googletest/docs/pkgconfig.md index 117166c..b9bef3f 100644 --- a/googletest/docs/pkgconfig.md +++ b/googletest/docs/pkgconfig.md @@ -45,77 +45,6 @@ splitting the pkg-config `Cflags` variable into include dirs and macros for goes for using `_LDFLAGS` over the more commonplace `_LIBRARIES`, which happens to discard `-L` flags and `-pthread`. -### Autotools - -Finding GoogleTest in Autoconf and using it from Automake is also fairly easy: - -In your `configure.ac`: - -``` -AC_PREREQ([2.69]) -AC_INIT([my_gtest_pkgconfig], [0.0.1]) -AC_CONFIG_SRCDIR([samples/sample3_unittest.cc]) -AC_PROG_CXX - -PKG_CHECK_MODULES([GTEST], [gtest_main]) - -AM_INIT_AUTOMAKE([foreign subdir-objects]) -AC_CONFIG_FILES([Makefile]) -AC_OUTPUT -``` - -and in your `Makefile.am`: - -``` -check_PROGRAMS = testapp -TESTS = $(check_PROGRAMS) - -testapp_SOURCES = samples/sample3_unittest.cc -testapp_CXXFLAGS = $(GTEST_CFLAGS) -testapp_LDADD = $(GTEST_LIBS) -``` - -### Meson - -Meson natively uses pkgconfig to query dependencies: - -``` -project('my_gtest_pkgconfig', 'cpp', version : '0.0.1') - -gtest_dep = dependency('gtest_main') - -testapp = executable( - 'testapp', - files(['samples/sample3_unittest.cc']), - dependencies : gtest_dep, - install : false) - -test('first_and_only_test', testapp) -``` - -### Plain Makefiles - -Since `pkg-config` is a small Unix command-line utility, it can be used in -handwritten `Makefile`s too: - -```makefile -GTEST_CFLAGS = `pkg-config --cflags gtest_main` -GTEST_LIBS = `pkg-config --libs gtest_main` - -.PHONY: tests all - -tests: all - ./testapp - -all: testapp - -testapp: testapp.o - $(CXX) $(CXXFLAGS) $(LDFLAGS) $< -o $@ $(GTEST_LIBS) - -testapp.o: samples/sample3_unittest.cc - $(CXX) $(CPPFLAGS) $(CXXFLAGS) $< -c -o $@ $(GTEST_CFLAGS) -``` - ### Help! pkg-config can't find GoogleTest! Let's say you have a `CMakeLists.txt` along the lines of the one in this -- cgit v0.12 From 1ced315a483f4ecac21893ce6ceeb502afb82eff Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 23 Mar 2020 15:15:58 -0400 Subject: Googletest export Add --gtest_fail_fast support to googletest. - Analogous functionality to to golang -test.failfast and python --failfast - Stops test execution upon first test failure. - Also add support Bazel equivalent env var (TESTBRIDGE_TEST_RUNNER_FAIL_FAST) PiperOrigin-RevId: 302488880 --- googletest/docs/advanced.md | 9 + googletest/include/gtest/gtest.h | 10 + googletest/src/gtest-internal-inl.h | 4 + googletest/src/gtest.cc | 130 +++++-- googletest/test/BUILD.bazel | 16 + googletest/test/googletest-env-var-test.py | 2 + googletest/test/googletest-env-var-test_.cc | 5 + googletest/test/googletest-failfast-unittest.py | 410 +++++++++++++++++++++++ googletest/test/googletest-failfast-unittest_.cc | 167 +++++++++ googletest/test/gtest_unittest.cc | 85 +++-- 10 files changed, 784 insertions(+), 54 deletions(-) create mode 100755 googletest/test/googletest-failfast-unittest.py create mode 100644 googletest/test/googletest-failfast-unittest_.cc diff --git a/googletest/docs/advanced.md b/googletest/docs/advanced.md index 5677643..1295c9d 100644 --- a/googletest/docs/advanced.md +++ b/googletest/docs/advanced.md @@ -2116,6 +2116,15 @@ For example: everything in test suite `FooTest` except `FooTest.Bar` and everything in 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 If you have a broken test that you cannot fix right away, you can add the diff --git a/googletest/include/gtest/gtest.h b/googletest/include/gtest/gtest.h index 0139fcc..deacb27 100644 --- a/googletest/include/gtest/gtest.h +++ b/googletest/include/gtest/gtest.h @@ -101,6 +101,10 @@ GTEST_DECLARE_bool_(catch_exceptions); // to let Google Test decide. 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 // the tests to run. If the filter is not given all tests are executed. GTEST_DECLARE_string_(filter); @@ -795,6 +799,9 @@ class GTEST_API_ TestInfo { // deletes it. void Run(); + // Skip and records the test result for this object. + void Skip(); + static void ClearTestResult(TestInfo* test_info) { test_info->result_.Clear(); } @@ -943,6 +950,9 @@ class GTEST_API_ TestSuite { // Runs every test in this TestSuite. void Run(); + // Skips the execution of tests under this TestSuite + void Skip(); + // Runs SetUpTestSuite() for this TestSuite. This wrapper is needed // for catching exceptions thrown from SetUpTestSuite(). void RunSetUpTestSuite() { diff --git a/googletest/src/gtest-internal-inl.h b/googletest/src/gtest-internal-inl.h index e42ff47..75ec352 100644 --- a/googletest/src/gtest-internal-inl.h +++ b/googletest/src/gtest-internal-inl.h @@ -84,6 +84,7 @@ const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; const char kBreakOnFailureFlag[] = "break_on_failure"; const char kCatchExceptionsFlag[] = "catch_exceptions"; const char kColorFlag[] = "color"; +const char kFailFast[] = "fail_fast"; const char kFilterFlag[] = "filter"; const char kListTestsFlag[] = "list_tests"; const char kOutputFlag[] = "output"; @@ -164,6 +165,7 @@ class GTestFlagSaver { color_ = GTEST_FLAG(color); death_test_style_ = GTEST_FLAG(death_test_style); death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); + fail_fast_ = GTEST_FLAG(fail_fast); filter_ = GTEST_FLAG(filter); internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); list_tests_ = GTEST_FLAG(list_tests); @@ -187,6 +189,7 @@ class GTestFlagSaver { GTEST_FLAG(death_test_style) = death_test_style_; GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; GTEST_FLAG(filter) = filter_; + GTEST_FLAG(fail_fast) = fail_fast_; GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; GTEST_FLAG(list_tests) = list_tests_; GTEST_FLAG(output) = output_; @@ -208,6 +211,7 @@ class GTestFlagSaver { std::string color_; std::string death_test_style_; bool death_test_use_fork_; + bool fail_fast_; std::string filter_; std::string internal_run_death_test_; bool list_tests_; diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 2eb2ecb..4c8b42f 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -213,6 +213,21 @@ static const char* GetDefaultFilter() { 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_( also_run_disabled_tests, internal::BoolFromGTestEnv("also_run_disabled_tests", false), @@ -2863,6 +2878,28 @@ void TestInfo::Run() { 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 // Gets the number of successful tests in this test suite. @@ -2975,6 +3012,12 @@ void TestSuite::Run() { start_timestamp_ = internal::GetTimeInMillis(); for (int i = 0; i < total_test_count(); i++) { 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_; @@ -2992,6 +3035,36 @@ void TestSuite::Run() { 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. void TestSuite::ClearResult() { ad_hoc_test_result_.Clear(); @@ -5523,6 +5596,13 @@ bool UnitTestImpl::RunAllTests() { for (int test_index = 0; test_index < total_test_suite_count(); test_index++) { 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; + } } } @@ -6127,31 +6207,31 @@ static const char kColorEncodedHelpMessage[] = static bool ParseGoogleTestFlag(const char* const arg) { return ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, >EST_FLAG(also_run_disabled_tests)) || - ParseBoolFlag(arg, kBreakOnFailureFlag, - >EST_FLAG(break_on_failure)) || - ParseBoolFlag(arg, kCatchExceptionsFlag, - >EST_FLAG(catch_exceptions)) || - ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || - ParseStringFlag(arg, kDeathTestStyleFlag, - >EST_FLAG(death_test_style)) || - ParseBoolFlag(arg, kDeathTestUseFork, - >EST_FLAG(death_test_use_fork)) || - ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || - ParseStringFlag(arg, kInternalRunDeathTestFlag, - >EST_FLAG(internal_run_death_test)) || - ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || - ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || - ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || - ParseBoolFlag(arg, kPrintUTF8Flag, >EST_FLAG(print_utf8)) || - ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || - ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || - ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || - ParseInt32Flag(arg, kStackTraceDepthFlag, - >EST_FLAG(stack_trace_depth)) || - ParseStringFlag(arg, kStreamResultToFlag, - >EST_FLAG(stream_result_to)) || - ParseBoolFlag(arg, kThrowOnFailureFlag, - >EST_FLAG(throw_on_failure)); + ParseBoolFlag(arg, kBreakOnFailureFlag, + >EST_FLAG(break_on_failure)) || + ParseBoolFlag(arg, kCatchExceptionsFlag, + >EST_FLAG(catch_exceptions)) || + ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || + ParseStringFlag(arg, kDeathTestStyleFlag, + >EST_FLAG(death_test_style)) || + ParseBoolFlag(arg, kDeathTestUseFork, + >EST_FLAG(death_test_use_fork)) || + ParseBoolFlag(arg, kFailFast, >EST_FLAG(fail_fast)) || + ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || + ParseStringFlag(arg, kInternalRunDeathTestFlag, + >EST_FLAG(internal_run_death_test)) || + ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || + ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || + ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || + ParseBoolFlag(arg, kPrintUTF8Flag, >EST_FLAG(print_utf8)) || + ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || + ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || + ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || + ParseInt32Flag(arg, kStackTraceDepthFlag, + >EST_FLAG(stack_trace_depth)) || + ParseStringFlag(arg, kStreamResultToFlag, + >EST_FLAG(stream_result_to)) || + ParseBoolFlag(arg, kThrowOnFailureFlag, >EST_FLAG(throw_on_failure)); } #if GTEST_USE_OWN_FLAGFILE_FLAG_ diff --git a/googletest/test/BUILD.bazel b/googletest/test/BUILD.bazel index dbbb5c0..e24f5f2 100644 --- a/googletest/test/BUILD.bazel +++ b/googletest/test/BUILD.bazel @@ -58,6 +58,7 @@ cc_test( "googletest-catch-exceptions-test_.cc", "googletest-color-test_.cc", "googletest-env-var-test_.cc", + "googletest-failfast-unittest_.cc", "googletest-filter-unittest_.cc", "googletest-break-on-failure-unittest_.cc", "googletest-listener-test.cc", @@ -223,6 +224,21 @@ py_test( ) 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( name = "googletest-filter-unittest_", testonly = 1, srcs = ["googletest-filter-unittest_.cc"], diff --git a/googletest/test/googletest-env-var-test.py b/googletest/test/googletest-env-var-test.py index 2f0e406..ce4d2a0 100755 --- a/googletest/test/googletest-env-var-test.py +++ b/googletest/test/googletest-env-var-test.py @@ -85,6 +85,8 @@ class GTestEnvVarTest(gtest_test_utils.TestCase): TestFlag('break_on_failure', '1', '0') TestFlag('color', 'yes', 'auto') + SetEnvVar('TESTBRIDGE_TEST_RUNNER_FAIL_FAST', None) # For 'fail_fast' test + TestFlag('fail_fast', '1', '0') TestFlag('filter', 'FooTest.Bar', '*') SetEnvVar('XML_OUTPUT_FILE', None) # For 'output' test TestFlag('output', 'xml:tmp/foo.xml', '') diff --git a/googletest/test/googletest-env-var-test_.cc b/googletest/test/googletest-env-var-test_.cc index fd2aa82..66d1871 100644 --- a/googletest/test/googletest-env-var-test_.cc +++ b/googletest/test/googletest-env-var-test_.cc @@ -72,6 +72,11 @@ void PrintFlag(const char* flag) { return; } + if (strcmp(flag, "fail_fast") == 0) { + cout << GTEST_FLAG(fail_fast); + return; + } + if (strcmp(flag, "filter") == 0) { cout << GTEST_FLAG(filter); return; diff --git a/googletest/test/googletest-failfast-unittest.py b/googletest/test/googletest-failfast-unittest.py new file mode 100755 index 0000000..3aeb2df --- /dev/null +++ b/googletest/test/googletest-failfast-unittest.py @@ -0,0 +1,410 @@ +#!/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() diff --git a/googletest/test/googletest-failfast-unittest_.cc b/googletest/test/googletest-failfast-unittest_.cc new file mode 100644 index 0000000..0b2c951 --- /dev/null +++ b/googletest/test/googletest-failfast-unittest_.cc @@ -0,0 +1,167 @@ +// 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 {}; + +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(); +} diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index 06c5e67..f3b7216 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -37,21 +37,22 @@ // code once "gtest.h" has been #included. // Do not move it after other gtest #includes. TEST(CommandLineFlagsTest, CanBeAccessedInCodeOnceGTestHIsIncluded) { - bool dummy = testing::GTEST_FLAG(also_run_disabled_tests) - || testing::GTEST_FLAG(break_on_failure) - || testing::GTEST_FLAG(catch_exceptions) - || testing::GTEST_FLAG(color) != "unknown" - || testing::GTEST_FLAG(filter) != "unknown" - || testing::GTEST_FLAG(list_tests) - || testing::GTEST_FLAG(output) != "unknown" - || testing::GTEST_FLAG(print_time) - || testing::GTEST_FLAG(random_seed) - || testing::GTEST_FLAG(repeat) > 0 - || testing::GTEST_FLAG(show_internal_stack_frames) - || testing::GTEST_FLAG(shuffle) - || testing::GTEST_FLAG(stack_trace_depth) > 0 - || testing::GTEST_FLAG(stream_result_to) != "unknown" - || testing::GTEST_FLAG(throw_on_failure); + bool dummy = testing::GTEST_FLAG(also_run_disabled_tests) || + testing::GTEST_FLAG(break_on_failure) || + testing::GTEST_FLAG(catch_exceptions) || + testing::GTEST_FLAG(color) != "unknown" || + testing::GTEST_FLAG(fail_fast) || + testing::GTEST_FLAG(filter) != "unknown" || + testing::GTEST_FLAG(list_tests) || + testing::GTEST_FLAG(output) != "unknown" || + testing::GTEST_FLAG(print_time) || + testing::GTEST_FLAG(random_seed) || + testing::GTEST_FLAG(repeat) > 0 || + testing::GTEST_FLAG(show_internal_stack_frames) || + testing::GTEST_FLAG(shuffle) || + testing::GTEST_FLAG(stack_trace_depth) > 0 || + testing::GTEST_FLAG(stream_result_to) != "unknown" || + testing::GTEST_FLAG(throw_on_failure); EXPECT_TRUE(dummy || !dummy); // Suppresses warning that dummy is unused. } @@ -202,6 +203,7 @@ using testing::GTEST_FLAG(break_on_failure); using testing::GTEST_FLAG(catch_exceptions); using testing::GTEST_FLAG(color); using testing::GTEST_FLAG(death_test_use_fork); +using testing::GTEST_FLAG(fail_fast); using testing::GTEST_FLAG(filter); using testing::GTEST_FLAG(list_tests); using testing::GTEST_FLAG(output); @@ -1598,6 +1600,7 @@ class GTestFlagSaverTest : public Test { GTEST_FLAG(catch_exceptions) = false; GTEST_FLAG(death_test_use_fork) = false; GTEST_FLAG(color) = "auto"; + GTEST_FLAG(fail_fast) = false; GTEST_FLAG(filter) = ""; GTEST_FLAG(list_tests) = false; GTEST_FLAG(output) = ""; @@ -1625,6 +1628,7 @@ class GTestFlagSaverTest : public Test { EXPECT_FALSE(GTEST_FLAG(catch_exceptions)); EXPECT_STREQ("auto", GTEST_FLAG(color).c_str()); EXPECT_FALSE(GTEST_FLAG(death_test_use_fork)); + EXPECT_FALSE(GTEST_FLAG(fail_fast)); EXPECT_STREQ("", GTEST_FLAG(filter).c_str()); EXPECT_FALSE(GTEST_FLAG(list_tests)); EXPECT_STREQ("", GTEST_FLAG(output).c_str()); @@ -1641,6 +1645,7 @@ class GTestFlagSaverTest : public Test { GTEST_FLAG(catch_exceptions) = true; GTEST_FLAG(color) = "no"; GTEST_FLAG(death_test_use_fork) = true; + GTEST_FLAG(fail_fast) = true; GTEST_FLAG(filter) = "abc"; GTEST_FLAG(list_tests) = true; GTEST_FLAG(output) = "xml:foo.xml"; @@ -5495,20 +5500,22 @@ TEST_F(SetUpTestSuiteTest, TestSetupTestSuite2) { // The Flags struct stores a copy of all Google Test flags. struct Flags { // Constructs a Flags struct where each flag has its default value. - Flags() : also_run_disabled_tests(false), - break_on_failure(false), - catch_exceptions(false), - death_test_use_fork(false), - filter(""), - list_tests(false), - output(""), - print_time(true), - random_seed(0), - repeat(1), - shuffle(false), - stack_trace_depth(kMaxStackTraceDepth), - stream_result_to(""), - throw_on_failure(false) {} + Flags() + : also_run_disabled_tests(false), + break_on_failure(false), + catch_exceptions(false), + death_test_use_fork(false), + fail_fast(false), + filter(""), + list_tests(false), + output(""), + print_time(true), + random_seed(0), + repeat(1), + shuffle(false), + stack_trace_depth(kMaxStackTraceDepth), + stream_result_to(""), + throw_on_failure(false) {} // Factory methods. @@ -5544,6 +5551,14 @@ struct 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 // value. static Flags Filter(const char* filter) { @@ -5629,6 +5644,7 @@ struct Flags { bool break_on_failure; bool catch_exceptions; bool death_test_use_fork; + bool fail_fast; const char* filter; bool list_tests; const char* output; @@ -5650,6 +5666,7 @@ class ParseFlagsTest : public Test { GTEST_FLAG(break_on_failure) = false; GTEST_FLAG(catch_exceptions) = false; GTEST_FLAG(death_test_use_fork) = false; + GTEST_FLAG(fail_fast) = false; GTEST_FLAG(filter) = ""; GTEST_FLAG(list_tests) = false; GTEST_FLAG(output) = ""; @@ -5680,6 +5697,7 @@ class ParseFlagsTest : public Test { EXPECT_EQ(expected.break_on_failure, GTEST_FLAG(break_on_failure)); 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.fail_fast, GTEST_FLAG(fail_fast)); EXPECT_STREQ(expected.filter, GTEST_FLAG(filter).c_str()); EXPECT_EQ(expected.list_tests, GTEST_FLAG(list_tests)); EXPECT_STREQ(expected.output, GTEST_FLAG(output).c_str()); @@ -5766,6 +5784,15 @@ TEST_F(ParseFlagsTest, NoFlag) { 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. TEST_F(ParseFlagsTest, FilterBad) { const char* argv[] = {"foo.exe", "--gtest_filter", nullptr}; -- cgit v0.12 From 61f010d703b32de9bfb20ab90ece38ab2f25977f Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 30 Mar 2020 14:26:22 -0400 Subject: Googletest export Do not use std::result_of as it was removed in C++20. PiperOrigin-RevId: 303783600 --- googlemock/include/gmock/gmock-actions.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index b4127e9..615651b 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -970,7 +970,8 @@ struct InvokeMethodWithoutArgsAction { Class* const obj_ptr; const MethodPtr method_ptr; - using ReturnType = typename std::result_of::type; + using ReturnType = + decltype((std::declval()->*std::declval())()); template ReturnType operator()(const Args&...) const { -- cgit v0.12 From c344cb5a8d2bea2a46dcf2805cdb859bb70fa6cb Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 1 Apr 2020 19:33:24 -0400 Subject: Googletest export This change updates testing::internal::IsAProtocolMessage to return true not just for full proto messages but also for lite ones (i.e. those inheriting directly from MessageLite). PiperOrigin-RevId: 304286535 --- googletest/include/gtest/internal/gtest-internal.h | 8 +++++--- googletest/test/gtest_unittest.cc | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h index 6bad878..7f1a5b0 100644 --- a/googletest/include/gtest/internal/gtest-internal.h +++ b/googletest/include/gtest/internal/gtest-internal.h @@ -90,7 +90,9 @@ #define GTEST_STRINGIFY_HELPER_(name, ...) #name #define GTEST_STRINGIFY_(...) GTEST_STRINGIFY_HELPER_(__VA_ARGS__, ) -namespace proto2 { class Message; } +namespace proto2 { +class MessageLite; +} namespace testing { @@ -879,10 +881,10 @@ class GTEST_API_ Random { typename std::remove_const::type>::type // IsAProtocolMessage::value is a compile-time bool constant that's -// true if and only if T is type proto2::Message or a subclass of it. +// true if and only if T is type proto2::MessageLite or a subclass of it. template struct IsAProtocolMessage - : public std::is_convertible {}; + : public std::is_convertible {}; // When the compiler sees expression IsContainerTest(0), if C is an // STL-style container class, the first overload of IsContainerTest diff --git a/googletest/test/gtest_unittest.cc b/googletest/test/gtest_unittest.cc index f3b7216..005a2d4 100644 --- a/googletest/test/gtest_unittest.cc +++ b/googletest/test/gtest_unittest.cc @@ -7104,7 +7104,7 @@ class ConversionHelperDerived : public ConversionHelperBase {}; // Tests that IsAProtocolMessage::value is a compile-time constant. TEST(IsAProtocolMessageTest, ValueIsCompileTimeConstant) { - GTEST_COMPILE_ASSERT_(IsAProtocolMessage<::proto2::Message>::value, + GTEST_COMPILE_ASSERT_(IsAProtocolMessage<::proto2::MessageLite>::value, const_true); GTEST_COMPILE_ASSERT_(!IsAProtocolMessage::value, const_false); } @@ -7112,7 +7112,7 @@ TEST(IsAProtocolMessageTest, ValueIsCompileTimeConstant) { // Tests that IsAProtocolMessage::value is true when T is // proto2::Message or a sub-class of it. TEST(IsAProtocolMessageTest, ValueIsTrueWhenTypeIsAProtocolMessage) { - EXPECT_TRUE(IsAProtocolMessage< ::proto2::Message>::value); + EXPECT_TRUE(IsAProtocolMessage<::proto2::MessageLite>::value); } // Tests that IsAProtocolMessage::value is false when T is neither -- cgit v0.12