diff options
54 files changed, 1147 insertions, 569 deletions
diff --git a/.github/ISSUE_TEMPLATE/90-question.md b/.github/ISSUE_TEMPLATE/90-question.md deleted file mode 100644 index 46ec8b0a..00000000 --- a/.github/ISSUE_TEMPLATE/90-question.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: Question -about: Can't find an answer to your question? Ask us! -title: '' -labels: 'question' -assignees: '' ---- diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 0086358d..3ba13e0c 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1 +1 @@ -blank_issues_enabled: true +blank_issues_enabled: false diff --git a/BUILD.bazel b/BUILD.bazel index 8099642a..965c518d 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -40,7 +40,15 @@ exports_files(["LICENSE"]) config_setting( name = "windows", - constraint_values = ["@bazel_tools//platforms:windows"], + constraint_values = ["@platforms//os:windows"], +) + +config_setting( + name = "msvc_compiler", + flag_values = { + "@bazel_tools//tools/cpp:compiler": "msvc-cl", + }, + visibility = [":__subpackages__"], ) config_setting( @@ -1,9 +1,5 @@ # GoogleTest -#### OSS Builds Status - -[](https://ci.appveyor.com/project/GoogleTestAppVeyor/googletest/branch/master) - ### Announcements #### Live at Head @@ -137,7 +133,8 @@ that generates stub code for GoogleTest. ## Contributing Changes -Please read [`CONTRIBUTING.md`](CONTRIBUTING.md) for details on how to -contribute to this project. +Please read +[`CONTRIBUTING.md`](https://github.com/google/googletest/blob/master/CONTRIBUTING.md) +for details on how to contribute to this project. Happy testing! diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 5c419c32..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,156 +0,0 @@ -version: '{build}' - -os: Visual Studio 2015 - -environment: - matrix: - - compiler: msvc-15-seh - generator: "Visual Studio 15 2017" - build_system: cmake - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - enabled_on_pr: yes - - - compiler: msvc-15-seh - generator: "Visual Studio 15 2017 Win64" - build_system: cmake - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - enabled_on_pr: yes - - - compiler: msvc-15-seh - build_system: bazel - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 - enabled_on_pr: yes - - - compiler: msvc-14-seh - build_system: cmake - generator: "Visual Studio 14 2015" - enabled_on_pr: yes - - - compiler: msvc-14-seh - build_system: cmake - generator: "Visual Studio 14 2015 Win64" - enabled_on_pr: yes - - - compiler: gcc-6.3.0-posix - build_system: cmake - generator: "MinGW Makefiles" - cxx_path: 'C:\mingw-w64\i686-6.3.0-posix-dwarf-rt_v5-rev1\mingw32\bin' - enabled_on_pr: yes - -configuration: - - Debug - -build: - verbosity: minimal - -install: -- ps: | - Write-Output "Compiler: $env:compiler" - Write-Output "Generator: $env:generator" - Write-Output "Env:Configuation: $env:configuration" - Write-Output "Env: $env" - if (-not (Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER)) { - Write-Output "This is *NOT* a pull request build" - } else { - Write-Output "This is a pull request build" - if (-not (Test-Path env:enabled_on_pr) -or $env:enabled_on_pr -ne "yes") { - Write-Output "PR builds are *NOT* explicitly enabled" - } - } - - # install Bazel - if ($env:build_system -eq "bazel") { - appveyor DownloadFile https://github.com/bazelbuild/bazel/releases/download/3.6.0/bazel-3.6.0-windows-x86_64.exe -FileName bazel.exe - } - - if ($env:build_system -eq "cmake") { - # git bash conflicts with MinGW makefiles - if ($env:generator -eq "MinGW Makefiles") { - $env:path = $env:path.replace("C:\Program Files\Git\usr\bin;", "") - if ($env:cxx_path -ne "") { - $env:path += ";$env:cxx_path" - } - } - } - -before_build: -- ps: | - $env:root=$env:APPVEYOR_BUILD_FOLDER - Write-Output "env:root: $env:root" - -build_script: -- ps: | - # Only enable some builds for pull requests, the AppVeyor queue is too long. - if ((Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER) -And (-not (Test-Path env:enabled_on_pr) -or $env:enabled_on_pr -ne "yes")) { - return - } else { - # special case - build with Bazel - if ($env:build_system -eq "bazel") { - & $env:root\bazel.exe build -c opt //:gtest_samples - if ($LastExitCode -eq 0) { # bazel writes to StdErr and PowerShell interprets it as an error - $host.SetShouldExit(0) - } else { # a real error - throw "Exec: $ErrorMessage" - } - return - } - } - # by default build with CMake - md _build -Force | Out-Null - cd _build - - $conf = if ($env:generator -eq "MinGW Makefiles") {"-DCMAKE_BUILD_TYPE=$env:configuration"} else {"-DCMAKE_CONFIGURATION_TYPES=Debug;Release"} - # Disable test for MinGW (gtest tests fail, gmock tests can not build) - $gtest_build_tests = if ($env:generator -eq "MinGW Makefiles") {"-Dgtest_build_tests=OFF"} else {"-Dgtest_build_tests=ON"} - $gmock_build_tests = if ($env:generator -eq "MinGW Makefiles") {"-Dgmock_build_tests=OFF"} else {"-Dgmock_build_tests=ON"} - & cmake -G "$env:generator" $conf -Dgtest_build_samples=ON $gtest_build_tests $gmock_build_tests .. - if ($LastExitCode -ne 0) { - throw "Exec: $ErrorMessage" - } - $cmake_parallel = if ($env:generator -eq "MinGW Makefiles") {"-j2"} else {"/m"} - & cmake --build . --config $env:configuration -- $cmake_parallel - if ($LastExitCode -ne 0) { - throw "Exec: $ErrorMessage" - } - - -skip_commits: - files: - - '**/*.md' - -test_script: -- ps: | - # Only enable some builds for pull requests, the AppVeyor queue is too long. - if ((Test-Path env:APPVEYOR_PULL_REQUEST_NUMBER) -And (-not (Test-Path env:enabled_on_pr) -or $env:enabled_on_pr -ne "yes")) { - return - } - if ($env:build_system -eq "bazel") { - # special case - testing with Bazel - & $env:root\bazel.exe test //:gtest_samples - if ($LastExitCode -eq 0) { # bazel writes to StdErr and PowerShell interprets it as an error - $host.SetShouldExit(0) - } else { # a real error - throw "Exec: $ErrorMessage" - } - } - if ($env:build_system -eq "cmake") { - # built with CMake - test with CTest - if ($env:generator -eq "MinGW Makefiles") { - return # No test available for MinGW - } - - & ctest -C $env:configuration --timeout 600 --output-on-failure - if ($LastExitCode -ne 0) { - throw "Exec: $ErrorMessage" - } - } - -artifacts: - - path: '_build/CMakeFiles/*.log' - name: logs - - path: '_build/Testing/**/*.xml' - name: test_results - - path: 'bazel-testlogs/**/test.log' - name: test_logs - - path: 'bazel-testlogs/**/test.xml' - name: test_results diff --git a/ci/linux-presubmit.sh b/ci/linux-presubmit.sh index 5cbd7c41..d02130c3 100644 --- a/ci/linux-presubmit.sh +++ b/ci/linux-presubmit.sh @@ -34,7 +34,9 @@ set -euox pipefail readonly LINUX_LATEST_CONTAINER="gcr.io/google.com/absl-177019/linux_hybrid-latest:20201008" readonly LINUX_GCC_FLOOR_CONTAINER="gcr.io/google.com/absl-177019/linux_gcc-floor:20201015" -SRC=$(realpath git/googletest) +if [[ -z ${GTEST_ROOT:-} ]]; then + GTEST_ROOT="$(realpath $(dirname ${0})/..)" +fi if [[ -z ${STD:-} ]]; then STD="c++11 c++14 c++17 c++20" @@ -44,7 +46,7 @@ fi for cc in /usr/local/bin/gcc /opt/llvm/clang/bin/clang; do for cmake_off_on in OFF ON; do time docker run \ - --volume="${SRC}:/src:ro" \ + --volume="${GTEST_ROOT}:/src:ro" \ --tmpfs="/build:exec" \ --workdir="/build" \ --rm \ @@ -66,7 +68,7 @@ done # Do one test with an older version of GCC time docker run \ - --volume="${SRC}:/src:ro" \ + --volume="${GTEST_ROOT}:/src:ro" \ --workdir="/src" \ --rm \ --env="CC=/usr/local/bin/gcc" \ @@ -83,7 +85,7 @@ time docker run \ for std in ${STD}; do for absl in 0 1; do time docker run \ - --volume="${SRC}:/src:ro" \ + --volume="${GTEST_ROOT}:/src:ro" \ --workdir="/src" \ --rm \ --env="CC=/usr/local/bin/gcc" \ @@ -103,7 +105,7 @@ done for std in ${STD}; do for absl in 0 1; do time docker run \ - --volume="${SRC}:/src:ro" \ + --volume="${GTEST_ROOT}:/src:ro" \ --workdir="/src" \ --rm \ --env="CC=/opt/llvm/clang/bin/clang" \ diff --git a/ci/macos-presubmit.sh b/ci/macos-presubmit.sh index 4a5dc3e9..d6423faa 100644 --- a/ci/macos-presubmit.sh +++ b/ci/macos-presubmit.sh @@ -31,13 +31,15 @@ set -euox pipefail -SRC=$(realpath git/googletest) +if [[ -z ${GTEST_ROOT:-} ]]; then + GTEST_ROOT="$(realpath $(dirname ${0})/..)" +fi # Test the CMake build for cmake_off_on in OFF ON; do BUILD_DIR=$(mktemp -d build_dir.XXXXXXXX) cd ${BUILD_DIR} - time cmake ${SRC} \ + time cmake ${GTEST_ROOT} \ -DCMAKE_CXX_STANDARD=11 \ -Dgtest_build_samples=ON \ -Dgtest_build_tests=ON \ @@ -59,7 +61,7 @@ else BAZEL_BIN="bazel" fi -cd ${SRC} +cd ${GTEST_ROOT} for absl in 0 1; do ${BAZEL_BIN} test ... \ --copt="-Wall" \ diff --git a/docs/_data/navigation.yml b/docs/_data/navigation.yml index b79f2505..355ebc8e 100644 --- a/docs/_data/navigation.yml +++ b/docs/_data/navigation.yml @@ -3,6 +3,10 @@ nav: items: - title: "Supported Platforms" url: "/platforms.html" + - title: "Quickstart: Bazel" + url: "/quickstart-bazel.html" + - title: "Quickstart: CMake" + url: "/quickstart-cmake.html" - section: "Guides" items: - title: "GoogleTest Primer" diff --git a/docs/advanced.md b/docs/advanced.md index 4103507b..ae4d7ee8 100644 --- a/docs/advanced.md +++ b/docs/advanced.md @@ -813,7 +813,8 @@ initialized from the command-line flag `--gtest_death_test_style`). consideration to be run - much like the `threadsafe` mode on POSIX. Other values for the variable are illegal and will cause the death test to fail. -Currently, the flag's default value is **"fast"** +Currently, the flag's default value is +**`"fast"`**. 1. the child's exit status satisfies the predicate, and 2. the child's stderr matches the regular expression. @@ -1204,10 +1205,10 @@ class FooTest : public testing::Test { } // You can define per-test set-up logic as usual. - virtual void SetUp() { ... } + void SetUp() override { ... } // You can define per-test tear-down logic as usual. - virtual void TearDown() { ... } + void TearDown() override { ... } // Some expensive resource shared by all tests. static T* shared_resource_; @@ -1238,7 +1239,7 @@ First, you subclass the `::testing::Environment` class to define a test environment, which knows how to set-up and tear-down: ```c++ -class Environment : public testing::Environment { +class Environment : public ::testing::Environment { public: ~Environment() override {} @@ -1374,7 +1375,7 @@ The following statement will instantiate tests from the `FooTest` test suite each with parameter values `"meeny"`, `"miny"`, and `"moe"`. ```c++ -INSTANTIATE_TEST_SUITE_P(InstantiationName, +INSTANTIATE_TEST_SUITE_P(MeenyMinyMoe, FooTest, testing::Values("meeny", "miny", "moe")); ``` @@ -1383,51 +1384,54 @@ INSTANTIATE_TEST_SUITE_P(InstantiationName, NOTE: The code above must be placed at global or namespace scope, not at function scope. -Per default, every `TEST_P` without a corresponding `INSTANTIATE_TEST_SUITE_P` -causes a failing test in test suite `GoogleTestVerification`. If you have a test -suite where that omission is not an error, for example it is in a library that -may be linked in for other reason or where the list of test cases is dynamic and -may be empty, then this check can be suppressed by tagging the test suite: +The first argument to `INSTANTIATE_TEST_SUITE_P` is a unique name for the +instantiation of the test suite. The next argument is the name of the test +pattern, and the last is the parameter generator. -```c++ -GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FooTest); -``` - -To distinguish different instances of the pattern (yes, you can instantiate it -more than once), the first argument to `INSTANTIATE_TEST_SUITE_P` is a prefix -that will be added to the actual test suite name. Remember to pick unique -prefixes for different instantiations. The tests from the instantiation above -will have these names: +You can instantiate a test pattern more than once, so to distinguish different +instances of the pattern, the instantiation name is added as a prefix to the +actual test suite name. Remember to pick unique prefixes for different +instantiations. The tests from the instantiation above will have these names: -* `InstantiationName/FooTest.DoesBlah/0` for `"meeny"` -* `InstantiationName/FooTest.DoesBlah/1` for `"miny"` -* `InstantiationName/FooTest.DoesBlah/2` for `"moe"` -* `InstantiationName/FooTest.HasBlahBlah/0` for `"meeny"` -* `InstantiationName/FooTest.HasBlahBlah/1` for `"miny"` -* `InstantiationName/FooTest.HasBlahBlah/2` for `"moe"` +* `MeenyMinyMoe/FooTest.DoesBlah/0` for `"meeny"` +* `MeenyMinyMoe/FooTest.DoesBlah/1` for `"miny"` +* `MeenyMinyMoe/FooTest.DoesBlah/2` for `"moe"` +* `MeenyMinyMoe/FooTest.HasBlahBlah/0` for `"meeny"` +* `MeenyMinyMoe/FooTest.HasBlahBlah/1` for `"miny"` +* `MeenyMinyMoe/FooTest.HasBlahBlah/2` for `"moe"` You can use these names in [`--gtest_filter`](#running-a-subset-of-the-tests). -This statement will instantiate all tests from `FooTest` again, each with -parameter values `"cat"` and `"dog"`: +The following statement will instantiate all tests from `FooTest` again, each +with parameter values `"cat"` and `"dog"`: ```c++ const char* pets[] = {"cat", "dog"}; -INSTANTIATE_TEST_SUITE_P(AnotherInstantiationName, FooTest, - testing::ValuesIn(pets)); +INSTANTIATE_TEST_SUITE_P(Pets, FooTest, testing::ValuesIn(pets)); ``` The tests from the instantiation above will have these names: -* `AnotherInstantiationName/FooTest.DoesBlah/0` for `"cat"` -* `AnotherInstantiationName/FooTest.DoesBlah/1` for `"dog"` -* `AnotherInstantiationName/FooTest.HasBlahBlah/0` for `"cat"` -* `AnotherInstantiationName/FooTest.HasBlahBlah/1` for `"dog"` +* `Pets/FooTest.DoesBlah/0` for `"cat"` +* `Pets/FooTest.DoesBlah/1` for `"dog"` +* `Pets/FooTest.HasBlahBlah/0` for `"cat"` +* `Pets/FooTest.HasBlahBlah/1` for `"dog"` Please note that `INSTANTIATE_TEST_SUITE_P` will instantiate *all* tests in the given test suite, whether their definitions come before or *after* the `INSTANTIATE_TEST_SUITE_P` statement. +Additionally, by default, every `TEST_P` without a corresponding +`INSTANTIATE_TEST_SUITE_P` causes a failing test in test suite +`GoogleTestVerification`. If you have a test suite where that omission is not an +error, for example it is in a library that may be linked in for other reasons or +where the list of test cases is dynamic and may be empty, then this check can be +suppressed by tagging the test suite: + +```c++ +GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FooTest); +``` + You can see [sample7_unittest.cc] and [sample8_unittest.cc] for more examples. [sample7_unittest.cc]: https://github.com/google/googletest/blob/master/googletest/samples/sample7_unittest.cc "Parameterized Test example" @@ -1737,10 +1741,11 @@ To test them, we use the following special techniques: } ``` - Pay special attention when your class is defined in a namespace, as you - should define your test fixtures and tests in the same namespace if you want - them to be friends of your class. For example, if the code to be tested - looks like: + Pay special attention when your class is defined in a namespace. If you want + your test fixtures and tests to be friends of your class, then they must be + defined in the exact same namespace (no anonymous or inline namespaces). + + For example, if the code to be tested looks like: ```c++ namespace my_namespace { @@ -1970,13 +1975,13 @@ Here's an example: ```c++ class MinimalistPrinter : public testing::EmptyTestEventListener { // Called before a test starts. - virtual void OnTestStart(const testing::TestInfo& test_info) { + void OnTestStart(const testing::TestInfo& test_info) override { printf("*** Test %s.%s starting.\n", test_info.test_suite_name(), test_info.name()); } // Called after a failed assertion or a SUCCESS(). - virtual void OnTestPartResult(const testing::TestPartResult& test_part_result) { + void OnTestPartResult(const testing::TestPartResult& test_part_result) override { printf("%s in %s:%d\n%s\n", test_part_result.failed() ? "*** Failure" : "Success", test_part_result.file_name(), @@ -1985,7 +1990,7 @@ Here's an example: } // Called after a test ends. - virtual void OnTestEnd(const testing::TestInfo& test_info) { + void OnTestEnd(const testing::TestInfo& test_info) override { printf("*** Test %s.%s ending.\n", test_info.test_suite_name(), test_info.name()); } diff --git a/docs/faq.md b/docs/faq.md index da443e33..40712321 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -60,9 +60,10 @@ the rule. ## Why does googletest support `EXPECT_EQ(NULL, ptr)` and `ASSERT_EQ(NULL, ptr)` but not `EXPECT_NE(NULL, ptr)` and `ASSERT_NE(NULL, ptr)`? -First of all you can use `EXPECT_NE(nullptr, ptr)` and `ASSERT_NE(nullptr, -ptr)`. This is the preferred syntax in the style guide because nullptr does not -have the type problems that NULL does. Which is why NULL does not work. +First of all, you can use `nullptr` with each of these macros, e.g. +`EXPECT_EQ(ptr, nullptr)`, `EXPECT_NE(ptr, nullptr)`, `ASSERT_EQ(ptr, nullptr)`, +`ASSERT_NE(ptr, nullptr)`. This is the preferred syntax in the style guide +because `nullptr` does not have the type problems that `NULL` does. Due to some peculiarity of C++, it requires some non-trivial template meta programming tricks to support using `NULL` as an argument of the `EXPECT_XX()` @@ -70,22 +71,21 @@ and `ASSERT_XX()` macros. Therefore we only do it where it's most needed (otherwise we make the implementation of googletest harder to maintain and more error-prone than necessary). -The `EXPECT_EQ()` macro takes the *expected* value as its first argument and the -*actual* value as the second. It's reasonable that someone wants to write -`EXPECT_EQ(NULL, some_expression)`, and this indeed was requested several times. -Therefore we implemented it. +Historically, the `EXPECT_EQ()` macro took the *expected* value as its first +argument and the *actual* value as the second, though this argument order is now +discouraged. It was reasonable that someone wanted +to write `EXPECT_EQ(NULL, some_expression)`, and this indeed was requested +several times. Therefore we implemented it. -The need for `EXPECT_NE(NULL, ptr)` isn't nearly as strong. When the assertion +The need for `EXPECT_NE(NULL, ptr)` wasn't nearly as strong. When the assertion fails, you already know that `ptr` must be `NULL`, so it doesn't add any information to print `ptr` in this case. That means `EXPECT_TRUE(ptr != NULL)` works just as well. -If we were to support `EXPECT_NE(NULL, ptr)`, for consistency we'll have to -support `EXPECT_NE(ptr, NULL)` as well, as unlike `EXPECT_EQ`, we don't have a -convention on the order of the two arguments for `EXPECT_NE`. This means using -the template meta programming tricks twice in the implementation, making it even -harder to understand and maintain. We believe the benefit doesn't justify the -cost. +If we were to support `EXPECT_NE(NULL, ptr)`, for consistency we'd have to +support `EXPECT_NE(ptr, NULL)` as well. This means using the template meta +programming tricks twice in the implementation, making it even harder to +understand and maintain. We believe the benefit doesn't justify the cost. Finally, with the growth of the gMock matcher library, we are encouraging people to use the unified `EXPECT_THAT(value, matcher)` syntax more often in tests. One @@ -706,12 +706,12 @@ whether the code is under test. ## How do I temporarily disable a test? If you have a broken test that you cannot fix right away, you can add the -DISABLED_ prefix to its name. This will exclude it from execution. This is -better than commenting out the code or using #if 0, as disabled tests are still -compiled (and thus won't rot). +`DISABLED_` prefix to its name. This will exclude it from execution. This is +better than commenting out the code or using `#if 0`, as disabled tests are +still compiled (and thus won't rot). To include disabled tests in test execution, just invoke the test program with -the --gtest_also_run_disabled_tests flag. +the `--gtest_also_run_disabled_tests` flag. ## Is it OK if I have two separate `TEST(Foo, Bar)` test methods defined in different namespaces? diff --git a/docs/gmock_cheat_sheet.md b/docs/gmock_cheat_sheet.md index 723cb7e1..90be4a3e 100644 --- a/docs/gmock_cheat_sheet.md +++ b/docs/gmock_cheat_sheet.md @@ -123,7 +123,7 @@ TEST(BarTest, DoesThis) { .WillRepeatedly(Return("Category 5")); // ... other expectations ... - EXPECT_EQ("good", MyProductionFunction(&foo)); // #5 + EXPECT_EQ(MyProductionFunction(&foo), "good"); // #5 } // #6 ``` @@ -162,8 +162,8 @@ Example usage: auto buzz1 = mock_buzzer_.MakeBuzz("hello"); auto buzz2 = mock_buzzer_.MakeBuzz("hello"); - EXPECT_NE(nullptr, buzz1); - EXPECT_NE(nullptr, buzz2); + EXPECT_NE(buzz1, nullptr); + EXPECT_NE(buzz2, nullptr); EXPECT_NE(buzz1, buzz2); // Resets the default action for return type std::unique_ptr<Buzz>, @@ -362,10 +362,11 @@ messages, you can use: int len)` -- see [Multi-argument Matchers](#MultiArgMatchers)). * The array being matched may be multi-dimensional (i.e. its elements can be arrays). -* `m` in `Pointwise(m, ...)` should be a matcher for `::std::tuple<T, U>` - where `T` and `U` are the element type of the actual container and the - expected container, respectively. For example, to compare two `Foo` - containers where `Foo` doesn't support `operator==`, one might write: +* `m` in `Pointwise(m, ...)` and `UnorderedPointwise(m, ...)` should be a + matcher for `::std::tuple<T, U>` where `T` and `U` are the element type of + the actual container and the expected container, respectively. For example, + to compare two `Foo` containers where `Foo` doesn't support `operator==`, + one might write: ```cpp using ::std::get; @@ -384,12 +385,28 @@ messages, you can use: | `Field(field_name, &class::field, m)` | The same as the two-parameter version, but provides a better error message. | | `Key(e)` | `argument.first` matches `e`, which can be either a value or a matcher. E.g. `Contains(Key(Le(5)))` can verify that a `map` contains a key `<= 5`. | | `Pair(m1, m2)` | `argument` is an `std::pair` whose `first` field matches `m1` and `second` field matches `m2`. | -| `FieldsAre(m...)` | `argument` is a compatible object where each field matches piecewise with `m...`. A compatible object is any that supports the `std::tuple_size<Obj>`+`get<I>(obj)` protocol. In C++17 and up this also supports types compatible with structured bindings, like aggregates. | +| `FieldsAre(m...)` | `argument` is a compatible object where each field matches piecewise with the matchers `m...`. A compatible object is any that supports the `std::tuple_size<Obj>`+`get<I>(obj)` protocol. In C++17 and up this also supports types compatible with structured bindings, like aggregates. | | `Property(&class::property, m)` | `argument.property()` (or `argument->property()` when `argument` is a plain pointer) matches matcher `m`, where `argument` is an object of type _class_. The method `property()` must take no argument and be declared as `const`. | | `Property(property_name, &class::property, m)` | The same as the two-parameter version, but provides a better error message. **Notes:** +* You can use `FieldsAre()` to match any type that supports structured + bindings, such as `std::tuple`, `std::pair`, `std::array`, and aggregate + types. For example: + + ```cpp + std::tuple<int, std::string> my_tuple{7, "hello world"}; + EXPECT_THAT(my_tuple, FieldsAre(Ge(0), HasSubstr("hello"))); + + struct MyStruct { + int value = 42; + std::string greeting = "aloha"; + }; + MyStruct s; + EXPECT_THAT(s, FieldsAre(42, "aloha")); + ``` + * Don't use `Property()` against member functions that you do not own, because taking addresses of functions is fragile and generally not part of the contract of the function. diff --git a/docs/gmock_cook_book.md b/docs/gmock_cook_book.md index 8ba5c989..c6a99912 100644 --- a/docs/gmock_cook_book.md +++ b/docs/gmock_cook_book.md @@ -251,9 +251,9 @@ tests. ### Mocking Free Functions -It's possible to use gMock to mock a free function (i.e. a C-style function or a -static method). You just need to rewrite your code to use an interface (abstract -class). +It is not possible to directly mock a free function (i.e. a C-style function or +a static method). If you need to, you can rewrite your code to use an interface +(abstract class). Instead of calling a free function (say, `OpenFile`) directly, introduce an interface for it and have a concrete subclass that calls the free function: @@ -268,7 +268,7 @@ class FileInterface { class File : public FileInterface { public: ... - virtual bool Open(const char* path, const char* mode) { + bool Open(const char* path, const char* mode) override { return OpenFile(path, mode); } }; @@ -512,9 +512,9 @@ The trick is to redispatch the method in the mock class: class ScopedMockLog : public LogSink { public: ... - virtual void send(LogSeverity severity, const char* full_filename, + void send(LogSeverity severity, const char* full_filename, const char* base_filename, int line, const tm* tm_time, - const char* message, size_t message_len) { + const char* message, size_t message_len) override { // We are only interested in the log severity, full file name, and // log message. Log(severity, full_filename, std::string(message, message_len)); @@ -2705,18 +2705,10 @@ behavior nondeterministic. A better way is to use gMock actions and `Notification` objects to force your asynchronous test to behave synchronously. ```cpp -using ::testing::DoAll; -using ::testing::InvokeWithoutArgs; -using ::testing::Return; - class MockEventDispatcher : public EventDispatcher { MOCK_METHOD(bool, DispatchEvent, (int32), (override)); }; -ACTION_P(Notify, notification) { - notification->Notify(); -} - TEST(EventQueueTest, EnqueueEventTest) { MockEventDispatcher mock_event_dispatcher; EventQueue event_queue(&mock_event_dispatcher); @@ -2724,7 +2716,7 @@ TEST(EventQueueTest, EnqueueEventTest) { const int32 kEventId = 321; absl::Notification done; EXPECT_CALL(mock_event_dispatcher, DispatchEvent(kEventId)) - .WillOnce(Notify(&done)); + .WillOnce([&done] { done.Notify(); }); event_queue.EnqueueEvent(kEventId); done.WaitForNotification(); diff --git a/docs/quickstart-bazel.md b/docs/quickstart-bazel.md new file mode 100644 index 00000000..362ee6d0 --- /dev/null +++ b/docs/quickstart-bazel.md @@ -0,0 +1,161 @@ +# Quickstart: Building with Bazel + +This tutorial aims to get you up and running with GoogleTest using the Bazel +build system. If you're using GoogleTest for the first time or need a refresher, +we recommend this tutorial as a starting point. + +## Prerequisites + +To complete this tutorial, you'll need: + +* A compatible operating system (e.g. Linux, macOS, Windows). +* A compatible C++ compiler that supports at least C++11. +* [Bazel](https://bazel.build/), the preferred build system used by the + GoogleTest team. + +See [Supported Platforms](platforms.md) for more information about platforms +compatible with GoogleTest. + +If you don't already have Bazel installed, see the +[Bazel installation guide](https://docs.bazel.build/versions/master/install.html). + +{: .callout .note} +Note: The terminal commands in this tutorial show a Unix shell prompt, but the +commands work on the Windows command line as well. + +## Set up a Bazel workspace + +A +[Bazel workspace](https://docs.bazel.build/versions/master/build-ref.html#workspace) +is a directory on your filesystem that you use to manage source files for the +software you want to build. Each workspace directory has a text file named +`WORKSPACE` which may be empty, or may contain references to external +dependencies required to build the outputs. + +First, create a directory for your workspace: + +``` +$ mkdir my_workspace && cd my_workspace +``` + +Next, you’ll create the `WORKSPACE` file to specify dependencies. A common and +recommended way to depend on GoogleTest is to use a +[Bazel external dependency](https://docs.bazel.build/versions/master/external.html) +via the +[`http_archive` rule](https://docs.bazel.build/versions/master/repo/http.html#http_archive). +To do this, in the root directory of your workspace (`my_workspace/`), create a +file named `WORKSPACE` with the following contents: + +``` +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +http_archive( + name = "com_google_googletest", + urls = ["https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip"], + strip_prefix = "googletest-609281088cfefc76f9d0ce82e1ff6c30cc3591e5", +) +``` + +The above configuration declares a dependency on GoogleTest which is downloaded +as a ZIP archive from GitHub. In the above example, +`609281088cfefc76f9d0ce82e1ff6c30cc3591e5` is the Git commit hash of the +GoogleTest version to use; we recommend updating the hash often to point to the +latest version. + +Bazel also needs a dependency on the +[`rules_cc` repository](https://github.com/bazelbuild/rules_cc) to build C++ +code, so add the following to the `WORKSPACE` file: + +``` +http_archive( + name = "rules_cc", + urls = ["https://github.com/bazelbuild/rules_cc/archive/40548a2974f1aea06215272d9c2b47a14a24e556.zip"], + strip_prefix = "rules_cc-40548a2974f1aea06215272d9c2b47a14a24e556", +) +``` + +Now you're ready to build C++ code that uses GoogleTest. + +## Create and run a binary + +With your Bazel workspace set up, you can now use GoogleTest code within your +own project. + +As an example, create a file named `hello_test.cc` in your `my_workspace` +directory with the following contents: + +```cpp +#include <gtest/gtest.h> + +// Demonstrate some basic assertions. +TEST(HelloTest, BasicAssertions) { + // Expect two strings not to be equal. + EXPECT_STRNE("hello", "world"); + // Expect equality. + EXPECT_EQ(7 * 6, 42); +} +``` + +GoogleTest provides [assertions](primer.md#assertions) that you use to test the +behavior of your code. The above sample includes the main GoogleTest header file +and demonstrates some basic assertions. + +To build the code, create a file named `BUILD` in the same directory with the +following contents: + +``` +load("@rules_cc//cc:defs.bzl", "cc_test") + +cc_test( + name = "hello_test", + size = "small", + srcs = ["hello_test.cc"], + deps = ["@com_google_googletest//:gtest_main"], +) +``` + +This `cc_test` rule declares the C++ test binary you want to build, and links to +GoogleTest (`//:gtest_main`) using the prefix you specified in the `WORKSPACE` +file (`@com_google_googletest`). For more information about Bazel `BUILD` files, +see the +[Bazel C++ Tutorial](https://docs.bazel.build/versions/master/tutorial/cpp.html). + +Now you can build and run your test: + +<pre> +<strong>my_workspace$ bazel test --test_output=all //:hello_test</strong> +INFO: Analyzed target //:hello_test (26 packages loaded, 362 targets configured). +INFO: Found 1 test target... +INFO: From Testing //:hello_test: +==================== Test output for //:hello_test: +Running main() from gmock_main.cc +[==========] Running 1 test from 1 test suite. +[----------] Global test environment set-up. +[----------] 1 test from HelloTest +[ RUN ] HelloTest.BasicAssertions +[ OK ] HelloTest.BasicAssertions (0 ms) +[----------] 1 test from HelloTest (0 ms total) + +[----------] Global test environment tear-down +[==========] 1 test from 1 test suite ran. (0 ms total) +[ PASSED ] 1 test. +================================================================================ +Target //:hello_test up-to-date: + bazel-bin/hello_test +INFO: Elapsed time: 4.190s, Critical Path: 3.05s +INFO: 27 processes: 8 internal, 19 linux-sandbox. +INFO: Build completed successfully, 27 total actions +//:hello_test PASSED in 0.1s + +INFO: Build completed successfully, 27 total actions +</pre> + +Congratulations! You've successfully built and run a test binary using +GoogleTest. + +## Next steps + +* [Check out the Primer](primer.md) to start learning how to write simple + tests. +* [See the code samples](samples.md) for more examples showing how to use a + variety of GoogleTest features. diff --git a/docs/quickstart-cmake.md b/docs/quickstart-cmake.md new file mode 100644 index 00000000..420f1d3a --- /dev/null +++ b/docs/quickstart-cmake.md @@ -0,0 +1,156 @@ +# Quickstart: Building with CMake + +This tutorial aims to get you up and running with GoogleTest using CMake. If +you're using GoogleTest for the first time or need a refresher, we recommend +this tutorial as a starting point. If your project uses Bazel, see the +[Quickstart for Bazel](quickstart-bazel.md) instead. + +## Prerequisites + +To complete this tutorial, you'll need: + +* A compatible operating system (e.g. Linux, macOS, Windows). +* A compatible C++ compiler that supports at least C++11. +* [CMake](https://cmake.org/) and a compatible build tool for building the + project. + * Compatible build tools include + [Make](https://www.gnu.org/software/make/), + [Ninja](https://ninja-build.org/), and others - see + [CMake Generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html) + for more information. + +See [Supported Platforms](platforms.md) for more information about platforms +compatible with GoogleTest. + +If you don't already have CMake installed, see the +[CMake installation guide](https://cmake.org/install). + +{: .callout .note} +Note: The terminal commands in this tutorial show a Unix shell prompt, but the +commands work on the Windows command line as well. + +## Set up a project + +CMake uses a file named `CMakeLists.txt` to configure the build system for a +project. You'll use this file to set up your project and declare a dependency on +GoogleTest. + +First, create a directory for your project: + +``` +$ mkdir my_project && cd my_project +``` + +Next, you'll create the `CMakeLists.txt` file and declare a dependency on +GoogleTest. There are many ways to express dependencies in the CMake ecosystem; +in this quickstart, you'll use the +[`FetchContent` CMake module](https://cmake.org/cmake/help/latest/module/FetchContent.html). +To do this, in your project directory (`my_project`), create a file named +`CMakeLists.txt` with the following contents: + +```cmake +cmake_minimum_required(VERSION 3.14) +project(my_project) + +# GoogleTest requires at least C++11 +set(CMAKE_CXX_STANDARD 11) + +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip +) +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) +FetchContent_MakeAvailable(googletest) +``` + +The above configuration declares a dependency on GoogleTest which is downloaded +from GitHub. In the above example, `609281088cfefc76f9d0ce82e1ff6c30cc3591e5` is +the Git commit hash of the GoogleTest version to use; we recommend updating the +hash often to point to the latest version. + +For more information about how to create `CMakeLists.txt` files, see the +[CMake Tutorial](https://cmake.org/cmake/help/latest/guide/tutorial/index.html). + +## Create and run a binary + +With GoogleTest declared as a dependency, you can use GoogleTest code within +your own project. + +As an example, create a file named `hello_test.cc` in your `my_project` +directory with the following contents: + +```cpp +#include <gtest/gtest.h> + +// Demonstrate some basic assertions. +TEST(HelloTest, BasicAssertions) { + // Expect two strings not to be equal. + EXPECT_STRNE("hello", "world"); + // Expect equality. + EXPECT_EQ(7 * 6, 42); +} +``` + +GoogleTest provides [assertions](primer.md#assertions) that you use to test the +behavior of your code. The above sample includes the main GoogleTest header file +and demonstrates some basic assertions. + +To build the code, add the following to the end of your `CMakeLists.txt` file: + +```cmake +enable_testing() + +add_executable( + hello_test + hello_test.cc +) +target_link_libraries( + hello_test + gtest_main +) + +include(GoogleTest) +gtest_discover_tests(hello_test) +``` + +The above configuration enables testing in CMake, declares the C++ test binary +you want to build (`hello_test`), and links it to GoogleTest (`gtest_main`). The +last two lines enable CMake's test runner to discover the tests included in the +binary, using the +[`GoogleTest` CMake module](https://cmake.org/cmake/help/git-stage/module/GoogleTest.html). + +Now you can build and run your test: + +<pre> +<strong>my_project$ cmake -S . -B build</strong> +-- The C compiler identification is GNU 10.2.1 +-- The CXX compiler identification is GNU 10.2.1 +... +-- Build files have been written to: .../my_project/build + +<strong>my_project$ cmake --build build</strong> +Scanning dependencies of target gtest +... +[100%] Built target gmock_main + +<strong>my_project$ cd build && ctest</strong> +Test project .../my_project/build + Start 1: HelloTest.BasicAssertions +1/1 Test #1: HelloTest.BasicAssertions ........ Passed 0.00 sec + +100% tests passed, 0 tests failed out of 1 + +Total Test time (real) = 0.01 sec +</pre> + +Congratulations! You've successfully built and run a test binary using +GoogleTest. + +## Next steps + +* [Check out the Primer](primer.md) to start learning how to write simple + tests. +* [See the code samples](samples.md) for more examples showing how to use a + variety of GoogleTest features. diff --git a/googlemock/include/gmock/gmock-actions.h b/googlemock/include/gmock/gmock-actions.h index 07cc8c2e..f2393bd3 100644 --- a/googlemock/include/gmock/gmock-actions.h +++ b/googlemock/include/gmock/gmock-actions.h @@ -127,8 +127,8 @@ // GOOGLETEST_CM0002 DO NOT DELETE -#ifndef GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ -#define GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ #ifndef _WIN32_WCE # include <errno.h> @@ -1684,4 +1684,4 @@ template <typename F, typename Impl> # pragma warning(pop) #endif -#endif // GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ diff --git a/googlemock/include/gmock/gmock-cardinalities.h b/googlemock/include/gmock/gmock-cardinalities.h index df81810b..fc7f803a 100644 --- a/googlemock/include/gmock/gmock-cardinalities.h +++ b/googlemock/include/gmock/gmock-cardinalities.h @@ -36,8 +36,8 @@ // GOOGLETEST_CM0002 DO NOT DELETE -#ifndef GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ -#define GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ #include <limits.h> #include <memory> @@ -154,4 +154,4 @@ inline Cardinality MakeCardinality(const CardinalityInterface* c) { GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 -#endif // GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ diff --git a/googlemock/include/gmock/gmock-function-mocker.h b/googlemock/include/gmock/gmock-function-mocker.h index 29543f33..0fc6f6f3 100644 --- a/googlemock/include/gmock/gmock-function-mocker.h +++ b/googlemock/include/gmock/gmock-function-mocker.h @@ -33,8 +33,8 @@ // GOOGLETEST_CM0002 DO NOT DELETE -#ifndef GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT -#define GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT +#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ // NOLINT #include <type_traits> // IWYU pragma: keep #include <utility> // IWYU pragma: keep @@ -476,4 +476,4 @@ using internal::FunctionMocker; #define GMOCK_MOCKER_(arity, constness, Method) \ GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) -#endif // GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_FUNCTION_MOCKER_H_ diff --git a/googlemock/include/gmock/gmock-matchers.h b/googlemock/include/gmock/gmock-matchers.h index 52588789..86be9c17 100644 --- a/googlemock/include/gmock/gmock-matchers.h +++ b/googlemock/include/gmock/gmock-matchers.h @@ -252,8 +252,8 @@ // GOOGLETEST_CM0002 DO NOT DELETE -#ifndef GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ -#define GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ #include <algorithm> #include <cmath> @@ -343,7 +343,7 @@ class MatcherCastImpl { // constructor from M (this usually happens when T has an implicit // constructor from any type). // - // It won't work to unconditionally implict_cast + // It won't work to unconditionally implicit_cast // polymorphic_matcher_or_value to Matcher<T> because it won't trigger // a user-defined conversion from M to T if one exists (assuming M is // a value). @@ -5389,4 +5389,4 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 5046 // declarations from this file. #include "gmock/internal/custom/gmock-matchers.h" -#endif // GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ diff --git a/googlemock/include/gmock/gmock-more-actions.h b/googlemock/include/gmock/gmock-more-actions.h index 43275f4d..fd293358 100644 --- a/googlemock/include/gmock/gmock-more-actions.h +++ b/googlemock/include/gmock/gmock-more-actions.h @@ -34,8 +34,8 @@ // GOOGLETEST_CM0002 DO NOT DELETE -#ifndef GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ -#define GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ #include <memory> #include <utility> @@ -570,4 +570,4 @@ InvokeArgument(Params&&... params) { } // namespace testing -#endif // GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_ diff --git a/googlemock/include/gmock/gmock-more-matchers.h b/googlemock/include/gmock/gmock-more-matchers.h index 0265d5d8..dfc77e35 100644 --- a/googlemock/include/gmock/gmock-more-matchers.h +++ b/googlemock/include/gmock/gmock-more-matchers.h @@ -37,8 +37,8 @@ // GOOGLETEST_CM0002 DO NOT DELETE -#ifndef GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ -#define GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ #include "gmock/gmock-matchers.h" @@ -89,4 +89,4 @@ MATCHER(IsFalse, negation ? "is true" : "is false") { } // namespace testing -#endif // GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_MORE_MATCHERS_H_ diff --git a/googlemock/include/gmock/gmock-nice-strict.h b/googlemock/include/gmock/gmock-nice-strict.h index bf02092b..b03b770c 100644 --- a/googlemock/include/gmock/gmock-nice-strict.h +++ b/googlemock/include/gmock/gmock-nice-strict.h @@ -60,8 +60,8 @@ // GOOGLETEST_CM0002 DO NOT DELETE -#ifndef GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ -#define GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ #include <type_traits> @@ -137,12 +137,11 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS NiceMock : private internal::NiceMockImpl<MockClass>, public MockClass { public: - static_assert( - !internal::HasStrictnessModifier<MockClass>(), - "Can't apply NiceMock to a class hierarchy that already has a " - "strictness modifier. See " - "https://github.com/google/googletest/blob/master/googlemock/docs/" - "cook_book.md#the-nice-the-strict-and-the-naggy-nicestrictnaggy"); + static_assert(!internal::HasStrictnessModifier<MockClass>(), + "Can't apply NiceMock to a class hierarchy that already has a " + "strictness modifier. See " + "https://google.github.io/googletest/" + "gmock_cook_book.html#NiceStrictNaggy"); NiceMock() : MockClass() { static_assert(sizeof(*this) == sizeof(MockClass), "The impl subclass shouldn't introduce any padding"); @@ -177,12 +176,11 @@ template <class MockClass> class GTEST_INTERNAL_EMPTY_BASE_CLASS NaggyMock : private internal::NaggyMockImpl<MockClass>, public MockClass { - static_assert( - !internal::HasStrictnessModifier<MockClass>(), - "Can't apply NaggyMock to a class hierarchy that already has a " - "strictness modifier. See " - "https://github.com/google/googletest/blob/master/googlemock/docs/" - "cook_book.md#the-nice-the-strict-and-the-naggy-nicestrictnaggy"); + static_assert(!internal::HasStrictnessModifier<MockClass>(), + "Can't apply NaggyMock to a class hierarchy that already has a " + "strictness modifier. See " + "https://google.github.io/googletest/" + "gmock_cook_book.html#NiceStrictNaggy"); public: NaggyMock() : MockClass() { @@ -224,8 +222,8 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock !internal::HasStrictnessModifier<MockClass>(), "Can't apply StrictMock to a class hierarchy that already has a " "strictness modifier. See " - "https://github.com/google/googletest/blob/master/googlemock/docs/" - "cook_book.md#the-nice-the-strict-and-the-naggy-nicestrictnaggy"); + "https://google.github.io/googletest/" + "gmock_cook_book.html#NiceStrictNaggy"); StrictMock() : MockClass() { static_assert(sizeof(*this) == sizeof(MockClass), "The impl subclass shouldn't introduce any padding"); @@ -260,4 +258,4 @@ class GTEST_INTERNAL_EMPTY_BASE_CLASS StrictMock } // namespace testing -#endif // GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_NICE_STRICT_H_ diff --git a/googlemock/include/gmock/gmock-spec-builders.h b/googlemock/include/gmock/gmock-spec-builders.h index 684c3c2e..f1bd79cf 100644 --- a/googlemock/include/gmock/gmock-spec-builders.h +++ b/googlemock/include/gmock/gmock-spec-builders.h @@ -58,8 +58,8 @@ // GOOGLETEST_CM0002 DO NOT DELETE -#ifndef GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ -#define GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ #include <functional> #include <map> @@ -2033,4 +2033,4 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 #define EXPECT_CALL(obj, call) \ GMOCK_ON_CALL_IMPL_(obj, InternalExpectedAt, call) -#endif // GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ diff --git a/googlemock/include/gmock/gmock.h b/googlemock/include/gmock/gmock.h index 20dba2a7..12469bc4 100644 --- a/googlemock/include/gmock/gmock.h +++ b/googlemock/include/gmock/gmock.h @@ -34,8 +34,8 @@ // GOOGLETEST_CM0002 DO NOT DELETE -#ifndef GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_ -#define GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_ // This file implements the following syntax: // @@ -95,4 +95,4 @@ GTEST_API_ void InitGoogleMock(); } // namespace testing -#endif // GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_GMOCK_H_ diff --git a/googlemock/include/gmock/internal/custom/gmock-generated-actions.h b/googlemock/include/gmock/internal/custom/gmock-generated-actions.h index 003aed3f..63f89996 100644 --- a/googlemock/include/gmock/internal/custom/gmock-generated-actions.h +++ b/googlemock/include/gmock/internal/custom/gmock-generated-actions.h @@ -1,6 +1,6 @@ // GOOGLETEST_CM0002 DO NOT DELETE -#ifndef GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ -#define GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ -#endif // GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ diff --git a/googlemock/include/gmock/internal/custom/gmock-matchers.h b/googlemock/include/gmock/internal/custom/gmock-matchers.h index 66ac8762..63842948 100644 --- a/googlemock/include/gmock/internal/custom/gmock-matchers.h +++ b/googlemock/include/gmock/internal/custom/gmock-matchers.h @@ -31,6 +31,6 @@ // // GOOGLETEST_CM0002 DO NOT DELETE -#ifndef GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ -#define GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ -#endif // GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_MATCHERS_H_ diff --git a/googlemock/include/gmock/internal/custom/gmock-port.h b/googlemock/include/gmock/internal/custom/gmock-port.h index bb91e241..14378692 100644 --- a/googlemock/include/gmock/internal/custom/gmock-port.h +++ b/googlemock/include/gmock/internal/custom/gmock-port.h @@ -33,7 +33,7 @@ // GOOGLETEST_CM0002 DO NOT DELETE -#ifndef GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ -#define GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ -#endif // GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ diff --git a/googlemock/include/gmock/internal/gmock-internal-utils.h b/googlemock/include/gmock/internal/gmock-internal-utils.h index 84543179..317544a7 100644 --- a/googlemock/include/gmock/internal/gmock-internal-utils.h +++ b/googlemock/include/gmock/internal/gmock-internal-utils.h @@ -36,8 +36,8 @@ // GOOGLETEST_CM0002 DO NOT DELETE -#ifndef GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ -#define GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ #include <stdio.h> #include <ostream> // NOLINT @@ -456,4 +456,4 @@ constexpr size_t Function<R(Args...)>::ArgumentCount; } // namespace internal } // namespace testing -#endif // GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ diff --git a/googlemock/include/gmock/internal/gmock-port.h b/googlemock/include/gmock/internal/gmock-port.h index 3f283c8c..367a44d3 100644 --- a/googlemock/include/gmock/internal/gmock-port.h +++ b/googlemock/include/gmock/internal/gmock-port.h @@ -37,8 +37,8 @@ // GOOGLETEST_CM0002 DO NOT DELETE -#ifndef GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ -#define GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ #include <assert.h> #include <stdlib.h> @@ -84,4 +84,4 @@ #endif // !defined(GMOCK_DECLARE_bool_) -#endif // GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ diff --git a/googlemock/include/gmock/internal/gmock-pp.h b/googlemock/include/gmock/internal/gmock-pp.h index 924dde8c..94d61c09 100644 --- a/googlemock/include/gmock/internal/gmock-pp.h +++ b/googlemock/include/gmock/internal/gmock-pp.h @@ -1,5 +1,5 @@ -#ifndef GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_ -#define GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_ +#ifndef GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_ +#define GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_ // Expands and concatenates the arguments. Constructed macros reevaluate. #define GMOCK_PP_CAT(_1, _2) GMOCK_PP_INTERNAL_CAT(_1, _2) @@ -276,4 +276,4 @@ GMOCK_PP_INTERNAL_FOR_EACH_IMPL_14(GMOCK_PP_INC(_i), _Macro, _Data, \ (GMOCK_PP_TAIL _Tuple)) -#endif // GOOGLETEST_GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_ +#endif // GOOGLEMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PP_H_ diff --git a/googlemock/scripts/generator/cpp/ast.py b/googlemock/scripts/generator/cpp/ast.py index db20de49..0e770163 100755 --- a/googlemock/scripts/generator/cpp/ast.py +++ b/googlemock/scripts/generator/cpp/ast.py @@ -336,7 +336,7 @@ class Class(_GenericDeclaration): # TODO(nnorwitz): handle namespaces, etc. if self.bases: for token_list in self.bases: - # TODO(nnorwitz): bases are tokens, do name comparision. + # TODO(nnorwitz): bases are tokens, do name comparison. for token in token_list: if token.name == node.name: return True @@ -379,7 +379,7 @@ class Function(_GenericDeclaration): def Requires(self, node): if self.parameters: - # TODO(nnorwitz): parameters are tokens, do name comparision. + # TODO(nnorwitz): parameters are tokens, do name comparison. for p in self.parameters: if p.name == node.name: return True @@ -895,7 +895,7 @@ class AstBuilder(object): nesting -= 1 return tokens, last_token - # TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necesary. + # TODO(nnorwitz): remove _IgnoreUpTo() it shouldn't be necessary. def _IgnoreUpTo(self, token_type, token): unused_tokens = self._GetTokensUpTo(token_type, token) diff --git a/googlemock/test/gmock-actions_test.cc b/googlemock/test/gmock-actions_test.cc index 18387284..e1ca7fe2 100644 --- a/googlemock/test/gmock-actions_test.cc +++ b/googlemock/test/gmock-actions_test.cc @@ -795,7 +795,7 @@ TEST(DoDefaultDeathTest, DiesIfUsedInCompositeAction) { } // Tests that DoDefault() returns the default value set by -// DefaultValue<T>::Set() when it's not overriden by an ON_CALL(). +// DefaultValue<T>::Set() when it's not overridden by an ON_CALL(). TEST(DoDefaultTest, ReturnsUserSpecifiedPerTypeDefaultValueWhenThereIsOne) { DefaultValue<int>::Set(1); MockClass mock; diff --git a/googletest/CMakeLists.txt b/googletest/CMakeLists.txt index 1379afb9..abdd98b7 100644 --- a/googletest/CMakeLists.txt +++ b/googletest/CMakeLists.txt @@ -92,10 +92,13 @@ include(cmake/internal_utils.cmake) config_compiler_and_linker() # Defined in internal_utils.cmake. +# Needed to set the namespace for both the export targets and the +# alias libraries +set(cmake_package_name GTest CACHE INTERNAL "") + # Create the CMake package file descriptors. if (INSTALL_GTEST) include(CMakePackageConfigHelpers) - set(cmake_package_name GTest) set(targets_export_name ${cmake_package_name}Targets CACHE INTERNAL "") set(generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated" CACHE INTERNAL "") set(cmake_files_install_dir "${CMAKE_INSTALL_LIBDIR}/cmake/${cmake_package_name}") diff --git a/googletest/README.md b/googletest/README.md index 2454cd61..1f8b349a 100644 --- a/googletest/README.md +++ b/googletest/README.md @@ -60,8 +60,8 @@ If you want to use GoogleTest in a project which already uses CMake, the easiest way is to get installed libraries and headers. * Import GoogleTest by using `find_package` (or `pkg_check_modules`). For - example, if `find_package(GTest CONFIG REQUIRED)` is succeed, you can use - the libraries as `GTest::gtest`, `GTest::gmock`. + example, if `find_package(GTest CONFIG REQUIRED)` succeeds, you can use the + libraries as `GTest::gtest`, `GTest::gmock`. And a more robust and flexible approach is to build GoogleTest as part of that project directly. This is done by making the GoogleTest source code available to @@ -82,16 +82,15 @@ main build can be done a few different ways: possible or appropriate. Git submodules, for example, have their own set of advantages and drawbacks. * Use CMake to download GoogleTest as part of the build's configure step. This - is just a little more complex, but doesn't have the limitations of the other - methods. + approach doesn't have the limitations of the other methods. -The last of the above methods is implemented with a small piece of CMake so the -code is pulled into the main build. +The last of the above methods is implemented with a small piece of CMake code +that downloads and pulls the GoogleTest code into the main build. Just add to your `CMakeLists.txt`: ```cmake -include (FetchContent) +include(FetchContent) FetchContent_Declare( googletest # Specify the commit you depend on and update it regularly. diff --git a/googletest/cmake/internal_utils.cmake b/googletest/cmake/internal_utils.cmake index 37cf1efc..8d8d60a8 100644 --- a/googletest/cmake/internal_utils.cmake +++ b/googletest/cmake/internal_utils.cmake @@ -72,7 +72,7 @@ macro(config_compiler_and_linker) if (MSVC) # Newlines inside flags variables break CMake's NMake generator. # TODO(vladl@google.com): Add -RTCs and -RTCu to debug builds. - set(cxx_base_flags "-GS -W4 -WX -wd4251 -wd4275 -nologo -J -Zi") + set(cxx_base_flags "-GS -W4 -WX -wd4251 -wd4275 -nologo -J") set(cxx_base_flags "${cxx_base_flags} -D_UNICODE -DUNICODE -DWIN32 -D_WIN32") set(cxx_base_flags "${cxx_base_flags} -DSTRICT -DWIN32_LEAN_AND_MEAN") set(cxx_exception_flags "-EHsc -D_HAS_EXCEPTIONS=1") @@ -81,6 +81,8 @@ macro(config_compiler_and_linker) # Suppress "unreachable code" warning # http://stackoverflow.com/questions/3232669 explains the issue. set(cxx_base_flags "${cxx_base_flags} -wd4702") + # Ensure MSVC treats source files as UTF-8 encoded. + set(cxx_base_flags "${cxx_base_flags} -utf-8") elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") set(cxx_base_flags "-Wall -Wshadow -Werror -Wconversion") set(cxx_exception_flags "-fexceptions") @@ -148,6 +150,7 @@ function(cxx_library_with_type name type cxx_flags) # type can be either STATIC or SHARED to denote a static or shared library. # ARGN refers to additional arguments after 'cxx_flags'. add_library(${name} ${type} ${ARGN}) + add_library(${cmake_package_name}::${name} ALIAS ${name}) set_target_properties(${name} PROPERTIES COMPILE_FLAGS "${cxx_flags}") diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h index a7e0a3c9..46fe8950 100644 --- a/googletest/include/gtest/gtest-printers.h +++ b/googletest/include/gtest/gtest-printers.h @@ -505,24 +505,21 @@ inline void PrintTo(unsigned char* s, ::std::ostream* os) { PrintTo(ImplicitCast_<const void*>(s), os); } #ifdef __cpp_char8_t -inline void PrintTo(const char8_t* s, ::std::ostream* os) { - PrintTo(ImplicitCast_<const void*>(s), os); -} +// Overloads for u8 strings. +void PrintTo(const char8_t* s, ::std::ostream* os); inline void PrintTo(char8_t* s, ::std::ostream* os) { - PrintTo(ImplicitCast_<const void*>(s), os); + PrintTo(ImplicitCast_<const char8_t*>(s), os); } #endif -inline void PrintTo(const char16_t* s, ::std::ostream* os) { - PrintTo(ImplicitCast_<const void*>(s), os); -} +// Overloads for u16 strings. +void PrintTo(const char16_t* s, ::std::ostream* os); inline void PrintTo(char16_t* s, ::std::ostream* os) { - PrintTo(ImplicitCast_<const void*>(s), os); -} -inline void PrintTo(const char32_t* s, ::std::ostream* os) { - PrintTo(ImplicitCast_<const void*>(s), os); + PrintTo(ImplicitCast_<const char16_t*>(s), os); } +// Overloads for u32 strings. +void PrintTo(const char32_t* s, ::std::ostream* os); inline void PrintTo(char32_t* s, ::std::ostream* os) { - PrintTo(ImplicitCast_<const void*>(s), os); + PrintTo(ImplicitCast_<const char32_t*>(s), os); } // MSVC can be configured to define wchar_t as a typedef of unsigned @@ -558,6 +555,26 @@ inline void PrintTo(const ::std::string& s, ::std::ostream* os) { PrintStringTo(s, os); } +// Overloads for ::std::u8string +#ifdef __cpp_char8_t +GTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os); +inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) { + PrintU8StringTo(s, os); +} +#endif + +// Overloads for ::std::u16string +GTEST_API_ void PrintU16StringTo(const ::std::u16string& s, ::std::ostream* os); +inline void PrintTo(const ::std::u16string& s, ::std::ostream* os) { + PrintU16StringTo(s, os); +} + +// Overloads for ::std::u32string +GTEST_API_ void PrintU32StringTo(const ::std::u32string& s, ::std::ostream* os); +inline void PrintTo(const ::std::u32string& s, ::std::ostream* os) { + PrintU32StringTo(s, os); +} + // Overloads for ::std::wstring. #if GTEST_HAS_STD_WSTRING GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os); @@ -805,6 +822,20 @@ void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) { GTEST_API_ void UniversalPrintArray( const char* begin, size_t len, ::std::ostream* os); +#ifdef __cpp_char8_t +// This overload prints a (const) char8_t array compactly. +GTEST_API_ void UniversalPrintArray(const char8_t* begin, size_t len, + ::std::ostream* os); +#endif + +// This overload prints a (const) char16_t array compactly. +GTEST_API_ void UniversalPrintArray(const char16_t* begin, size_t len, + ::std::ostream* os); + +// This overload prints a (const) char32_t array compactly. +GTEST_API_ void UniversalPrintArray(const char32_t* begin, size_t len, + ::std::ostream* os); + // This overload prints a (const) wchar_t array compactly. GTEST_API_ void UniversalPrintArray( const wchar_t* begin, size_t len, ::std::ostream* os); @@ -877,12 +908,55 @@ class UniversalTersePrinter<const char*> { } }; template <> -class UniversalTersePrinter<char*> { +class UniversalTersePrinter<char*> : public UniversalTersePrinter<const char*> { +}; + +#ifdef __cpp_char8_t +template <> +class UniversalTersePrinter<const char8_t*> { + public: + static void Print(const char8_t* str, ::std::ostream* os) { + if (str == nullptr) { + *os << "NULL"; + } else { + UniversalPrint(::std::u8string(str), os); + } + } +}; +template <> +class UniversalTersePrinter<char8_t*> + : public UniversalTersePrinter<const char8_t*> {}; +#endif + +template <> +class UniversalTersePrinter<const char16_t*> { + public: + static void Print(const char16_t* str, ::std::ostream* os) { + if (str == nullptr) { + *os << "NULL"; + } else { + UniversalPrint(::std::u16string(str), os); + } + } +}; +template <> +class UniversalTersePrinter<char16_t*> + : public UniversalTersePrinter<const char16_t*> {}; + +template <> +class UniversalTersePrinter<const char32_t*> { public: - static void Print(char* str, ::std::ostream* os) { - UniversalTersePrinter<const char*>::Print(str, os); + static void Print(const char32_t* str, ::std::ostream* os) { + if (str == nullptr) { + *os << "NULL"; + } else { + UniversalPrint(::std::u32string(str), os); + } } }; +template <> +class UniversalTersePrinter<char32_t*> + : public UniversalTersePrinter<const char32_t*> {}; #if GTEST_HAS_STD_WSTRING template <> diff --git a/googletest/include/gtest/gtest.h b/googletest/include/gtest/gtest.h index 1088e110..7a5d057c 100644 --- a/googletest/include/gtest/gtest.h +++ b/googletest/include/gtest/gtest.h @@ -673,7 +673,7 @@ class GTEST_API_ TestResult { // Protects mutable state of the property vector and of owned // properties, whose values may be updated. - internal::Mutex test_properites_mutex_; + internal::Mutex test_properties_mutex_; // The vector of TestPartResults std::vector<TestPartResult> test_part_results_; @@ -1962,19 +1962,38 @@ class TestWithParam : public Test, public WithParamInterface<T> { // Boolean assertions. Condition can be either a Boolean expression or an // AssertionResult. For more information on how to use AssertionResult with // these macros see comments on that class. -#define EXPECT_TRUE(condition) \ +#define GTEST_EXPECT_TRUE(condition) \ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ GTEST_NONFATAL_FAILURE_) -#define EXPECT_FALSE(condition) \ +#define GTEST_EXPECT_FALSE(condition) \ GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ GTEST_NONFATAL_FAILURE_) -#define ASSERT_TRUE(condition) \ +#define GTEST_ASSERT_TRUE(condition) \ GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ GTEST_FATAL_FAILURE_) -#define ASSERT_FALSE(condition) \ +#define GTEST_ASSERT_FALSE(condition) \ GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ GTEST_FATAL_FAILURE_) +// Define these macros to 1 to omit the definition of the corresponding +// EXPECT or ASSERT, which clashes with some users' own code. + +#if !GTEST_DONT_DEFINE_EXPECT_TRUE +#define EXPECT_TRUE(condition) GTEST_EXPECT_TRUE(condition) +#endif + +#if !GTEST_DONT_DEFINE_EXPECT_FALSE +#define EXPECT_FALSE(condition) GTEST_EXPECT_FALSE(condition) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_TRUE +#define ASSERT_TRUE(condition) GTEST_ASSERT_TRUE(condition) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_FALSE +#define ASSERT_FALSE(condition) GTEST_ASSERT_FALSE(condition) +#endif + // Macros for testing equalities and inequalities. // // * {ASSERT|EXPECT}_EQ(v1, v2): Tests that v1 == v2 diff --git a/googletest/include/gtest/internal/gtest-filepath.h b/googletest/include/gtest/internal/gtest-filepath.h index 4b5aa3b4..0c033abc 100644 --- a/googletest/include/gtest/internal/gtest-filepath.h +++ b/googletest/include/gtest/internal/gtest-filepath.h @@ -195,7 +195,7 @@ class GTEST_API_ FilePath { void Normalize(); - // Returns a pointer to the last occurence of a valid path separator in + // Returns a pointer to the last occurrence of a valid path separator in // the FilePath. On Windows, for example, both '/' and '\' are valid path // separators. Returns NULL if no path separator was found. const char* FindLastPathSeparator() const; diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h index 632ef2b6..f8cbdbd8 100644 --- a/googletest/include/gtest/internal/gtest-internal.h +++ b/googletest/include/gtest/internal/gtest-internal.h @@ -895,16 +895,16 @@ template <typename T> class HasDebugStringAndShortDebugString { private: template <typename C> - static constexpr auto CheckDebugString(C*) -> typename std::is_same< + static auto CheckDebugString(C*) -> typename std::is_same< std::string, decltype(std::declval<const C>().DebugString())>::type; template <typename> - static constexpr std::false_type CheckDebugString(...); + static std::false_type CheckDebugString(...); template <typename C> - static constexpr auto CheckShortDebugString(C*) -> typename std::is_same< + static auto CheckShortDebugString(C*) -> typename std::is_same< std::string, decltype(std::declval<const C>().ShortDebugString())>::type; template <typename> - static constexpr std::false_type CheckShortDebugString(...); + static std::false_type CheckShortDebugString(...); using HasDebugStringType = decltype(CheckDebugString<T>(nullptr)); using HasShortDebugStringType = decltype(CheckShortDebugString<T>(nullptr)); @@ -1495,7 +1495,7 @@ class NeverThrown { // Implements Boolean test assertions such as EXPECT_TRUE. expression can be // either a boolean expression or an AssertionResult. text is a textual -// represenation of expression as it was passed into the EXPECT_TRUE. +// representation of expression as it was passed into the EXPECT_TRUE. #define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (const ::testing::AssertionResult gtest_ar_ = \ diff --git a/googletest/include/gtest/internal/gtest-port-arch.h b/googletest/include/gtest/internal/gtest-port-arch.h index ffe63003..dd845915 100644 --- a/googletest/include/gtest/internal/gtest-port-arch.h +++ b/googletest/include/gtest/internal/gtest-port-arch.h @@ -107,6 +107,8 @@ #define GTEST_OS_ESP8266 1 #elif defined ESP32 #define GTEST_OS_ESP32 1 +#elif defined(__XTENSA__) +#define GTEST_OS_XTENSA 1 #endif // __CYGWIN__ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index f3b1c8c8..0953a781 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -359,6 +359,10 @@ typedef struct _CRITICAL_SECTION GTEST_CRITICAL_SECTION; // WindowsTypesTest.CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION. typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; #endif +#elif GTEST_OS_XTENSA +#include <unistd.h> +// Xtensa toolchains define strcasecmp in the string.h header instead of +// strings.h. string.h is already included. #else // This assumes that non-Windows OSes provide unistd.h. For OSes where this // is not the case, we need to include headers that provide the functions @@ -379,7 +383,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // On Android, <regex.h> is only available starting with Gingerbread. # define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) # else -# define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS) +#define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS && !GTEST_OS_XTENSA) # endif #endif @@ -464,7 +468,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // no support for it at least as recent as Froyo (2.2). #define GTEST_HAS_STD_WSTRING \ (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ - GTEST_OS_HAIKU || GTEST_OS_ESP32 || GTEST_OS_ESP8266)) + GTEST_OS_HAIKU || GTEST_OS_ESP32 || GTEST_OS_ESP8266 || GTEST_OS_XTENSA)) #endif // GTEST_HAS_STD_WSTRING @@ -589,7 +593,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // By default, we assume that stream redirection is supported on all // platforms except known mobile ones. #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ - GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 + GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA # define GTEST_HAS_STREAM_REDIRECTION 0 # else # define GTEST_HAS_STREAM_REDIRECTION 1 @@ -1936,6 +1940,19 @@ inline bool IsUpper(char ch) { inline bool IsXDigit(char ch) { return isxdigit(static_cast<unsigned char>(ch)) != 0; } +#ifdef __cpp_char8_t +inline bool IsXDigit(char8_t ch) { + return isxdigit(static_cast<unsigned char>(ch)) != 0; +} +#endif +inline bool IsXDigit(char16_t ch) { + const unsigned char low_byte = static_cast<unsigned char>(ch); + return ch == low_byte && isxdigit(low_byte) != 0; +} +inline bool IsXDigit(char32_t ch) { + const unsigned char low_byte = static_cast<unsigned char>(ch); + return ch == low_byte && isxdigit(low_byte) != 0; +} inline bool IsXDigit(wchar_t ch) { const unsigned char low_byte = static_cast<unsigned char>(ch); return ch == low_byte && isxdigit(low_byte) != 0; @@ -2051,7 +2068,8 @@ GTEST_DISABLE_MSC_DEPRECATED_PUSH_() // StrError() aren't needed on Windows CE at this time and thus not // defined there. -#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT +#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && \ + !GTEST_OS_WINDOWS_RT && !GTEST_OS_ESP8266 && !GTEST_OS_XTENSA inline int ChDir(const char* dir) { return chdir(dir); } #endif inline FILE* FOpen(const char* path, const char* mode) { @@ -2084,7 +2102,7 @@ inline const char* StrError(int errnum) { return strerror(errnum); } #endif inline const char* GetEnv(const char* name) { #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ - GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 + GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA // We are on an embedded platform, which has no environment variables. static_cast<void>(name); // To prevent 'unused argument' warning. return nullptr; diff --git a/googletest/scripts/release_docs.py b/googletest/scripts/release_docs.py index 1291347f..8d24f28f 100755 --- a/googletest/scripts/release_docs.py +++ b/googletest/scripts/release_docs.py @@ -37,7 +37,7 @@ SYNOPSIS interlinked wiki files. When we release a new version of Google Test or Google Mock, we need to branch the wiki files such that users of a specific version of Google Test/Mock can - look up documenation relevant for that version. This script + look up documentation relevant for that version. This script automates that process by: - branching the current wiki pages (which document the diff --git a/googletest/src/gtest-death-test.cc b/googletest/src/gtest-death-test.cc index c3d6dfcc..d3d5feb7 100644 --- a/googletest/src/gtest-death-test.cc +++ b/googletest/src/gtest-death-test.cc @@ -865,7 +865,7 @@ class Arguments { } int size() { - return args_.size() - 1; + return static_cast<int>(args_.size()) - 1; } private: @@ -953,13 +953,13 @@ int FuchsiaDeathTest::Wait() { ReadAndInterpretStatusByte(); - zx_info_process_t buffer; + zx_info_process_v2_t buffer; status_zx = child_process_.get_info( - ZX_INFO_PROCESS, &buffer, sizeof(buffer), nullptr, nullptr); + ZX_INFO_PROCESS_V2, &buffer, sizeof(buffer), nullptr, nullptr); GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK); - GTEST_DEATH_TEST_CHECK_(buffer.exited); - set_status(buffer.return_code); + GTEST_DEATH_TEST_CHECK_(buffer.flags & ZX_INFO_PROCESS_FLAG_EXITED); + set_status(static_cast<int>(buffer.return_code)); return status(); } diff --git a/googletest/src/gtest-filepath.cc b/googletest/src/gtest-filepath.cc index af297684..9504f0f5 100644 --- a/googletest/src/gtest-filepath.cc +++ b/googletest/src/gtest-filepath.cc @@ -92,8 +92,9 @@ static bool IsPathSeparator(char c) { // Returns the current working directory, or "" if unsuccessful. FilePath FilePath::GetCurrentDir() { -#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ - GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_ESP32 +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ + GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_ESP32 || \ + GTEST_OS_XTENSA // These platforms do not have a current directory, so we just return // something reasonable. return FilePath(kCurrentDirectoryString); @@ -323,7 +324,7 @@ bool FilePath::CreateFolder() const { delete [] unicode; #elif GTEST_OS_WINDOWS int result = _mkdir(pathname_.c_str()); -#elif GTEST_OS_ESP8266 +#elif GTEST_OS_ESP8266 || GTEST_OS_XTENSA // do nothing int result = 0; #else diff --git a/googletest/src/gtest-internal-inl.h b/googletest/src/gtest-internal-inl.h index cff534ee..6d8cecbb 100644 --- a/googletest/src/gtest-internal-inl.h +++ b/googletest/src/gtest-internal-inl.h @@ -1164,13 +1164,13 @@ class StreamingListener : public EmptyTestEventListener { } // Note that "event=TestCaseStart" is a wire format and has to remain - // "case" for compatibilty + // "case" for compatibility void OnTestCaseStart(const TestCase& test_case) override { SendLn(std::string("event=TestCaseStart&name=") + test_case.name()); } // Note that "event=TestCaseEnd" is a wire format and has to remain - // "case" for compatibilty + // "case" for compatibility void OnTestCaseEnd(const TestCase& test_case) override { SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) + "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) + diff --git a/googletest/src/gtest-printers.cc b/googletest/src/gtest-printers.cc index 20ce1b86..1b68fcb5 100644 --- a/googletest/src/gtest-printers.cc +++ b/googletest/src/gtest-printers.cc @@ -42,12 +42,16 @@ // defines Foo. #include "gtest/gtest-printers.h" + #include <stdio.h> + #include <cctype> #include <cstdint> #include <cwchar> #include <ostream> // NOLINT #include <string> +#include <type_traits> + #include "gtest/internal/gtest-port.h" #include "src/gtest-internal-inl.h" @@ -103,6 +107,16 @@ void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, *os << ">"; } +// Helpers for widening a character to char32_t. Since the standard does not +// specify if char / wchar_t is signed or unsigned, it is important to first +// convert it to the unsigned type of the same width before widening it to +// char32_t. +template <typename CharType> +char32_t ToChar32(CharType in) { + return static_cast<char32_t>( + static_cast<typename std::make_unsigned<CharType>::type>(in)); +} + } // namespace namespace internal { @@ -131,18 +145,15 @@ enum CharFormat { // Returns true if c is a printable ASCII character. We test the // value of c directly instead of calling isprint(), which is buggy on // Windows Mobile. -inline bool IsPrintableAscii(wchar_t c) { - return 0x20 <= c && c <= 0x7E; -} +inline bool IsPrintableAscii(char32_t c) { return 0x20 <= c && c <= 0x7E; } -// Prints a wide or narrow char c as a character literal without the -// quotes, escaping it when necessary; returns how c was formatted. -// The template argument UnsignedChar is the unsigned version of Char, -// which is the type of c. -template <typename UnsignedChar, typename Char> +// Prints c (of type char, char8_t, char16_t, char32_t, or wchar_t) as a +// character literal without the quotes, escaping it when necessary; returns how +// c was formatted. +template <typename Char> static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { - wchar_t w_c = static_cast<wchar_t>(c); - switch (w_c) { + const char32_t u_c = ToChar32(c); + switch (u_c) { case L'\0': *os << "\\0"; break; @@ -174,13 +185,12 @@ static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { *os << "\\v"; break; default: - if (IsPrintableAscii(w_c)) { + if (IsPrintableAscii(u_c)) { *os << static_cast<char>(c); return kAsIs; } else { ostream::fmtflags flags = os->flags(); - *os << "\\x" << std::hex << std::uppercase - << static_cast<int>(static_cast<UnsignedChar>(c)); + *os << "\\x" << std::hex << std::uppercase << static_cast<int>(u_c); os->flags(flags); return kHexEscape; } @@ -188,9 +198,9 @@ static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { return kSpecialEscape; } -// Prints a wchar_t c as if it's part of a string literal, escaping it when +// Prints a char32_t c as if it's part of a string literal, escaping it when // necessary; returns how c was formatted. -static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { +static CharFormat PrintAsStringLiteralTo(char32_t c, ostream* os) { switch (c) { case L'\'': *os << "'"; @@ -199,26 +209,68 @@ static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { *os << "\\\""; return kSpecialEscape; default: - return PrintAsCharLiteralTo<wchar_t>(c, os); + return PrintAsCharLiteralTo(c, os); } } +static const char* GetCharWidthPrefix(char) { + return ""; +} + +static const char* GetCharWidthPrefix(signed char) { + return ""; +} + +static const char* GetCharWidthPrefix(unsigned char) { + return ""; +} + +#ifdef __cpp_char8_t +static const char* GetCharWidthPrefix(char8_t) { + return "u8"; +} +#endif + +static const char* GetCharWidthPrefix(char16_t) { + return "u"; +} + +static const char* GetCharWidthPrefix(char32_t) { + return "U"; +} + +static const char* GetCharWidthPrefix(wchar_t) { + return "L"; +} + // Prints a char c as if it's part of a string literal, escaping it when // necessary; returns how c was formatted. static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { - return PrintAsStringLiteralTo( - static_cast<wchar_t>(static_cast<unsigned char>(c)), os); + return PrintAsStringLiteralTo(ToChar32(c), os); +} + +#ifdef __cpp_char8_t +static CharFormat PrintAsStringLiteralTo(char8_t c, ostream* os) { + return PrintAsStringLiteralTo(ToChar32(c), os); +} +#endif + +static CharFormat PrintAsStringLiteralTo(char16_t c, ostream* os) { + return PrintAsStringLiteralTo(ToChar32(c), os); } -// Prints a wide or narrow character c and its code. '\0' is printed -// as "'\\0'", other unprintable characters are also properly escaped -// using the standard C++ escape sequence. The template argument -// UnsignedChar is the unsigned version of Char, which is the type of c. -template <typename UnsignedChar, typename Char> +static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { + return PrintAsStringLiteralTo(ToChar32(c), os); +} + +// Prints a character c (of type char, char8_t, char16_t, char32_t, or wchar_t) +// and its code. '\0' is printed as "'\\0'", other unprintable characters are +// also properly escaped using the standard C++ escape sequence. +template <typename Char> void PrintCharAndCodeTo(Char c, ostream* os) { // First, print c as a literal in the most readable form we can find. - *os << ((sizeof(c) > 1) ? "L'" : "'"); - const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os); + *os << GetCharWidthPrefix(c) << "'"; + const CharFormat format = PrintAsCharLiteralTo(c, os); *os << "'"; // To aid user debugging, we also print c's code in decimal, unless @@ -239,26 +291,21 @@ void PrintCharAndCodeTo(Char c, ostream* os) { *os << ")"; } -void PrintTo(unsigned char c, ::std::ostream* os) { - PrintCharAndCodeTo<unsigned char>(c, os); -} -void PrintTo(signed char c, ::std::ostream* os) { - PrintCharAndCodeTo<unsigned char>(c, os); -} +void PrintTo(unsigned char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); } +void PrintTo(signed char c, ::std::ostream* os) { PrintCharAndCodeTo(c, os); } // Prints a wchar_t as a symbol if it is printable or as its internal // code otherwise and also as its code. L'\0' is printed as "L'\\0'". -void PrintTo(wchar_t wc, ostream* os) { - PrintCharAndCodeTo<wchar_t>(wc, os); -} +void PrintTo(wchar_t wc, ostream* os) { PrintCharAndCodeTo(wc, os); } +// TODO(dcheng): Consider making this delegate to PrintCharAndCodeTo() as well. void PrintTo(char32_t c, ::std::ostream* os) { *os << std::hex << "U+" << std::uppercase << std::setfill('0') << std::setw(4) << static_cast<uint32_t>(c); } // Prints the given array of characters to the ostream. CharType must be either -// char or wchar_t. +// char, char8_t, char16_t, char32_t, or wchar_t. // The array starts at begin, the length is len, it may include '\0' characters // and may not be NUL-terminated. template <typename CharType> @@ -268,8 +315,8 @@ GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static CharFormat PrintCharsAsStringTo( const CharType* begin, size_t len, ostream* os) { - const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; - *os << kQuoteBegin; + const char* const quote_prefix = GetCharWidthPrefix(*begin); + *os << quote_prefix << "\""; bool is_previous_hex = false; CharFormat print_format = kAsIs; for (size_t index = 0; index < len; ++index) { @@ -278,7 +325,7 @@ static CharFormat PrintCharsAsStringTo( // Previous character is of '\x..' form and this character can be // interpreted as another hexadecimal digit in its number. Break string to // disambiguate. - *os << "\" " << kQuoteBegin; + *os << "\" " << quote_prefix << "\""; } is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; // Remember if any characters required hex escaping. @@ -324,22 +371,57 @@ void UniversalPrintArray(const char* begin, size_t len, ostream* os) { UniversalPrintCharArray(begin, len, os); } +#ifdef __cpp_char8_t +// Prints a (const) char8_t array of 'len' elements, starting at address +// 'begin'. +void UniversalPrintArray(const char8_t* begin, size_t len, ostream* os) { + UniversalPrintCharArray(begin, len, os); +} +#endif + +// Prints a (const) char16_t array of 'len' elements, starting at address +// 'begin'. +void UniversalPrintArray(const char16_t* begin, size_t len, ostream* os) { + UniversalPrintCharArray(begin, len, os); +} + +// Prints a (const) char32_t array of 'len' elements, starting at address +// 'begin'. +void UniversalPrintArray(const char32_t* begin, size_t len, ostream* os) { + UniversalPrintCharArray(begin, len, os); +} + // Prints a (const) wchar_t array of 'len' elements, starting at address // 'begin'. void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { UniversalPrintCharArray(begin, len, os); } -// Prints the given C string to the ostream. -void PrintTo(const char* s, ostream* os) { +namespace { + +// Prints a null-terminated C-style string to the ostream. +template <typename Char> +void PrintCStringTo(const Char* s, ostream* os) { if (s == nullptr) { *os << "NULL"; } else { *os << ImplicitCast_<const void*>(s) << " pointing to "; - PrintCharsAsStringTo(s, strlen(s), os); + PrintCharsAsStringTo(s, std::char_traits<Char>::length(s), os); } } +} // anonymous namespace + +void PrintTo(const char* s, ostream* os) { PrintCStringTo(s, os); } + +#ifdef __cpp_char8_t +void PrintTo(const char8_t* s, ostream* os) { PrintCStringTo(s, os); } +#endif + +void PrintTo(const char16_t* s, ostream* os) { PrintCStringTo(s, os); } + +void PrintTo(const char32_t* s, ostream* os) { PrintCStringTo(s, os); } + // MSVC compiler can be configured to define whar_t as a typedef // of unsigned short. Defining an overload for const wchar_t* in that case // would cause pointers to unsigned shorts be printed as wide strings, @@ -348,14 +430,7 @@ void PrintTo(const char* s, ostream* os) { // wchar_t is implemented as a native type. #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) // Prints the given wide C string to the ostream. -void PrintTo(const wchar_t* s, ostream* os) { - if (s == nullptr) { - *os << "NULL"; - } else { - *os << ImplicitCast_<const void*>(s) << " pointing to "; - PrintCharsAsStringTo(s, wcslen(s), os); - } -} +void PrintTo(const wchar_t* s, ostream* os) { PrintCStringTo(s, os); } #endif // wchar_t is native namespace { @@ -433,6 +508,20 @@ void PrintStringTo(const ::std::string& s, ostream* os) { } } +#ifdef __cpp_char8_t +void PrintU8StringTo(const ::std::u8string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif + +void PrintU16StringTo(const ::std::u16string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} + +void PrintU32StringTo(const ::std::u32string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} + #if GTEST_HAS_STD_WSTRING void PrintWideStringTo(const ::std::wstring& s, ostream* os) { PrintCharsAsStringTo(s.data(), s.size(), os); diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 707e1a51..21c611af 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -1044,7 +1044,7 @@ class Timer { } private: - std::chrono::time_point<std::chrono::steady_clock> start_; + std::chrono::steady_clock::time_point start_; }; // Returns a timestamp as milliseconds since the epoch. Note this time may jump @@ -2241,7 +2241,7 @@ void TestResult::RecordProperty(const std::string& xml_element, if (!ValidateTestProperty(xml_element, test_property)) { return; } - internal::MutexLock lock(&test_properites_mutex_); + internal::MutexLock lock(&test_properties_mutex_); const std::vector<TestProperty>::iterator property_with_matching_key = std::find_if(test_properties_.begin(), test_properties_.end(), internal::TestPropertyKeyIs(test_property.key())); @@ -3928,6 +3928,12 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener { // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. static void OutputXmlCDataSection(::std::ostream* stream, const char* data); + // Streams a test suite XML stanza containing the given test result. + // + // Requires: result.Failed() + static void OutputXmlTestSuiteForTestResult(::std::ostream* stream, + const TestResult& result); + // Streams an XML representation of a TestResult object. static void OutputXmlTestResult(::std::ostream* stream, const TestResult& result); @@ -4090,6 +4096,10 @@ static bool PortableLocaltime(time_t seconds, struct tm* out) { if (tm_ptr == nullptr) return false; *out = *tm_ptr; return true; +#elif defined(__STDC_LIB_EXT1__) + // Uses localtime_s when available as localtime_r is only available from + // C23 standard. + return localtime_s(&seconds, out) != nullptr; #else return localtime_r(&seconds, out) != nullptr; #endif @@ -4147,6 +4157,43 @@ void XmlUnitTestResultPrinter::OutputXmlAttribute( *stream << " " << name << "=\"" << EscapeXmlAttribute(value) << "\""; } +// Streams a test suite XML stanza containing the given test result. +void XmlUnitTestResultPrinter::OutputXmlTestSuiteForTestResult( + ::std::ostream* stream, const TestResult& result) { + // Output the boilerplate for a minimal test suite with one test. + *stream << " <testsuite"; + OutputXmlAttribute(stream, "testsuite", "name", "NonTestSuiteFailure"); + OutputXmlAttribute(stream, "testsuite", "tests", "1"); + OutputXmlAttribute(stream, "testsuite", "failures", "1"); + OutputXmlAttribute(stream, "testsuite", "disabled", "0"); + OutputXmlAttribute(stream, "testsuite", "skipped", "0"); + OutputXmlAttribute(stream, "testsuite", "errors", "0"); + OutputXmlAttribute(stream, "testsuite", "time", + FormatTimeInMillisAsSeconds(result.elapsed_time())); + OutputXmlAttribute( + stream, "testsuite", "timestamp", + FormatEpochTimeInMillisAsIso8601(result.start_timestamp())); + *stream << ">"; + + // Output the boilerplate for a minimal test case with a single test. + *stream << " <testcase"; + OutputXmlAttribute(stream, "testcase", "name", ""); + OutputXmlAttribute(stream, "testcase", "status", "run"); + OutputXmlAttribute(stream, "testcase", "result", "completed"); + OutputXmlAttribute(stream, "testcase", "classname", ""); + OutputXmlAttribute(stream, "testcase", "time", + FormatTimeInMillisAsSeconds(result.elapsed_time())); + OutputXmlAttribute( + stream, "testcase", "timestamp", + FormatEpochTimeInMillisAsIso8601(result.start_timestamp())); + + // Output the actual test result. + OutputXmlTestResult(stream, result); + + // Complete the test suite. + *stream << " </testsuite>\n"; +} + // Prints an XML representation of a TestInfo object. void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, const char* test_suite_name, @@ -4309,6 +4356,13 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream, if (unit_test.GetTestSuite(i)->reportable_test_count() > 0) PrintXmlTestSuite(stream, *unit_test.GetTestSuite(i)); } + + // If there was a test failure outside of one of the test suites (like in a + // test environment) include that in the output. + if (unit_test.ad_hoc_test_result().Failed()) { + OutputXmlTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result()); + } + *stream << "</" << kTestsuites << ">\n"; } @@ -4399,6 +4453,12 @@ class JsonUnitTestResultPrinter : public EmptyTestEventListener { const std::string& indent, bool comma = true); + // Streams a test suite JSON stanza containing the given test result. + // + // Requires: result.Failed() + static void OutputJsonTestSuiteForTestResult(::std::ostream* stream, + const TestResult& result); + // Streams a JSON representation of a TestResult object. static void OutputJsonTestResult(::std::ostream* stream, const TestResult& result); @@ -4553,6 +4613,48 @@ void JsonUnitTestResultPrinter::OutputJsonKey( *stream << ",\n"; } +// Streams a test suite JSON stanza containing the given test result. +void JsonUnitTestResultPrinter::OutputJsonTestSuiteForTestResult( + ::std::ostream* stream, const TestResult& result) { + // Output the boilerplate for a new test suite. + *stream << Indent(4) << "{\n"; + OutputJsonKey(stream, "testsuite", "name", "NonTestSuiteFailure", Indent(6)); + OutputJsonKey(stream, "testsuite", "tests", 1, Indent(6)); + if (!GTEST_FLAG(list_tests)) { + OutputJsonKey(stream, "testsuite", "failures", 1, Indent(6)); + OutputJsonKey(stream, "testsuite", "disabled", 0, Indent(6)); + OutputJsonKey(stream, "testsuite", "skipped", 0, Indent(6)); + OutputJsonKey(stream, "testsuite", "errors", 0, Indent(6)); + OutputJsonKey(stream, "testsuite", "time", + FormatTimeInMillisAsDuration(result.elapsed_time()), + Indent(6)); + OutputJsonKey(stream, "testsuite", "timestamp", + FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()), + Indent(6)); + } + *stream << Indent(6) << "\"testsuite\": [\n"; + + // Output the boilerplate for a new test case. + *stream << Indent(8) << "{\n"; + OutputJsonKey(stream, "testcase", "name", "", Indent(10)); + OutputJsonKey(stream, "testcase", "status", "RUN", Indent(10)); + OutputJsonKey(stream, "testcase", "result", "COMPLETED", Indent(10)); + OutputJsonKey(stream, "testcase", "timestamp", + FormatEpochTimeInMillisAsRFC3339(result.start_timestamp()), + Indent(10)); + OutputJsonKey(stream, "testcase", "time", + FormatTimeInMillisAsDuration(result.elapsed_time()), + Indent(10)); + OutputJsonKey(stream, "testcase", "classname", "", Indent(10), false); + *stream << TestPropertiesAsJson(result, Indent(10)); + + // Output the actual test result. + OutputJsonTestResult(stream, result); + + // Finish the test suite. + *stream << "\n" << Indent(6) << "]\n" << Indent(4) << "}"; +} + // Prints a JSON representation of a TestInfo object. void JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream, const char* test_suite_name, @@ -4712,6 +4814,12 @@ void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream, } } + // If there was a test failure outside of one of the test suites (like in a + // test environment) include that in the output. + if (unit_test.ad_hoc_test_result().Failed()) { + OutputJsonTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result()); + } + *stream << "\n" << kIndent << "]\n" << "}\n"; } diff --git a/googletest/test/BUILD.bazel b/googletest/test/BUILD.bazel index 8f24988a..b06a00a1 100644 --- a/googletest/test/BUILD.bazel +++ b/googletest/test/BUILD.bazel @@ -83,6 +83,10 @@ cc_test( copts = select({ "//:windows": ["-DGTEST_USE_OWN_TR1_TUPLE=0"], "//conditions:default": ["-DGTEST_USE_OWN_TR1_TUPLE=1"], + }) + select({ + # Ensure MSVC treats source files as UTF-8 encoded. + "//:msvc_compiler": ["-utf-8"], + "//conditions:default": [], }), includes = [ "googletest", @@ -146,7 +150,6 @@ cc_test( name = "gtest_unittest", size = "small", srcs = ["gtest_unittest.cc"], - args = ["--heap_check=strict"], shard_count = 2, deps = ["//:gtest_main"], ) diff --git a/googletest/test/googletest-json-output-unittest.py b/googletest/test/googletest-json-output-unittest.py index e799d473..41c85651 100644 --- a/googletest/test/googletest-json-output-unittest.py +++ b/googletest/test/googletest-json-output-unittest.py @@ -612,15 +612,59 @@ EXPECTED_FILTERED = { }], } -EXPECTED_EMPTY = { - u'tests': 0, - u'failures': 0, - u'disabled': 0, - u'errors': 0, - u'time': u'*', - u'timestamp': u'*', - u'name': u'AllTests', - u'testsuites': [], +EXPECTED_NO_TEST = { + u'tests': + 0, + u'failures': + 0, + u'disabled': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'name': + u'AllTests', + u'testsuites': [{ + u'name': + u'NonTestSuiteFailure', + u'tests': + 1, + u'failures': + 1, + u'disabled': + 0, + u'skipped': + 0, + u'errors': + 0, + u'time': + u'*', + u'timestamp': + u'*', + u'testsuite': [{ + u'name': + u'', + u'status': + u'RUN', + u'result': + u'COMPLETED', + u'time': + u'*', + u'timestamp': + u'*', + u'classname': + u'', + u'failures': [{ + u'failure': u'gtest_no_test_unittest.cc:*\n' + u'Expected equality of these values:\n' + u' 1\n 2' + STACK_TRACE_TEMPLATE, + u'type': u'', + }] + }] + }], } GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME) @@ -645,14 +689,14 @@ class GTestJsonOutputUnitTest(gtest_test_utils.TestCase): """ self._TestJsonOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY, 1) - def testEmptyJsonOutput(self): + def testNoTestJsonOutput(self): """Verifies JSON output for a Google Test binary without actual tests. - Runs a test program that generates an empty JSON output, and - tests that the JSON output is expected. + Runs a test program that generates an JSON output for a binary with no + tests, and tests that the JSON output is expected. """ - self._TestJsonOutput('gtest_no_test_unittest', EXPECTED_EMPTY, 0) + self._TestJsonOutput('gtest_no_test_unittest', EXPECTED_NO_TEST, 0) def testTimestampValue(self): """Checks whether the timestamp attribute in the JSON output is valid. diff --git a/googletest/test/googletest-options-test.cc b/googletest/test/googletest-options-test.cc index f07b316d..11fb1f22 100644 --- a/googletest/test/googletest-options-test.cc +++ b/googletest/test/googletest-options-test.cc @@ -42,6 +42,9 @@ # include <windows.h> #elif GTEST_OS_WINDOWS # include <direct.h> +#elif GTEST_OS_OS2 +// For strcasecmp on OS/2 +#include <strings.h> #endif // GTEST_OS_WINDOWS_MOBILE #include "src/gtest-internal-inl.h" diff --git a/googletest/test/googletest-output-test_.cc b/googletest/test/googletest-output-test_.cc index 97009b5f..074f64ef 100644 --- a/googletest/test/googletest-output-test_.cc +++ b/googletest/test/googletest-output-test_.cc @@ -1029,7 +1029,7 @@ auto dynamic_test = ( "BadDynamicFixture1", "TestBase", nullptr, nullptr, __FILE__, __LINE__, []() -> testing::Test* { return new DynamicTest<true>; }), - // Register two tests with the same fixture incorrectly by ommiting the + // Register two tests with the same fixture incorrectly by omitting the // return type. testing::RegisterTest( "BadDynamicFixture2", "FixtureBase", nullptr, nullptr, __FILE__, diff --git a/googletest/test/googletest-param-test-test.cc b/googletest/test/googletest-param-test-test.cc index c852220e..023aa46d 100644 --- a/googletest/test/googletest-param-test-test.cc +++ b/googletest/test/googletest-param-test-test.cc @@ -835,14 +835,14 @@ TEST(MacroNameing, LookupNames) { } } - // Check that the expected form of the test suit name actualy exists. + // Check that the expected form of the test suit name actually exists. EXPECT_NE( // know_suite_names.find("FortyTwo/MacroNamingTest"), know_suite_names.end()); EXPECT_NE( know_suite_names.find("MacroNamingTestNonParametrized"), know_suite_names.end()); - // Check that the expected form of the test name actualy exists. + // Check that the expected form of the test name actually exists. EXPECT_NE( // know_test_names.find("FortyTwo/MacroNamingTest.FooSomeTestName/0"), know_test_names.end()); diff --git a/googletest/test/googletest-printers-test.cc b/googletest/test/googletest-printers-test.cc index f037480b..4e8d66e9 100644 --- a/googletest/test/googletest-printers-test.cc +++ b/googletest/test/googletest-printers-test.cc @@ -201,7 +201,7 @@ OutputStream& operator<<(OutputStream& os, return os; } -// A user-defined streamable but recursivly-defined container type in +// A user-defined streamable but recursively-defined container type in // a user namespace, it mimics therefore std::filesystem::path or // boost::filesystem::path. class PathLike { @@ -493,6 +493,92 @@ TEST(PrintCStringTest, EscapesProperly) { Print(p)); } +#ifdef __cpp_char8_t +// const char8_t*. +TEST(PrintU8StringTest, Const) { + const char8_t* p = u8"界"; + EXPECT_EQ(PrintPointer(p) + " pointing to u8\"\\xE7\\x95\\x8C\"", Print(p)); +} + +// char8_t*. +TEST(PrintU8StringTest, NonConst) { + char8_t p[] = u8"世"; + EXPECT_EQ(PrintPointer(p) + " pointing to u8\"\\xE4\\xB8\\x96\"", + Print(static_cast<char8_t*>(p))); +} + +// NULL u8 string. +TEST(PrintU8StringTest, Null) { + const char8_t* p = nullptr; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests that u8 strings are escaped properly. +TEST(PrintU8StringTest, EscapesProperly) { + const char8_t* p = u8"'\"?\\\a\b\f\n\r\t\v\x7F\xFF hello 世界"; + EXPECT_EQ(PrintPointer(p) + + " pointing to u8\"'\\\"?\\\\\\a\\b\\f\\n\\r\\t\\v\\x7F\\xFF " + "hello \\xE4\\xB8\\x96\\xE7\\x95\\x8C\"", + Print(p)); +} +#endif + +// const char16_t*. +TEST(PrintU16StringTest, Const) { + const char16_t* p = u"界"; + EXPECT_EQ(PrintPointer(p) + " pointing to u\"\\x754C\"", Print(p)); +} + +// char16_t*. +TEST(PrintU16StringTest, NonConst) { + char16_t p[] = u"世"; + EXPECT_EQ(PrintPointer(p) + " pointing to u\"\\x4E16\"", + Print(static_cast<char16_t*>(p))); +} + +// NULL u16 string. +TEST(PrintU16StringTest, Null) { + const char16_t* p = nullptr; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests that u16 strings are escaped properly. +TEST(PrintU16StringTest, EscapesProperly) { + const char16_t* p = u"'\"?\\\a\b\f\n\r\t\v\x7F\xFF hello 世界"; + EXPECT_EQ(PrintPointer(p) + + " pointing to u\"'\\\"?\\\\\\a\\b\\f\\n\\r\\t\\v\\x7F\\xFF " + "hello \\x4E16\\x754C\"", + Print(p)); +} + +// const char32_t*. +TEST(PrintU32StringTest, Const) { + const char32_t* p = U"🗺️"; + EXPECT_EQ(PrintPointer(p) + " pointing to U\"\\x1F5FA\\xFE0F\"", Print(p)); +} + +// char32_t*. +TEST(PrintU32StringTest, NonConst) { + char32_t p[] = U"🌌"; + EXPECT_EQ(PrintPointer(p) + " pointing to U\"\\x1F30C\"", + Print(static_cast<char32_t*>(p))); +} + +// NULL u32 string. +TEST(PrintU32StringTest, Null) { + const char32_t* p = nullptr; + EXPECT_EQ("NULL", Print(p)); +} + +// Tests that u32 strings are escaped properly. +TEST(PrintU32StringTest, EscapesProperly) { + const char32_t* p = U"'\"?\\\a\b\f\n\r\t\v\x7F\xFF hello 🗺️"; + EXPECT_EQ(PrintPointer(p) + + " pointing to U\"'\\\"?\\\\\\a\\b\\f\\n\\r\\t\\v\\x7F\\xFF " + "hello \\x1F5FA\\xFE0F\"", + Print(p)); +} + // MSVC compiler can be configured to define whar_t as a typedef // of unsigned short. Defining an overload for const wchar_t* in that case // would cause pointers to unsigned shorts be printed as wide strings, @@ -564,56 +650,6 @@ TEST(PrintCharPointerTest, ConstUnsignedChar) { EXPECT_EQ("NULL", Print(p)); } -#ifdef __cpp_char8_t -// char8_t* -TEST(PrintCharPointerTest, Char8) { - char8_t* p = reinterpret_cast<char8_t*>(0x1234); - EXPECT_EQ(PrintPointer(p), Print(p)); - p = nullptr; - EXPECT_EQ("NULL", Print(p)); -} - -// const char8_t* -TEST(PrintCharPointerTest, ConstChar8) { - const char8_t* p = reinterpret_cast<const char8_t*>(0x1234); - EXPECT_EQ(PrintPointer(p), Print(p)); - p = nullptr; - EXPECT_EQ("NULL", Print(p)); -} -#endif - -// char16_t* -TEST(PrintCharPointerTest, Char16) { - char16_t* p = reinterpret_cast<char16_t*>(0x1234); - EXPECT_EQ(PrintPointer(p), Print(p)); - p = nullptr; - EXPECT_EQ("NULL", Print(p)); -} - -// const char16_t* -TEST(PrintCharPointerTest, ConstChar16) { - const char16_t* p = reinterpret_cast<const char16_t*>(0x1234); - EXPECT_EQ(PrintPointer(p), Print(p)); - p = nullptr; - EXPECT_EQ("NULL", Print(p)); -} - -// char32_t* -TEST(PrintCharPointerTest, Char32) { - char32_t* p = reinterpret_cast<char32_t*>(0x1234); - EXPECT_EQ(PrintPointer(p), Print(p)); - p = nullptr; - EXPECT_EQ("NULL", Print(p)); -} - -// const char32_t* -TEST(PrintCharPointerTest, ConstChar32) { - const char32_t* p = reinterpret_cast<const char32_t*>(0x1234); - EXPECT_EQ(PrintPointer(p), Print(p)); - p = nullptr; - EXPECT_EQ("NULL", Print(p)); -} - // Tests printing pointers to simple, built-in types. // bool*. @@ -753,62 +789,68 @@ TEST(PrintArrayTest, CharArrayWithNoTerminatingNul) { EXPECT_EQ("\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); } -// const char array with terminating NUL. -TEST(PrintArrayTest, ConstCharArrayWithTerminatingNul) { +// char array with terminating NUL. +TEST(PrintArrayTest, CharArrayWithTerminatingNul) { const char a[] = "\0Hi"; EXPECT_EQ("\"\\0Hi\"", PrintArrayHelper(a)); } -// const wchar_t array without terminating NUL. -TEST(PrintArrayTest, WCharArrayWithNoTerminatingNul) { +#ifdef __cpp_char8_t +// char_t array without terminating NUL. +TEST(PrintArrayTest, Char8ArrayWithNoTerminatingNul) { // Array a contains '\0' in the middle and doesn't end with '\0'. - const wchar_t a[] = { L'H', L'\0', L'i' }; - EXPECT_EQ("L\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); + const char8_t a[] = {u8'H', u8'\0', u8'i'}; + EXPECT_EQ("u8\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); } -// wchar_t array with terminating NUL. -TEST(PrintArrayTest, WConstCharArrayWithTerminatingNul) { - const wchar_t a[] = L"\0Hi"; - EXPECT_EQ("L\"\\0Hi\"", PrintArrayHelper(a)); -} - -#ifdef __cpp_char8_t -// char8_t array. -TEST(PrintArrayTest, Char8Array) { - const char8_t a[] = u8"Hello, world!"; +// char8_t array with terminating NUL. +TEST(PrintArrayTest, Char8ArrayWithTerminatingNul) { + const char8_t a[] = u8"\0世界"; EXPECT_EQ( - "{ U+0048, U+0065, U+006C, U+006C, U+006F, U+002C, U+0020, U+0077, " - "U+006F, U+0072, U+006C, U+0064, U+0021, U+0000 }", + "u8\"\\0\\xE4\\xB8\\x96\\xE7\\x95\\x8C\"", PrintArrayHelper(a)); } #endif -// char16_t array. -#ifdef _MSC_VER -// TODO(b/173029407): Figure out why this doesn't work under MSVC. -TEST(PrintArrayTest, DISABLED_Char16Array) { -#else -TEST(PrintArrayTest, Char16Array) { -#endif - const char16_t a[] = u"Hello, 世界"; - EXPECT_EQ( - "{ U+0048, U+0065, U+006C, U+006C, U+006F, U+002C, U+0020, U+4E16, " - "U+754C, U+0000 }", - PrintArrayHelper(a)); +// const char16_t array without terminating NUL. +TEST(PrintArrayTest, Char16ArrayWithNoTerminatingNul) { + // Array a contains '\0' in the middle and doesn't end with '\0'. + const char16_t a[] = {u'こ', u'\0', u'ん', u'に', u'ち', u'は'}; + EXPECT_EQ("u\"\\x3053\\0\\x3093\\x306B\\x3061\\x306F\" (no terminating NUL)", + PrintArrayHelper(a)); } -// char32_t array. -#ifdef _MSC_VER -// TODO(b/173029407): Figure out why this doesn't work under MSVC. -TEST(PrintArrayTest, DISABLED_Char32Array) { -#else -TEST(PrintArrayTest, Char32Array) { -#endif - const char32_t a[] = U"Hello, 世界"; - EXPECT_EQ( - "{ U+0048, U+0065, U+006C, U+006C, U+006F, U+002C, U+0020, U+4E16, " - "U+754C, U+0000 }", - PrintArrayHelper(a)); +// char16_t array with terminating NUL. +TEST(PrintArrayTest, Char16ArrayWithTerminatingNul) { + const char16_t a[] = u"\0こんにちは"; + EXPECT_EQ("u\"\\0\\x3053\\x3093\\x306B\\x3061\\x306F\"", PrintArrayHelper(a)); +} + +// char32_t array without terminating NUL. +TEST(PrintArrayTest, Char32ArrayWithNoTerminatingNul) { + // Array a contains '\0' in the middle and doesn't end with '\0'. + const char32_t a[] = {U'👋', U'\0', U'🌌'}; + EXPECT_EQ("U\"\\x1F44B\\0\\x1F30C\" (no terminating NUL)", + PrintArrayHelper(a)); +} + +// char32_t array with terminating NUL. +TEST(PrintArrayTest, Char32ArrayWithTerminatingNul) { + const char32_t a[] = U"\0👋🌌"; + EXPECT_EQ("U\"\\0\\x1F44B\\x1F30C\"", PrintArrayHelper(a)); +} + +// wchar_t array without terminating NUL. +TEST(PrintArrayTest, WCharArrayWithNoTerminatingNul) { + // Array a contains '\0' in the middle and doesn't end with '\0'. + const wchar_t a[] = {L'H', L'\0', L'i'}; + EXPECT_EQ("L\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); +} + +// wchar_t array with terminating NUL. +TEST(PrintArrayTest, WCharArrayWithTerminatingNul) { + const wchar_t a[] = L"\0Hi"; + EXPECT_EQ("L\"\\0Hi\"", PrintArrayHelper(a)); } // Array of objects. @@ -872,41 +914,22 @@ TEST(PrintWideStringTest, StringAmbiguousHex) { #ifdef __cpp_char8_t TEST(PrintStringTest, U8String) { - std::u8string str = u8"Hello, world!"; + std::u8string str = u8"Hello, 世界"; EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type. - EXPECT_EQ( - "{ U+0048, U+0065, U+006C, U+006C, U+006F, U+002C, U+0020, U+0077, " - "U+006F, U+0072, U+006C, U+0064, U+0021 }", - Print(str)); + EXPECT_EQ("u8\"Hello, \\xE4\\xB8\\x96\\xE7\\x95\\x8C\"", Print(str)); } #endif -#ifdef _MSC_VER -// TODO(b/173029407): Figure out why this doesn't work under MSVC. -TEST(PrintStringTest, DISABLED_U16String) { -#else TEST(PrintStringTest, U16String) { -#endif std::u16string str = u"Hello, 世界"; EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type. - EXPECT_EQ( - "{ U+0048, U+0065, U+006C, U+006C, U+006F, U+002C, U+0020, U+4E16, " - "U+754C }", - Print(str)); + EXPECT_EQ("u\"Hello, \\x4E16\\x754C\"", Print(str)); } -#ifdef _MSC_VER -// TODO(b/173029407): Figure out why this doesn't work under MSVC. -TEST(PrintStringTest, DISABLED_U32String) { -#else TEST(PrintStringTest, U32String) { -#endif - std::u32string str = U"Hello, 世界"; - EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type. - EXPECT_EQ( - "{ U+0048, U+0065, U+006C, U+006C, U+006F, U+002C, U+0020, U+4E16, " - "U+754C }", - Print(str)); + std::u32string str = U"Hello, 🗺️"; + EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type + EXPECT_EQ("U\"Hello, \\x1F5FA\\xFE0F\"", Print(str)); } // Tests printing types that support generic streaming (i.e. streaming diff --git a/googletest/test/gtest_xml_output_unittest.py b/googletest/test/gtest_xml_output_unittest.py index de8b8c75..eade7aac 100755 --- a/googletest/test/gtest_xml_output_unittest.py +++ b/googletest/test/gtest_xml_output_unittest.py @@ -216,10 +216,20 @@ EXPECTED_SHARDED_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?> </testsuite> </testsuites>""" -EXPECTED_EMPTY_XML = """<?xml version="1.0" encoding="UTF-8"?> +EXPECTED_NO_TEST_XML = """<?xml version="1.0" encoding="UTF-8"?> <testsuites tests="0" failures="0" disabled="0" errors="0" time="*" timestamp="*" name="AllTests"> -</testsuites>""" + <testsuite name="NonTestSuiteFailure" tests="1" failures="1" disabled="0" skipped="0" errors="0" time="*" timestamp="*"> + <testcase name="" status="run" result="completed" time="*" timestamp="*" classname=""> + <failure message="gtest_no_test_unittest.cc:*
Expected equality of these values:
 1
 2" type=""><![CDATA[gtest_no_test_unittest.cc:* +Expected equality of these values: + 1 + 2%(stack)s]]></failure> + </testcase> + </testsuite> +</testsuites>""" % { + 'stack': STACK_TRACE_TEMPLATE +} GTEST_PROGRAM_PATH = gtest_test_utils.GetTestExecutablePath(GTEST_PROGRAM_NAME) @@ -242,14 +252,14 @@ class GTestXMLOutputUnitTest(gtest_xml_test_utils.GTestXMLTestCase): """ self._TestXmlOutput(GTEST_PROGRAM_NAME, EXPECTED_NON_EMPTY_XML, 1) - def testEmptyXmlOutput(self): + def testNoTestXmlOutput(self): """Verifies XML output for a Google Test binary without actual tests. - Runs a test program that generates an empty XML output, and - tests that the XML output is expected. + Runs a test program that generates an XML output for a binary without tests, + and tests that the XML output is expected. """ - self._TestXmlOutput('gtest_no_test_unittest', EXPECTED_EMPTY_XML, 0) + self._TestXmlOutput('gtest_no_test_unittest', EXPECTED_NO_TEST_XML, 0) def testTimestampValue(self): """Checks whether the timestamp attribute in the XML output is valid. diff --git a/googletest/test/gtest_xml_test_utils.py b/googletest/test/gtest_xml_test_utils.py index 5dd0eb92..ec42c62c 100755 --- a/googletest/test/gtest_xml_test_utils.py +++ b/googletest/test/gtest_xml_test_utils.py @@ -70,7 +70,7 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): self.assertEquals(expected_node.tagName, actual_node.tagName) expected_attributes = expected_node.attributes - actual_attributes = actual_node .attributes + actual_attributes = actual_node.attributes self.assertEquals( expected_attributes.length, actual_attributes.length, 'attribute numbers differ in element %s:\nExpected: %r\nActual: %r' % ( @@ -78,7 +78,7 @@ class GTestXMLTestCase(gtest_test_utils.TestCase): actual_attributes.keys())) for i in range(expected_attributes.length): expected_attr = expected_attributes.item(i) - actual_attr = actual_attributes.get(expected_attr.name) + actual_attr = actual_attributes.get(expected_attr.name) self.assert_( actual_attr is not None, 'expected attribute %s not found in element %s' % |