Compare commits

...

39 Commits

Author SHA1 Message Date
Anshul Nigham
cd8e73f067 Move flagfile_value into a ParseFlagFileFlag helper to fix -Wunused-variable warning.
PiperOrigin-RevId: 1004210529
Change-Id: I415314113263122b84b68c0abe7afdb20f97aff6
2026-10-21 13:59:59 -07:00
Derek Mauro
b66cffcd5f Eliminate exit-time destructor in TypedTestSuitePState.
`TYPED_TEST_SUITE_P` defines a static `TypedTestSuitePState` variable at namespace scope. Storing registered tests in a `std::map<std::string, CodeLocation>` required dynamic initialization, heap allocations, and an exit-time destructor, triggering `-Wexit-time-destructors` warnings in builds that enforce trivial exit.

Store registered tests in an intrusive sorted singly-linked list of static POD `RegisteredTest` nodes defined by `TYPED_TEST_P`. `TypedTestSuitePState` is now `constexpr`-constructible and trivially destructible without heap allocations.

PiperOrigin-RevId: 998634744
Change-Id: I0c833ffeebdf21b155038b7e95e497637e68564a
2026-10-13 07:54:40 -07:00
Abseil Team
988ea2c179 Automated Code Change
PiperOrigin-RevId: 992706416
Change-Id: Iec4b79ba6fca28fcf6dcfbb3bde1f73e1b16fa67
2026-10-02 22:20:04 -07:00
Abseil Team
bc548fd273 Automated Code Change
PiperOrigin-RevId: 990949949
Change-Id: I5dcfface3b418684c8c7e16ccdd9b2bf60e25b19
2026-09-30 06:30:45 -07:00
Abseil Team
3ca3771f9c Automated Code Change
PiperOrigin-RevId: 990940938
Change-Id: I052d1ea54207708646fbf8608a13185d76225df2
2026-09-30 06:07:46 -07:00
Abseil Team
5a4a3c968b Automated Code Change
PiperOrigin-RevId: 990912713
Change-Id: Iae4b372309fb0cf3d790dbbd5014bd49b0e06930
2026-09-30 04:57:32 -07:00
Abseil Team
4267679b68 Fix the compilation of the matcher UnorderedElementsAre when used with
a native pointer and size

PiperOrigin-RevId: 983276604
Change-Id: I76ee9771bae7b0801e6aa74c0786bf5809b43226
2026-09-17 10:23:06 -07:00
Abseil Team
f840327b0f Fix misc-override-with-different-visibility warning
TEST_P overrides TestBody() with public visibility instead
of private as defined in the Test base class

PiperOrigin-RevId: 981828756
Change-Id: I9ad0852642520b6b8585df15c3e63885f6fbd135
2026-09-15 08:06:08 -07:00
Abseil Team
8eff9e3366 Fix a null initializer for pthread_t in GTest's Mutex.
Static (linker-initialized) global mutex has a
pthread_t member, which is currently initialized
with 0. This is incorrect, since pthread_t is
an opaque type, which can be a struct in some
libc implementations (e.g. in LLVM-libc). Using
POSIX-specified PTHREAD_NULL is a better option,
however it may not be available on older platforms.
So, use PTHREAD_NULL if it's available, but
fallback to the original behavior for compatibility.

PiperOrigin-RevId: 979239391
Change-Id: I79a292868f85f62bb1962b3ac956ad40eb145907
2026-09-10 09:47:58 -07:00
Abseil Team
dd0a37b843 Use std::regex (defining GTEST_USES_STD_RE) instead of hand-rolled regex engine (defining GTEST_USES_SIMPLE_RE) in GoogleTest
Previously, non-Abseil builds of GoogleTest used either the POSIX <regex.h> header, or a hand-rolled bare-bones regex engine in GoogleTest.

This commit removes the custom regex engine and switches to the C++11 <regex> header instead, which primarily affects Windows builds. Correspondingly, the GTEST_USES_SIMPLE_RE macro is removed and GTEST_USES_STD_RE is defined in its place, so users that depend on the macro should update their code accordingly.

This commit may break on any exotic toolchains or platforms that lack all of these libraries, but these have been long unsupported, as GoogleTest requires C++17.

Note: MSVC's engine can be prone to overflowing the stack on some patterns and inputs. As a trivial example:

    #include <regex>

    int main() {
      std::string corpus;
      for (size_t i = 0; i < 1000; ++i) {
         corpus += "a\n";
      }
      // Stack overflow
      std::regex_match(corpus, std::regex("(\n|.)*", std::regex_constants::ECMAScript));
    }

In such cases, it is recommended to use alternative patterns accomplishing the same goal, such as checking for pieces of a pattern independently.

PiperOrigin-RevId: 978659894
Change-Id: I4594285e696af12a008e1e4cee300f292bbdbf32
2026-09-09 11:34:13 -07:00
Copybara-Service
7e91a413e8 Merge pull request #5082 from Muszic:fix-json-utf8-output
PiperOrigin-RevId: 978191552
Change-Id: I2744f219171a97622333f7b84aa76f78dd63e975
2026-09-08 17:06:36 -07:00
Abseil Team
283c17563f Remove workarounds for MSVC with versions _MSC_VER < 1925
GoogleTest only supports Visual Studio 2022 or later.

PiperOrigin-RevId: 975742423
Change-Id: Ibc09f5cd2c8cb1f9097bd27b584ec136ec2ce42a
2026-09-03 08:29:26 -07:00
Abseil Team
efbef50b59 Remove workarounds for MSVC with versions _MSC_VER < 1915
Compilers before this do not support C++17 at all, which is required by GoogleTest.

PiperOrigin-RevId: 975312508
Change-Id: I77a0649a11ea9162010a8a26807e4a970610616f
2026-09-02 14:02:24 -07:00
Abseil Team
8ecdd89c69 Remove obsolete IBM VisualAge / XL C++ workarounds in googletest
Classic IBM XL C/C++ (__IBMCPP__) only supported up to C++14 (V16.1 for AIX) before IBM retired the proprietary frontend and transitioned to IBM Open XL C/C++ (which is Clang-based and defines __clang__).

Since the legacy XL frontend never supported C++17, the workarounds are obsolete and should be removed.

PiperOrigin-RevId: 975123206
Change-Id: Ia706c7759d3f1df73d375fca68f91eee3aaef825
2026-09-02 07:37:31 -07:00
Muszic
b769fc08a4
Preserve UTF-8 strings in JSON output 2026-09-02 16:13:49 +05:30
Abseil Team
5f31f20eda Remove obsolete Borland C++ workarounds in googletest
Classic Borland C++ (bcc32) only supported up to C++98/C++03 before Embarcadero transitioned C++Builder to Clang-based compilers (bcc32c/bcc64, which define __clang__) and is long obsolete.

PiperOrigin-RevId: 974883761
Change-Id: I220f736485710f37fe4a2b922bda3116304e3812
2026-09-01 21:38:56 -07:00
Abseil Team
3b49a56fe3 Remove obsolete Sun Studio/Solaris workarounds in googletest
Oracle Developer Studio 12.6 (released July 2017) was the final release of the SunPro/Solaris Studio compiler suite, providing only partial/experimental support for C++14 before Oracle discontinued active compiler development. Sun Studio never supported C++17.

Additionally, Solaris 8 and 9 reached EOL over a decade ago. Therefore, workarounds for non-standard putenv/getenv memory behavior in legacy Solaris libc are obsolete, and should be removed.

PiperOrigin-RevId: 974866696
Change-Id: I29db7a1123642c7db0975522c641bd0500a40682
2026-09-01 20:54:21 -07:00
Abseil Team
c3e1e7fe8e Avoid linter warning about multiline comments
PiperOrigin-RevId: 974701766
Change-Id: I8098fe21ed27f0e3bed9568837579551fe0918dd
2026-09-01 14:16:50 -07:00
Abseil Team
defb708946 Remove obsolete HP aC++ workarounds in googletest
HP aC++ for HP-UX on Itanium (A.06.28) only supported up to C++03 and partial C++11 before HPE placed HP-UX and Itanium into maintenance mode. It was discontinued without ever supporting C++14 or C++17.

As GoogleTest requires C++17, the HP-specific workarounds are obsolete and should be removed.

PiperOrigin-RevId: 974700202
Change-Id: Iff9a41101f90f65d76394752bf197b8f2e97311f
2026-09-01 14:13:40 -07:00
Abseil Team
4957858705 Remove some obsolete GCC workarounds
PiperOrigin-RevId: 974635453
Change-Id: I7bb066be8461080d6f908671d2001dbca3ee4a03
2026-09-01 12:12:57 -07:00
Abseil Team
c06edf0146 Remove obsolete Clang check for __has_warning("-Wzero-as-null-pointer-constant")
The warning has been in Clang since version 5.0.

