From b4d4e6e348014aec06655637390e23896e323704 Mon Sep 17 00:00:00 2001 From: Ludger Paehler Date: Thu, 25 Nov 2021 16:53:19 +0100 Subject: [PATCH 1/5] Fix typo in the queue test. --- docs/primer.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/primer.md b/docs/primer.md index aecc368b..f6318a5d 100644 --- a/docs/primer.md +++ b/docs/primer.md @@ -274,8 +274,8 @@ First, define a fixture class. By convention, you should give it the name class QueueTest : public ::testing::Test { protected: void SetUp() override { - q1_.Enqueue(1); - q2_.Enqueue(2); + q0_.Enqueue(1); + q1_.Enqueue(2); q2_.Enqueue(3); } From 71d4e2f7423274d178b446e94b88082559f2fa7a Mon Sep 17 00:00:00 2001 From: Derek Mauro Date: Tue, 21 Dec 2021 13:15:49 -0800 Subject: [PATCH 2/5] Makes TestForDeathTest.CRTDebugDeath only run when _DEBUG is defined PiperOrigin-RevId: 417678422 Change-Id: I8e42a906459b8fd5a7789a7ed728d12448046c44 --- googletest/test/googletest-death-test-test.cc | 32 +++++-------------- 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/googletest/test/googletest-death-test-test.cc b/googletest/test/googletest-death-test-test.cc index e7e0cd70..62a84b47 100644 --- a/googletest/test/googletest-death-test-test.cc +++ b/googletest/test/googletest-death-test-test.cc @@ -668,35 +668,19 @@ TEST_F(TestForDeathTest, TestExpectDebugDeath) { # if GTEST_OS_WINDOWS -// Tests that EXPECT_DEBUG_DEATH works as expected when in debug mode -// the Windows CRT crashes the process with an assertion failure. +// https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/crtsetreportmode +// In debug mode, the calls to _CrtSetReportMode and _CrtSetReportFile enable +// the dumping of assertions to stderr. Tests that EXPECT_DEATH works as +// expected when in CRT debug mode (compiled with /MTd or /MDd, which defines +// _DEBUG) the Windows CRT crashes the process with an assertion failure. // 1. Asserts on death. // 2. Has no side effect (doesn't pop up a window or wait for user input). -// -// And in opt mode, it: -// 1. Has side effects but does not assert. +#ifdef _DEBUG TEST_F(TestForDeathTest, CRTDebugDeath) { - int sideeffect = 0; - - // Put the regex in a local variable to make sure we don't get an "unused" - // warning in opt mode. - const char* regex = "dup.* : Assertion failed"; - - EXPECT_DEBUG_DEATH(DieInCRTDebugElse12(&sideeffect), regex) + EXPECT_DEATH(DieInCRTDebugElse12(nullptr), "dup.* : Assertion failed") << "Must accept a streamed message"; - -# ifdef NDEBUG - - // Checks that the assignment occurs in opt mode (sideeffect). - EXPECT_EQ(12, sideeffect); - -# else - - // Checks that the assignment does not occur in dbg mode (no sideeffect). - EXPECT_EQ(0, sideeffect); - -# endif } +#endif // _DEBUG # endif // GTEST_OS_WINDOWS From c58f562fa2b287ab58a51b702f3c7295efe89904 Mon Sep 17 00:00:00 2001 From: Derek Mauro Date: Wed, 22 Dec 2021 13:00:44 -0800 Subject: [PATCH 3/5] Makes the Python imports consistently use full paths from the repository root, unifying the behavior between Bazel and CMake This fixes one of the CI failures on Windows PiperOrigin-RevId: 417872531 Change-Id: I156989323b7e6d4a4420f4f9691b078829db933d --- googlemock/test/gmock_leak_test.py | 2 +- googlemock/test/gmock_output_test.py | 2 +- googlemock/test/gmock_test_utils.py | 14 +------------- googletest/cmake/internal_utils.cmake | 2 ++ .../test/googletest-break-on-failure-unittest.py | 2 +- .../test/googletest-catch-exceptions-test.py | 2 +- googletest/test/googletest-color-test.py | 2 +- googletest/test/googletest-env-var-test.py | 2 +- googletest/test/googletest-failfast-unittest.py | 2 +- googletest/test/googletest-filter-unittest.py | 2 +- .../test/googletest-global-environment-unittest.py | 2 +- googletest/test/googletest-json-outfiles-test.py | 4 ++-- googletest/test/googletest-json-output-unittest.py | 4 ++-- googletest/test/googletest-list-tests-unittest.py | 2 +- googletest/test/googletest-output-test.py | 2 +- .../googletest-param-test-invalid-name1-test.py | 2 +- .../googletest-param-test-invalid-name2-test.py | 2 +- googletest/test/googletest-setuptestsuite-test.py | 2 +- googletest/test/googletest-shuffle-test.py | 2 +- .../test/googletest-throw-on-failure-test.py | 2 +- googletest/test/googletest-uninitialized-test.py | 2 +- googletest/test/gtest_help_test.py | 2 +- googletest/test/gtest_list_output_unittest.py | 2 +- googletest/test/gtest_skip_check_output_test.py | 2 +- .../gtest_skip_environment_check_output_test.py | 2 +- googletest/test/gtest_testbridge_test.py | 2 +- googletest/test/gtest_xml_outfiles_test.py | 4 ++-- googletest/test/gtest_xml_output_unittest.py | 4 ++-- googletest/test/gtest_xml_test_utils.py | 2 +- 29 files changed, 34 insertions(+), 44 deletions(-) diff --git a/googlemock/test/gmock_leak_test.py b/googlemock/test/gmock_leak_test.py index 7e4b1eea..4f41c7bb 100755 --- a/googlemock/test/gmock_leak_test.py +++ b/googlemock/test/gmock_leak_test.py @@ -31,7 +31,7 @@ """Tests that leaked mock objects can be caught be Google Mock.""" -import gmock_test_utils +from googlemock.test import gmock_test_utils PROGRAM_PATH = gmock_test_utils.GetTestExecutablePath('gmock_leak_test_') TEST_WITH_EXPECT_CALL = [PROGRAM_PATH, '--gtest_filter=*ExpectCall*'] diff --git a/googlemock/test/gmock_output_test.py b/googlemock/test/gmock_output_test.py index 25f99f2b..71532c55 100755 --- a/googlemock/test/gmock_output_test.py +++ b/googlemock/test/gmock_output_test.py @@ -43,7 +43,7 @@ from io import open # pylint: disable=redefined-builtin, g-importing-member import os import re import sys -import gmock_test_utils +from googlemock.test import gmock_test_utils # The flag for generating the golden file diff --git a/googlemock/test/gmock_test_utils.py b/googlemock/test/gmock_test_utils.py index 7dc4e119..d7bc0974 100755 --- a/googlemock/test/gmock_test_utils.py +++ b/googlemock/test/gmock_test_utils.py @@ -30,21 +30,9 @@ """Unit test utilities for Google C++ Mocking Framework.""" import os -import sys - -# Determines path to gtest_test_utils and imports it. -SCRIPT_DIR = os.path.dirname(__file__) or '.' - -# isdir resolves symbolic links. -gtest_tests_util_dir = os.path.join(SCRIPT_DIR, '../../googletest/test') -if os.path.isdir(gtest_tests_util_dir): - GTEST_TESTS_UTIL_DIR = gtest_tests_util_dir -else: - GTEST_TESTS_UTIL_DIR = os.path.join(SCRIPT_DIR, '../../googletest/test') -sys.path.append(GTEST_TESTS_UTIL_DIR) # pylint: disable=C6204 -import gtest_test_utils +from googletest.test import gtest_test_utils def GetSourceDir(): diff --git a/googletest/cmake/internal_utils.cmake b/googletest/cmake/internal_utils.cmake index 58fc9bfb..0c7983ae 100644 --- a/googletest/cmake/internal_utils.cmake +++ b/googletest/cmake/internal_utils.cmake @@ -304,6 +304,8 @@ function(py_test name) COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test/${name}.py --build_dir=${CMAKE_CURRENT_BINARY_DIR}/\${CTEST_CONFIGURATION_TYPE} ${ARGN}) endif() + # Make the Python import path consistent between Bazel and CMake. + set_tests_properties(${name} PROPERTIES ENVIRONMENT PYTHONPATH=${CMAKE_SOURCE_DIR}) endif(PYTHONINTERP_FOUND) endfunction() diff --git a/googletest/test/googletest-break-on-failure-unittest.py b/googletest/test/googletest-break-on-failure-unittest.py index a5dfbc69..4eafba3e 100755 --- a/googletest/test/googletest-break-on-failure-unittest.py +++ b/googletest/test/googletest-break-on-failure-unittest.py @@ -39,7 +39,7 @@ Google Test) with different environments and command line flags. """ import os -import gtest_test_utils +from googletest.test import gtest_test_utils # Constants. diff --git a/googletest/test/googletest-catch-exceptions-test.py b/googletest/test/googletest-catch-exceptions-test.py index 442397a4..d38d91a6 100755 --- a/googletest/test/googletest-catch-exceptions-test.py +++ b/googletest/test/googletest-catch-exceptions-test.py @@ -35,7 +35,7 @@ googletest-catch-exceptions-ex-test_ (programs written with Google Test) and verifies their output. """ -import gtest_test_utils +from googletest.test import gtest_test_utils # Constants. FLAG_PREFIX = '--gtest_' diff --git a/googletest/test/googletest-color-test.py b/googletest/test/googletest-color-test.py index f3b7c999..c22752db 100755 --- a/googletest/test/googletest-color-test.py +++ b/googletest/test/googletest-color-test.py @@ -32,7 +32,7 @@ """Verifies that Google Test correctly determines whether to use colors.""" import os -import gtest_test_utils +from googletest.test import gtest_test_utils IS_WINDOWS = os.name == 'nt' diff --git a/googletest/test/googletest-env-var-test.py b/googletest/test/googletest-env-var-test.py index 02c3655c..bc4d87d9 100755 --- a/googletest/test/googletest-env-var-test.py +++ b/googletest/test/googletest-env-var-test.py @@ -32,7 +32,7 @@ """Verifies that Google Test correctly parses environment variables.""" import os -import gtest_test_utils +from googletest.test import gtest_test_utils IS_WINDOWS = os.name == 'nt' diff --git a/googletest/test/googletest-failfast-unittest.py b/googletest/test/googletest-failfast-unittest.py index 3aeb2dff..1356d4f8 100755 --- a/googletest/test/googletest-failfast-unittest.py +++ b/googletest/test/googletest-failfast-unittest.py @@ -41,7 +41,7 @@ line flags. """ import os -import gtest_test_utils +from googletest.test import gtest_test_utils # Constants. diff --git a/googletest/test/googletest-filter-unittest.py b/googletest/test/googletest-filter-unittest.py index 6b32f2d2..bd1d5a5d 100755 --- a/googletest/test/googletest-filter-unittest.py +++ b/googletest/test/googletest-filter-unittest.py @@ -47,7 +47,7 @@ try: except ImportError: pass import sys -import gtest_test_utils +from googletest.test import gtest_test_utils # Constants. diff --git a/googletest/test/googletest-global-environment-unittest.py b/googletest/test/googletest-global-environment-unittest.py index f3475599..ef2cfb85 100644 --- a/googletest/test/googletest-global-environment-unittest.py +++ b/googletest/test/googletest-global-environment-unittest.py @@ -36,7 +36,7 @@ googletest-global-environment-unittest_ (a program written with Google Test). """ import re -import gtest_test_utils +from googletest.test import gtest_test_utils def RunAndReturnOutput(args=None): diff --git a/googletest/test/googletest-json-outfiles-test.py b/googletest/test/googletest-json-outfiles-test.py index 8ef47b8f..db9716c2 100644 --- a/googletest/test/googletest-json-outfiles-test.py +++ b/googletest/test/googletest-json-outfiles-test.py @@ -32,8 +32,8 @@ import json import os -import gtest_json_test_utils -import gtest_test_utils +from googletest.test import gtest_json_test_utils +from googletest.test import gtest_test_utils GTEST_OUTPUT_SUBDIR = 'json_outfiles' GTEST_OUTPUT_1_TEST = 'gtest_xml_outfile1_test_' diff --git a/googletest/test/googletest-json-output-unittest.py b/googletest/test/googletest-json-output-unittest.py index 41c85651..cb31965e 100644 --- a/googletest/test/googletest-json-output-unittest.py +++ b/googletest/test/googletest-json-output-unittest.py @@ -37,8 +37,8 @@ import os import re import sys -import gtest_json_test_utils -import gtest_test_utils +from googletest.test import gtest_json_test_utils +from googletest.test import gtest_test_utils GTEST_FILTER_FLAG = '--gtest_filter' GTEST_LIST_TESTS_FLAG = '--gtest_list_tests' diff --git a/googletest/test/googletest-list-tests-unittest.py b/googletest/test/googletest-list-tests-unittest.py index 81423a33..9d56883d 100755 --- a/googletest/test/googletest-list-tests-unittest.py +++ b/googletest/test/googletest-list-tests-unittest.py @@ -38,7 +38,7 @@ Google Test) the command line flags. """ import re -import gtest_test_utils +from googletest.test import gtest_test_utils # Constants. diff --git a/googletest/test/googletest-output-test.py b/googletest/test/googletest-output-test.py index 09028f66..ff444833 100755 --- a/googletest/test/googletest-output-test.py +++ b/googletest/test/googletest-output-test.py @@ -42,7 +42,7 @@ import difflib import os import re import sys -import gtest_test_utils +from googletest.test import gtest_test_utils # The flag for generating the golden file diff --git a/googletest/test/googletest-param-test-invalid-name1-test.py b/googletest/test/googletest-param-test-invalid-name1-test.py index 2a08477a..b8d609a7 100644 --- a/googletest/test/googletest-param-test-invalid-name1-test.py +++ b/googletest/test/googletest-param-test-invalid-name1-test.py @@ -30,7 +30,7 @@ """Verifies that Google Test warns the user when not initialized properly.""" -import gtest_test_utils +from googletest.test import gtest_test_utils binary_name = 'googletest-param-test-invalid-name1-test_' COMMAND = gtest_test_utils.GetTestExecutablePath(binary_name) diff --git a/googletest/test/googletest-param-test-invalid-name2-test.py b/googletest/test/googletest-param-test-invalid-name2-test.py index ab838f46..d92fa065 100644 --- a/googletest/test/googletest-param-test-invalid-name2-test.py +++ b/googletest/test/googletest-param-test-invalid-name2-test.py @@ -30,7 +30,7 @@ """Verifies that Google Test warns the user when not initialized properly.""" -import gtest_test_utils +from googletest.test import gtest_test_utils binary_name = 'googletest-param-test-invalid-name2-test_' COMMAND = gtest_test_utils.GetTestExecutablePath(binary_name) diff --git a/googletest/test/googletest-setuptestsuite-test.py b/googletest/test/googletest-setuptestsuite-test.py index c82162fc..9d1fd029 100755 --- a/googletest/test/googletest-setuptestsuite-test.py +++ b/googletest/test/googletest-setuptestsuite-test.py @@ -31,7 +31,7 @@ """Verifies that SetUpTestSuite and TearDownTestSuite errors are noticed.""" -import gtest_test_utils +from googletest.test import gtest_test_utils COMMAND = gtest_test_utils.GetTestExecutablePath( 'googletest-setuptestsuite-test_') diff --git a/googletest/test/googletest-shuffle-test.py b/googletest/test/googletest-shuffle-test.py index 573cc5ec..9d2adc12 100755 --- a/googletest/test/googletest-shuffle-test.py +++ b/googletest/test/googletest-shuffle-test.py @@ -31,7 +31,7 @@ """Verifies that test shuffling works.""" import os -import gtest_test_utils +from googletest.test import gtest_test_utils # Command to run the googletest-shuffle-test_ program. COMMAND = gtest_test_utils.GetTestExecutablePath('googletest-shuffle-test_') diff --git a/googletest/test/googletest-throw-on-failure-test.py b/googletest/test/googletest-throw-on-failure-test.py index ea627c47..772bbc5f 100755 --- a/googletest/test/googletest-throw-on-failure-test.py +++ b/googletest/test/googletest-throw-on-failure-test.py @@ -36,7 +36,7 @@ Google Test) with different environments and command line flags. """ import os -import gtest_test_utils +from googletest.test import gtest_test_utils # Constants. diff --git a/googletest/test/googletest-uninitialized-test.py b/googletest/test/googletest-uninitialized-test.py index 69595a0d..73c91764 100755 --- a/googletest/test/googletest-uninitialized-test.py +++ b/googletest/test/googletest-uninitialized-test.py @@ -31,7 +31,7 @@ """Verifies that Google Test warns the user when not initialized properly.""" -import gtest_test_utils +from googletest.test import gtest_test_utils COMMAND = gtest_test_utils.GetTestExecutablePath('googletest-uninitialized-test_') diff --git a/googletest/test/gtest_help_test.py b/googletest/test/gtest_help_test.py index 54d45047..3e628ae5 100755 --- a/googletest/test/gtest_help_test.py +++ b/googletest/test/gtest_help_test.py @@ -39,7 +39,7 @@ SYNOPSIS import os import re -import gtest_test_utils +from googletest.test import gtest_test_utils IS_LINUX = os.name == 'posix' and os.uname()[0] == 'Linux' diff --git a/googletest/test/gtest_list_output_unittest.py b/googletest/test/gtest_list_output_unittest.py index a442fc16..faacf103 100644 --- a/googletest/test/gtest_list_output_unittest.py +++ b/googletest/test/gtest_list_output_unittest.py @@ -40,7 +40,7 @@ This script tests such functionality by invoking gtest_list_output_unittest_ import os import re -import gtest_test_utils +from googletest.test import gtest_test_utils GTEST_LIST_TESTS_FLAG = '--gtest_list_tests' GTEST_OUTPUT_FLAG = '--gtest_output' diff --git a/googletest/test/gtest_skip_check_output_test.py b/googletest/test/gtest_skip_check_output_test.py index 14e63ab8..1c87b44f 100755 --- a/googletest/test/gtest_skip_check_output_test.py +++ b/googletest/test/gtest_skip_check_output_test.py @@ -35,7 +35,7 @@ output. import re -import gtest_test_utils +from googletest.test import gtest_test_utils # Path to the gtest_skip_in_environment_setup_test binary EXE_PATH = gtest_test_utils.GetTestExecutablePath('gtest_skip_test') diff --git a/googletest/test/gtest_skip_environment_check_output_test.py b/googletest/test/gtest_skip_environment_check_output_test.py index 6e791556..6960b11a 100755 --- a/googletest/test/gtest_skip_environment_check_output_test.py +++ b/googletest/test/gtest_skip_environment_check_output_test.py @@ -33,7 +33,7 @@ This script invokes gtest_skip_in_environment_setup_test_ and verifies its output. """ -import gtest_test_utils +from googletest.test import gtest_test_utils # Path to the gtest_skip_in_environment_setup_test binary EXE_PATH = gtest_test_utils.GetTestExecutablePath( diff --git a/googletest/test/gtest_testbridge_test.py b/googletest/test/gtest_testbridge_test.py index 87ffad73..1c2a303a 100755 --- a/googletest/test/gtest_testbridge_test.py +++ b/googletest/test/gtest_testbridge_test.py @@ -31,7 +31,7 @@ import os -import gtest_test_utils +from googletest.test import gtest_test_utils binary_name = 'gtest_testbridge_test_' COMMAND = gtest_test_utils.GetTestExecutablePath(binary_name) diff --git a/googletest/test/gtest_xml_outfiles_test.py b/googletest/test/gtest_xml_outfiles_test.py index ac66feb6..916bdf4d 100755 --- a/googletest/test/gtest_xml_outfiles_test.py +++ b/googletest/test/gtest_xml_outfiles_test.py @@ -33,8 +33,8 @@ import os from xml.dom import minidom, Node -import gtest_test_utils -import gtest_xml_test_utils +from googletest.test import gtest_test_utils +from googletest.test import gtest_xml_test_utils GTEST_OUTPUT_SUBDIR = "xml_outfiles" GTEST_OUTPUT_1_TEST = "gtest_xml_outfile1_test_" diff --git a/googletest/test/gtest_xml_output_unittest.py b/googletest/test/gtest_xml_output_unittest.py index eade7aac..f0b0c3b9 100755 --- a/googletest/test/gtest_xml_output_unittest.py +++ b/googletest/test/gtest_xml_output_unittest.py @@ -38,8 +38,8 @@ import re import sys from xml.dom import minidom, Node -import gtest_test_utils -import gtest_xml_test_utils +from googletest.test import gtest_test_utils +from googletest.test import gtest_xml_test_utils GTEST_FILTER_FLAG = '--gtest_filter' GTEST_LIST_TESTS_FLAG = '--gtest_list_tests' diff --git a/googletest/test/gtest_xml_test_utils.py b/googletest/test/gtest_xml_test_utils.py index ec42c62c..50c6e7dc 100755 --- a/googletest/test/gtest_xml_test_utils.py +++ b/googletest/test/gtest_xml_test_utils.py @@ -31,7 +31,7 @@ import re from xml.dom import minidom, Node -import gtest_test_utils +from googletest.test import gtest_test_utils GTEST_DEFAULT_OUTPUT_FILE = 'test_detail.xml' From d81ae2f0bf2bb3fbb23691cae68e75a7563ae19d Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Wed, 22 Dec 2021 22:49:37 -0800 Subject: [PATCH 4/5] Clarify "package" means "Bazel package", and promote `testonly=True` rather than `testing` sub-directory. PiperOrigin-RevId: 417945818 Change-Id: I8686ee0414fb80269528677f291877a231d1c991 --- docs/gmock_for_dummies.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/gmock_for_dummies.md b/docs/gmock_for_dummies.md index 0392b5de..fa1296ee 100644 --- a/docs/gmock_for_dummies.md +++ b/docs/gmock_for_dummies.md @@ -190,12 +190,12 @@ Some people put it in a `_test.cc`. This is fine when the interface being mocked `Foo` changes it, your test could break. (You can't really expect `Foo`'s maintainer to fix every test that uses `Foo`, can you?) -So, the rule of thumb is: if you need to mock `Foo` and it's owned by others, -define the mock class in `Foo`'s package (better, in a `testing` sub-package -such that you can clearly separate production code and testing utilities), put -it in a `.h` and a `cc_library`. Then everyone can reference them from their -tests. If `Foo` ever changes, there is only one copy of `MockFoo` to change, and -only tests that depend on the changed methods need to be fixed. +Generally, you should not define mock classes you don't own. If you must mock +such a class owned by others, define the mock class in `Foo`'s Bazel package +(usually the same directory or a `testing` sub-directory), and put it in a `.h` +and a `cc_library` with `testonly=True`. Then everyone can reference them from +their tests. If `Foo` ever changes, there is only one copy of `MockFoo` to +change, and only tests that depend on the changed methods need to be fixed. Another way to do it: you can introduce a thin layer `FooAdaptor` on top of `Foo` and code to this new interface. Since you own `FooAdaptor`, you can absorb From 6b74da4757a549563d7c37c8fae3e704662a043b Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Mon, 27 Dec 2021 08:04:50 -0800 Subject: [PATCH 5/5] Include the param names in the generated description of the MATCHER_P matchers. PiperOrigin-RevId: 418497526 Change-Id: Ie53c3c0810c10a32cbcb941e3ca1ee8fb1ddd9f9 --- googlemock/include/gmock/gmock-matchers.h | 36 ++++++++++------- .../gmock/internal/gmock-internal-utils.h | 6 ++- googlemock/src/gmock-internal-utils.cc | 30 +++++++------- googlemock/src/gmock-matchers.cc | 12 ++++-- googlemock/test/gmock-internal-utils_test.cc | 23 ++++++----- googlemock/test/gmock-matchers_test.cc | 39 ++++++++++--------- googlemock/test/gmock_output_test_golden.txt | 2 +- 7 files changed, 83 insertions(+), 65 deletions(-) diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index d9523695..2f846ba0 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -3864,9 +3864,9 @@ BoundSecondMatcher MatcherBindSecond( // 'negation' is false; otherwise returns the description of the // negation of the matcher. 'param_values' contains a list of strings // that are the print-out of the matcher's parameters. -GTEST_API_ std::string FormatMatcherDescription(bool negation, - const char* matcher_name, - const Strings& param_values); +GTEST_API_ std::string FormatMatcherDescription( + bool negation, const char* matcher_name, + const std::vector& param_names, const Strings& param_values); // Implements a matcher that checks the value of a optional<> type variable. template @@ -5449,7 +5449,7 @@ PolymorphicMatcher> ThrowsMessage( return gmock_description; \ } \ return ::testing::internal::FormatMatcherDescription(negation, #name, \ - {}); \ + {}, {}); \ } \ }; \ }; \ @@ -5461,33 +5461,41 @@ PolymorphicMatcher> ThrowsMessage( const #define MATCHER_P(name, p0, description) \ - GMOCK_INTERNAL_MATCHER(name, name##MatcherP, description, (p0)) -#define MATCHER_P2(name, p0, p1, description) \ - GMOCK_INTERNAL_MATCHER(name, name##MatcherP2, description, (p0, p1)) -#define MATCHER_P3(name, p0, p1, p2, description) \ - GMOCK_INTERNAL_MATCHER(name, name##MatcherP3, description, (p0, p1, p2)) -#define MATCHER_P4(name, p0, p1, p2, p3, description) \ - GMOCK_INTERNAL_MATCHER(name, name##MatcherP4, description, (p0, p1, p2, p3)) + GMOCK_INTERNAL_MATCHER(name, name##MatcherP, description, (#p0), (p0)) +#define MATCHER_P2(name, p0, p1, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP2, description, (#p0, #p1), \ + (p0, p1)) +#define MATCHER_P3(name, p0, p1, p2, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP3, description, (#p0, #p1, #p2), \ + (p0, p1, p2)) +#define MATCHER_P4(name, p0, p1, p2, p3, description) \ + GMOCK_INTERNAL_MATCHER(name, name##MatcherP4, description, \ + (#p0, #p1, #p2, #p3), (p0, p1, p2, p3)) #define MATCHER_P5(name, p0, p1, p2, p3, p4, description) \ GMOCK_INTERNAL_MATCHER(name, name##MatcherP5, description, \ - (p0, p1, p2, p3, p4)) + (#p0, #p1, #p2, #p3, #p4), (p0, p1, p2, p3, p4)) #define MATCHER_P6(name, p0, p1, p2, p3, p4, p5, description) \ GMOCK_INTERNAL_MATCHER(name, name##MatcherP6, description, \ + (#p0, #p1, #p2, #p3, #p4, #p5), \ (p0, p1, p2, p3, p4, p5)) #define MATCHER_P7(name, p0, p1, p2, p3, p4, p5, p6, description) \ GMOCK_INTERNAL_MATCHER(name, name##MatcherP7, description, \ + (#p0, #p1, #p2, #p3, #p4, #p5, #p6), \ (p0, p1, p2, p3, p4, p5, p6)) #define MATCHER_P8(name, p0, p1, p2, p3, p4, p5, p6, p7, description) \ GMOCK_INTERNAL_MATCHER(name, name##MatcherP8, description, \ + (#p0, #p1, #p2, #p3, #p4, #p5, #p6, #p7), \ (p0, p1, p2, p3, p4, p5, p6, p7)) #define MATCHER_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, description) \ GMOCK_INTERNAL_MATCHER(name, name##MatcherP9, description, \ + (#p0, #p1, #p2, #p3, #p4, #p5, #p6, #p7, #p8), \ (p0, p1, p2, p3, p4, p5, p6, p7, p8)) #define MATCHER_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, description) \ GMOCK_INTERNAL_MATCHER(name, name##MatcherP10, description, \ + (#p0, #p1, #p2, #p3, #p4, #p5, #p6, #p7, #p8, #p9), \ (p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) -#define GMOCK_INTERNAL_MATCHER(name, full_name, description, args) \ +#define GMOCK_INTERNAL_MATCHER(name, full_name, description, arg_names, args) \ template \ class full_name : public ::testing::internal::MatcherBaseImpl< \ full_name> { \ @@ -5516,7 +5524,7 @@ PolymorphicMatcher> ThrowsMessage( return gmock_description; \ } \ return ::testing::internal::FormatMatcherDescription( \ - negation, #name, \ + negation, #name, {GMOCK_PP_REMOVE_PARENS(arg_names)}, \ ::testing::internal::UniversalTersePrintTupleFieldsToStrings( \ ::std::tuple( \ GMOCK_INTERNAL_MATCHER_MEMBERS_USAGE(args)))); \ diff --git a/googlemock/include/gmock/internal/gmock-internal-utils.h b/googlemock/include/gmock/internal/gmock-internal-utils.h index 2975fad9..577f52fd 100644 --- a/googlemock/include/gmock/internal/gmock-internal-utils.h +++ b/googlemock/include/gmock/internal/gmock-internal-utils.h @@ -38,9 +38,12 @@ #define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ #include + #include // NOLINT #include #include +#include + #include "gmock/internal/gmock-port.h" #include "gtest/gtest.h" @@ -61,7 +64,8 @@ namespace internal { // Joins a vector of strings as if they are fields of a tuple; returns // the joined string. -GTEST_API_ std::string JoinAsTuple(const Strings& fields); +GTEST_API_ std::string JoinAsKeyValueTuple( + const std::vector& names, const Strings& values); // Converts an identifier name to a space-separated list of lower-case // words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is diff --git a/googlemock/src/gmock-internal-utils.cc b/googlemock/src/gmock-internal-utils.cc index 7d4ec611..6020736e 100644 --- a/googlemock/src/gmock-internal-utils.cc +++ b/googlemock/src/gmock-internal-utils.cc @@ -44,6 +44,7 @@ #include #include // NOLINT #include +#include #include "gmock/gmock.h" #include "gmock/internal/gmock-port.h" @@ -54,21 +55,22 @@ namespace internal { // Joins a vector of strings as if they are fields of a tuple; returns // the joined string. -GTEST_API_ std::string JoinAsTuple(const Strings& fields) { - switch (fields.size()) { - case 0: - return ""; - case 1: - return fields[0]; - default: - std::string result = "(" + fields[0]; - for (size_t i = 1; i < fields.size(); i++) { - result += ", "; - result += fields[i]; - } - result += ")"; - return result; +GTEST_API_ std::string JoinAsKeyValueTuple( + const std::vector& names, const Strings& values) { + GTEST_CHECK_(names.size() == values.size()); + if (values.empty()) { + return ""; } + const auto build_one = [&](const size_t i) { + return std::string(names[i]) + ": " + values[i]; + }; + std::string result = "(" + build_one(0); + for (size_t i = 1; i < values.size(); i++) { + result += ", "; + result += build_one(i); + } + result += ")"; + return result; } // Converts an identifier name to a space-separated list of lower-case diff --git a/googlemock/src/gmock-matchers.cc b/googlemock/src/gmock-matchers.cc index dded437a..873527b1 100644 --- a/googlemock/src/gmock-matchers.cc +++ b/googlemock/src/gmock-matchers.cc @@ -36,9 +36,11 @@ #include "gmock/gmock-matchers.h" #include + #include #include #include +#include namespace testing { namespace internal { @@ -48,11 +50,13 @@ namespace internal { // 'negation' is false; otherwise returns the description of the // negation of the matcher. 'param_values' contains a list of strings // that are the print-out of the matcher's parameters. -GTEST_API_ std::string FormatMatcherDescription(bool negation, - const char* matcher_name, - const Strings& param_values) { +GTEST_API_ std::string FormatMatcherDescription( + bool negation, const char* matcher_name, + const std::vector& param_names, const Strings& param_values) { std::string result = ConvertIdentifierNameToWords(matcher_name); - if (param_values.size() >= 1) result += " " + JoinAsTuple(param_values); + if (param_values.size() >= 1) { + result += " " + JoinAsKeyValueTuple(param_names, param_values); + } return negation ? "not (" + result + ")" : result; } diff --git a/googlemock/test/gmock-internal-utils_test.cc b/googlemock/test/gmock-internal-utils_test.cc index 494b1fce..800ee8ad 100644 --- a/googlemock/test/gmock-internal-utils_test.cc +++ b/googlemock/test/gmock-internal-utils_test.cc @@ -70,24 +70,23 @@ namespace internal { namespace { -TEST(JoinAsTupleTest, JoinsEmptyTuple) { - EXPECT_EQ("", JoinAsTuple(Strings())); +TEST(JoinAsKeyValueTupleTest, JoinsEmptyTuple) { + EXPECT_EQ("", JoinAsKeyValueTuple({}, Strings())); } -TEST(JoinAsTupleTest, JoinsOneTuple) { - const char* fields[] = {"1"}; - EXPECT_EQ("1", JoinAsTuple(Strings(fields, fields + 1))); +TEST(JoinAsKeyValueTupleTest, JoinsOneTuple) { + EXPECT_EQ("(a: 1)", JoinAsKeyValueTuple({"a"}, {"1"})); } -TEST(JoinAsTupleTest, JoinsTwoTuple) { - const char* fields[] = {"1", "a"}; - EXPECT_EQ("(1, a)", JoinAsTuple(Strings(fields, fields + 2))); +TEST(JoinAsKeyValueTupleTest, JoinsTwoTuple) { + EXPECT_EQ("(a: 1, b: 2)", JoinAsKeyValueTuple({"a", "b"}, {"1", "2"})); } -TEST(JoinAsTupleTest, JoinsTenTuple) { - const char* fields[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}; - EXPECT_EQ("(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)", - JoinAsTuple(Strings(fields, fields + 10))); +TEST(JoinAsKeyValueTupleTest, JoinsTenTuple) { + EXPECT_EQ( + "(a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10)", + JoinAsKeyValueTuple({"a", "b", "c", "d", "e", "f", "g", "h", "i", "j"}, + {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"})); } TEST(ConvertIdentifierNameToWordsTest, WorksWhenNameContainsNoWord) { diff --git a/googlemock/test/gmock-matchers_test.cc b/googlemock/test/gmock-matchers_test.cc index ade2bc94..34282e6f 100644 --- a/googlemock/test/gmock-matchers_test.cc +++ b/googlemock/test/gmock-matchers_test.cc @@ -6439,19 +6439,16 @@ TEST(IsReadableTypeNameTest, ReturnsFalseForLongFunctionTypeNames) { TEST(FormatMatcherDescriptionTest, WorksForEmptyDescription) { EXPECT_EQ("is even", - FormatMatcherDescription(false, "IsEven", Strings())); + FormatMatcherDescription(false, "IsEven", {}, Strings())); EXPECT_EQ("not (is even)", - FormatMatcherDescription(true, "IsEven", Strings())); + FormatMatcherDescription(true, "IsEven", {}, Strings())); - const char* params[] = {"5"}; - EXPECT_EQ("equals 5", - FormatMatcherDescription(false, "Equals", - Strings(params, params + 1))); + EXPECT_EQ("equals (a: 5)", + FormatMatcherDescription(false, "Equals", {"a"}, {"5"})); - const char* params2[] = {"5", "8"}; - EXPECT_EQ("is in range (5, 8)", - FormatMatcherDescription(false, "IsInRange", - Strings(params2, params2 + 2))); + EXPECT_EQ( + "is in range (a: 5, b: 8)", + FormatMatcherDescription(false, "IsInRange", {"a", "b"}, {"5", "8"})); } // Tests PolymorphicMatcher::mutable_impl(). @@ -7810,8 +7807,8 @@ TEST(MatcherPMacroTest, Works) { EXPECT_TRUE(m.Matches(36)); EXPECT_FALSE(m.Matches(5)); - EXPECT_EQ("is greater than 32 and 5", Describe(m)); - EXPECT_EQ("not (is greater than 32 and 5)", DescribeNegation(m)); + EXPECT_EQ("is greater than 32 and (n: 5)", Describe(m)); + EXPECT_EQ("not (is greater than 32 and (n: 5))", DescribeNegation(m)); EXPECT_EQ("", Explain(m, 36)); EXPECT_EQ("", Explain(m, 5)); } @@ -7822,8 +7819,8 @@ MATCHER_P(_is_Greater_Than32and_, n, "") { return arg > 32 && arg > n; } TEST(MatcherPMacroTest, GeneratesCorrectDescription) { const Matcher m = _is_Greater_Than32and_(5); - EXPECT_EQ("is greater than 32 and 5", Describe(m)); - EXPECT_EQ("not (is greater than 32 and 5)", DescribeNegation(m)); + EXPECT_EQ("is greater than 32 and (n: 5)", Describe(m)); + EXPECT_EQ("not (is greater than 32 and (n: 5))", DescribeNegation(m)); EXPECT_EQ("", Explain(m, 36)); EXPECT_EQ("", Explain(m, 5)); } @@ -7856,7 +7853,8 @@ TEST(MatcherPMacroTest, WorksWhenExplicitlyInstantiatedWithReference) { // likely it will just annoy the user. If the address is // interesting, the user should consider passing the parameter by // pointer instead. - EXPECT_EQ("references uncopyable 1-byte object <31>", Describe(m)); + EXPECT_EQ("references uncopyable (variable: 1-byte object <31>)", + Describe(m)); } // Tests that the body of MATCHER_Pn() can reference the parameter @@ -7907,8 +7905,10 @@ TEST(MatcherPnMacroTest, // likely they will just annoy the user. If the addresses are // interesting, the user should consider passing the parameters by // pointers instead. - EXPECT_EQ("references any of (1-byte object <31>, 1-byte object <32>)", - Describe(m)); + EXPECT_EQ( + "references any of (variable1: 1-byte object <31>, variable2: 1-byte " + "object <32>)", + Describe(m)); } // Tests that a simple MATCHER_P2() definition works. @@ -7920,8 +7920,9 @@ TEST(MatcherPnMacroTest, Works) { EXPECT_TRUE(m.Matches(36L)); EXPECT_FALSE(m.Matches(15L)); - EXPECT_EQ("is not in closed range (10, 20)", Describe(m)); - EXPECT_EQ("not (is not in closed range (10, 20))", DescribeNegation(m)); + EXPECT_EQ("is not in closed range (low: 10, hi: 20)", Describe(m)); + EXPECT_EQ("not (is not in closed range (low: 10, hi: 20))", + DescribeNegation(m)); EXPECT_EQ("", Explain(m, 36L)); EXPECT_EQ("", Explain(m, 15L)); } diff --git a/googlemock/test/gmock_output_test_golden.txt b/googlemock/test/gmock_output_test_golden.txt index 4846c124..fdf224fd 100644 --- a/googlemock/test/gmock_output_test_golden.txt +++ b/googlemock/test/gmock_output_test_golden.txt @@ -291,7 +291,7 @@ Stack trace: [ RUN ] GMockOutputTest.PrintsMatcher FILE:#: Failure Value of: (std::pair(42, true)) -Expected: is pair (is >= 48, true) +Expected: is pair (first: is >= 48, second: true) Actual: (42, true) (of type std::pair) [ FAILED ] GMockOutputTest.PrintsMatcher [ FAILED ] GMockOutputTest.UnexpectedCall