PiperOrigin-RevId: 974506387
Change-Id: I0d1c37511f098fdd6336c48fffd8db8218c19586
2026-09-01 08:17:40 -07:00
Abseil Team
d94a7326e9 Remove BiggestInt and just use intmax_t
PiperOrigin-RevId: 974011716
Change-Id: I5dacc23eae25b749ad6c77b10b9bc0d75fac11c5
2026-08-31 12:16:29 -07:00
Abseil Team
36ba75f0ad UnorderedElementsAre(): Allow matching containers where end is a [sentinel](https://en.cppreference.com/cpp/iterator/sentinel_for). ElementsAre already supports that.
PiperOrigin-RevId: 971869110
Change-Id: I1316463fbd0b532bdf5d636d47165aace84b3801
2026-08-27 04:14:10 -07:00
Abseil Team
938220d0f6 Use non-POSIX function names on MSVC to avoid errors when _CRT_DECLARE_NONSTDC_NAMES = 0
Fixes: #4571
PiperOrigin-RevId: 971422465
Change-Id: Ic32cceedd80490bd688cb240600becc23efb7191
2026-08-26 12:05:52 -07:00
Abseil Team
e273a2d81e Use non-POSIX function names on MSVC to avoid errors when _CRT_DECLARE_NONSTDC_NAMES = 0
Fixes: #4571
PiperOrigin-RevId: 970216754
Change-Id: Iadfed64d59d0cfd32568a3f46001b19f64cfb125
2026-08-24 18:40:34 -07:00
Abseil Team
bfff9fc387 Use non-POSIX function names on MSVC to avoid errors when _CRT_DECLARE_NONSTDC_NAMES = 0
Fixes: #4571
PiperOrigin-RevId: 970040273
Change-Id: Id1aed06aeddde7dbcdff6eaa4702f356c034cadb
2026-08-24 13:25:36 -07:00
Copybara-Service
7260682388 Merge pull request #5046 from UditDewan:fix/print-invalid-char-code-units
PiperOrigin-RevId: 968678073
Change-Id: I669221b694231e385acb9a0bf6640e6f1c319e1e
2026-08-21 14:02:47 -07:00
Copybara-Service
0daf775f8c Merge pull request #4824 from DoDoENT:fix/emscripten-without-threads
PiperOrigin-RevId: 967351125
Change-Id: I4637dd19dfbd8c39d31a4a2bb6f4068e0f631e15
2026-08-19 12:35:58 -07:00
Nenad Mikša
1a447fdce7 avoid -lpthread link option when building with emscripten without threads
- having this flag causes emscripten to generate binary with pthread
  support, which is not compatible with browsers that do not support
  pthreads or with web pages that do not enable pthread support
2026-08-19 17:40:01 +02:00
Abseil Team
91c99b6ffe Add missing const in INSTANTIATE_TEST_SUITE_P.
Dropping this causes tools like [misc-const-correctness](http://clang.llvm.org/extra/clang-tidy/checks/misc/const-correctness.html) to flag GTEST macro invocations as non-const-correct.

PiperOrigin-RevId: 966588433
Change-Id: I896acca9e079288e971a2912c7aa6d17ec6a15e4
2026-08-18 07:44:33 -07:00
Abseil Team
7358557f03 Remove wchar_t overloads if GTEST_HAS_STD_WSTRING is disabled
PiperOrigin-RevId: 966053142
Change-Id: I6535e5577b430186a57ad9c401877aaa83cf37d1
2026-08-17 10:35:06 -07:00
Abseil Team
71edd0ef29 Extract GTEST_HAS_NATIVE_WCHAR
Define `GTEST_HAS_NATIVE_WCHAR` as a replacement for the `!defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)` condition used to remove `wchar_t*` overloads when `wchar_t` is a typedef. Remove `GMOCK_WCHAR_T_IS_NATIVE_` and migrate its uses to the GTest define.

PiperOrigin-RevId: 966022317
Change-Id: Ic929f45763566b9e8d194f280d1f32f5a582ff61
2026-08-17 09:42:15 -07:00
Abseil Team
a2118f6587 Use std::make_unique to avoid clang-tidy false positive in GTEST_TEST_ macro.
PiperOrigin-RevId: 965352463
Change-Id: I4062f4f7a48cba6bf514abd7860d422f6e98cee7
2026-08-15 18:34:42 -07:00
Abseil Team
49495eacfd Use STL capabilities to choose GTEST_HAS_STD_WSTRING default
If the standard library claims not to support wide character strings, disable `GTEST_HAS_STD_WSTRING` and disallow users overriding it. If the standard library implementation can't be recognized, fall back to using the existing list of OSes with a known lack of support.

PiperOrigin-RevId: 964237076
Change-Id: I906f296259f8f17099990d51447a0d0d04dead66
2026-08-13 12:44:03 -07:00
Abseil Team
aa1eefe02c Don't reference std::char_traits<wchar_t> when !GTEST_HAS_STD_WSTRING
If the standard library doesn't support wide character strings, `std::char_traits<Char>` won't be defined, so the definition of `PrintTo` shouldn't reference it. Use `wstrlen` directly instead.

PiperOrigin-RevId: 964168903
Change-Id: Ic628e6583679073b47bb1218dcf52b4c9eadaaf6
2026-08-13 10:39:39 -07:00
Abseil Team
002d14757f When Return is passed to WillOnce (i.e. converted to OnceAction) delegate to be equivalent to Return(ByMove(...))
This should eliminate most required usages of ByMove(...).

PiperOrigin-RevId: 964026018
Change-Id: I2dd5a56842ae3823b200c16b575960b6c367ca20
2026-08-13 05:34:04 -07:00
Abseil Team
02e50550c6 Default-enable wstring support for Android API level 21 and above.
Android started supporting std::wstring with API Level 21 (Lollipop). On Android, unless `GTEST_HAS_STD_WSTRING` is explicitly defined, set it based on the current Android API level.

PiperOrigin-RevId: 963538624
Change-Id: I1a19c4e5b0fef841e0650a1f95b45fa3439dee92
2026-08-12 10:47:59 -07:00
Prashant Kumar
963dd8ea18 Update version strings to 1.18
PiperOrigin-RevId: 962756240
Change-Id: Ibb440cda59a55a1dafc721f00140cbe0d726d077
2026-08-11 06:59:21 -07:00
uditDewan
806b89cf63 Print char8_t/char16_t code units that aren't code points as code units
PrintTo(char8_t) and PrintTo(char16_t) widened their argument to char32_t
and printed it with the U+XXXX notation. That notation names a code point,
but char8_t and char16_t hold code units, so it is wrong for every value
that does not encode a code point on its own: any non-ASCII char8_t (always
part of a multi-unit UTF-8 sequence) and the UTF-16 surrogates D800-DFFF.
For example, PrintTo(char8_t(0x80)) printed "U+0080", the code point of a
character that value cannot represent.

Print those values as code units instead, using the same escape-plus-code
form already used for char, unsigned char and wchar_t: char8_t(0x80) now
prints as u8'\x80' (128) and char16_t(0xD800) as u'\xD800' (55296). Values
that do encode a code point keep the U+XXXX notation.

Fixes #4762
2026-07-26 15:58:15 -04:00
47 changed files with 631 additions and 1376 deletions

View File

@ -58,6 +58,16 @@ config_setting(
constraint_values = ["@platforms//os:openbsd"], constraint_values = ["@platforms//os:openbsd"],
) )
config_setting(
name = "emscripten_without_threads",
constraint_values = [
"@platforms//os:emscripten",
],
values = {
"features": "-use_pthreads",
},
)
# NOTE: Fuchsia is not an officially supported platform. # NOTE: Fuchsia is not an officially supported platform.
config_setting( config_setting(
name = "fuchsia", name = "fuchsia",
@ -113,10 +123,12 @@ cc_library(
copts = select({ copts = select({
":qnx": [], ":qnx": [],
":windows": [], ":windows": [],
":emscripten_without_threads": [],
"//conditions:default": ["-pthread"], "//conditions:default": ["-pthread"],
}), }),
defines = select({ defines = select({
":has_absl": ["GTEST_HAS_ABSL=1"], ":has_absl": ["GTEST_HAS_ABSL=1"],
":emscripten_without_threads": ["GTEST_HAS_PTHREAD=0"],
"//conditions:default": [], "//conditions:default": [],
}), }),
features = select({ features = select({
@ -140,6 +152,7 @@ cc_library(
"-lm", "-lm",
"-pthread", "-pthread",
], ],
":emscripten_without_threads": [],
"//conditions:default": ["-pthread"], "//conditions:default": ["-pthread"],
}), }),
deps = select({ deps = select({

View File

@ -8,12 +8,12 @@ Our documentation is now live on GitHub Pages at
https://google.github.io/googletest/. We recommend browsing the documentation on https://google.github.io/googletest/. We recommend browsing the documentation on
GitHub Pages rather than directly in the repository. GitHub Pages rather than directly in the repository.
#### Release 1.17.0 #### Release 1.18.0
[Release 1.17.0](https://github.com/google/googletest/releases/tag/v1.17.0) is [Release 1.18.0](https://github.com/google/googletest/releases/tag/v1.18.0) is
now available. now available.
The 1.17.x branch The 1.18.x branch
[requires at least C++17](https://opensource.google/documentation/policies/cplusplus-support#c_language_standard). [requires at least C++17](https://opensource.google/documentation/policies/cplusplus-support#c_language_standard).
#### Continuous Integration #### Continuous Integration

View File

@ -69,7 +69,7 @@ IF EXIST "%KOKORO_GFILE_DIR%\distdir\googletest_vendor.tar.gz" (
--keep_going ^ --keep_going ^
--per_file_copt=external/.*@/w ^ --per_file_copt=external/.*@/w ^
--test_output=errors ^ --test_output=errors ^
--test_tag_filters=-no_test_msvc2017 ^ --test_tag_filters=-no_test_msvc2022 ^
%VENDOR_FLAG% %VENDOR_FLAG%
IF %errorlevel% neq 0 EXIT /B 1 IF %errorlevel% neq 0 EXIT /B 1
@ -84,6 +84,6 @@ IF %errorlevel% neq 0 EXIT /B 1
--keep_going ^ --keep_going ^
--per_file_copt=external/.*@/w ^ --per_file_copt=external/.*@/w ^
--test_output=errors ^ --test_output=errors ^
--test_tag_filters=-no_test_msvc2017 ^ --test_tag_filters=-no_test_msvc2022 ^
%VENDOR_FLAG% %VENDOR_FLAG%
IF %errorlevel% neq 0 EXIT /B 1 IF %errorlevel% neq 0 EXIT /B 1

View File

@ -416,41 +416,16 @@ systems (Linux, Cygwin, Mac), GoogleTest uses the
syntax. To learn about POSIX syntax, you may want to read this syntax. To learn about POSIX syntax, you may want to read this
[Wikipedia entry](https://en.wikipedia.org/wiki/Regular_expression#POSIX_extended). [Wikipedia entry](https://en.wikipedia.org/wiki/Regular_expression#POSIX_extended).
On Windows, GoogleTest uses its own simple regular expression implementation. It Otherwise (e.g. on Windows), GoogleTest uses the
lacks many features. For example, we don't support union (`"x|y"`), grouping [`std::regex`](https://en.cppreference.com/w/cpp/regex) implementation from the
(`"(xy)"`), brackets (`"[xy]"`), and repetition count (`"x{5,7}"`), among C++ standard library with the
others. Below is what we do support (`A` denotes a literal character, period [ECMAScript](https://en.cppreference.com/w/cpp/regex/ecmascript) syntax.
(`.`), or a single `\\ ` escape sequence; `x` and `y` denote regular
expressions.):
Expression | Meaning
---------- | --------------------------------------------------------------
`c` | matches any literal character `c`
`\\d` | matches any decimal digit
`\\D` | matches any character that's not a decimal digit
`\\f` | matches `\f`
`\\n` | matches `\n`
`\\r` | matches `\r`
`\\s` | matches any ASCII whitespace, including `\n`
`\\S` | matches any character that's not a whitespace
`\\t` | matches `\t`
`\\v` | matches `\v`
`\\w` | matches any letter, `_`, or decimal digit
`\\W` | matches any character that `\\w` doesn't match
`\\c` | matches any literal character `c`, which must be a punctuation
`.` | matches any single character except `\n`
`A?` | matches 0 or 1 occurrences of `A`
`A*` | matches 0 or many occurrences of `A`
`A+` | matches 1 or many occurrences of `A`
`^` | matches the beginning of a string (not that of each line)
`$` | matches the end of a string (not that of each line)
`xy` | matches `x` followed by `y`
To help you determine which capability is available on your system, GoogleTest To help you determine which capability is available on your system, GoogleTest
defines macros to govern which regular expression it is using. The macros are: defines macros to govern which regular expression it is using. The macros are:
`GTEST_USES_SIMPLE_RE=1` or `GTEST_USES_POSIX_RE=1`. If you want your death `GTEST_USES_RE2=1`, `GTEST_USES_POSIX_RE=1`, or `GTEST_USES_STD_RE=1`. If you
tests to work in all cases, you can either `#if` on these macros or use the more want your death tests to work in all cases, you can either `#if` on these macros
limited syntax only. or use regular expressions supported by all engines.
## Death Tests ## Death Tests

View File

@ -48,7 +48,7 @@ with the following content:
# Choose the most recent version available at # Choose the most recent version available at
# https://registry.bazel.build/modules/googletest # https://registry.bazel.build/modules/googletest
bazel_dep(name = "googletest", version = "1.17.0") bazel_dep(name = "googletest", version = "1.18.0")
``` ```
Now you're ready to build C++ code that uses GoogleTest. Now you're ready to build C++ code that uses GoogleTest.

View File

@ -146,6 +146,7 @@
#include "gmock/internal/gmock-internal-utils.h" #include "gmock/internal/gmock-internal-utils.h"
#include "gmock/internal/gmock-port.h" #include "gmock/internal/gmock-port.h"
#include "gmock/internal/gmock-pp.h" #include "gmock/internal/gmock-pp.h"
#include "gtest/gtest.h"
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100) GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
@ -249,7 +250,7 @@ GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(char, '\0');
// There's also no need for a default action for unsigned wchar_t, as // There's also no need for a default action for unsigned wchar_t, as
// that type is the same as unsigned int for gcc, and invalid for // that type is the same as unsigned int for gcc, and invalid for
// MSVC. // MSVC.
#if GMOCK_WCHAR_T_IS_NATIVE_ #if GTEST_HAS_NATIVE_WCHAR
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(wchar_t, 0U); // NOLINT GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(wchar_t, 0U); // NOLINT
#endif #endif
@ -940,7 +941,7 @@ class [[nodiscard]] ReturnAction final {
std::is_convertible<R, U>, // std::is_convertible<R, U>, //
std::is_move_constructible<U>>::value>::type> std::is_move_constructible<U>>::value>::type>
operator OnceAction<U(Args...)>() && { // NOLINT operator OnceAction<U(Args...)>() && { // NOLINT
return Impl<U>(std::move(value_)); return OnceImpl<U>(std::move(value_));
} }
template <typename U, typename... Args, template <typename U, typename... Args,
@ -959,13 +960,6 @@ class [[nodiscard]] ReturnAction final {
template <typename U> template <typename U>
class Impl final { class Impl final {
public: public:
// The constructor used when the return value is allowed to move from the
// input value (i.e. we are converting to OnceAction).
explicit Impl(R&& input_value)
: state_(new State(std::move(input_value))) {}
// The constructor used when the return value is not allowed to move from
// the input value (i.e. we are converting to Action).
explicit Impl(const R& input_value) : state_(new State(input_value)) {} explicit Impl(const R& input_value) : state_(new State(input_value)) {}
U operator()() && { return std::move(state_->value); } U operator()() && { return std::move(state_->value); }
@ -996,18 +990,6 @@ class [[nodiscard]] ReturnAction final {
// explicit constructor from R. // explicit constructor from R.
value(ImplicitCast_<U>(internal::as_const(input_value))) {} value(ImplicitCast_<U>(internal::as_const(input_value))) {}
// As above, but for the case where we're moving from the ReturnAction
// object because it's being used as a OnceAction.
explicit State(R&& input_value_in)
: input_value(std::move(input_value_in)),
// For the same reason as above we make an implicit conversion to U
// before initializing the value.
//
// Unlike above we provide the input value as an rvalue to the
// implicit conversion because this is a OnceAction: it's fine if it
// wants to consume the input value.
value(ImplicitCast_<U>(std::move(input_value))) {}
// A copy of the value originally provided by the user. We retain this in // A copy of the value originally provided by the user. We retain this in
// addition to the value of the mock function's result type below in case // addition to the value of the mock function's result type below in case
// the latter is a reference-like type. See the std::string_view example // the latter is a reference-like type. See the std::string_view example
@ -1085,6 +1067,23 @@ class [[nodiscard]] ReturnAction final {
const std::shared_ptr<State> state_; const std::shared_ptr<State> state_;
}; };
// Implements the Return(x) action for a mock function that returns type U,
// but is only executed at most once. This allows us to store the original
// value and move construct the return value type on the first (and only)
// call.
template <typename U>
class OnceImpl final {
public:
explicit OnceImpl(R&& input_value)
: input_value_(new R(std::move(input_value))) {}
U operator()() && { return std::move(*input_value_); }
private:
// Move the input value to the heap and make it copyable.
const std::shared_ptr<R> input_value_;
};
R value_; R value_;
}; };

View File

@ -277,13 +277,6 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-internal.h"
// MSVC warning C5046 is new as of VS2017 version 15.8.
#if defined(_MSC_VER) && _MSC_VER >= 1915
#define GMOCK_MAYBE_5046_ 5046
#else
#define GMOCK_MAYBE_5046_
#endif
#if GTEST_HAS_RTTI #if GTEST_HAS_RTTI
namespace proto2 { namespace proto2 {
namespace internal { namespace internal {
@ -323,8 +316,8 @@ T* DynamicCastMessageForGtest(proto2::MessageLite* msg) {
#endif // GTEST_HAS_RTTI #endif // GTEST_HAS_RTTI
GTEST_DISABLE_MSC_WARNINGS_PUSH_( GTEST_DISABLE_MSC_WARNINGS_PUSH_(
4251 GMOCK_MAYBE_5046_ /* class A needs to have dll-interface to be used by // class A needs to have dll-interface to be used by clients of class B
clients of class B */ 4251 5046
/* Symbol involving type with internal linkage not defined */) /* Symbol involving type with internal linkage not defined */)
namespace testing { namespace testing {
@ -3971,8 +3964,8 @@ class [[nodiscard]] UnorderedElementsAreMatcherImpl
} }
private: private:
template <typename ElementIter> template <typename ElementIter, typename ElementIterEnd>
MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last, MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIterEnd elem_last,
::std::vector<std::string>* element_printouts, ::std::vector<std::string>* element_printouts,
MatchResultListener* listener) const { MatchResultListener* listener) const {
element_printouts->clear(); element_printouts->clear();
@ -4157,7 +4150,8 @@ class [[nodiscard]] UnorderedElementsAreMatcher {
template <typename Container> template <typename Container>
operator Matcher<Container>() const { operator Matcher<Container>() const {
typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer; typedef GTEST_REMOVE_REFERENCE_AND_CONST_(Container) RawContainer;
typedef typename internal::RangeTraits<RawContainer>::value_type Element; typedef typename internal::StlContainerView<RawContainer>::type View;
typedef typename internal::RangeTraits<View>::value_type Element;
typedef ::std::vector<Matcher<const Element&>> MatcherVec; typedef ::std::vector<Matcher<const Element&>> MatcherVec;
MatcherVec matchers; MatcherVec matchers;
matchers.reserve(::std::tuple_size<MatcherTuple>::value); matchers.reserve(::std::tuple_size<MatcherTuple>::value);
@ -4538,7 +4532,7 @@ class [[nodiscard]] ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
bool MatchAndExplain(ArgsTuple args, bool MatchAndExplain(ArgsTuple args,
MatchResultListener* listener) const override { MatchResultListener* listener) const override {
// Workaround spurious C4100 on MSVC<=15.7 when k is empty. // Workaround spurious GCC warning when k is empty.
(void)args; (void)args;
const SelectedArgs& selected_args = const SelectedArgs& selected_args =
std::forward_as_tuple(std::get<k>(args)...); std::forward_as_tuple(std::get<k>(args)...);
@ -4571,7 +4565,7 @@ class [[nodiscard]] ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
static void PrintIndices(::std::ostream* os) { static void PrintIndices(::std::ostream* os) {
*os << "whose fields ("; *os << "whose fields (";
const char* sep = ""; const char* sep = "";
// Workaround spurious C4189 on MSVC<=15.7 when k is empty. // Workaround spurious GCC warning when k is empty.
(void)sep; (void)sep;
// The static_cast to void is needed to silence Clang's -Wcomma warning. // The static_cast to void is needed to silence Clang's -Wcomma warning.
// This pattern looks suspiciously like we may have mismatched parentheses // This pattern looks suspiciously like we may have mismatched parentheses

View File

@ -50,11 +50,6 @@ namespace testing {
// Silence C4100 (unreferenced formal // Silence C4100 (unreferenced formal
// parameter) for MSVC // parameter) for MSVC
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100) GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100)
#if defined(_MSC_VER) && (_MSC_VER == 1900)
// and silence C4800 (C4800: 'int *const ': forcing value
// to bool 'true' or 'false') for MSVC 14
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800)
#endif
namespace internal { namespace internal {
@ -123,9 +118,6 @@ MATCHER(IsFalse, negation ? "is true" : "is false") {
return !static_cast<bool>(arg); return !static_cast<bool>(arg);
} }
#if defined(_MSC_VER) && (_MSC_VER == 1900)
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4800
#endif
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100
} // namespace testing } // namespace testing

View File

@ -111,16 +111,6 @@ inline Element* GetRawPointer(Element* p) {
#define GMOCK_INTERNAL_WARNING_POP() _Pragma("clang diagnostic pop") #define GMOCK_INTERNAL_WARNING_POP() _Pragma("clang diagnostic pop")
#endif #endif
// MSVC treats wchar_t as a native type usually, but treats it as the
// same as unsigned short when the compiler option /Zc:wchar_t- is
// specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t
// is a native type.
#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED)
// wchar_t is a typedef.
#else
#define GMOCK_WCHAR_T_IS_NATIVE_ 1
#endif
// In what follows, we use the term "kind" to indicate whether a type // In what follows, we use the term "kind" to indicate whether a type
// is bool, an integer type (excluding bool), a floating-point type, // is bool, an integer type (excluding bool), a floating-point type,
// or none of them. This categorization is useful for determining // or none of them. This categorization is useful for determining
@ -156,7 +146,7 @@ GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(long long, kInteger); // NOLINT GMOCK_DECLARE_KIND_(long long, kInteger); // NOLINT
GMOCK_DECLARE_KIND_(unsigned long long, kInteger); // NOLINT GMOCK_DECLARE_KIND_(unsigned long long, kInteger); // NOLINT
#if GMOCK_WCHAR_T_IS_NATIVE_ #if GTEST_HAS_NATIVE_WCHAR
GMOCK_DECLARE_KIND_(wchar_t, kInteger); GMOCK_DECLARE_KIND_(wchar_t, kInteger);
#endif #endif

View File

@ -62,10 +62,11 @@
#include "absl/flags/flag.h" #include "absl/flags/flag.h"
#endif #endif
// For MS Visual C++, check the compiler version. At least VS 2015 is // For MS Visual C++, check the compiler version. At least VS 2022 is
// required to compile Google Mock. // required to compile Google Mock (_MSC_VER >= 1930). We use a slightly lower
#if defined(_MSC_VER) && _MSC_VER < 1900 // version for internal toolchains lagging behind.
#error "At least Visual C++ 2015 (14.0) is required to compile Google Mock." #if defined(_MSC_VER) && _MSC_VER < 1925
#error "At least Visual C++ 2022 (17.0) is required to compile Google Mock."
#endif #endif
// Macro for referencing flags. This is public as we want the user to // Macro for referencing flags. This is public as we want the user to

View File

@ -56,12 +56,6 @@
#include <qurt_event.h> #include <qurt_event.h>
#endif #endif
// Silence C4800 (C4800: 'int *const ': forcing value
// to bool 'true' or 'false') for MSVC 15
#if defined(_MSC_VER) && (_MSC_VER == 1900)
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800)
#endif
namespace testing { namespace testing {
namespace internal { namespace internal {
@ -786,7 +780,3 @@ InSequence::~InSequence() {
} }
} // namespace testing } // namespace testing
#if defined(_MSC_VER) && (_MSC_VER == 1900)
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4800
#endif

View File

@ -74,8 +74,7 @@ py_test(
":gmock_test_utils", ":gmock_test_utils",
], ],
tags = [ tags = [
"no_test_msvc2015", "no_test_msvc2022",
"no_test_msvc2017",
], ],
) )
@ -105,8 +104,7 @@ py_test(
":gmock_output_test_golden.txt", ":gmock_output_test_golden.txt",
], ],
tags = [ tags = [
"no_test_msvc2015", "no_test_msvc2022",
"no_test_msvc2017",
], ],
deps = [":gmock_test_utils"], deps = [":gmock_test_utils"],
) )

View File

@ -53,11 +53,6 @@
// Silence C4100 (unreferenced formal parameter) and C4503 (decorated name // Silence C4100 (unreferenced formal parameter) and C4503 (decorated name
// length exceeded) for MSVC. // length exceeded) for MSVC.
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100 4503) GTEST_DISABLE_MSC_WARNINGS_PUSH_(4100 4503)
#if defined(_MSC_VER) && (_MSC_VER == 1900)
// and silence C4800 (C4800: 'int *const ': forcing value
// to bool 'true' or 'false') for MSVC 15
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800)
#endif
namespace testing { namespace testing {
namespace { namespace {
@ -270,7 +265,7 @@ TEST(BuiltInDefaultValueTest, IsZeroForNumericTypes) {
EXPECT_EQ(0U, BuiltInDefaultValue<unsigned char>::Get()); EXPECT_EQ(0U, BuiltInDefaultValue<unsigned char>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<signed char>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<signed char>::Get());
EXPECT_EQ(0, BuiltInDefaultValue<char>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<char>::Get());
#if GMOCK_WCHAR_T_IS_NATIVE_ #if GTEST_HAS_NATIVE_WCHAR
#if !defined(__WCHAR_UNSIGNED__) #if !defined(__WCHAR_UNSIGNED__)
EXPECT_EQ(0, BuiltInDefaultValue<wchar_t>::Get()); EXPECT_EQ(0, BuiltInDefaultValue<wchar_t>::Get());
#else #else
@ -299,7 +294,7 @@ TEST(BuiltInDefaultValueTest, ExistsForNumericTypes) {
EXPECT_TRUE(BuiltInDefaultValue<unsigned char>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<unsigned char>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<signed char>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<signed char>::Exists());
EXPECT_TRUE(BuiltInDefaultValue<char>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<char>::Exists());
#if GMOCK_WCHAR_T_IS_NATIVE_ #if GTEST_HAS_NATIVE_WCHAR
EXPECT_TRUE(BuiltInDefaultValue<wchar_t>::Exists()); EXPECT_TRUE(BuiltInDefaultValue<wchar_t>::Exists());
#endif #endif
EXPECT_TRUE(BuiltInDefaultValue<unsigned short>::Exists()); // NOLINT EXPECT_TRUE(BuiltInDefaultValue<unsigned short>::Exists()); // NOLINT
@ -1101,6 +1096,7 @@ TEST(SetArgPointeeTest, AcceptsStringLiteral) {
EXPECT_STREQ("world", ptr); EXPECT_STREQ("world", ptr);
} }
#if GTEST_HAS_STD_WSTRING
TEST(SetArgPointeeTest, AcceptsWideStringLiteral) { TEST(SetArgPointeeTest, AcceptsWideStringLiteral) {
typedef void MyFunction(const wchar_t**); typedef void MyFunction(const wchar_t**);
Action<MyFunction> a = SetArgPointee<0>(L"world"); Action<MyFunction> a = SetArgPointee<0>(L"world");
@ -1108,16 +1104,13 @@ TEST(SetArgPointeeTest, AcceptsWideStringLiteral) {
a.Perform(std::make_tuple(&ptr)); a.Perform(std::make_tuple(&ptr));
EXPECT_STREQ(L"world", ptr); EXPECT_STREQ(L"world", ptr);
#if GTEST_HAS_STD_WSTRING
typedef void MyStringFunction(std::wstring*); typedef void MyStringFunction(std::wstring*);
Action<MyStringFunction> a2 = SetArgPointee<0>(L"world"); Action<MyStringFunction> a2 = SetArgPointee<0>(L"world");
std::wstring str = L""; std::wstring str = L"";
a2.Perform(std::make_tuple(&str)); a2.Perform(std::make_tuple(&str));
EXPECT_EQ(L"world", str); EXPECT_EQ(L"world", str);
#endif
} }
#endif
// Tests that SetArgPointee<N>() accepts a char pointer. // Tests that SetArgPointee<N>() accepts a char pointer.
TEST(SetArgPointeeTest, AcceptsCharPointer) { TEST(SetArgPointeeTest, AcceptsCharPointer) {
@ -2219,7 +2212,4 @@ TEST(ActionMacro, LargeArity) {
} // namespace } // namespace
} // namespace testing } // namespace testing
#if defined(_MSC_VER) && (_MSC_VER == 1900)
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4800
#endif
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 4503 GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 4503

View File

@ -1046,12 +1046,7 @@ struct MoveHelper {
MOCK_METHOD1(Call, void(MoveOnly)); MOCK_METHOD1(Call, void(MoveOnly));
}; };
// Disable this test in VS 2015 (version 14), where it fails when SEH is enabled
#if defined(_MSC_VER) && (_MSC_VER < 1910)
TEST(ComparisonBaseTest, DISABLED_WorksWithMoveOnly) {
#else
TEST(ComparisonBaseTest, WorksWithMoveOnly) { TEST(ComparisonBaseTest, WorksWithMoveOnly) {
#endif
MoveOnly m{0}; MoveOnly m{0};
MoveHelper helper; MoveHelper helper;

View File

@ -78,6 +78,52 @@ TEST(ContainsTest, WorksWithMoveOnly) {
INSTANTIATE_GTEST_MATCHER_TEST_P(ElementsAreTest); INSTANTIATE_GTEST_MATCHER_TEST_P(ElementsAreTest);
// A range of decreasing, positive integers.
class DecreasingIntRange {
public:
explicit DecreasingIntRange(int start) : v_(start) {}
struct Sentinel {};
class Iterator {
public:
using difference_type = std::ptrdiff_t;
using value_type = int;
using iterator_category = std::input_iterator_tag;
using pointer = void;
using reference = int;
explicit Iterator(int v) : v_(v) {}
int operator*() const { return v_; }
Iterator& operator++() {
--v_;
return *this;
}
Iterator operator++(int) {
auto tmp = *this;
++*this;
return tmp;
}
bool operator==(const Iterator& other) const { return v_ == other.v_; }
bool operator!=(const Iterator& other) const { return v_ != other.v_; }
bool operator==(const Sentinel&) const { return v_ < 0; }
bool operator!=(const Sentinel&) const { return v_ >= 0; }
private:
int v_;
};
Iterator begin() const { return Iterator(v_); }
Sentinel end() const { return Sentinel{}; }
private:
int v_;
};
// Tests the variadic version of the ElementsAreMatcher // Tests the variadic version of the ElementsAreMatcher
TEST(ElementsAreTest, HugeMatcher) { TEST(ElementsAreTest, HugeMatcher) {
vector<int> test_vector{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; vector<int> test_vector{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
@ -87,6 +133,13 @@ TEST(ElementsAreTest, HugeMatcher) {
Eq(8), Eq(9), Eq(10), Gt(1), Eq(12))); Eq(8), Eq(9), Eq(10), Gt(1), Eq(12)));
} }
// Tests ElementsAreMatcher with a range that uses a sentinel.
TEST(ElementsAreTest, HugeMatcherSentinel) {
DecreasingIntRange range(3);
EXPECT_THAT(range, ElementsAre(Eq(3), Eq(2), Eq(1), Eq(0)));
}
// Tests the variadic version of the UnorderedElementsAreMatcher // Tests the variadic version of the UnorderedElementsAreMatcher
TEST(ElementsAreTest, HugeMatcherStr) { TEST(ElementsAreTest, HugeMatcherStr) {
vector<std::string> test_vector{ vector<std::string> test_vector{
@ -105,6 +158,13 @@ TEST(ElementsAreTest, HugeMatcherUnordered) {
Eq(3), Eq(9), Eq(12), Eq(11), Ne(122))); Eq(3), Eq(9), Eq(12), Eq(11), Ne(122)));
} }
// Tests the UnorderedElementsAreMatcher with a range that uses a sentinel.
TEST(ElementsAreTest, HugeMatcherUnorderedSentinel) {
DecreasingIntRange range(3);
EXPECT_THAT(range, UnorderedElementsAre(Eq(2), Eq(1), Eq(3), Eq(0)));
}
// Tests that ASSERT_THAT() and EXPECT_THAT() work when the value // Tests that ASSERT_THAT() and EXPECT_THAT() work when the value
// matches the matcher. // matches the matcher.
TEST(MatcherAssertionTest, WorksWhenMatcherIsSatisfied) { TEST(MatcherAssertionTest, WorksWhenMatcherIsSatisfied) {
@ -2228,6 +2288,13 @@ TEST_F(UnorderedElementsAreTest, WorksWithUncopyable) {
UnorderedElementsAre(Truly(ValueIsPositive), UncopyableIs(-3))); UnorderedElementsAre(Truly(ValueIsPositive), UncopyableIs(-3)));
} }
TEST_F(UnorderedElementsAreTest, WorksWithNativeArrayPassedAsPointerAndSize) {
int array[] = {0, 1};
::std::tuple<int*, size_t> array_as_tuple(array, 2);
EXPECT_THAT(array_as_tuple, UnorderedElementsAre(1, 0));
EXPECT_THAT(array_as_tuple, Not(UnorderedElementsAre(0)));
}
TEST_F(UnorderedElementsAreTest, SucceedsWhenExpected) { TEST_F(UnorderedElementsAreTest, SucceedsWhenExpected) {
const int a[] = {1, 2, 3}; const int a[] = {1, 2, 3};
std::vector<int> s(std::begin(a), std::end(a)); std::vector<int> s(std::begin(a), std::end(a));

View File

@ -1088,22 +1088,16 @@ TEST(UnexpectedCallTest, UnsatisfiedPrerequisites) {
// Verifies that the failure message contains the two unsatisfied // Verifies that the failure message contains the two unsatisfied
// pre-requisites but not the satisfied one. // pre-requisites but not the satisfied one.
#ifdef GTEST_USES_POSIX_RE
EXPECT_THAT(r.message(), EXPECT_THAT(r.message(),
ContainsRegex( ContainsRegex(
// POSIX RE doesn't understand the (?s) prefix, but has no // POSIX RE doesn't understand the (?s) prefix, but has no
// trouble with (.|\n). // trouble with [^\b]. MSVC <regex> raises
// std::regex_constants::error_stack on some strings with
// (.|\n) but also has no trouble with [^\b].
"the following immediate pre-requisites are not satisfied:\n" "the following immediate pre-requisites are not satisfied:\n"
"(.|\n)*: pre-requisite #0\n" "[^\b]*: pre-requisite #0\n"
"(.|\n)*: pre-requisite #1")); "[^\b]*: pre-requisite #1"))
#else << r.message();
// We can only use Google Test's own simple regex.
EXPECT_THAT(r.message(),
ContainsRegex(
"the following immediate pre-requisites are not satisfied:"));
EXPECT_THAT(r.message(), ContainsRegex(": pre-requisite #0"));
EXPECT_THAT(r.message(), ContainsRegex(": pre-requisite #1"));
#endif // GTEST_USES_POSIX_RE
b.DoB(1); b.DoB(1);
b.DoB(3); b.DoB(3);

View File

@ -87,10 +87,10 @@ TEST(InitGoogleMockTest, ParsesSingleFlag) {
TEST(InitGoogleMockTest, ParsesMultipleFlags) { TEST(InitGoogleMockTest, ParsesMultipleFlags) {
int old_default_behavior = GMOCK_FLAG_GET(default_mock_behavior); int old_default_behavior = GMOCK_FLAG_GET(default_mock_behavior);
const wchar_t* argv[] = {L"foo.exe", L"--gmock_verbose=info", const char* argv[] = {"foo.exe", "--gmock_verbose=info",
L"--gmock_default_mock_behavior=2", nullptr}; "--gmock_default_mock_behavior=2", nullptr};
const wchar_t* new_argv[] = {L"foo.exe", nullptr}; const char* new_argv[] = {"foo.exe", nullptr};
TestInitGoogleMock(argv, new_argv, "info"); TestInitGoogleMock(argv, new_argv, "info");
EXPECT_EQ(2, GMOCK_FLAG_GET(default_mock_behavior)); EXPECT_EQ(2, GMOCK_FLAG_GET(default_mock_behavior));
@ -115,6 +115,8 @@ TEST(InitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
TestInitGoogleMock(argv, new_argv, "error"); TestInitGoogleMock(argv, new_argv, "error");
} }
#if GTEST_HAS_STD_WSTRING
TEST(WideInitGoogleMockTest, ParsesInvalidCommandLine) { TEST(WideInitGoogleMockTest, ParsesInvalidCommandLine) {
const wchar_t* argv[] = {nullptr}; const wchar_t* argv[] = {nullptr};
@ -168,6 +170,7 @@ TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
TestInitGoogleMock(argv, new_argv, "error"); TestInitGoogleMock(argv, new_argv, "error");
} }
#endif // GTEST_HAS_STD_WSTRING
#endif // !defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) #endif // !defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)

View File

@ -226,13 +226,10 @@ if (gtest_build_tests)
############################################################ ############################################################
# C++ tests built with non-standard compiler flags. # C++ tests built with non-standard compiler flags.
# MSVC 7.1 does not support STL with exceptions disabled.
if (NOT MSVC OR MSVC_VERSION GREATER 1310)
cxx_library(gtest_no_exception "${cxx_no_exception}" cxx_library(gtest_no_exception "${cxx_no_exception}"
src/gtest-all.cc) src/gtest-all.cc)
cxx_library(gtest_main_no_exception "${cxx_no_exception}" cxx_library(gtest_main_no_exception "${cxx_no_exception}"
src/gtest-all.cc src/gtest_main.cc) src/gtest-all.cc src/gtest_main.cc)
endif()
cxx_library(gtest_main_no_rtti "${cxx_no_rtti}" cxx_library(gtest_main_no_rtti "${cxx_no_rtti}"
src/gtest-all.cc src/gtest_main.cc) src/gtest-all.cc src/gtest_main.cc)
@ -264,14 +261,11 @@ if (gtest_build_tests)
py_test(gtest_skip_check_output_test) py_test(gtest_skip_check_output_test)
py_test(gtest_skip_environment_check_output_test) py_test(gtest_skip_environment_check_output_test)
# Visual Studio .NET 2003 does not support STL with exceptions disabled.
if (NOT MSVC OR MSVC_VERSION GREATER 1310) # 1310 is Visual Studio .NET 2003
cxx_executable_with_flags( cxx_executable_with_flags(
googletest-catch-exceptions-no-ex-test_ googletest-catch-exceptions-no-ex-test_
"${cxx_no_exception}" "${cxx_no_exception}"
gtest_main_no_exception gtest_main_no_exception
test/googletest-catch-exceptions-test_.cc) test/googletest-catch-exceptions-test_.cc)
endif()
cxx_executable_with_flags( cxx_executable_with_flags(
googletest-catch-exceptions-ex-test_ googletest-catch-exceptions-ex-test_
@ -301,14 +295,11 @@ if (gtest_build_tests)
cxx_executable(googletest-shuffle-test_ test gtest) cxx_executable(googletest-shuffle-test_ test gtest)
py_test(googletest-shuffle-test) py_test(googletest-shuffle-test)
# MSVC 7.1 does not support STL with exceptions disabled.
if (NOT MSVC OR MSVC_VERSION GREATER 1310)
cxx_executable(googletest-throw-on-failure-test_ test gtest_no_exception) cxx_executable(googletest-throw-on-failure-test_ test gtest_no_exception)
set_target_properties(googletest-throw-on-failure-test_ set_target_properties(googletest-throw-on-failure-test_
PROPERTIES PROPERTIES
COMPILE_FLAGS "${cxx_no_exception}") COMPILE_FLAGS "${cxx_no_exception}")
py_test(googletest-throw-on-failure-test) py_test(googletest-throw-on-failure-test)
endif()
cxx_executable(googletest-uninitialized-test_ test gtest) cxx_executable(googletest-uninitialized-test_ test gtest)
py_test(googletest-uninitialized-test) py_test(googletest-uninitialized-test)

View File

@ -25,7 +25,7 @@ When building GoogleTest as a standalone project, the typical workflow starts
with with
``` ```
git clone https://github.com/google/googletest.git -b v1.17.0 git clone https://github.com/google/googletest.git -b v1.18.0
cd googletest # Main directory of the cloned repository. cd googletest # Main directory of the cloned repository.
mkdir build # Create a directory to hold the build output. mkdir build # Create a directory to hold the build output.
cd build cd build

View File

@ -113,39 +113,12 @@ macro(config_compiler_and_linker)
endif() endif()
endif() endif()
elseif (CMAKE_COMPILER_IS_GNUCXX) elseif (CMAKE_COMPILER_IS_GNUCXX)
set(cxx_base_flags "-Wall -Wshadow -Wundef") set(cxx_base_flags "-Wall -Wshadow -Wundef -Wno-error=dangling-else")
if(NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7.0.0)
set(cxx_base_flags "${cxx_base_flags} -Wno-error=dangling-else")
endif()
set(cxx_exception_flags "-fexceptions") set(cxx_exception_flags "-fexceptions")
set(cxx_no_exception_flags "-fno-exceptions") set(cxx_no_exception_flags "-fno-exceptions")
# Until version 4.3.2, GCC doesn't define a macro to indicate set(cxx_no_rtti_flags "-fno-rtti")
# whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
# explicitly.
set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0")
set(cxx_strict_flags set(cxx_strict_flags
"-Wextra -Wno-unused-parameter -Wno-missing-field-initializers") "-Wextra -Wno-unused-parameter -Wno-missing-field-initializers")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
set(cxx_exception_flags "-features=except")
# Sun Pro doesn't provide macros to indicate whether exceptions and
# RTTI are enabled, so we define GTEST_HAS_* explicitly.
set(cxx_no_exception_flags "-features=no%except -DGTEST_HAS_EXCEPTIONS=0")
set(cxx_no_rtti_flags "-features=no%rtti -DGTEST_HAS_RTTI=0")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "VisualAge" OR
CMAKE_CXX_COMPILER_ID STREQUAL "XL")
# CMake 2.8 changes Visual Age's compiler ID to "XL".
set(cxx_exception_flags "-qeh")
set(cxx_no_exception_flags "-qnoeh")
# Until version 9.0, Visual Age doesn't define a macro to indicate
# whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
# explicitly.
set(cxx_no_rtti_flags "-qnortti -DGTEST_HAS_RTTI=0")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "HP")
set(cxx_base_flags "-AA -mt")
set(cxx_exception_flags "-DGTEST_HAS_EXCEPTIONS=1")
set(cxx_no_exception_flags "+noeh -DGTEST_HAS_EXCEPTIONS=0")
# RTTI can not be disabled in HP aCC compiler.
set(cxx_no_rtti_flags "")
endif() endif()
# The pthreads library is available and allowed? # The pthreads library is available and allowed?

View File

@ -143,13 +143,9 @@ class GTEST_API_ [[nodiscard]] AssertionResult {
// Used in EXPECT_TRUE/FALSE(assertion_result). // Used in EXPECT_TRUE/FALSE(assertion_result).
AssertionResult(const AssertionResult& other); AssertionResult(const AssertionResult& other);
// C4800 is a level 3 warning in Visual Studio 2015 and earlier. // C4800 is off by default starting in Visual Studio 2019 but can be
// This warning is not emitted in Visual Studio 2017.
// This warning is off by default starting in Visual Studio 2019 but can be
// enabled with command-line options. // enabled with command-line options.
#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */) GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */)
#endif
// Used in the EXPECT_TRUE/FALSE(bool_expression). // Used in the EXPECT_TRUE/FALSE(bool_expression).
// //
@ -171,9 +167,7 @@ class GTEST_API_ [[nodiscard]] AssertionResult {
int> = 0> int> = 0>
explicit AssertionResult(const T& success) : success_(success) {} explicit AssertionResult(const T& success) : success_(success) {}
#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)
GTEST_DISABLE_MSC_WARNINGS_POP_() GTEST_DISABLE_MSC_WARNINGS_POP_()
#endif
// Assignment operator. // Assignment operator.
AssertionResult& operator=(AssertionResult other) { AssertionResult& operator=(AssertionResult other) {

View File

@ -105,54 +105,10 @@ GTEST_API_ bool InDeathTestChild();
// //
// On the regular expressions used in death tests: // On the regular expressions used in death tests:
// //
// On POSIX-compliant systems (*nix), we use the <regex.h> library, // Depending on the platform, this may use RE2, the POSIX <regex.h> library,
// which uses the POSIX extended regex syntax. // the C++11 standard library's <regex> engine with ECMAScript syntax, or
// // another similar engine. Regular expressions should be simple and portable
// On other platforms (e.g. Windows or Mac), we only support a simple regex // enough to work across the engines of interest.
// syntax implemented as part of Google Test. This limited
// implementation should be enough most of the time when writing
// death tests; though it lacks many features you can find in PCRE
// or POSIX extended regex syntax. For example, we don't support
// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
// repetition count ("x{5,7}"), among others.
//
// Below is the syntax that we do support. We chose it to be a
// subset of both PCRE and POSIX extended regex, so it's easy to
// learn wherever you come from. In the following: 'A' denotes a
// literal character, period (.), or a single \\ escape sequence;
// 'x' and 'y' denote regular expressions; 'm' and 'n' are for
// natural numbers.
//
// c matches any literal character c
// \\d matches any decimal digit
// \\D matches any character that's not a decimal digit
// \\f matches \f
// \\n matches \n
// \\r matches \r
// \\s matches any ASCII whitespace, including \n
// \\S matches any character that's not a whitespace
// \\t matches \t
// \\v matches \v
// \\w matches any letter, _, or decimal digit
// \\W matches any character that \\w doesn't match
// \\c matches any literal character c, which must be a punctuation
// . matches any single character except \n
// A? matches 0 or 1 occurrences of A
// A* matches 0 or many occurrences of A
// A+ matches 1 or many occurrences of A
// ^ matches the beginning of a string (not that of each line)
// $ matches the end of a string (not that of each line)
// xy matches x followed by y
//
// If you accidentally use PCRE or POSIX extended regex features
// not implemented by us, you will get a run-time failure. In that
// case, please try to rewrite your regular expression within the
// above syntax.
//
// This implementation is *not* meant to be as highly tuned or robust
// as a compiled regex library, but should perform well enough for a
// death test, which already incurs significant overhead by launching
// a child process.
// //
// Known caveats: // Known caveats:
// //

View File

@ -52,16 +52,9 @@
#include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h"
// MSVC warning C5046 is new as of VS2017 version 15.8.
#if defined(_MSC_VER) && _MSC_VER >= 1915
#define GTEST_MAYBE_5046_ 5046
#else
#define GTEST_MAYBE_5046_
#endif
GTEST_DISABLE_MSC_WARNINGS_PUSH_( GTEST_DISABLE_MSC_WARNINGS_PUSH_(
4251 GTEST_MAYBE_5046_ /* class A needs to have dll-interface to be used by // class A needs to have dll-interface to be used by clients of class B
clients of class B */ 4251 5046
/* Symbol involving type with internal linkage not defined */) /* Symbol involving type with internal linkage not defined */)
namespace testing { namespace testing {

View File

@ -510,9 +510,9 @@ auto ConvertGenerator(Gen&& gen, Func&& f) {
private ::testing::internal::GTestNonCopyable { \ private ::testing::internal::GTestNonCopyable { \
public: \ public: \
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \
void TestBody() override; \
\ \
private: \ private: \
void TestBody() override; \
static int AddToRegistry() { \ static int AddToRegistry() { \
::testing::UnitTest::GetInstance() \ ::testing::UnitTest::GetInstance() \
->parameterized_test_registry() \ ->parameterized_test_registry() \
@ -562,7 +562,7 @@ auto ConvertGenerator(Gen&& gen, Func&& f) {
__VA_ARGS__, \ __VA_ARGS__, \
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \ ::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
DUMMY_PARAM_))); \ DUMMY_PARAM_))); \
auto t = std::make_tuple(__VA_ARGS__); \ const auto t = std::make_tuple(__VA_ARGS__); \
static_assert(std::tuple_size<decltype(t)>::value <= 2, \ static_assert(std::tuple_size<decltype(t)>::value <= 2, \
"Too Many Args!"); \ "Too Many Args!"); \
} \ } \

View File

@ -104,6 +104,8 @@
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
#include <stdint.h>
#include <any> #include <any>
#include <functional> #include <functional>
#include <memory> #include <memory>
@ -279,15 +281,13 @@ struct ProtobufPrinter {
struct ConvertibleToIntegerPrinter { struct ConvertibleToIntegerPrinter {
// Since T has no << operator or PrintTo() but can be implicitly // Since T has no << operator or PrintTo() but can be implicitly
// converted to BiggestInt, we print it as a BiggestInt. // converted to intmax_t, we print it as an intmax_t.
// //
// Most likely T is an enum type (either named or unnamed), in which // Most likely T is an enum type (either named or unnamed), in which
// case printing it as an integer is the desired behavior. In case // case printing it as an integer is the desired behavior. In case
// T is not an enum, printing it as an integer is the best we can do // T is not an enum, printing it as an integer is the best we can do
// given that it has no user-defined printer. // given that it has no user-defined printer.
static void PrintValue(internal::BiggestInt value, ::std::ostream* os) { static void PrintValue(intmax_t value, ::std::ostream* os) { *os << value; }
*os << value;
}
}; };
struct ConvertibleToStringViewPrinter { struct ConvertibleToStringViewPrinter {
@ -347,7 +347,7 @@ struct FindFirstPrinter<
// - Print object pointers. // - Print object pointers.
// - Print protocol buffers. // - Print protocol buffers.
// - Use the stream operator, if available. // - Use the stream operator, if available.
// - Print types convertible to BiggestInt. // - Print types convertible to intmax_t.
// - Print types convertible to StringView, if available. // - Print types convertible to StringView, if available.
// - Fallback to printing the raw bytes of the object. // - Fallback to printing the raw bytes of the object.
template <typename T> template <typename T>
@ -522,17 +522,14 @@ inline void PrintTo(bool x, ::std::ostream* os) {
GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os); GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os);
GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os); GTEST_API_ void PrintTo(char32_t c, ::std::ostream* os);
inline void PrintTo(char16_t c, ::std::ostream* os) {
// TODO(b/418738869): Incorrect for values not representing valid codepoints. // Overloads for the UTF-8 and UTF-16 code unit types. A code unit that
// Also see https://github.com/google/googletest/issues/4762. // encodes a code point all by itself is printed with the U+XXXX notation;
PrintTo(static_cast<char32_t>(c), os); // one that does not (any non-ASCII char8_t, and the UTF-16 surrogates) is
} // printed as a code unit instead, the way wchar_t is.
GTEST_API_ void PrintTo(char16_t c, ::std::ostream* os);
#ifdef __cpp_lib_char8_t #ifdef __cpp_lib_char8_t
inline void PrintTo(char8_t c, ::std::ostream* os) { GTEST_API_ void PrintTo(char8_t c, ::std::ostream* os);
// TODO(b/418738869): Incorrect for values not representing valid codepoints.
// Also see https://github.com/google/googletest/issues/4762.
PrintTo(static_cast<char32_t>(c), os);
}
#endif #endif
// gcc/clang __{u,}int128_t // gcc/clang __{u,}int128_t
@ -674,12 +671,12 @@ inline void PrintTo(char32_t* s, ::std::ostream* os) {
PrintTo(ImplicitCast_<const char32_t*>(s), os); PrintTo(ImplicitCast_<const char32_t*>(s), os);
} }
// MSVC can be configured to define wchar_t as a typedef of unsigned // Only add an overload for printing wchar_t* if:
// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native // 1. Wide string support is enabled.
// type. When wchar_t is a typedef, defining an overload for const // 2. wchar_t is a distinct native type. (If it's a typedef, the overload could
// wchar_t* would cause unsigned short* be printed as a wide string, // cause a pointer to the underlying type to be mistakenly treated as a
// possibly causing invalid memory accesses. // string.)
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) #if GTEST_HAS_STD_WSTRING && GTEST_HAS_NATIVE_WCHAR
// Overloads for wide C strings // Overloads for wide C strings
GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os); GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os);
inline void PrintTo(wchar_t* s, ::std::ostream* os) { inline void PrintTo(wchar_t* s, ::std::ostream* os) {
@ -1173,15 +1170,12 @@ class [[nodiscard]] UniversalTersePrinter<const wchar_t*> {
} }
} }
}; };
#endif
template <> template <>
class [[nodiscard]] UniversalTersePrinter<wchar_t*> { class [[nodiscard]] UniversalTersePrinter<wchar_t*>
public: : public UniversalTersePrinter<const wchar_t*> {};
static void Print(wchar_t* str, ::std::ostream* os) {
UniversalTersePrinter<const wchar_t*>::Print(str, os); #endif // GTEST_HAS_STD_WSTRING
}
};
template <typename T> template <typename T>
void UniversalTersePrint(const T& value, ::std::ostream* os) { void UniversalTersePrint(const T& value, ::std::ostream* os) {

View File

@ -256,8 +256,11 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
// The variables defined in the type-parameterized test macros are // The variables defined in the type-parameterized test macros are
// static as typically these macros are used in a .h file that can be // static as typically these macros are used in a .h file that can be
// #included in multiple translation units linked together. // #included in multiple translation units linked together.
// Marked [[maybe_unused]] because TypedTestSuitePState is
// constexpr-constructible and trivially destructible, so an uninstantiated
// suite would otherwise trigger -Wunused-variable.
#define TYPED_TEST_SUITE_P(SuiteName) \ #define TYPED_TEST_SUITE_P(SuiteName) \
static ::testing::internal::TypedTestSuitePState \ [[maybe_unused]] static ::testing::internal::TypedTestSuitePState \
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName) GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName)
// Legacy API is deprecated but still available // Legacy API is deprecated but still available
@ -276,10 +279,12 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
typedef gtest_TypeParam_ TypeParam; \ typedef gtest_TypeParam_ TypeParam; \
void TestBody() override; \ void TestBody() override; \
}; \ }; \
static ::testing::internal::TypedTestSuitePState::RegisteredTest \
gtest_##TestName##_registered_test_ = {GTEST_STRINGIFY_(TestName), \
__FILE__, __LINE__, nullptr}; \
[[maybe_unused]] static bool gtest_##TestName##_defined_ = \ [[maybe_unused]] static bool gtest_##TestName##_defined_ = \
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \ GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTest( \
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \ &gtest_##TestName##_registered_test_, GTEST_STRINGIFY_(SuiteName)); \
GTEST_STRINGIFY_(TestName)); \
} \ } \
template <typename gtest_TypeParam_> \ template <typename gtest_TypeParam_> \
void GTEST_SUITE_NAMESPACE_( \ void GTEST_SUITE_NAMESPACE_( \

View File

@ -71,7 +71,7 @@
#include "gtest/gtest-typed-test.h" // IWYU pragma: export #include "gtest/gtest-typed-test.h" // IWYU pragma: export
#include "gtest/gtest_pred_impl.h" // IWYU pragma: export #include "gtest/gtest_pred_impl.h" // IWYU pragma: export
#include "gtest/gtest_prod.h" // IWYU pragma: export #include "gtest/gtest_prod.h" // IWYU pragma: export
#include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-internal.h" // IWYU pragma: export
#include "gtest/internal/gtest-string.h" #include "gtest/internal/gtest-string.h"
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
@ -1419,14 +1419,14 @@ class [[nodiscard]] EqHelper {
} }
// With this overloaded version, we allow anonymous enums to be used // With this overloaded version, we allow anonymous enums to be used
// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums can be
// enums can be implicitly cast to BiggestInt. // implicitly cast to intmax_t.
// //
// Even though its body looks the same as the above version, we // Even though its body looks the same as the above version, we
// cannot merge the two, as it will make anonymous enums unhappy. // cannot merge the two, as it will make anonymous enums unhappy.
static AssertionResult Compare(const char* lhs_expression, static AssertionResult Compare(const char* lhs_expression,
const char* rhs_expression, BiggestInt lhs, const char* rhs_expression, intmax_t lhs,
BiggestInt rhs) { intmax_t rhs) {
return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs); return CmpHelperEQ(lhs_expression, rhs_expression, lhs, rhs);
} }
@ -1514,6 +1514,8 @@ GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
const char* s2_expression, const char* s2_expression,
const char* s1, const char* s2); const char* s1, const char* s2);
#if GTEST_HAS_STD_WSTRING
// Helper function for *_STREQ on wide strings. // Helper function for *_STREQ on wide strings.
// //
// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM.
@ -1528,6 +1530,8 @@ GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression,
const char* s2_expression, const char* s2_expression,
const wchar_t* s1, const wchar_t* s2); const wchar_t* s1, const wchar_t* s2);
#endif // GTEST_HAS_STD_WSTRING
} // namespace internal } // namespace internal
// IsSubstring() and IsNotSubstring() are intended to be used as the // IsSubstring() and IsNotSubstring() are intended to be used as the
@ -1542,18 +1546,10 @@ GTEST_API_ AssertionResult IsSubstring(const char* needle_expr,
const char* haystack_expr, const char* haystack_expr,
const char* needle, const char* needle,
const char* haystack); const char* haystack);
GTEST_API_ AssertionResult IsSubstring(const char* needle_expr,
const char* haystack_expr,
const wchar_t* needle,
const wchar_t* haystack);
GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr, GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,
const char* haystack_expr, const char* haystack_expr,
const char* needle, const char* needle,
const char* haystack); const char* haystack);
GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,
const char* haystack_expr,
const wchar_t* needle,
const wchar_t* haystack);
GTEST_API_ AssertionResult IsSubstring(const char* needle_expr, GTEST_API_ AssertionResult IsSubstring(const char* needle_expr,
const char* haystack_expr, const char* haystack_expr,
const ::std::string& needle, const ::std::string& needle,
@ -1564,6 +1560,14 @@ GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,
const ::std::string& haystack); const ::std::string& haystack);
#if GTEST_HAS_STD_WSTRING #if GTEST_HAS_STD_WSTRING
GTEST_API_ AssertionResult IsSubstring(const char* needle_expr,
const char* haystack_expr,
const wchar_t* needle,
const wchar_t* haystack);
GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,
const char* haystack_expr,
const wchar_t* needle,
const wchar_t* haystack);
GTEST_API_ AssertionResult IsSubstring(const char* needle_expr, GTEST_API_ AssertionResult IsSubstring(const char* needle_expr,
const char* haystack_expr, const char* haystack_expr,
const ::std::wstring& needle, const ::std::wstring& needle,

View File

@ -39,7 +39,7 @@
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-port.h" // IWYU pragma: export
#ifdef GTEST_OS_LINUX #ifdef GTEST_OS_LINUX
#include <stdlib.h> #include <stdlib.h>
@ -577,51 +577,87 @@ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */) /* class A needs to have dll-interface to be used by clients of class B */)
// State of the definition of a type-parameterized test suite. // State of the definition of a type-parameterized test suite.
// Uses an intrusive linked list of caller-allocated POD RegisteredTest nodes
// rather than an STL container.
// REQUIRES: TypedTestSuitePState must be constexpr-constructible and trivially
// destructible so that namespace-scope static instances defined by
// TYPED_TEST_SUITE_P avoid -Wglobal-constructors and -Wexit-time-destructors.
class GTEST_API_ [[nodiscard]] TypedTestSuitePState { class GTEST_API_ [[nodiscard]] TypedTestSuitePState {
public: public:
TypedTestSuitePState() : registered_(false) {} // Caller-owned POD node linked into registered_tests_; must outlive this
// TypedTestSuitePState instance.
struct RegisteredTest {
const char* name;
const char* file;
int line;
RegisteredTest* next;
};
// Adds the given test name to defined_test_names_ and return true constexpr TypedTestSuitePState() = default;
// if the test suite hasn't been registered; otherwise aborts the
// program. // Adds the given test to registered_tests_ and returns true if the test
bool AddTestName(const char* file, int line, const char* case_name, // suite hasn't been registered; otherwise aborts the program.
const char* test_name) { bool AddTest(RegisteredTest* test, const char* case_name) {
if (registered_) { if (registered_) {
fprintf(stderr, fprintf(stderr,
"%s Test %s must be defined before " "%s Test %s must be defined before "
"REGISTER_TYPED_TEST_SUITE_P(%s, ...).\n", "REGISTER_TYPED_TEST_SUITE_P(%s, ...).\n",
FormatFileLocation(file, line).c_str(), test_name, case_name); FormatFileLocation(test->file, test->line).c_str(), test->name,
case_name);
fflush(stderr); fflush(stderr);
posix::Abort(); posix::Abort();
} }
registered_tests_.emplace(test_name, CodeLocation(file, line)); // Insert into registered_tests_ in lexicographical order by test name
// (ignoring duplicates) so VerifyRegisteredTestNames reports missing tests
// in deterministic sorted order.
RegisteredTest** p = &registered_tests_;
while (*p != nullptr && strcmp((*p)->name, test->name) < 0) {
p = &(*p)->next;
}
if (*p == nullptr || strcmp((*p)->name, test->name) != 0) {
test->next = *p;
*p = test;
}
return true; return true;
} }
bool TestExists(const std::string& test_name) const { bool TestExists(const std::string& test_name) const {
return registered_tests_.count(test_name) > 0; return FindTest(test_name) != nullptr;
} }
const CodeLocation& GetCodeLocation(const std::string& test_name) const { CodeLocation GetCodeLocation(const std::string& test_name) const {
RegisteredTestsMap::const_iterator it = registered_tests_.find(test_name); const RegisteredTest* test = FindTest(test_name);
GTEST_CHECK_(it != registered_tests_.end()); GTEST_CHECK_(test != nullptr);
return it->second; return CodeLocation(test->file, test->line);
} }
// Verifies that registered_tests match the test names in // Verifies that registered_tests match the test names in
// defined_test_names_; returns registered_tests if successful, or // registered_tests_; returns registered_tests if successful, or
// aborts the program otherwise. // aborts the program otherwise.
const char* VerifyRegisteredTestNames(const char* test_suite_name, const char* VerifyRegisteredTestNames(const char* test_suite_name,
const char* file, int line, const char* file, int line,
const char* registered_tests); const char* registered_tests);
private: private:
typedef ::std::map<std::string, CodeLocation, std::less<>> RegisteredTestsMap; const RegisteredTest* FindTest(const std::string& test_name) const {
for (const RegisteredTest* it = registered_tests_; it != nullptr;
it = it->next) {
if (test_name == it->name) {
return it;
}
}
return nullptr;
}
bool registered_; bool registered_ = false;
RegisteredTestsMap registered_tests_; RegisteredTest* registered_tests_ = nullptr;
}; };
static_assert((static_cast<void>(TypedTestSuitePState{}), true),
"TypedTestSuitePState must be constexpr-constructible");
static_assert(std::is_trivially_destructible_v<TypedTestSuitePState>,
"TypedTestSuitePState must be trivially destructible");
// Legacy API is deprecated but still available // Legacy API is deprecated but still available
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_ #ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
using TypedTestCasePState = TypedTestSuitePState; using TypedTestCasePState = TypedTestSuitePState;
@ -1516,8 +1552,9 @@ class [[nodiscard]] NeverThrown {
parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__), \ parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__), \
::testing::internal::SuiteApiResolver< \ ::testing::internal::SuiteApiResolver< \
parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__), \ parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__), \
new ::testing::internal::TestFactoryImpl<GTEST_TEST_CLASS_NAME_( \ ::std::make_unique<::testing::internal::TestFactoryImpl< \
test_suite_name, test_name)>); \ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)>>() \
.release()); \
void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody() void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_

View File

@ -601,7 +601,7 @@ class [[nodiscard]] ParameterizedTestSuiteInfo
MakeAndRegisterTestInfo( MakeAndRegisterTestInfo(
test_suite_name, test_name.c_str(), test_suite_name, test_name.c_str(),
nullptr, // No type parameter. /*type_param=*/nullptr, // No type parameter.
PrintToString(param).c_str(), test_info->code_location, PrintToString(param).c_str(), test_info->code_location,
GetTestSuiteTypeId(), GetTestSuiteTypeId(),
SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line), SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),

View File

@ -176,7 +176,7 @@
// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with // GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with
// GTEST_HAS_POSIX_RE (see above) which users can // GTEST_HAS_POSIX_RE (see above) which users can
// define themselves. // define themselves.
// GTEST_USES_SIMPLE_RE - our own simple regex is used; // GTEST_USES_STD_RE - std::regex from the C++ standard library is used;
// the above RE\b(s) are mutually exclusive. // the above RE\b(s) are mutually exclusive.
// GTEST_HAS_ABSL - Google Test is compiled with Abseil. // GTEST_HAS_ABSL - Google Test is compiled with Abseil.
@ -236,7 +236,6 @@
// Integer types: // Integer types:
// TypeWithSize - maps an integer to a int type. // TypeWithSize - maps an integer to a int type.
// TimeInMillis - integers of known sizes. // TimeInMillis - integers of known sizes.
// BiggestInt - the biggest signed integer type.
// //
// Command-line utilities: // Command-line utilities:
// GetInjectableArgvs() - returns the command line as a vector of strings. // GetInjectableArgvs() - returns the command line as a vector of strings.
@ -342,13 +341,6 @@
#define GTEST_INIT_GOOGLE_TEST_NAME_ "testing::InitGoogleTest" #define GTEST_INIT_GOOGLE_TEST_NAME_ "testing::InitGoogleTest"
#endif // !defined(GTEST_INIT_GOOGLE_TEST_NAME_) #endif // !defined(GTEST_INIT_GOOGLE_TEST_NAME_)
// Determines the version of gcc that is used to compile this.
#ifdef __GNUC__
// 40302 means version 4.3.2.
#define GTEST_GCC_VER_ \
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif // __GNUC__
// Macros for disabling Microsoft Visual C++ warnings. // Macros for disabling Microsoft Visual C++ warnings.
// //
// GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 4385) // GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 4385)
@ -446,8 +438,9 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#include <regex.h> // NOLINT #include <regex.h> // NOLINT
#define GTEST_USES_POSIX_RE 1 #define GTEST_USES_POSIX_RE 1
#else #else
// Use our own simple regex implementation. // Use std::regex from the C++ standard library.
#define GTEST_USES_SIMPLE_RE 1 #include <regex> // NOLINT
#define GTEST_USES_STD_RE 1
#endif #endif
#ifndef GTEST_HAS_EXCEPTIONS #ifndef GTEST_HAS_EXCEPTIONS
@ -456,14 +449,6 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#if defined(_MSC_VER) && defined(_CPPUNWIND) #if defined(_MSC_VER) && defined(_CPPUNWIND)
// MSVC defines _CPPUNWIND to 1 if and only if exceptions are enabled. // MSVC defines _CPPUNWIND to 1 if and only if exceptions are enabled.
#define GTEST_HAS_EXCEPTIONS 1 #define GTEST_HAS_EXCEPTIONS 1
#elif defined(__BORLANDC__)
// C++Builder's implementation of the STL uses the _HAS_EXCEPTIONS
// macro to enable exceptions, so we'll do the same.
// Assumes that exceptions are enabled by default.
#ifndef _HAS_EXCEPTIONS
#define _HAS_EXCEPTIONS 1
#endif // _HAS_EXCEPTIONS
#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS
#elif defined(__clang__) #elif defined(__clang__)
// clang defines __EXCEPTIONS if and only if exceptions are enabled before clang // clang defines __EXCEPTIONS if and only if exceptions are enabled before clang
// 220714, but if and only if cleanups are enabled after that. In Obj-C++ files, // 220714, but if and only if cleanups are enabled after that. In Obj-C++ files,
@ -481,41 +466,89 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#elif defined(__GNUC__) && defined(__EXCEPTIONS) && __EXCEPTIONS #elif defined(__GNUC__) && defined(__EXCEPTIONS) && __EXCEPTIONS
// gcc defines __EXCEPTIONS to 1 if and only if exceptions are enabled. // gcc defines __EXCEPTIONS to 1 if and only if exceptions are enabled.
#define GTEST_HAS_EXCEPTIONS 1 #define GTEST_HAS_EXCEPTIONS 1
#elif defined(__SUNPRO_CC)
// Sun Pro CC supports exceptions. However, there is no compile-time way of
// detecting whether they are enabled or not. Therefore, we assume that
// they are enabled unless the user tells us otherwise.
#define GTEST_HAS_EXCEPTIONS 1
#elif defined(__IBMCPP__) && defined(__EXCEPTIONS) && __EXCEPTIONS
// xlC defines __EXCEPTIONS to 1 if and only if exceptions are enabled.
#define GTEST_HAS_EXCEPTIONS 1
#elif defined(__HP_aCC)
// Exception handling is in effect by default in HP aCC compiler. It has to
// be turned of by +noeh compiler option if desired.
#define GTEST_HAS_EXCEPTIONS 1
#else #else
// For other compilers, we assume exceptions are disabled to be // For other compilers, we assume exceptions are disabled to be
// conservative. // conservative.
#define GTEST_HAS_EXCEPTIONS 0 #define GTEST_HAS_EXCEPTIONS 0
#endif // defined(_MSC_VER) || defined(__BORLANDC__) #endif // defined(_MSC_VER) && defined(_CPPUNWIND)
#endif // GTEST_HAS_EXCEPTIONS #endif // GTEST_HAS_EXCEPTIONS
#ifndef GTEST_HAS_STD_WSTRING // MSVC either defines wchar_t as a typedef of unsigned short, or as a native
// The user didn't tell us whether ::std::wstring is available, so we need // type (in which case, it defines _NATIVE_WCHAR_T_DEFINED). When wchar_t is a
// to figure it out. // typedef, defining an overload for const wchar_t* would cause unsigned short*
// Cygwin 1.7 and below doesn't support ::std::wstring. // be printed as a wide string, possibly causing invalid memory accesses, so we
// Solaris' libc++ doesn't support it either. Android has // omit wchar_t overloads in that case.
// no support for it at least as recent as Froyo (2.2). #if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED)
#if (!(defined(GTEST_OS_LINUX_ANDROID) || defined(GTEST_OS_CYGWIN) || \ #define GTEST_HAS_NATIVE_WCHAR 0
defined(GTEST_OS_SOLARIS) || defined(GTEST_OS_HAIKU) || \
defined(GTEST_OS_ESP32) || defined(GTEST_OS_ESP8266) || \
defined(GTEST_OS_XTENSA) || defined(GTEST_OS_QURT) || \
defined(GTEST_OS_NXP_QN9090) || defined(GTEST_OS_NRF52)))
#define GTEST_HAS_STD_WSTRING 1
#else #else
#define GTEST_HAS_STD_WSTRING 0 #define GTEST_HAS_NATIVE_WCHAR 1
#endif
// 1. Calculate default GTEST_HAS_STD_WSTRING values based on STL capabilities.
#if defined(_MSVC_STL_VERSION)
// Microsoft's STL implementation always supports ::std::wstring.
#define GTEST_HAS_STD_WSTRING_DEFAULT 1
#elif defined(_LIBCPP_VERSION)
// Modern libc++ always defines _LIBCPP_HAS_WIDE_CHARACTERS; its value
// determines whether wide characters are supported.
// Older libc++ omits a definition for _LIBCPP_HAS_NO_WIDE_CHARACTERS when wide
// characters are supported.
#if (defined(_LIBCPP_HAS_WIDE_CHARACTERS) && !_LIBCPP_HAS_WIDE_CHARACTERS) || \
defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
#define GTEST_HAS_STD_WSTRING_DEFAULT 0
#else
#define GTEST_HAS_STD_WSTRING_DEFAULT 1
#endif
#elif defined(__GLIBCXX__)
#if defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_WCHAR_T
#define GTEST_HAS_STD_WSTRING_DEFAULT 1
#else
#define GTEST_HAS_STD_WSTRING_DEFAULT 0
#endif
#else
// Unknown standard library implementation; fall back looking at the OS.
//
// Always let the user override the defaults in this case; they might have more
// information about what's supported than we do.
#if defined(GTEST_OS_LINUX_ANDROID)
// Android started supporting std::wstring with API Level 21 (Lollipop).
#define GTEST_HAS_STD_WSTRING_DEFAULT (__ANDROID_API__ >= 21)
// The following platforms are known not to support ::std::wstring; assume it's
// supported on all others.
//
// Cygwin 1.7 and below doesn't support ::std::wstring.
// Solaris' libc++ doesn't support it either.
#elif defined(GTEST_OS_CYGWIN) || defined(GTEST_OS_SOLARIS) || \
defined(GTEST_OS_HAIKU) || defined(GTEST_OS_ESP32) || \
defined(GTEST_OS_ESP8266) || defined(GTEST_OS_XTENSA) || \
defined(GTEST_OS_QURT) || defined(GTEST_OS_NXP_QN9090) || \
defined(GTEST_OS_NRF52)
#define GTEST_HAS_STD_WSTRING_DEFAULT 0
#else
#define GTEST_HAS_STD_WSTRING_DEFAULT 1
#endif
#endif
// 2. Validate explicit user overrides (if user passed -DGTEST_HAS_*=1) against
// what the standard library implementation tells us it supports.
#if defined(GTEST_HAS_STD_WSTRING) && GTEST_HAS_STD_WSTRING
#if defined(_LIBCPP_VERSION) && \
((defined(_LIBCPP_HAS_WIDE_CHARACTERS) && !_LIBCPP_HAS_WIDE_CHARACTERS) || \
defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS))
#error Cannot explicitly enable GTEST_HAS_STD_WSTRING without libc++ wide character support.
#elif defined(__GLIBCXX__) && \
!(defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_WCHAR_T)
#error Cannot explicitly enable GTEST_HAS_STD_WSTRING without libstdc++ wide character support.
#endif
#endif
// 3. Set final values if not explicitly overridden by user
#if !defined(GTEST_HAS_STD_WSTRING)
#define GTEST_HAS_STD_WSTRING GTEST_HAS_STD_WSTRING_DEFAULT
#endif #endif
#endif // GTEST_HAS_STD_WSTRING
#ifndef GTEST_HAS_FILE_SYSTEM #ifndef GTEST_HAS_FILE_SYSTEM
// Most platforms support a file system. // Most platforms support a file system.
@ -561,16 +594,6 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#define GTEST_HAS_RTTI __has_feature(cxx_rtti) #define GTEST_HAS_RTTI __has_feature(cxx_rtti)
// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if
// both the typeid and dynamic_cast features are present.
#elif defined(__IBMCPP__) && (__IBMCPP__ >= 900)
#ifdef __RTTI_ALL__
#define GTEST_HAS_RTTI 1
#else
#define GTEST_HAS_RTTI 0
#endif
#else #else
// For all other compilers, we assume RTTI is enabled. // For all other compilers, we assume RTTI is enabled.
@ -692,8 +715,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0, // Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0,
// Sun Pro CC, IBM Visual Age, and HP aCC support. // Sun Pro CC, IBM Visual Age, and HP aCC support.
#if defined(__GNUC__) || defined(_MSC_VER) || defined(__SUNPRO_CC) || \ #if defined(__GNUC__) || defined(_MSC_VER)
defined(__IBMCPP__) || defined(__HP_aCC)
#define GTEST_HAS_TYPED_TEST 1 #define GTEST_HAS_TYPED_TEST 1
#define GTEST_HAS_TYPED_TEST_P 1 #define GTEST_HAS_TYPED_TEST_P 1
#endif #endif
@ -807,8 +829,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
#ifndef GTEST_HAS_SEH #ifndef GTEST_HAS_SEH
// The user didn't tell us, so we need to figure it out. // The user didn't tell us, so we need to figure it out.
#if defined(_MSC_VER) || defined(__BORLANDC__) #ifdef _MSC_VER
// These two compilers are known to support SEH.
#define GTEST_HAS_SEH 1 #define GTEST_HAS_SEH 1
#else #else
// Assume no SEH. // Assume no SEH.
@ -972,12 +993,11 @@ class GTEST_API_ [[nodiscard]] RE {
RE2 regex_; RE2 regex_;
}; };
#elif defined(GTEST_USES_POSIX_RE) || defined(GTEST_USES_SIMPLE_RE) #elif defined(GTEST_USES_POSIX_RE) || defined(GTEST_USES_STD_RE)
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
/* class A needs to have dll-interface to be used by clients of class B */) /* class A needs to have dll-interface to be used by clients of class B */)
// A simple C++ wrapper for <regex.h>. It uses the POSIX Extended // A simple C++ wrapper for <regex.h> or <regex>.
// Regular Expression syntax.
class GTEST_API_ [[nodiscard]] RE { class GTEST_API_ [[nodiscard]] RE {
public: public:
// A copy constructor is required by the Standard to initialize object // A copy constructor is required by the Standard to initialize object
@ -1017,9 +1037,9 @@ class GTEST_API_ [[nodiscard]] RE {
regex_t full_regex_; // For FullMatch(). regex_t full_regex_; // For FullMatch().
regex_t partial_regex_; // For PartialMatch(). regex_t partial_regex_; // For PartialMatch().
#else // GTEST_USES_SIMPLE_RE #else // GTEST_USES_STD_RE
std::string full_pattern_; // For FullMatch(); std::regex regex_;
#endif #endif
}; };
@ -1735,14 +1755,16 @@ class [[nodiscard]] MutexBase {
#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ #define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
extern ::testing::internal::MutexBase mutex extern ::testing::internal::MutexBase mutex
#if defined(PTHREAD_NULL)
#define GTEST_INTERNAL_PTHREAD_NULL PTHREAD_NULL
#else
#define GTEST_INTERNAL_PTHREAD_NULL (pthread_t{})
#endif
// Defines and statically (i.e. at link time) initializes a static mutex. // Defines and statically (i.e. at link time) initializes a static mutex.
// The initialization list here does not explicitly initialize each field,
// instead relying on default initialization for the unspecified fields. In
// particular, the owner_ field (a pthread_t) is not explicitly initialized.
// This allows initialization to work whether pthread_t is a scalar or struct.
// The flag -Wmissing-field-initializers must not be specified for this to work.
#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ #define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
::testing::internal::MutexBase mutex = {PTHREAD_MUTEX_INITIALIZER, false, 0} ::testing::internal::MutexBase mutex = {PTHREAD_MUTEX_INITIALIZER, false, \
GTEST_INTERNAL_PTHREAD_NULL}
// The Mutex class can only be used for mutexes created at runtime. It // The Mutex class can only be used for mutexes created at runtime. It
// shares its API with MutexBase otherwise. // shares its API with MutexBase otherwise.
@ -2086,12 +2108,6 @@ inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); }
#ifdef GTEST_OS_WINDOWS #ifdef GTEST_OS_WINDOWS
#ifdef __BORLANDC__
inline int DoIsATTY(int fd) { return isatty(fd); }
inline int StrCaseCmp(const char* s1, const char* s2) {
return stricmp(s1, s2);
}
#else // !__BORLANDC__
#if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_ZOS) || \ #if defined(GTEST_OS_WINDOWS_MOBILE) || defined(GTEST_OS_ZOS) || \
defined(GTEST_OS_IOS) || defined(GTEST_OS_WINDOWS_PHONE) || \ defined(GTEST_OS_IOS) || defined(GTEST_OS_WINDOWS_PHONE) || \
defined(GTEST_OS_WINDOWS_RT) || defined(ESP_PLATFORM) defined(GTEST_OS_WINDOWS_RT) || defined(ESP_PLATFORM)
@ -2102,7 +2118,6 @@ inline int DoIsATTY(int fd) { return _isatty(fd); }
inline int StrCaseCmp(const char* s1, const char* s2) { inline int StrCaseCmp(const char* s1, const char* s2) {
return _stricmp(s1, s2); return _stricmp(s1, s2);
} }
#endif // __BORLANDC__
#else #else
@ -2136,7 +2151,13 @@ GTEST_DISABLE_DEPRECATED_PUSH_()
!defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES) && \ !defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES) && \
!defined(GTEST_OS_ESP8266) && !defined(GTEST_OS_XTENSA) && \ !defined(GTEST_OS_ESP8266) && !defined(GTEST_OS_XTENSA) && \
!defined(GTEST_OS_QURT) !defined(GTEST_OS_QURT)
inline int ChDir(const char* dir) { return chdir(dir); } inline int ChDir(const char* dir) {
#ifdef GTEST_OS_WINDOWS
return _chdir(dir);
#else
return chdir(dir);
#endif
}
#endif #endif
inline FILE* FOpen(const char* path, const char* mode) { inline FILE* FOpen(const char* path, const char* mode) {
#if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MINGW) #if defined(GTEST_OS_WINDOWS) && !defined(GTEST_OS_WINDOWS_MINGW)
@ -2153,17 +2174,37 @@ inline FILE* FOpen(const char* path, const char* mode) {
inline FILE* FReopen(const char* path, const char* mode, FILE* stream) { inline FILE* FReopen(const char* path, const char* mode, FILE* stream) {
return freopen(path, mode, stream); return freopen(path, mode, stream);
} }
inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } inline FILE* FDOpen(int fd, const char* mode) {
#ifdef GTEST_OS_WINDOWS
return _fdopen(fd, mode);
#else
return fdopen(fd, mode);
#endif
}
#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT #endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT
inline int FClose(FILE* fp) { return fclose(fp); } inline int FClose(FILE* fp) { return fclose(fp); }
#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_QURT) #if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_QURT)
inline int Read(int fd, void* buf, unsigned int count) { inline int Read(int fd, void* buf, unsigned int count) {
#ifdef GTEST_OS_WINDOWS
return static_cast<int>(_read(fd, buf, count));
#else
return static_cast<int>(read(fd, buf, count)); return static_cast<int>(read(fd, buf, count));
#endif
} }
inline int Write(int fd, const void* buf, unsigned int count) { inline int Write(int fd, const void* buf, unsigned int count) {
#ifdef GTEST_OS_WINDOWS
return static_cast<int>(_write(fd, buf, count));
#else
return static_cast<int>(write(fd, buf, count)); return static_cast<int>(write(fd, buf, count));
#endif
}
inline int Close(int fd) {
#ifdef GTEST_OS_WINDOWS
return _close(fd);
#else
return close(fd);
#endif
} }
inline int Close(int fd) { return close(fd); }
#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT #endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT
#endif // GTEST_HAS_FILE_SYSTEM #endif // GTEST_HAS_FILE_SYSTEM
@ -2178,11 +2219,6 @@ inline const char* GetEnv(const char* name) {
// We are on an embedded platform, which has no environment variables. // We are on an embedded platform, which has no environment variables.
static_cast<void>(name); // To prevent 'unused argument' warning. static_cast<void>(name); // To prevent 'unused argument' warning.
return nullptr; return nullptr;
#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
// Environment variables which we programmatically clear will be set to the
// empty string rather than unset (NULL). Handle that case.
const char* const env = getenv(name);
return (env != nullptr && env[0] != '\0') ? env : nullptr;
#else #else
return getenv(name); return getenv(name);
#endif #endif
@ -2217,14 +2253,6 @@ GTEST_DISABLE_DEPRECATED_POP_()
#define GTEST_SNPRINTF_ snprintf #define GTEST_SNPRINTF_ snprintf
#endif #endif
// The biggest signed integer type the compiler supports.
//
// long long is guaranteed to be at least 64-bits in C++11.
using BiggestInt = long long; // NOLINT
// The maximum number a BiggestInt can represent.
constexpr BiggestInt kMaxBiggestInt = (std::numeric_limits<BiggestInt>::max)();
// This template class serves as a compile-time function from size to // This template class serves as a compile-time function from size to
// type. It maps a size in bytes to a primitive type with that // type. It maps a size in bytes to a primitive type with that
// size. e.g. // size. e.g.

View File

@ -43,11 +43,6 @@
#ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_
#ifdef __BORLANDC__
// string.h is not guaranteed to provide strcpy on C++ Builder.
#include <mem.h>
#endif
#include <string.h> #include <string.h>
#include <cstdint> #include <cstdint>

View File

@ -47,8 +47,6 @@
// libstdc++ (which is where cxxabi.h comes from). // libstdc++ (which is where cxxabi.h comes from).
#if GTEST_HAS_CXXABI_H_ #if GTEST_HAS_CXXABI_H_
#include <cxxabi.h> #include <cxxabi.h>
#elif defined(__HP_aCC)
#include <acxx_demangle.h>
#endif // GTEST_HASH_CXXABI_H_ #endif // GTEST_HASH_CXXABI_H_
namespace testing { namespace testing {
@ -90,13 +88,11 @@ inline std::string CanonicalizeForStdLibVersioning(std::string s) {
// GetTypeName(const std::type_info&) returns a human-readable name of type T. // GetTypeName(const std::type_info&) returns a human-readable name of type T.
inline std::string GetTypeName(const std::type_info& type) { inline std::string GetTypeName(const std::type_info& type) {
const char* const name = type.name(); const char* const name = type.name();
#if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) #if GTEST_HAS_CXXABI_H_
int status = 0; int status = 0;
// gcc's implementation of typeid(T).name() mangles the type name, // gcc's implementation of typeid(T).name() mangles the type name,
// so we have to demangle it. // so we have to demangle it.
#if GTEST_HAS_CXXABI_H_
using abi::__cxa_demangle; using abi::__cxa_demangle;
#endif // GTEST_HAS_CXXABI_H_
char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status); char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status);
const std::string name_str(status == 0 ? readable_name : name); const std::string name_str(status == 0 ? readable_name : name);
free(readable_name); free(readable_name);
@ -117,7 +113,7 @@ inline std::string GetTypeName(const std::type_info& type) {
return s; return s;
#else #else
return name; return name;
#endif // GTEST_HAS_CXXABI_H_ || __HP_aCC #endif // GTEST_HAS_CXXABI_H_
} }
#endif // GTEST_HAS_RTTI #endif // GTEST_HAS_RTTI

View File

@ -325,7 +325,7 @@ FilePath FilePath::GenerateUniqueFileName(const FilePath& directory,
// This does NOT check that a directory (or file) actually exists. // This does NOT check that a directory (or file) actually exists.
bool FilePath::IsDirectory() const { bool FilePath::IsDirectory() const {
return !pathname_.empty() && return !pathname_.empty() &&
IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); IsPathSeparator(pathname_[pathname_.length() - 1]);
} }
// Create directories so that path exists. Returns true if successful or if // Create directories so that path exists. Returns true if successful or if

View File

@ -980,26 +980,7 @@ inline UnitTestImpl* GetUnitTestImpl() {
return UnitTest::GetInstance()->impl(); return UnitTest::GetInstance()->impl();
} }
#ifdef GTEST_USES_SIMPLE_RE
// Internal helper functions for implementing the simple regular
// expression matcher.
GTEST_API_ bool IsInSet(char ch, const char* str);
GTEST_API_ bool IsAsciiDigit(char ch);
GTEST_API_ bool IsAsciiPunct(char ch);
GTEST_API_ bool IsRepeat(char ch);
GTEST_API_ bool IsAsciiWhiteSpace(char ch);
GTEST_API_ bool IsAsciiWordChar(char ch);
GTEST_API_ bool IsValidEscape(char ch);
GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch);
GTEST_API_ bool ValidateRegex(const char* regex);
GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str);
GTEST_API_ bool MatchRepetitionAndRegexAtHead(bool escaped, char ch,
char repeat, const char* regex,
const char* str);
GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str);
#endif // GTEST_USES_SIMPLE_RE
// Parses the command line for Google Test flags, without initializing // Parses the command line for Google Test flags, without initializing
// other parts of Google Test. // other parts of Google Test.

View File

@ -766,249 +766,46 @@ void RE::Init(const char* regex) {
delete[] full_pattern; delete[] full_pattern;
} }
#elif defined(GTEST_USES_SIMPLE_RE) #elif defined(GTEST_USES_STD_RE)
// Returns true if and only if ch appears anywhere in str (excluding the
// terminating '\0' character).
bool IsInSet(char ch, const char* str) {
return ch != '\0' && strchr(str, ch) != nullptr;
}
// Returns true if and only if ch belongs to the given classification.
// Unlike similar functions in <ctype.h>, these aren't affected by the
// current locale.
bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; }
bool IsAsciiPunct(char ch) {
return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~");
}
bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); }
bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); }
bool IsAsciiWordChar(char ch) {
return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||
('0' <= ch && ch <= '9') || ch == '_';
}
// Returns true if and only if "\\c" is a supported escape sequence.
bool IsValidEscape(char c) {
return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW"));
}
// Returns true if and only if the given atom (specified by escaped and
// pattern) matches ch. The result is undefined if the atom is invalid.
bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
if (escaped) { // "\\p" where p is pattern_char.
switch (pattern_char) {
case 'd':
return IsAsciiDigit(ch);
case 'D':
return !IsAsciiDigit(ch);
case 'f':
return ch == '\f';
case 'n':
return ch == '\n';
case 'r':
return ch == '\r';
case 's':
return IsAsciiWhiteSpace(ch);
case 'S':
return !IsAsciiWhiteSpace(ch);
case 't':
return ch == '\t';
case 'v':
return ch == '\v';
case 'w':
return IsAsciiWordChar(ch);
case 'W':
return !IsAsciiWordChar(ch);
}
return IsAsciiPunct(pattern_char) && pattern_char == ch;
}
return (pattern_char == '.' && ch != '\n') || pattern_char == ch;
}
// Helper function used by ValidateRegex() to format error messages.
static std::string FormatRegexSyntaxError(const char* regex, int index) {
return (Message() << "Syntax error at index " << index
<< " in simple regular expression \"" << regex << "\": ")
.GetString();
}
// Generates non-fatal failures and returns false if regex is invalid;
// otherwise returns true.
bool ValidateRegex(const char* regex) {
if (regex == nullptr) {
ADD_FAILURE() << "NULL is not a valid simple regular expression.";
return false;
}
bool is_valid = true;
// True if and only if ?, *, or + can follow the previous atom.
bool prev_repeatable = false;
for (int i = 0; regex[i]; i++) {
if (regex[i] == '\\') { // An escape sequence
i++;
if (regex[i] == '\0') {
ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
<< "'\\' cannot appear at the end.";
return false;
}
if (!IsValidEscape(regex[i])) {
ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
<< "invalid escape sequence \"\\" << regex[i] << "\".";
is_valid = false;
}
prev_repeatable = true;
} else { // Not an escape sequence.
const char ch = regex[i];
if (ch == '^' && i > 0) {
ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
<< "'^' can only appear at the beginning.";
is_valid = false;
} else if (ch == '$' && regex[i + 1] != '\0') {
ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
<< "'$' can only appear at the end.";
is_valid = false;
} else if (IsInSet(ch, "()[]{}|")) {
ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch
<< "' is unsupported.";
is_valid = false;
} else if (IsRepeat(ch) && !prev_repeatable) {
ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch
<< "' can only follow a repeatable token.";
is_valid = false;
}
prev_repeatable = !IsInSet(ch, "^$?*+");
}
}
return is_valid;
}
// Matches a repeated regex atom followed by a valid simple regular
// expression. The regex atom is defined as c if escaped is false,
// or \c otherwise. repeat is the repetition meta character (?, *,
// or +). The behavior is undefined if str contains too many
// characters to be indexable by size_t, in which case the test will
// probably time out anyway. We are fine with this limitation as
// std::string has it too.
bool MatchRepetitionAndRegexAtHead(bool escaped, char c, char repeat,
const char* regex, const char* str) {
const size_t min_count = (repeat == '+') ? 1 : 0;
const size_t max_count = (repeat == '?') ? 1 : static_cast<size_t>(-1) - 1;
// We cannot call numeric_limits::max() as it conflicts with the
// max() macro on Windows.
for (size_t i = 0; i <= max_count; ++i) {
// We know that the atom matches each of the first i characters in str.
if (i >= min_count && MatchRegexAtHead(regex, str + i)) {
// We have enough matches at the head, and the tail matches too.
// Since we only care about *whether* the pattern matches str
// (as opposed to *how* it matches), there is no need to find a
// greedy match.
return true;
}
if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) return false;
}
return false;
}
// Returns true if and only if regex matches a prefix of str. regex must
// be a valid simple regular expression and not start with "^", or the
// result is undefined.
bool MatchRegexAtHead(const char* regex, const char* str) {
if (*regex == '\0') // An empty regex matches a prefix of anything.
return true;
// "$" only matches the end of a string. Note that regex being
// valid guarantees that there's nothing after "$" in it.
if (*regex == '$') return *str == '\0';
// Is the first thing in regex an escape sequence?
const bool escaped = *regex == '\\';
if (escaped) ++regex;
if (IsRepeat(regex[1])) {
// MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so
// here's an indirect recursion. It terminates as the regex gets
// shorter in each recursion.
return MatchRepetitionAndRegexAtHead(escaped, regex[0], regex[1], regex + 2,
str);
} else {
// regex isn't empty, isn't "$", and doesn't start with a
// repetition. We match the first atom of regex with the first
// character of str and recurse.
return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) &&
MatchRegexAtHead(regex + 1, str + 1);
}
}
// Returns true if and only if regex matches any substring of str. regex must
// be a valid simple regular expression, or the result is undefined.
//
// The algorithm is recursive, but the recursion depth doesn't exceed
// the regex length, so we won't need to worry about running out of
// stack space normally. In rare cases the time complexity can be
// exponential with respect to the regex length + the string length,
// but usually it's must faster (often close to linear).
bool MatchRegexAnywhere(const char* regex, const char* str) {
if (regex == nullptr || str == nullptr) return false;
if (*regex == '^') return MatchRegexAtHead(regex + 1, str);
// A successful match can be anywhere in str.
do {
if (MatchRegexAtHead(regex, str)) return true;
} while (*str++ != '\0');
return false;
}
// Implements the RE class.
RE::~RE() = default; RE::~RE() = default;
// Returns true if and only if regular expression re matches the entire str. // Returns true if and only if regular expression re matches the entire str.
bool RE::FullMatch(const char* str, const RE& re) { bool RE::FullMatch(const char* str, const RE& re) {
return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_.c_str(), str); if (!re.is_valid_ || str == nullptr) return false;
return std::regex_match(str, re.regex_);
} }
// Returns true if and only if regular expression re matches a substring of // Returns true if and only if regular expression re matches a substring of
// str (including str itself). // str (including str itself).
bool RE::PartialMatch(const char* str, const RE& re) { bool RE::PartialMatch(const char* str, const RE& re) {
return re.is_valid_ && MatchRegexAnywhere(re.pattern_.c_str(), str); if (!re.is_valid_ || str == nullptr) return false;
return std::regex_search(str, re.regex_);
} }
// Initializes an RE from its string representation. // Initializes an RE from its string representation.
void RE::Init(const char* regex) { void RE::Init(const char* regex) {
full_pattern_.clear(); pattern_ = regex == nullptr ? "" : regex;
pattern_.clear(); is_valid_ = false;
if (regex != nullptr) { if (regex == nullptr) {
pattern_ = regex; ADD_FAILURE() << "NULL is not a valid regular expression.";
}
is_valid_ = ValidateRegex(regex);
if (!is_valid_) {
// No need to calculate the full pattern when the regex is invalid.
return; return;
} }
// Reserves enough bytes to hold the regular expression used for a #if GTEST_HAS_EXCEPTIONS
// full match: we need space to prepend a '^' and append a '$'. try {
full_pattern_.reserve(pattern_.size() + 2); regex_ = std::regex(regex, std::regex_constants::ECMAScript);
} catch (const std::regex_error& e) {
if (pattern_.empty() || pattern_.front() != '^') { ADD_FAILURE() << "Regular expression \"" << regex
full_pattern_.push_back('^'); // Makes sure full_pattern_ starts with '^'. << "\" is not a valid regular expression: " << e.what();
return;
} }
#else
regex_ = std::regex(regex, std::regex_constants::ECMAScript);
#endif
full_pattern_.append(pattern_); is_valid_ = true;
if (pattern_.empty() || pattern_.back() != '$') {
full_pattern_.push_back('$'); // Makes sure full_pattern_ ends with '$'.
}
} }
#endif // GTEST_USES_POSIX_RE #endif // GTEST_USES_POSIX_RE
@ -1085,7 +882,14 @@ bool EndsWithPathSeparator(const std::string& path) {
class CapturedStream { class CapturedStream {
public: public:
// The ctor redirects the stream to a temporary file. // The ctor redirects the stream to a temporary file.
explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { explicit CapturedStream(int fd)
: fd_(fd),
#ifdef GTEST_OS_WINDOWS
uncaptured_fd_(_dup(fd))
#else
uncaptured_fd_(dup(fd))
#endif
{
#ifdef GTEST_OS_WINDOWS #ifdef GTEST_OS_WINDOWS
char temp_dir_path[MAX_PATH + 1] = {'\0'}; // NOLINT char temp_dir_path[MAX_PATH + 1] = {'\0'}; // NOLINT
char temp_file_path[MAX_PATH + 1] = {'\0'}; // NOLINT char temp_file_path[MAX_PATH + 1] = {'\0'}; // NOLINT
@ -1097,7 +901,7 @@ class CapturedStream {
GTEST_CHECK_(success != 0) GTEST_CHECK_(success != 0)
<< "Failed to create temporary file in " << temp_dir_path << "Failed to create temporary file in " << temp_dir_path
<< " with error " << ::GetLastError(); << " with error " << ::GetLastError();
const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); const int captured_fd = _creat(temp_file_path, _S_IREAD | _S_IWRITE);
GTEST_CHECK_(captured_fd != -1) GTEST_CHECK_(captured_fd != -1)
<< "Failed to open temporary file " << temp_file_path << " with error " << "Failed to open temporary file " << temp_file_path << " with error "
<< ::GetLastError(); << ::GetLastError();
@ -1167,8 +971,12 @@ class CapturedStream {
filename_ = std::move(name_template); filename_ = std::move(name_template);
#endif // GTEST_OS_WINDOWS #endif // GTEST_OS_WINDOWS
fflush(nullptr); fflush(nullptr);
#ifdef GTEST_OS_WINDOWS
_dup2(captured_fd, fd_);
#else
dup2(captured_fd, fd_); dup2(captured_fd, fd_);
close(captured_fd); #endif
posix::Close(captured_fd);
} }
~CapturedStream() { remove(filename_.c_str()); } ~CapturedStream() { remove(filename_.c_str()); }
@ -1177,8 +985,12 @@ class CapturedStream {
if (uncaptured_fd_ != -1) { if (uncaptured_fd_ != -1) {
// Restores the original stream. // Restores the original stream.
fflush(nullptr); fflush(nullptr);
#ifdef GTEST_OS_WINDOWS
_dup2(uncaptured_fd_, fd_);
#else
dup2(uncaptured_fd_, fd_); dup2(uncaptured_fd_, fd_);
close(uncaptured_fd_); #endif
posix::Close(uncaptured_fd_);
uncaptured_fd_ = -1; uncaptured_fd_ = -1;
} }
@ -1227,14 +1039,14 @@ static std::string GetCapturedStream(CapturedStream** captured_stream) {
return content; return content;
} }
#if defined(_MSC_VER) || defined(__BORLANDC__) #if defined(_MSC_VER)
// MSVC and C++Builder do not provide a definition of STDERR_FILENO. // MSVC does not provide a definition of STDERR_FILENO.
const int kStdOutFileno = 1; const int kStdOutFileno = 1;
const int kStdErrFileno = 2; const int kStdErrFileno = 2;
#else #else
const int kStdOutFileno = STDOUT_FILENO; const int kStdOutFileno = STDOUT_FILENO;
const int kStdErrFileno = STDERR_FILENO; const int kStdErrFileno = STDERR_FILENO;
#endif // defined(_MSC_VER) || defined(__BORLANDC__) #endif // defined(_MSC_VER)
// Starts capturing stdout. // Starts capturing stdout.
void CaptureStdout() { void CaptureStdout() {
@ -1331,7 +1143,7 @@ static std::string FlagToEnvVar(const char* flag) {
Message env_var; Message env_var;
for (size_t i = 0; i != full_flag.length(); i++) { for (size_t i = 0; i != full_flag.length(); i++) {
env_var << ToUpper(full_flag.c_str()[i]); env_var << ToUpper(full_flag[i]);
} }
return env_var.GetString(); return env_var.GetString();

View File

@ -50,6 +50,7 @@
#include <iomanip> #include <iomanip>
#include <ios> #include <ios>
#include <ostream> // NOLINT #include <ostream> // NOLINT
#include <string>
#include <string_view> #include <string_view>
#include <type_traits> #include <type_traits>
@ -285,6 +286,28 @@ void PrintTo(char32_t c, ::std::ostream* os) {
<< static_cast<uint32_t>(c); << static_cast<uint32_t>(c);
} }
// char8_t and char16_t hold code units, not code points, so the U+XXXX
// notation only applies to the values that encode a code point on their own.
// The rest -- non-ASCII char8_t, which are always part of a multi-unit UTF-8
// sequence, and the UTF-16 surrogates -- are printed as code units.
void PrintTo(char16_t c, ::std::ostream* os) {
if (c >= 0xD800 && c <= 0xDFFF) {
PrintCharAndCodeTo(c, os);
} else {
PrintTo(static_cast<char32_t>(c), os);
}
}
#ifdef __cpp_lib_char8_t
void PrintTo(char8_t c, ::std::ostream* os) {
if (c >= 0x80) {
PrintCharAndCodeTo(c, os);
} else {
PrintTo(static_cast<char32_t>(c), os);
}
}
#endif
// gcc/clang __{u,}int128_t // gcc/clang __{u,}int128_t
#if defined(__SIZEOF_INT128__) #if defined(__SIZEOF_INT128__)
void PrintTo(__uint128_t v, ::std::ostream* os) { void PrintTo(__uint128_t v, ::std::ostream* os) {
@ -422,6 +445,28 @@ void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {
namespace { namespace {
template <typename Char>
size_t GetLength(const Char* s) {
return std::char_traits<Char>::length(s);
}
#if !GTEST_HAS_STD_WSTRING
// If GTEST_HAS_STD_WSTRING is unset because the standard library has disabled
// wide character support, std::char_traits<wchar_t> won't be defined, which
// will cause a compile error, even if user code never actually could print a
// wide cstring. In that case, instead use `wcslen` directly.
//
// If `libc` _also_ lacks wide character support, this (and a bunch of other
// calls to wc functions) will fail to link, but only if user code actually
// uses them.
template <>
size_t GetLength<wchar_t>(const wchar_t* s) {
return wcslen(s);
}
#endif // GTEST_HAS_STD_WSTRING
// Prints a null-terminated C-style string to the ostream. // Prints a null-terminated C-style string to the ostream.
template <typename Char> template <typename Char>
void PrintCStringTo(const Char* s, ostream* os) { void PrintCStringTo(const Char* s, ostream* os) {
@ -429,7 +474,7 @@ void PrintCStringTo(const Char* s, ostream* os) {
*os << "NULL"; *os << "NULL";
} else { } else {
*os << ImplicitCast_<const void*>(s) << " pointing to "; *os << ImplicitCast_<const void*>(s) << " pointing to ";
PrintCharsAsStringTo(s, std::char_traits<Char>::length(s), os); PrintCharsAsStringTo(s, GetLength(s), os);
} }
} }
@ -445,16 +490,9 @@ void PrintTo(const char16_t* s, ostream* os) { PrintCStringTo(s, os); }
void PrintTo(const char32_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 #if GTEST_HAS_STD_WSTRING && GTEST_HAS_NATIVE_WCHAR
// of unsigned short. Defining an overload for const wchar_t* in that case
// would cause pointers to unsigned shorts be printed as wide strings,
// possibly accessing more memory than intended and causing invalid
// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
// 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) { PrintCStringTo(s, os); } void PrintTo(const wchar_t* s, ostream* os) { PrintCStringTo(s, os); }
#endif // wchar_t is native #endif
namespace { namespace {

View File

@ -62,7 +62,6 @@ const char* TypedTestSuitePState::VerifyRegisteredTestNames(
const char* registered_tests) { const char* registered_tests) {
RegisterTypeParameterizedTestSuite(test_suite_name, CodeLocation(file, line)); RegisterTypeParameterizedTestSuite(test_suite_name, CodeLocation(file, line));
typedef RegisteredTestsMap::const_iterator RegisteredTestIter;
registered_ = true; registered_ = true;
std::vector<std::string> name_vec = SplitIntoTestNames(registered_tests); std::vector<std::string> name_vec = SplitIntoTestNames(registered_tests);
@ -78,7 +77,7 @@ const char* TypedTestSuitePState::VerifyRegisteredTestNames(
continue; continue;
} }
if (registered_tests_.count(name) != 0) { if (TestExists(name)) {
tests.insert(name); tests.insert(name);
} else { } else {
errors << "No test named " << name errors << "No test named " << name
@ -86,10 +85,10 @@ const char* TypedTestSuitePState::VerifyRegisteredTestNames(
} }
} }
for (RegisteredTestIter it = registered_tests_.begin(); for (const RegisteredTest* it = registered_tests_; it != nullptr;
it != registered_tests_.end(); ++it) { it = it->next) {
if (tests.count(it->first) == 0) { if (tests.count(it->name) == 0) {
errors << "You forgot to list test " << it->first << ".\n"; errors << "You forgot to list test " << it->name << ".\n";
} }
} }

View File

@ -1876,11 +1876,13 @@ bool IsSubstringPred(const char* needle, const char* haystack) {
return strstr(haystack, needle) != nullptr; return strstr(haystack, needle) != nullptr;
} }
#if GTEST_HAS_STD_WSTRING
bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) {
if (needle == nullptr || haystack == nullptr) return needle == haystack; if (needle == nullptr || haystack == nullptr) return needle == haystack;
return wcsstr(haystack, needle) != nullptr; return wcsstr(haystack, needle) != nullptr;
} }
#endif // GTEST_HAS_STD_WSTRING
// StringType here can be either ::std::string or ::std::wstring. // StringType here can be either ::std::string or ::std::wstring.
template <typename StringType> template <typename StringType>
@ -1922,23 +1924,12 @@ AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr,
return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
} }
AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr,
const wchar_t* needle, const wchar_t* haystack) {
return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
}
AssertionResult IsNotSubstring(const char* needle_expr, AssertionResult IsNotSubstring(const char* needle_expr,
const char* haystack_expr, const char* needle, const char* haystack_expr, const char* needle,
const char* haystack) { const char* haystack) {
return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
} }
AssertionResult IsNotSubstring(const char* needle_expr,
const char* haystack_expr, const wchar_t* needle,
const wchar_t* haystack) {
return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
}
AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr, AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr,
const ::std::string& needle, const ::std::string& needle,
const ::std::string& haystack) { const ::std::string& haystack) {
@ -1953,6 +1944,17 @@ AssertionResult IsNotSubstring(const char* needle_expr,
} }
#if GTEST_HAS_STD_WSTRING #if GTEST_HAS_STD_WSTRING
AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr,
const wchar_t* needle, const wchar_t* haystack) {
return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack);
}
AssertionResult IsNotSubstring(const char* needle_expr,
const char* haystack_expr, const wchar_t* needle,
const wchar_t* haystack) {
return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack);
}
AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr, AssertionResult IsSubstring(const char* needle_expr, const char* haystack_expr,
const ::std::wstring& needle, const ::std::wstring& needle,
const ::std::wstring& haystack) { const ::std::wstring& haystack) {
@ -2182,6 +2184,7 @@ bool String::WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs) {
return wcscmp(lhs, rhs) == 0; return wcscmp(lhs, rhs) == 0;
} }
#if GTEST_HAS_STD_WSTRING
// Helper function for *_STREQ on wide strings. // Helper function for *_STREQ on wide strings.
AssertionResult CmpHelperSTREQ(const char* lhs_expression, AssertionResult CmpHelperSTREQ(const char* lhs_expression,
const char* rhs_expression, const wchar_t* lhs, const char* rhs_expression, const wchar_t* lhs,
@ -2206,6 +2209,7 @@ AssertionResult CmpHelperSTRNE(const char* s1_expression,
<< "Expected: (" << s1_expression << ") != (" << s2_expression << "Expected: (" << s1_expression << ") != (" << s2_expression
<< "), actual: " << PrintToString(s1) << " vs " << PrintToString(s2); << "), actual: " << PrintToString(s1) << " vs " << PrintToString(s2);
} }
#endif // GTEST_HAS_STD_WSTRING
// Compares two C strings, ignoring case. Returns true if and only if they have // Compares two C strings, ignoring case. Returns true if and only if they have
// the same content. // the same content.
@ -4644,7 +4648,7 @@ std::string JsonUnitTestResultPrinter::EscapeJson(const std::string& str) {
m << "\\r"; m << "\\r";
break; break;
default: default:
if (ch < ' ') { if (static_cast<unsigned char>(ch) < ' ' || ch == '\x7F') {
m << "\\u00" << String::FormatByte(static_cast<unsigned char>(ch)); m << "\\u00" << String::FormatByte(static_cast<unsigned char>(ch));
} else { } else {
m << ch; m << ch;
@ -5285,17 +5289,8 @@ void TestEventListeners::SuppressEventForwarding(bool suppress) {
// call this before main() starts, from which point on the return // call this before main() starts, from which point on the return
// value will never change. // value will never change.
UnitTest* UnitTest::GetInstance() { UnitTest* UnitTest::GetInstance() {
// CodeGear C++Builder insists on a public destructor for the
// default implementation. Use this implementation to keep good OO
// design with private destructor.
#if defined(__BORLANDC__)
static UnitTest* const instance = new UnitTest;
return instance;
#else
static UnitTest instance; static UnitTest instance;
return &instance; return &instance;
#endif // defined(__BORLANDC__)
} }
// Gets the number of successful test suites. // Gets the number of successful test suites.
@ -6862,6 +6857,16 @@ static void LoadFlagsFromFile(const std::string& path) {
if (!ParseGoogleTestFlag(lines[i].c_str())) g_help_flag = true; if (!ParseGoogleTestFlag(lines[i].c_str())) g_help_flag = true;
} }
} }
static bool ParseFlagFileFlag(const char* const arg) {
std::string flagfile_value;
if (!ParseFlag(arg, "flagfile", &flagfile_value)) {
return false;
}
GTEST_FLAG_SET(flagfile, flagfile_value);
LoadFlagsFromFile(flagfile_value);
return true;
}
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM #endif // GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM
// Parses the command line for Google Test flags, without initializing // Parses the command line for Google Test flags, without initializing
@ -6869,7 +6874,6 @@ static void LoadFlagsFromFile(const std::string& path) {
// instantiated to either char or wchar_t. // instantiated to either char or wchar_t.
template <typename CharType> template <typename CharType>
void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
std::string flagfile_value;
for (int i = 1; i < *argc; i++) { for (int i = 1; i < *argc; i++) {
const std::string arg_string = StreamableToString(argv[i]); const std::string arg_string = StreamableToString(argv[i]);
const char* const arg = arg_string.c_str(); const char* const arg = arg_string.c_str();
@ -6880,9 +6884,7 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
if (ParseGoogleTestFlag(arg)) { if (ParseGoogleTestFlag(arg)) {
remove_flag = true; remove_flag = true;
#if GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM #if GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM
} else if (ParseFlag(arg, "flagfile", &flagfile_value)) { } else if (ParseFlagFileFlag(arg)) {
GTEST_FLAG_SET(flagfile, flagfile_value);
LoadFlagsFromFile(flagfile_value);
remove_flag = true; remove_flag = true;
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM #endif // GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM
} else if (arg_string == "--help" || HasGoogleTestFlagPrefix(arg)) { } else if (arg_string == "--help" || HasGoogleTestFlagPrefix(arg)) {

View File

@ -611,8 +611,7 @@ py_test(
srcs = ["googletest-param-test-invalid-name1-test.py"], srcs = ["googletest-param-test-invalid-name1-test.py"],
data = [":googletest-param-test-invalid-name1-test_"], data = [":googletest-param-test-invalid-name1-test_"],
tags = [ tags = [
"no_test_msvc2015", "no_test_msvc2022",
"no_test_msvc2017",
], ],
deps = [":gtest_test_utils"], deps = [":gtest_test_utils"],
) )
@ -623,8 +622,7 @@ py_test(
srcs = ["googletest-param-test-invalid-name2-test.py"], srcs = ["googletest-param-test-invalid-name2-test.py"],
data = [":googletest-param-test-invalid-name2-test_"], data = [":googletest-param-test-invalid-name2-test_"],
tags = [ tags = [
"no_test_msvc2015", "no_test_msvc2022",
"no_test_msvc2017",
], ],
deps = [":gtest_test_utils"], deps = [":gtest_test_utils"],
) )

View File

@ -1362,11 +1362,8 @@ void DieWithMessage(const char* message) {
TEST(MatcherDeathTest, DoesNotBreakBareRegexMatching) { TEST(MatcherDeathTest, DoesNotBreakBareRegexMatching) {
// googletest tests this, of course; here we ensure that including googlemock // googletest tests this, of course; here we ensure that including googlemock
// has not broken it. // has not broken it.
#ifdef GTEST_USES_POSIX_RE
EXPECT_DEATH(DieWithMessage("O, I die, Horatio."), "I d[aeiou]e"); EXPECT_DEATH(DieWithMessage("O, I die, Horatio."), "I d[aeiou]e");
#else
EXPECT_DEATH(DieWithMessage("O, I die, Horatio."), "I di?e"); EXPECT_DEATH(DieWithMessage("O, I die, Horatio."), "I di?e");
#endif
} }
TEST(MatcherDeathTest, MonomorphicMatcherMatches) { TEST(MatcherDeathTest, MonomorphicMatcherMatches) {

View File

@ -336,7 +336,7 @@ EXPECTED_NON_EMPTY = {
'time': '*', 'time': '*',
'timestamp': '*', 'timestamp': '*',
'classname': 'PropertyRecordingTest', 'classname': 'PropertyRecordingTest',
'key_1': '1', 'key_1': '\u007f!caf\u00e9 \u4e2d',
}, },
{ {
'name': 'IntValuedProperty', 'name': 'IntValuedProperty',
@ -878,7 +878,7 @@ class GTestJsonOutputUnitTest(gtest_test_utils.TestCase):
'the expected exit code %s.' 'the expected exit code %s.'
% (command, p.exit_code, expected_exit_code), % (command, p.exit_code, expected_exit_code),
) )
with open(json_path) as f: with open(json_path, encoding='utf-8') as f:
actual = json.load(f) actual = json.load(f)
return actual return actual

View File

@ -395,11 +395,11 @@ TEST(RegexEngineSelectionTest, SelectsCorrectRegexEngine) {
#elif GTEST_HAS_POSIX_RE #elif GTEST_HAS_POSIX_RE
EXPECT_TRUE(GTEST_USES_POSIX_RE); EXPECT_TRUE(GTEST_USES_POSIX_RE);
#else #else
EXPECT_TRUE(GTEST_USES_SIMPLE_RE); EXPECT_TRUE(GTEST_USES_STD_RE);
#endif #endif
} }
#ifdef GTEST_USES_POSIX_RE #if defined(GTEST_USES_POSIX_RE) || defined(GTEST_USES_STD_RE)
template <typename Str> template <typename Str>
class RETest : public ::testing::Test {}; class RETest : public ::testing::Test {};
@ -424,9 +424,15 @@ TYPED_TEST(RETest, ImplicitConstructorWorks) {
// Tests that RE's constructors reject invalid regular expressions. // Tests that RE's constructors reject invalid regular expressions.
TYPED_TEST(RETest, RejectsInvalidRegex) { TYPED_TEST(RETest, RejectsInvalidRegex) {
#ifdef GTEST_USES_POSIX_RE
EXPECT_NONFATAL_FAILURE( EXPECT_NONFATAL_FAILURE(
{ const RE invalid(TypeParam("?")); }, { const RE invalid(TypeParam("?")); },
"\"?\" is not a valid POSIX Extended regular expression."); "\"?\" is not a valid POSIX Extended regular expression.");
#elif GTEST_USES_STD_RE && GTEST_HAS_EXCEPTIONS
EXPECT_NONFATAL_FAILURE(
{ const RE invalid(TypeParam("?")); },
"\"?\" is not a valid regular expression");
#endif
} }
// Tests RE::FullMatch(). // Tests RE::FullMatch().
@ -456,467 +462,7 @@ TYPED_TEST(RETest, PartialMatchWorks) {
EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re)); EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re));
} }
#elif defined(GTEST_USES_SIMPLE_RE) #endif // GTEST_USES_POSIX_RE || GTEST_USES_STD_RE
TEST(IsInSetTest, NulCharIsNotInAnySet) {
EXPECT_FALSE(IsInSet('\0', ""));
EXPECT_FALSE(IsInSet('\0', "\0"));
EXPECT_FALSE(IsInSet('\0', "a"));
}
TEST(IsInSetTest, WorksForNonNulChars) {
EXPECT_FALSE(IsInSet('a', "Ab"));
EXPECT_FALSE(IsInSet('c', ""));
EXPECT_TRUE(IsInSet('b', "bcd"));
EXPECT_TRUE(IsInSet('b', "ab"));
}
TEST(IsAsciiDigitTest, IsFalseForNonDigit) {
EXPECT_FALSE(IsAsciiDigit('\0'));
EXPECT_FALSE(IsAsciiDigit(' '));
EXPECT_FALSE(IsAsciiDigit('+'));
EXPECT_FALSE(IsAsciiDigit('-'));
EXPECT_FALSE(IsAsciiDigit('.'));
EXPECT_FALSE(IsAsciiDigit('a'));
}
TEST(IsAsciiDigitTest, IsTrueForDigit) {
EXPECT_TRUE(IsAsciiDigit('0'));
EXPECT_TRUE(IsAsciiDigit('1'));
EXPECT_TRUE(IsAsciiDigit('5'));
EXPECT_TRUE(IsAsciiDigit('9'));
}
TEST(IsAsciiPunctTest, IsFalseForNonPunct) {
EXPECT_FALSE(IsAsciiPunct('\0'));
EXPECT_FALSE(IsAsciiPunct(' '));
EXPECT_FALSE(IsAsciiPunct('\n'));
EXPECT_FALSE(IsAsciiPunct('a'));
EXPECT_FALSE(IsAsciiPunct('0'));
}
TEST(IsAsciiPunctTest, IsTrueForPunct) {
for (const char* p = "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"; *p; p++) {
EXPECT_PRED1(IsAsciiPunct, *p);
}
}
TEST(IsRepeatTest, IsFalseForNonRepeatChar) {
EXPECT_FALSE(IsRepeat('\0'));
EXPECT_FALSE(IsRepeat(' '));
EXPECT_FALSE(IsRepeat('a'));
EXPECT_FALSE(IsRepeat('1'));
EXPECT_FALSE(IsRepeat('-'));
}
TEST(IsRepeatTest, IsTrueForRepeatChar) {
EXPECT_TRUE(IsRepeat('?'));
EXPECT_TRUE(IsRepeat('*'));
EXPECT_TRUE(IsRepeat('+'));
}
TEST(IsAsciiWhiteSpaceTest, IsFalseForNonWhiteSpace) {
EXPECT_FALSE(IsAsciiWhiteSpace('\0'));
EXPECT_FALSE(IsAsciiWhiteSpace('a'));
EXPECT_FALSE(IsAsciiWhiteSpace('1'));
EXPECT_FALSE(IsAsciiWhiteSpace('+'));
EXPECT_FALSE(IsAsciiWhiteSpace('_'));
}
TEST(IsAsciiWhiteSpaceTest, IsTrueForWhiteSpace) {
EXPECT_TRUE(IsAsciiWhiteSpace(' '));
EXPECT_TRUE(IsAsciiWhiteSpace('\n'));
EXPECT_TRUE(IsAsciiWhiteSpace('\r'));
EXPECT_TRUE(IsAsciiWhiteSpace('\t'));
EXPECT_TRUE(IsAsciiWhiteSpace('\v'));
EXPECT_TRUE(IsAsciiWhiteSpace('\f'));
}
TEST(IsAsciiWordCharTest, IsFalseForNonWordChar) {
EXPECT_FALSE(IsAsciiWordChar('\0'));
EXPECT_FALSE(IsAsciiWordChar('+'));
EXPECT_FALSE(IsAsciiWordChar('.'));
EXPECT_FALSE(IsAsciiWordChar(' '));
EXPECT_FALSE(IsAsciiWordChar('\n'));
}
TEST(IsAsciiWordCharTest, IsTrueForLetter) {
EXPECT_TRUE(IsAsciiWordChar('a'));
EXPECT_TRUE(IsAsciiWordChar('b'));
EXPECT_TRUE(IsAsciiWordChar('A'));
EXPECT_TRUE(IsAsciiWordChar('Z'));
}
TEST(IsAsciiWordCharTest, IsTrueForDigit) {
EXPECT_TRUE(IsAsciiWordChar('0'));
EXPECT_TRUE(IsAsciiWordChar('1'));
EXPECT_TRUE(IsAsciiWordChar('7'));
EXPECT_TRUE(IsAsciiWordChar('9'));
}
TEST(IsAsciiWordCharTest, IsTrueForUnderscore) {
EXPECT_TRUE(IsAsciiWordChar('_'));
}
TEST(IsValidEscapeTest, IsFalseForNonPrintable) {
EXPECT_FALSE(IsValidEscape('\0'));
EXPECT_FALSE(IsValidEscape('\007'));
}
TEST(IsValidEscapeTest, IsFalseForDigit) {
EXPECT_FALSE(IsValidEscape('0'));
EXPECT_FALSE(IsValidEscape('9'));
}
TEST(IsValidEscapeTest, IsFalseForWhiteSpace) {
EXPECT_FALSE(IsValidEscape(' '));
EXPECT_FALSE(IsValidEscape('\n'));
}
TEST(IsValidEscapeTest, IsFalseForSomeLetter) {
EXPECT_FALSE(IsValidEscape('a'));
EXPECT_FALSE(IsValidEscape('Z'));
}
TEST(IsValidEscapeTest, IsTrueForPunct) {
EXPECT_TRUE(IsValidEscape('.'));
EXPECT_TRUE(IsValidEscape('-'));
EXPECT_TRUE(IsValidEscape('^'));
EXPECT_TRUE(IsValidEscape('$'));
EXPECT_TRUE(IsValidEscape('('));
EXPECT_TRUE(IsValidEscape(']'));
EXPECT_TRUE(IsValidEscape('{'));
EXPECT_TRUE(IsValidEscape('|'));
}
TEST(IsValidEscapeTest, IsTrueForSomeLetter) {
EXPECT_TRUE(IsValidEscape('d'));
EXPECT_TRUE(IsValidEscape('D'));
EXPECT_TRUE(IsValidEscape('s'));
EXPECT_TRUE(IsValidEscape('S'));
EXPECT_TRUE(IsValidEscape('w'));
EXPECT_TRUE(IsValidEscape('W'));
}
TEST(AtomMatchesCharTest, EscapedPunct) {
EXPECT_FALSE(AtomMatchesChar(true, '\\', '\0'));
EXPECT_FALSE(AtomMatchesChar(true, '\\', ' '));
EXPECT_FALSE(AtomMatchesChar(true, '_', '.'));
EXPECT_FALSE(AtomMatchesChar(true, '.', 'a'));
EXPECT_TRUE(AtomMatchesChar(true, '\\', '\\'));
EXPECT_TRUE(AtomMatchesChar(true, '_', '_'));
EXPECT_TRUE(AtomMatchesChar(true, '+', '+'));
EXPECT_TRUE(AtomMatchesChar(true, '.', '.'));
}
TEST(AtomMatchesCharTest, Escaped_d) {
EXPECT_FALSE(AtomMatchesChar(true, 'd', '\0'));
EXPECT_FALSE(AtomMatchesChar(true, 'd', 'a'));
EXPECT_FALSE(AtomMatchesChar(true, 'd', '.'));
EXPECT_TRUE(AtomMatchesChar(true, 'd', '0'));
EXPECT_TRUE(AtomMatchesChar(true, 'd', '9'));
}
TEST(AtomMatchesCharTest, Escaped_D) {
EXPECT_FALSE(AtomMatchesChar(true, 'D', '0'));
EXPECT_FALSE(AtomMatchesChar(true, 'D', '9'));
EXPECT_TRUE(AtomMatchesChar(true, 'D', '\0'));
EXPECT_TRUE(AtomMatchesChar(true, 'D', 'a'));
EXPECT_TRUE(AtomMatchesChar(true, 'D', '-'));
}
TEST(AtomMatchesCharTest, Escaped_s) {
EXPECT_FALSE(AtomMatchesChar(true, 's', '\0'));
EXPECT_FALSE(AtomMatchesChar(true, 's', 'a'));
EXPECT_FALSE(AtomMatchesChar(true, 's', '.'));
EXPECT_FALSE(AtomMatchesChar(true, 's', '9'));
EXPECT_TRUE(AtomMatchesChar(true, 's', ' '));
EXPECT_TRUE(AtomMatchesChar(true, 's', '\n'));
EXPECT_TRUE(AtomMatchesChar(true, 's', '\t'));
}
TEST(AtomMatchesCharTest, Escaped_S) {
EXPECT_FALSE(AtomMatchesChar(true, 'S', ' '));
EXPECT_FALSE(AtomMatchesChar(true, 'S', '\r'));
EXPECT_TRUE(AtomMatchesChar(true, 'S', '\0'));
EXPECT_TRUE(AtomMatchesChar(true, 'S', 'a'));
EXPECT_TRUE(AtomMatchesChar(true, 'S', '9'));
}
TEST(AtomMatchesCharTest, Escaped_w) {
EXPECT_FALSE(AtomMatchesChar(true, 'w', '\0'));
EXPECT_FALSE(AtomMatchesChar(true, 'w', '+'));
EXPECT_FALSE(AtomMatchesChar(true, 'w', ' '));
EXPECT_FALSE(AtomMatchesChar(true, 'w', '\n'));
EXPECT_TRUE(AtomMatchesChar(true, 'w', '0'));
EXPECT_TRUE(AtomMatchesChar(true, 'w', 'b'));
EXPECT_TRUE(AtomMatchesChar(true, 'w', 'C'));
EXPECT_TRUE(AtomMatchesChar(true, 'w', '_'));
}
TEST(AtomMatchesCharTest, Escaped_W) {
EXPECT_FALSE(AtomMatchesChar(true, 'W', 'A'));
EXPECT_FALSE(AtomMatchesChar(true, 'W', 'b'));
EXPECT_FALSE(AtomMatchesChar(true, 'W', '9'));
EXPECT_FALSE(AtomMatchesChar(true, 'W', '_'));
EXPECT_TRUE(AtomMatchesChar(true, 'W', '\0'));
EXPECT_TRUE(AtomMatchesChar(true, 'W', '*'));
EXPECT_TRUE(AtomMatchesChar(true, 'W', '\n'));
}
TEST(AtomMatchesCharTest, EscapedWhiteSpace) {
EXPECT_FALSE(AtomMatchesChar(true, 'f', '\0'));
EXPECT_FALSE(AtomMatchesChar(true, 'f', '\n'));
EXPECT_FALSE(AtomMatchesChar(true, 'n', '\0'));
EXPECT_FALSE(AtomMatchesChar(true, 'n', '\r'));
EXPECT_FALSE(AtomMatchesChar(true, 'r', '\0'));
EXPECT_FALSE(AtomMatchesChar(true, 'r', 'a'));
EXPECT_FALSE(AtomMatchesChar(true, 't', '\0'));
EXPECT_FALSE(AtomMatchesChar(true, 't', 't'));
EXPECT_FALSE(AtomMatchesChar(true, 'v', '\0'));
EXPECT_FALSE(AtomMatchesChar(true, 'v', '\f'));
EXPECT_TRUE(AtomMatchesChar(true, 'f', '\f'));
EXPECT_TRUE(AtomMatchesChar(true, 'n', '\n'));
EXPECT_TRUE(AtomMatchesChar(true, 'r', '\r'));
EXPECT_TRUE(AtomMatchesChar(true, 't', '\t'));
EXPECT_TRUE(AtomMatchesChar(true, 'v', '\v'));
}
TEST(AtomMatchesCharTest, UnescapedDot) {
EXPECT_FALSE(AtomMatchesChar(false, '.', '\n'));
EXPECT_TRUE(AtomMatchesChar(false, '.', '\0'));
EXPECT_TRUE(AtomMatchesChar(false, '.', '.'));
EXPECT_TRUE(AtomMatchesChar(false, '.', 'a'));
EXPECT_TRUE(AtomMatchesChar(false, '.', ' '));
}
TEST(AtomMatchesCharTest, UnescapedChar) {
EXPECT_FALSE(AtomMatchesChar(false, 'a', '\0'));
EXPECT_FALSE(AtomMatchesChar(false, 'a', 'b'));
EXPECT_FALSE(AtomMatchesChar(false, '$', 'a'));
EXPECT_TRUE(AtomMatchesChar(false, '$', '$'));
EXPECT_TRUE(AtomMatchesChar(false, '5', '5'));
EXPECT_TRUE(AtomMatchesChar(false, 'Z', 'Z'));
}
TEST(ValidateRegexTest, GeneratesFailureAndReturnsFalseForInvalid) {
EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(NULL)),
"NULL is not a valid simple regular expression");
EXPECT_NONFATAL_FAILURE(
ASSERT_FALSE(ValidateRegex("a\\")),
"Syntax error at index 1 in simple regular expression \"a\\\": ");
EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a\\")),
"'\\' cannot appear at the end");
EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\n\\")),
"'\\' cannot appear at the end");
EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("\\s\\hb")),
"invalid escape sequence \"\\h\"");
EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^^")),
"'^' can only appear at the beginning");
EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex(".*^b")),
"'^' can only appear at the beginning");
EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("$$")),
"'$' can only appear at the end");
EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^$a")),
"'$' can only appear at the end");
EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a(b")),
"'(' is unsupported");
EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("ab)")),
"')' is unsupported");
EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("[ab")),
"'[' is unsupported");
EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("a{2")),
"'{' is unsupported");
EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("?")),
"'?' can only follow a repeatable token");
EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("^*")),
"'*' can only follow a repeatable token");
EXPECT_NONFATAL_FAILURE(ASSERT_FALSE(ValidateRegex("5*+")),
"'+' can only follow a repeatable token");
}
TEST(ValidateRegexTest, ReturnsTrueForValid) {
EXPECT_TRUE(ValidateRegex(""));
EXPECT_TRUE(ValidateRegex("a"));
EXPECT_TRUE(ValidateRegex(".*"));
EXPECT_TRUE(ValidateRegex("^a_+"));
EXPECT_TRUE(ValidateRegex("^a\\t\\&?"));
EXPECT_TRUE(ValidateRegex("09*$"));
EXPECT_TRUE(ValidateRegex("^Z$"));
EXPECT_TRUE(ValidateRegex("a\\^Z\\$\\(\\)\\|\\[\\]\\{\\}"));
}
TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrOne) {
EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "a", "ba"));
// Repeating more than once.
EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "aab"));
// Repeating zero times.
EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ba"));
// Repeating once.
EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, 'a', '?', "b", "ab"));
EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '#', '?', ".", "##"));
}
TEST(MatchRepetitionAndRegexAtHeadTest, WorksForZeroOrMany) {
EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '*', "a$", "baab"));
// Repeating zero times.
EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "bc"));
// Repeating once.
EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '*', "b", "abc"));
// Repeating more than once.
EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '*', "-", "ab_1-g"));
}
TEST(MatchRepetitionAndRegexAtHeadTest, WorksForOneOrMany) {
EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "a$", "baab"));
// Repeating zero times.
EXPECT_FALSE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "bc"));
// Repeating once.
EXPECT_TRUE(MatchRepetitionAndRegexAtHead(false, '.', '+', "b", "abc"));
// Repeating more than once.
EXPECT_TRUE(MatchRepetitionAndRegexAtHead(true, 'w', '+', "-", "ab_1-g"));
}
TEST(MatchRegexAtHeadTest, ReturnsTrueForEmptyRegex) {
EXPECT_TRUE(MatchRegexAtHead("", ""));
EXPECT_TRUE(MatchRegexAtHead("", "ab"));
}
TEST(MatchRegexAtHeadTest, WorksWhenDollarIsInRegex) {
EXPECT_FALSE(MatchRegexAtHead("$", "a"));
EXPECT_TRUE(MatchRegexAtHead("$", ""));
EXPECT_TRUE(MatchRegexAtHead("a$", "a"));
}
TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithEscapeSequence) {
EXPECT_FALSE(MatchRegexAtHead("\\w", "+"));
EXPECT_FALSE(MatchRegexAtHead("\\W", "ab"));
EXPECT_TRUE(MatchRegexAtHead("\\sa", "\nab"));
EXPECT_TRUE(MatchRegexAtHead("\\d", "1a"));
}
TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithRepetition) {
EXPECT_FALSE(MatchRegexAtHead(".+a", "abc"));
EXPECT_FALSE(MatchRegexAtHead("a?b", "aab"));
EXPECT_TRUE(MatchRegexAtHead(".*a", "bc12-ab"));
EXPECT_TRUE(MatchRegexAtHead("a?b", "b"));
EXPECT_TRUE(MatchRegexAtHead("a?b", "ab"));
}
TEST(MatchRegexAtHeadTest, WorksWhenRegexStartsWithRepetionOfEscapeSequence) {
EXPECT_FALSE(MatchRegexAtHead("\\.+a", "abc"));
EXPECT_FALSE(MatchRegexAtHead("\\s?b", " b"));
EXPECT_TRUE(MatchRegexAtHead("\\(*a", "((((ab"));
EXPECT_TRUE(MatchRegexAtHead("\\^?b", "^b"));
EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "b"));
EXPECT_TRUE(MatchRegexAtHead("\\\\?b", "\\b"));
}
TEST(MatchRegexAtHeadTest, MatchesSequentially) {
EXPECT_FALSE(MatchRegexAtHead("ab.*c", "acabc"));
EXPECT_TRUE(MatchRegexAtHead("ab.*c", "ab-fsc"));
}
TEST(MatchRegexAnywhereTest, ReturnsFalseWhenStringIsNull) {
EXPECT_FALSE(MatchRegexAnywhere("", NULL));
}
TEST(MatchRegexAnywhereTest, WorksWhenRegexStartsWithCaret) {
EXPECT_FALSE(MatchRegexAnywhere("^a", "ba"));
EXPECT_FALSE(MatchRegexAnywhere("^$", "a"));
EXPECT_TRUE(MatchRegexAnywhere("^a", "ab"));
EXPECT_TRUE(MatchRegexAnywhere("^", "ab"));
EXPECT_TRUE(MatchRegexAnywhere("^$", ""));
}
TEST(MatchRegexAnywhereTest, ReturnsFalseWhenNoMatch) {
EXPECT_FALSE(MatchRegexAnywhere("a", "bcde123"));
EXPECT_FALSE(MatchRegexAnywhere("a.+a", "--aa88888888"));
}
TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingPrefix) {
EXPECT_TRUE(MatchRegexAnywhere("\\w+", "ab1_ - 5"));
EXPECT_TRUE(MatchRegexAnywhere(".*=", "="));
EXPECT_TRUE(MatchRegexAnywhere("x.*ab?.*bc", "xaaabc"));
}
TEST(MatchRegexAnywhereTest, ReturnsTrueWhenMatchingNonPrefix) {
EXPECT_TRUE(MatchRegexAnywhere("\\w+", "$$$ ab1_ - 5"));
EXPECT_TRUE(MatchRegexAnywhere("\\.+=", "= ...="));
}
// Tests RE's implicit constructors.
TEST(RETest, ImplicitConstructorWorks) {
const RE empty("");
EXPECT_STREQ("", empty.pattern());
const RE simple("hello");
EXPECT_STREQ("hello", simple.pattern());
}
// Tests that RE's constructors reject invalid regular expressions.
TEST(RETest, RejectsInvalidRegex) {
EXPECT_NONFATAL_FAILURE({ const RE normal(NULL); },
"NULL is not a valid simple regular expression");
EXPECT_NONFATAL_FAILURE({ const RE normal(".*(\\w+"); },
"'(' is unsupported");
EXPECT_NONFATAL_FAILURE({ const RE invalid("^?"); },
"'?' can only follow a repeatable token");
}
// Tests RE::FullMatch().
TEST(RETest, FullMatchWorks) {
const RE empty("");
EXPECT_TRUE(RE::FullMatch("", empty));
EXPECT_FALSE(RE::FullMatch("a", empty));
const RE re1("a");
EXPECT_TRUE(RE::FullMatch("a", re1));
const RE re("a.*z");
EXPECT_TRUE(RE::FullMatch("az", re));
EXPECT_TRUE(RE::FullMatch("axyz", re));
EXPECT_FALSE(RE::FullMatch("baz", re));
EXPECT_FALSE(RE::FullMatch("azy", re));
}
// Tests RE::PartialMatch().
TEST(RETest, PartialMatchWorks) {
const RE empty("");
EXPECT_TRUE(RE::PartialMatch("", empty));
EXPECT_TRUE(RE::PartialMatch("a", empty));
const RE re("a.*z");
EXPECT_TRUE(RE::PartialMatch("az", re));
EXPECT_TRUE(RE::PartialMatch("axyz", re));
EXPECT_TRUE(RE::PartialMatch("baz", re));
EXPECT_TRUE(RE::PartialMatch("azy", re));
EXPECT_FALSE(RE::PartialMatch("zza", re));
}
#endif // GTEST_USES_POSIX_RE
#ifndef GTEST_OS_WINDOWS_MOBILE #ifndef GTEST_OS_WINDOWS_MOBILE

View File

@ -95,10 +95,12 @@ void PrintTo(EnumWithPrintTo e, std::ostream* os) {
*os << (e == kEWPT1 ? "kEWPT1" : "invalid"); *os << (e == kEWPT1 ? "kEWPT1" : "invalid");
} }
// A class implicitly convertible to BiggestInt. // A class implicitly convertible to intmax_t.
class BiggestIntConvertible { class BiggestIntConvertible {
public: public:
operator ::testing::internal::BiggestInt() const { return 42; } operator intmax_t() const { // NOLINT(google-explicit-constructor)
return 42;
}
}; };
// A parent class with two child classes. The parent and one of the kids have // A parent class with two child classes. The parent and one of the kids have
@ -356,7 +358,7 @@ TEST(PrintEnumTest, EnumWithPrintTo) {
TEST(PrintClassTest, AbslStringify) { EXPECT_EQ("(10, 20)", Print(Point())); } TEST(PrintClassTest, AbslStringify) { EXPECT_EQ("(10, 20)", Print(Point())); }
#endif #endif
// Tests printing a class implicitly convertible to BiggestInt. // Tests printing a class implicitly convertible to intmax_t.
TEST(PrintClassTest, BiggestIntConvertible) { TEST(PrintClassTest, BiggestIntConvertible) {
EXPECT_EQ("42", Print(BiggestIntConvertible())); EXPECT_EQ("42", Print(BiggestIntConvertible()));
@ -396,12 +398,24 @@ TEST(PrintCharTest, UnsignedChar) {
EXPECT_EQ("'b' (98, 0x62)", Print(static_cast<unsigned char>('b'))); EXPECT_EQ("'b' (98, 0x62)", Print(static_cast<unsigned char>('b')));
} }
TEST(PrintCharTest, Char16) { EXPECT_EQ("U+0041", Print(u'A')); } TEST(PrintCharTest, Char16) {
EXPECT_EQ("U+0041", Print(u'A'));
EXPECT_EQ("U+754C", Print(u'界'));
// Surrogates are not code points, so they are printed as code units.
EXPECT_EQ("u'\\xD800' (55296)", Print(static_cast<char16_t>(0xD800)));
EXPECT_EQ("u'\\xDFFF' (57343)", Print(static_cast<char16_t>(0xDFFF)));
}
TEST(PrintCharTest, Char32) { EXPECT_EQ("U+0041", Print(U'A')); } TEST(PrintCharTest, Char32) { EXPECT_EQ("U+0041", Print(U'A')); }
#ifdef __cpp_lib_char8_t #ifdef __cpp_lib_char8_t
TEST(PrintCharTest, Char8) { EXPECT_EQ("U+0041", Print(u8'A')); } TEST(PrintCharTest, Char8) {
EXPECT_EQ("U+0041", Print(u8'A'));
// Only ASCII code units encode a code point on their own; the rest are
// printed as code units.
EXPECT_EQ("u8'\\x80' (128)", Print(static_cast<char8_t>(0x80)));
EXPECT_EQ("u8'\\xFF' (255)", Print(static_cast<char8_t>(0xFF)));
}
#endif #endif
// Tests printing other simple, built-in types. // Tests printing other simple, built-in types.
@ -456,7 +470,7 @@ TEST(PrintBuiltInTypeTest, Integer) {
#ifdef __cpp_lib_char8_t #ifdef __cpp_lib_char8_t
EXPECT_EQ("U+0000", EXPECT_EQ("U+0000",
Print(std::numeric_limits<char8_t>::min())); // char8_t Print(std::numeric_limits<char8_t>::min())); // char8_t
EXPECT_EQ("U+00FF", EXPECT_EQ("u8'\\xFF' (255)",
Print(std::numeric_limits<char8_t>::max())); // char8_t Print(std::numeric_limits<char8_t>::max())); // char8_t
#endif #endif
EXPECT_EQ("U+0000", EXPECT_EQ("U+0000",
@ -648,13 +662,8 @@ TEST(PrintU32StringTest, EscapesProperly) {
Print(p)); Print(p));
} }
// MSVC compiler can be configured to define whar_t as a typedef #if GTEST_HAS_NATIVE_WCHAR
// of unsigned short. Defining an overload for const wchar_t* in that case #if GTEST_HAS_STD_WSTRING
// would cause pointers to unsigned shorts be printed as wide strings,
// possibly accessing more memory than intended and causing invalid
// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when
// wchar_t is implemented as a native type.
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
// const wchar_t*. // const wchar_t*.
TEST(PrintWideCStringTest, Const) { TEST(PrintWideCStringTest, Const) {
@ -685,7 +694,8 @@ TEST(PrintWideCStringTest, EscapesProperly) {
"\\n\\r\\t\\v\\xD3\\x576\\x8D3\\xC74D a\"", "\\n\\r\\t\\v\\xD3\\x576\\x8D3\\xC74D a\"",
Print(static_cast<const wchar_t*>(s))); Print(static_cast<const wchar_t*>(s)));
} }
#endif // native wchar_t #endif // GTEST_HAS_STD_WSTRING
#endif // GTEST_HAS_NATIVE_WCHAR
// Tests printing pointers to other char types. // Tests printing pointers to other char types.
@ -765,7 +775,7 @@ TEST(PrintPointerTest, NonMemberFunctionPointer) {
// pointers to objects, and some compilers (e.g. GCC 3.4) enforce // pointers to objects, and some compilers (e.g. GCC 3.4) enforce
// this limitation. // this limitation.
EXPECT_EQ(PrintPointer(reinterpret_cast<const void*>( EXPECT_EQ(PrintPointer(reinterpret_cast<const void*>(
reinterpret_cast<internal::BiggestInt>(&MyFunction))), reinterpret_cast<intmax_t>(&MyFunction))),
Print(&MyFunction)); Print(&MyFunction));
int (*p)(bool) = NULL; // NOLINT int (*p)(bool) = NULL; // NOLINT
EXPECT_EQ("NULL", Print(p)); EXPECT_EQ("NULL", Print(p));
@ -1466,8 +1476,8 @@ TEST(PrintReferenceTest, HandlesFunctionPointer) {
// standard disallows casting between pointers to functions and // standard disallows casting between pointers to functions and
// pointers to objects, and some compilers (e.g. GCC 3.4) enforce // pointers to objects, and some compilers (e.g. GCC 3.4) enforce
// this limitation. // this limitation.
const std::string fp_string = PrintPointer(reinterpret_cast<const void*>( const std::string fp_string = PrintPointer(
reinterpret_cast<internal::BiggestInt>(fp))); reinterpret_cast<const void*>(reinterpret_cast<intmax_t>(fp)));
EXPECT_EQ("@" + fp_pointer_string + " " + fp_string, PrintByRef(fp)); EXPECT_EQ("@" + fp_pointer_string + " " + fp_string, PrintByRef(fp));
} }

View File

@ -200,12 +200,15 @@ using testing::internal::TypedTestSuitePState;
class TypedTestSuitePStateTest : public Test { class TypedTestSuitePStateTest : public Test {
protected: protected:
void SetUp() override { void SetUp() override {
state_.AddTestName("foo.cc", 0, "FooTest", "A"); state_.AddTest(&test_a_, "FooTest");
state_.AddTestName("foo.cc", 0, "FooTest", "B"); state_.AddTest(&test_b_, "FooTest");
state_.AddTestName("foo.cc", 0, "FooTest", "C"); state_.AddTest(&test_c_, "FooTest");
} }
TypedTestSuitePState state_; TypedTestSuitePState state_;
TypedTestSuitePState::RegisteredTest test_a_ = {"A", "foo.cc", 0, nullptr};
TypedTestSuitePState::RegisteredTest test_b_ = {"B", "foo.cc", 0, nullptr};
TypedTestSuitePState::RegisteredTest test_c_ = {"C", "foo.cc", 0, nullptr};
}; };
TEST_F(TypedTestSuitePStateTest, SucceedsForMatchingList) { TEST_F(TypedTestSuitePStateTest, SucceedsForMatchingList) {
@ -246,8 +249,9 @@ TEST_F(TypedTestSuitePStateDeathTest, DetectsMissedTest) {
// a run-time error if the test case has been registered. // a run-time error if the test case has been registered.
TEST_F(TypedTestSuitePStateDeathTest, DetectsTestAfterRegistration) { TEST_F(TypedTestSuitePStateDeathTest, DetectsTestAfterRegistration) {
state_.VerifyRegisteredTestNames("Suite", "foo.cc", 1, "A, B, C"); state_.VerifyRegisteredTestNames("Suite", "foo.cc", 1, "A, B, C");
TypedTestSuitePState::RegisteredTest test_d = {"D", "foo.cc", 2, nullptr};
EXPECT_DEATH_IF_SUPPORTED( EXPECT_DEATH_IF_SUPPORTED(
state_.AddTestName("foo.cc", 2, "FooTest", "D"), state_.AddTest(&test_d, "FooTest"),
"foo\\.cc.2.?: Test D must be defined before REGISTER_TYPED_TEST_SUITE_P" "foo\\.cc.2.?: Test D must be defined before REGISTER_TYPED_TEST_SUITE_P"
"\\(FooTest, \\.\\.\\.\\)\\."); "\\(FooTest, \\.\\.\\.\\)\\.");
} }

View File

@ -34,6 +34,7 @@
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include <iterator> #include <iterator>
#include <limits>
// Verifies that the command line flag variables can be accessed in // Verifies that the command line flag variables can be accessed in
// code once "gtest.h" has been #included. // code once "gtest.h" has been #included.
@ -484,9 +485,11 @@ class FormatEpochTimeInMillisAsIso8601Test : public Test {
const std::string env_var = const std::string env_var =
std::string("TZ=") + (time_zone ? time_zone : ""); std::string("TZ=") + (time_zone ? time_zone : "");
_putenv(env_var.c_str()); _putenv(env_var.c_str());
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996 /* deprecated function */) #if defined(GTEST_OS_WINDOWS)
_tzset();
#else
tzset(); tzset();
GTEST_DISABLE_MSC_WARNINGS_POP_() #endif
#else #else
#if defined(GTEST_OS_LINUX_ANDROID) && __ANDROID_API__ < 21 #if defined(GTEST_OS_LINUX_ANDROID) && __ANDROID_API__ < 21
// Work around KitKat bug in tzset by setting "UTC" before setting "UTC+00". // Work around KitKat bug in tzset by setting "UTC" before setting "UTC+00".
@ -534,11 +537,6 @@ TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsEpochStart) {
#endif // __EMSCRIPTEN__ #endif // __EMSCRIPTEN__
#ifdef __BORLANDC__
// Silences warnings: "Condition is always true", "Unreachable code"
#pragma option push -w-ccc -w-rch
#endif
// Tests that the LHS of EXPECT_EQ or ASSERT_EQ can be used as a null literal // Tests that the LHS of EXPECT_EQ or ASSERT_EQ can be used as a null literal
// when the RHS is a pointer type. // when the RHS is a pointer type.
TEST(NullLiteralTest, LHSAllowsNullLiterals) { TEST(NullLiteralTest, LHSAllowsNullLiterals) {
@ -595,10 +593,8 @@ TEST(NullLiteralTest, ImplicitConversion) {
#ifdef __clang__ #ifdef __clang__
#pragma clang diagnostic push #pragma clang diagnostic push
#if __has_warning("-Wzero-as-null-pointer-constant")
#pragma clang diagnostic error "-Wzero-as-null-pointer-constant" #pragma clang diagnostic error "-Wzero-as-null-pointer-constant"
#endif #endif
#endif
TEST(NullLiteralTest, NoConversionNoWarning) { TEST(NullLiteralTest, NoConversionNoWarning) {
// Test that gtests detection and handling of null pointer constants // Test that gtests detection and handling of null pointer constants
@ -611,11 +607,6 @@ TEST(NullLiteralTest, NoConversionNoWarning) {
#pragma clang diagnostic pop #pragma clang diagnostic pop
#endif #endif
#ifdef __BORLANDC__
// Restores warnings after previous "#pragma option push" suppressed them.
#pragma option pop
#endif
// //
// Tests CodePointToUtf8(). // Tests CodePointToUtf8().
@ -1275,11 +1266,6 @@ TEST_F(ExpectFatalFailureTest, CatchesFatalFailureOnAllThreads) {
"Expected fatal failure."); "Expected fatal failure.");
} }
#ifdef __BORLANDC__
// Silences warnings: "Condition is always true"
#pragma option push -w-ccc
#endif
// Tests that EXPECT_FATAL_FAILURE() can be used in a non-void // Tests that EXPECT_FATAL_FAILURE() can be used in a non-void
// function even when the statement in it contains ASSERT_*. // function even when the statement in it contains ASSERT_*.
@ -1303,11 +1289,6 @@ void DoesNotAbortHelper(bool* aborted) {
*aborted = false; *aborted = false;
} }
#ifdef __BORLANDC__
// Restores warnings after previous "#pragma option push" suppressed them.
#pragma option pop
#endif
TEST_F(ExpectFatalFailureTest, DoesNotAbort) { TEST_F(ExpectFatalFailureTest, DoesNotAbort) {
bool aborted = true; bool aborted = true;
DoesNotAbortHelper(&aborted); DoesNotAbortHelper(&aborted);
@ -1322,15 +1303,12 @@ static int global_var = 0;
#define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++ #define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++
TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) { TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) {
#ifndef __BORLANDC__
// ICE's in C++Builder.
EXPECT_FATAL_FAILURE( EXPECT_FATAL_FAILURE(
{ {
GTEST_USE_UNPROTECTED_COMMA_; GTEST_USE_UNPROTECTED_COMMA_;
AddFatalFailure(); AddFatalFailure();
}, },
""); "");
#endif
EXPECT_FATAL_FAILURE_ON_ALL_THREADS( EXPECT_FATAL_FAILURE_ON_ALL_THREADS(
{ {
@ -1711,26 +1689,6 @@ static void SetEnv(const char* name, const char* value) {
#ifdef GTEST_OS_WINDOWS_MOBILE #ifdef GTEST_OS_WINDOWS_MOBILE
// Environment variables are not supported on Windows CE. // Environment variables are not supported on Windows CE.
return; return;
#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9)
// C++Builder's putenv only stores a pointer to its parameter; we have to
// ensure that the string remains valid as long as it might be needed.
// We use an std::map to do so.
static std::map<std::string, std::string*> added_env;
// Because putenv stores a pointer to the string buffer, we can't delete the
// previous string (if present) until after it's replaced.
std::string* prev_env = NULL;
if (added_env.find(name) != added_env.end()) {
prev_env = added_env[name];
}
added_env[name] =
new std::string((Message() << name << "=" << value).GetString());
// The standard signature of putenv accepts a 'char*' argument. Other
// implementations, like C++Builder's, accept a 'const char*'.
// We cast away the 'const' since that would work for both variants.
putenv(const_cast<char*>(added_env[name]->c_str()));
delete prev_env;
#elif defined(GTEST_OS_WINDOWS) // If we are on Windows proper. #elif defined(GTEST_OS_WINDOWS) // If we are on Windows proper.
_putenv((Message() << name << "=" << value).GetString().c_str()); _putenv((Message() << name << "=" << value).GetString().c_str());
#else #else
@ -2564,6 +2522,7 @@ TEST(StringAssertionTest, ASSERT_STRCASENE) {
EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("Hi", "hi"), "(ignoring case)"); EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("Hi", "hi"), "(ignoring case)");
} }
#if GTEST_HAS_STD_WSTRING
// Tests *_STREQ on wide strings. // Tests *_STREQ on wide strings.
TEST(StringAssertionTest, STREQ_Wide) { TEST(StringAssertionTest, STREQ_Wide) {
// NULL strings. // NULL strings.
@ -2619,6 +2578,7 @@ TEST(StringAssertionTest, STRNE_Wide) {
// The streaming variation. // The streaming variation.
ASSERT_STRNE(L"abc\x8119", L"abc\x8120") << "This shouldn't happen"; ASSERT_STRNE(L"abc\x8119", L"abc\x8120") << "This shouldn't happen";
} }
#endif // GTEST_HAS_STD_WSTRING
// Tests for ::testing::IsSubstring(). // Tests for ::testing::IsSubstring().
@ -2633,18 +2593,6 @@ TEST(IsSubstringTest, ReturnsCorrectResultForCString) {
EXPECT_TRUE(IsSubstring("", "", "needle", "two needles")); EXPECT_TRUE(IsSubstring("", "", "needle", "two needles"));
} }
// Tests that IsSubstring() returns the correct result when the input
// argument type is const wchar_t*.
TEST(IsSubstringTest, ReturnsCorrectResultForWideCString) {
EXPECT_FALSE(IsSubstring("", "", kNull, L"a"));
EXPECT_FALSE(IsSubstring("", "", L"b", kNull));
EXPECT_FALSE(IsSubstring("", "", L"needle", L"haystack"));
EXPECT_TRUE(
IsSubstring("", "", static_cast<const wchar_t*>(nullptr), nullptr));
EXPECT_TRUE(IsSubstring("", "", L"needle", L"two needles"));
}
// Tests that IsSubstring() generates the correct message when the input // Tests that IsSubstring() generates the correct message when the input
// argument type is const char*. // argument type is const char*.
TEST(IsSubstringTest, GeneratesCorrectMessageForCString) { TEST(IsSubstringTest, GeneratesCorrectMessageForCString) {
@ -2665,6 +2613,18 @@ TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) {
} }
#if GTEST_HAS_STD_WSTRING #if GTEST_HAS_STD_WSTRING
// Tests that IsSubstring() returns the correct result when the input
// argument type is const wchar_t*.
TEST(IsSubstringTest, ReturnsCorrectResultForWideCString) {
EXPECT_FALSE(IsSubstring("", "", kNull, L"a"));
EXPECT_FALSE(IsSubstring("", "", L"b", kNull));
EXPECT_FALSE(IsSubstring("", "", L"needle", L"haystack"));
EXPECT_TRUE(
IsSubstring("", "", static_cast<const wchar_t*>(nullptr), nullptr));
EXPECT_TRUE(IsSubstring("", "", L"needle", L"two needles"));
}
// Tests that IsSubstring returns the correct result when the input // Tests that IsSubstring returns the correct result when the input
// argument type is ::std::wstring. // argument type is ::std::wstring.
TEST(IsSubstringTest, ReturnsCorrectResultForStdWstring) { TEST(IsSubstringTest, ReturnsCorrectResultForStdWstring) {
@ -2696,25 +2656,6 @@ TEST(IsNotSubstringTest, ReturnsCorrectResultForCString) {
EXPECT_FALSE(IsNotSubstring("", "", "needle", "two needles")); EXPECT_FALSE(IsNotSubstring("", "", "needle", "two needles"));
} }
// Tests that IsNotSubstring() returns the correct result when the input
// argument type is const wchar_t*.
TEST(IsNotSubstringTest, ReturnsCorrectResultForWideCString) {
EXPECT_TRUE(IsNotSubstring("", "", L"needle", L"haystack"));
EXPECT_FALSE(IsNotSubstring("", "", L"needle", L"two needles"));
}
// Tests that IsNotSubstring() generates the correct message when the input
// argument type is const wchar_t*.
TEST(IsNotSubstringTest, GeneratesCorrectMessageForWideCString) {
EXPECT_STREQ(
"Value of: needle_expr\n"
" Actual: L\"needle\"\n"
"Expected: not a substring of haystack_expr\n"
"Which is: L\"two needles\"",
IsNotSubstring("needle_expr", "haystack_expr", L"needle", L"two needles")
.failure_message());
}
// Tests that IsNotSubstring returns the correct result when the input // Tests that IsNotSubstring returns the correct result when the input
// argument type is ::std::string. // argument type is ::std::string.
TEST(IsNotSubstringTest, ReturnsCorrectResultsForStdString) { TEST(IsNotSubstringTest, ReturnsCorrectResultsForStdString) {
@ -2736,6 +2677,25 @@ TEST(IsNotSubstringTest, GeneratesCorrectMessageForStdString) {
#if GTEST_HAS_STD_WSTRING #if GTEST_HAS_STD_WSTRING
// Tests that IsNotSubstring() returns the correct result when the input
// argument type is const wchar_t*.
TEST(IsNotSubstringTest, ReturnsCorrectResultForWideCString) {
EXPECT_TRUE(IsNotSubstring("", "", L"needle", L"haystack"));
EXPECT_FALSE(IsNotSubstring("", "", L"needle", L"two needles"));
}
// Tests that IsNotSubstring() generates the correct message when the input
// argument type is const wchar_t*.
TEST(IsNotSubstringTest, GeneratesCorrectMessageForWideCString) {
EXPECT_STREQ(
"Value of: needle_expr\n"
" Actual: L\"needle\"\n"
"Expected: not a substring of haystack_expr\n"
"Which is: L\"two needles\"",
IsNotSubstring("needle_expr", "haystack_expr", L"needle", L"two needles")
.failure_message());
}
// Tests that IsNotSubstring returns the correct result when the input // Tests that IsNotSubstring returns the correct result when the input
// argument type is ::std::wstring. // argument type is ::std::wstring.
TEST(IsNotSubstringTest, ReturnsCorrectResultForStdWstring) { TEST(IsNotSubstringTest, ReturnsCorrectResultForStdWstring) {
@ -3706,11 +3666,6 @@ TEST(AssertionTest, AppendUserMessage) {
EXPECT_STREQ("foo\nbar", AppendUserMessage(foo, msg).c_str()); EXPECT_STREQ("foo\nbar", AppendUserMessage(foo, msg).c_str());
} }
#ifdef __BORLANDC__
// Silences warnings: "Condition is always true", "Unreachable code"
#pragma option push -w-ccc -w-rch
#endif
// Tests ASSERT_TRUE. // Tests ASSERT_TRUE.
TEST(AssertionTest, ASSERT_TRUE) { TEST(AssertionTest, ASSERT_TRUE) {
ASSERT_TRUE(2 > 1); // NOLINT ASSERT_TRUE(2 > 1); // NOLINT
@ -3729,13 +3684,10 @@ TEST(AssertionTest, ASSERT_TRUE) {
// Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult. // Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult.
TEST(AssertionTest, AssertTrueWithAssertionResult) { TEST(AssertionTest, AssertTrueWithAssertionResult) {
ASSERT_TRUE(ResultIsEven(2)); ASSERT_TRUE(ResultIsEven(2));
#ifndef __BORLANDC__
// ICE's in C++Builder.
EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEven(3)), EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEven(3)),
"Value of: ResultIsEven(3)\n" "Value of: ResultIsEven(3)\n"
" Actual: false (3 is odd)\n" " Actual: false (3 is odd)\n"
"Expected: true"); "Expected: true");
#endif
ASSERT_TRUE(ResultIsEvenNoExplanation(2)); ASSERT_TRUE(ResultIsEvenNoExplanation(2));
EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEvenNoExplanation(3)), EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEvenNoExplanation(3)),
"Value of: ResultIsEvenNoExplanation(3)\n" "Value of: ResultIsEvenNoExplanation(3)\n"
@ -3764,13 +3716,10 @@ TEST(AssertionTest, ASSERT_FALSE) {
// Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult. // Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult.
TEST(AssertionTest, AssertFalseWithAssertionResult) { TEST(AssertionTest, AssertFalseWithAssertionResult) {
ASSERT_FALSE(ResultIsEven(3)); ASSERT_FALSE(ResultIsEven(3));
#ifndef __BORLANDC__
// ICE's in C++Builder.
EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEven(2)), EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEven(2)),
"Value of: ResultIsEven(2)\n" "Value of: ResultIsEven(2)\n"
" Actual: true (2 is even)\n" " Actual: true (2 is even)\n"
"Expected: false"); "Expected: false");
#endif
ASSERT_FALSE(ResultIsEvenNoExplanation(3)); ASSERT_FALSE(ResultIsEvenNoExplanation(3));
EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEvenNoExplanation(2)), EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEvenNoExplanation(2)),
"Value of: ResultIsEvenNoExplanation(2)\n" "Value of: ResultIsEvenNoExplanation(2)\n"
@ -3778,11 +3727,6 @@ TEST(AssertionTest, AssertFalseWithAssertionResult) {
"Expected: false"); "Expected: false");
} }
#ifdef __BORLANDC__
// Restores warnings after previous "#pragma option push" suppressed them
#pragma option pop
#endif
// Tests using ASSERT_EQ on double values. The purpose is to make // Tests using ASSERT_EQ on double values. The purpose is to make
// sure that the specialization we did for integer and anonymous enums // sure that the specialization we did for integer and anonymous enums
// isn't used for double arguments. // isn't used for double arguments.
@ -3873,9 +3817,6 @@ void ThrowNothing() {}
TEST(AssertionTest, ASSERT_THROW) { TEST(AssertionTest, ASSERT_THROW) {
ASSERT_THROW(ThrowAnInteger(), int); ASSERT_THROW(ThrowAnInteger(), int);
#ifndef __BORLANDC__
// ICE's in C++Builder 2007 and 2009.
EXPECT_FATAL_FAILURE( EXPECT_FATAL_FAILURE(
ASSERT_THROW(ThrowAnInteger(), bool), ASSERT_THROW(ThrowAnInteger(), bool),
"Expected: ThrowAnInteger() throws an exception of type bool.\n" "Expected: ThrowAnInteger() throws an exception of type bool.\n"
@ -3887,7 +3828,6 @@ TEST(AssertionTest, ASSERT_THROW) {
"Actual: it throws " ERROR_DESC "Actual: it throws " ERROR_DESC
" " " "
"with description \"A description\"."); "with description \"A description\".");
#endif
EXPECT_FATAL_FAILURE( EXPECT_FATAL_FAILURE(
ASSERT_THROW(ThrowNothing(), bool), ASSERT_THROW(ThrowNothing(), bool),
@ -4007,9 +3947,6 @@ TEST(AssertionTest, NamedEnum) {
EXPECT_NONFATAL_FAILURE(EXPECT_EQ(kE1, kE2), "Which is: 1"); EXPECT_NONFATAL_FAILURE(EXPECT_EQ(kE1, kE2), "Which is: 1");
} }
// Sun Studio and HP aCC2reject this code.
#if !defined(__SUNPRO_CC) && !defined(__HP_aCC)
// Tests using assertions with anonymous enums. // Tests using assertions with anonymous enums.
enum { enum {
kCaseA = -1, kCaseA = -1,
@ -4025,7 +3962,7 @@ enum {
// On Linux, kCaseB and kCaseA have the same value when truncated to // On Linux, kCaseB and kCaseA have the same value when truncated to
// int size. We want to test whether this will confuse the // int size. We want to test whether this will confuse the
// assertions. // assertions.
kCaseB = testing::internal::kMaxBiggestInt, kCaseB = (std::numeric_limits<intmax_t>::max)(),
#else #else
@ -4059,18 +3996,12 @@ TEST(AssertionTest, AnonymousEnum) {
ASSERT_GT(kCaseB, kCaseA); ASSERT_GT(kCaseB, kCaseA);
ASSERT_GE(kCaseA, kCaseA); ASSERT_GE(kCaseA, kCaseA);
#ifndef __BORLANDC__
// ICE's in C++Builder.
EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseB), " kCaseB\n Which is: "); EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseB), " kCaseB\n Which is: ");
EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), "\n Which is: 42"); EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), "\n Which is: 42");
#endif
EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), "\n Which is: -1"); EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), "\n Which is: -1");
} }
#endif // !GTEST_OS_MAC && !defined(__SUNPRO_CC)
#ifdef GTEST_OS_WINDOWS #ifdef GTEST_OS_WINDOWS
static HRESULT UnexpectedHRESULTFailure() { return E_UNEXPECTED; } static HRESULT UnexpectedHRESULTFailure() { return E_UNEXPECTED; }
@ -4115,13 +4046,9 @@ TEST(HRESULTAssertionTest, EXPECT_HRESULT_FAILED) {
TEST(HRESULTAssertionTest, ASSERT_HRESULT_FAILED) { TEST(HRESULTAssertionTest, ASSERT_HRESULT_FAILED) {
ASSERT_HRESULT_FAILED(E_UNEXPECTED); ASSERT_HRESULT_FAILED(E_UNEXPECTED);
#ifndef __BORLANDC__
// ICE's in C++Builder 2007 and 2009.
EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(OkHRESULTSuccess()), EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(OkHRESULTSuccess()),
"Expected: (OkHRESULTSuccess()) fails.\n" "Expected: (OkHRESULTSuccess()) fails.\n"
" Actual: 0x0"); " Actual: 0x0");
#endif
EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(FalseHRESULTSuccess()), EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(FalseHRESULTSuccess()),
"Expected: (FalseHRESULTSuccess()) fails.\n" "Expected: (FalseHRESULTSuccess()) fails.\n"
@ -4139,13 +4066,9 @@ TEST(HRESULTAssertionTest, Streaming) {
<< "expected failure", << "expected failure",
"expected failure"); "expected failure");
#ifndef __BORLANDC__
// ICE's in C++Builder 2007 and 2009.
EXPECT_FATAL_FAILURE(ASSERT_HRESULT_SUCCEEDED(E_UNEXPECTED) EXPECT_FATAL_FAILURE(ASSERT_HRESULT_SUCCEEDED(E_UNEXPECTED)
<< "expected failure", << "expected failure",
"expected failure"); "expected failure");
#endif
EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(S_OK) << "expected failure", EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(S_OK) << "expected failure",
"expected failure"); "expected failure");
@ -4523,11 +4446,6 @@ TEST(ExpectTest, ExpectFalseWithAssertionResult) {
"Expected: false"); "Expected: false");
} }
#ifdef __BORLANDC__
// Restores warnings after previous "#pragma option push" suppressed them
#pragma option pop
#endif
// Tests EXPECT_EQ. // Tests EXPECT_EQ.
TEST(ExpectTest, EXPECT_EQ) { TEST(ExpectTest, EXPECT_EQ) {
EXPECT_EQ(5, 2 + 3); EXPECT_EQ(5, 2 + 3);
@ -5040,13 +4958,10 @@ TEST(ComparisonAssertionTest, AcceptsUnprintableArgs) {
// Code tested by EXPECT_FATAL_FAILURE cannot reference local // Code tested by EXPECT_FATAL_FAILURE cannot reference local
// variables, so we have to write UnprintableChar('x') instead of x. // variables, so we have to write UnprintableChar('x') instead of x.
#ifndef __BORLANDC__
// ICE's in C++Builder.
EXPECT_FATAL_FAILURE(ASSERT_NE(UnprintableChar('x'), UnprintableChar('x')), EXPECT_FATAL_FAILURE(ASSERT_NE(UnprintableChar('x'), UnprintableChar('x')),
"1-byte object <78>"); "1-byte object <78>");
EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')), EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')),
"1-byte object <78>"); "1-byte object <78>");
#endif
EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')), EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')),
"1-byte object <79>"); "1-byte object <79>");
EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')), EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')),
@ -6539,11 +6454,6 @@ TEST(StreamingAssertionsTest, Unconditional) {
EXPECT_FATAL_FAILURE(FAIL() << "expected failure", "expected failure"); EXPECT_FATAL_FAILURE(FAIL() << "expected failure", "expected failure");
} }
#ifdef __BORLANDC__
// Silences warnings: "Condition is always true", "Unreachable code"
#pragma option push -w-ccc -w-rch
#endif
TEST(StreamingAssertionsTest, Truth) { TEST(StreamingAssertionsTest, Truth) {
EXPECT_TRUE(true) << "unexpected failure"; EXPECT_TRUE(true) << "unexpected failure";
ASSERT_TRUE(true) << "unexpected failure"; ASSERT_TRUE(true) << "unexpected failure";
@ -6562,11 +6472,6 @@ TEST(StreamingAssertionsTest, Truth2) {
"expected failure"); "expected failure");
} }
#ifdef __BORLANDC__
// Restores warnings after previous "#pragma option push" suppressed them
#pragma option pop
#endif
TEST(StreamingAssertionsTest, IntegerEquals) { TEST(StreamingAssertionsTest, IntegerEquals) {
EXPECT_EQ(1, 1) << "unexpected failure"; EXPECT_EQ(1, 1) << "unexpected failure";
ASSERT_EQ(1, 1) << "unexpected failure"; ASSERT_EQ(1, 1) << "unexpected failure";
@ -7490,10 +7395,8 @@ TEST(CopyArrayTest, WorksForDegeneratedArrays) {
TEST(CopyArrayTest, WorksForOneDimensionalArrays) { TEST(CopyArrayTest, WorksForOneDimensionalArrays) {
const char a[3] = "hi"; const char a[3] = "hi";
int b[3]; int b[3];
#ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions.
CopyArray(a, &b); CopyArray(a, &b);
EXPECT_TRUE(ArrayEq(a, b)); EXPECT_TRUE(ArrayEq(a, b));
#endif
int c[3]; int c[3];
CopyArray(a, 3, c); CopyArray(a, 3, c);
@ -7503,10 +7406,8 @@ TEST(CopyArrayTest, WorksForOneDimensionalArrays) {
TEST(CopyArrayTest, WorksForTwoDimensionalArrays) { TEST(CopyArrayTest, WorksForTwoDimensionalArrays) {
const int a[2][3] = {{0, 1, 2}, {3, 4, 5}}; const int a[2][3] = {{0, 1, 2}, {3, 4, 5}};
int b[2][3]; int b[2][3];
#ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions.
CopyArray(a, &b); CopyArray(a, &b);
EXPECT_TRUE(ArrayEq(a, b)); EXPECT_TRUE(ArrayEq(a, b));
#endif
int c[2][3]; int c[2][3];
CopyArray(a, 2, c); CopyArray(a, 2, c);

View File

@ -144,7 +144,7 @@ It is good practice to tell why you skip a test.
</properties> </properties>
<testcase name="OneProperty" file="gtest_xml_output_unittest_.cc" line="125" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest"> <testcase name="OneProperty" file="gtest_xml_output_unittest_.cc" line="125" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest">
<properties> <properties>
<property name="key_1" value="1"/> <property name="key_1" value="\u007f!caf\u00e9 \u4e2d"/>
</properties> </properties>
</testcase> </testcase>
<testcase name="IntValuedProperty" file="gtest_xml_output_unittest_.cc" line="129" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest"> <testcase name="IntValuedProperty" file="gtest_xml_output_unittest_.cc" line="129" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest">

View File

@ -123,7 +123,7 @@ class PropertyRecordingTest : public Test {
}; };
TEST_F(PropertyRecordingTest, OneProperty) { TEST_F(PropertyRecordingTest, OneProperty) {
RecordProperty("key_1", "1"); RecordProperty("key_1", "\x7F!caf\xC3\xA9 \xE4\xB8\xAD");
} }
TEST_F(PropertyRecordingTest, IntValuedProperty) { TEST_F(PropertyRecordingTest, IntValuedProperty) {