Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7260682388 | ||
|
|
0daf775f8c | ||
|
|
1a447fdce7 | ||
|
|
91c99b6ffe | ||
|
|
7358557f03 | ||
|
|
71edd0ef29 | ||
|
|
a2118f6587 | ||
|
|
49495eacfd | ||
|
|
aa1eefe02c | ||
|
|
002d14757f | ||
|
|
02e50550c6 | ||
|
|
963dd8ea18 | ||
|
|
806b89cf63 |
+13
@@ -58,6 +58,16 @@ config_setting(
|
||||
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.
|
||||
config_setting(
|
||||
name = "fuchsia",
|
||||
@@ -113,10 +123,12 @@ cc_library(
|
||||
copts = select({
|
||||
":qnx": [],
|
||||
":windows": [],
|
||||
":emscripten_without_threads": [],
|
||||
"//conditions:default": ["-pthread"],
|
||||
}),
|
||||
defines = select({
|
||||
":has_absl": ["GTEST_HAS_ABSL=1"],
|
||||
":emscripten_without_threads": ["GTEST_HAS_PTHREAD=0"],
|
||||
"//conditions:default": [],
|
||||
}),
|
||||
features = select({
|
||||
@@ -140,6 +152,7 @@ cc_library(
|
||||
"-lm",
|
||||
"-pthread",
|
||||
],
|
||||
":emscripten_without_threads": [],
|
||||
"//conditions:default": ["-pthread"],
|
||||
}),
|
||||
deps = select({
|
||||
|
||||
@@ -8,12 +8,12 @@ Our documentation is now live on GitHub Pages at
|
||||
https://google.github.io/googletest/. We recommend browsing the documentation on
|
||||
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.
|
||||
|
||||
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).
|
||||
|
||||
#### Continuous Integration
|
||||
|
||||
@@ -48,7 +48,7 @@ with the following content:
|
||||
|
||||
# Choose the most recent version available at
|
||||
# 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.
|
||||
|
||||
@@ -146,6 +146,7 @@
|
||||
#include "gmock/internal/gmock-internal-utils.h"
|
||||
#include "gmock/internal/gmock-port.h"
|
||||
#include "gmock/internal/gmock-pp.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
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
|
||||
// that type is the same as unsigned int for gcc, and invalid for
|
||||
// MSVC.
|
||||
#if GMOCK_WCHAR_T_IS_NATIVE_
|
||||
#if GTEST_HAS_NATIVE_WCHAR
|
||||
GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(wchar_t, 0U); // NOLINT
|
||||
#endif
|
||||
|
||||
@@ -940,7 +941,7 @@ class [[nodiscard]] ReturnAction final {
|
||||
std::is_convertible<R, U>, //
|
||||
std::is_move_constructible<U>>::value>::type>
|
||||
operator OnceAction<U(Args...)>() && { // NOLINT
|
||||
return Impl<U>(std::move(value_));
|
||||
return OnceImpl<U>(std::move(value_));
|
||||
}
|
||||
|
||||
template <typename U, typename... Args,
|
||||
@@ -959,13 +960,6 @@ class [[nodiscard]] ReturnAction final {
|
||||
template <typename U>
|
||||
class Impl final {
|
||||
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)) {}
|
||||
|
||||
U operator()() && { return std::move(state_->value); }
|
||||
@@ -996,18 +990,6 @@ class [[nodiscard]] ReturnAction final {
|
||||
// explicit constructor from R.
|
||||
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
|
||||
// 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
|
||||
@@ -1085,6 +1067,23 @@ class [[nodiscard]] ReturnAction final {
|
||||
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_;
|
||||
};
|
||||
|
||||
|
||||
@@ -111,16 +111,6 @@ inline Element* GetRawPointer(Element* p) {
|
||||
#define GMOCK_INTERNAL_WARNING_POP() _Pragma("clang diagnostic pop")
|
||||
#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
|
||||
// is bool, an integer type (excluding bool), a floating-point type,
|
||||
// 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_(unsigned long long, kInteger); // NOLINT
|
||||
|
||||
#if GMOCK_WCHAR_T_IS_NATIVE_
|
||||
#if GTEST_HAS_NATIVE_WCHAR
|
||||
GMOCK_DECLARE_KIND_(wchar_t, kInteger);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -270,7 +270,7 @@ TEST(BuiltInDefaultValueTest, IsZeroForNumericTypes) {
|
||||
EXPECT_EQ(0U, BuiltInDefaultValue<unsigned char>::Get());
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<signed char>::Get());
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<char>::Get());
|
||||
#if GMOCK_WCHAR_T_IS_NATIVE_
|
||||
#if GTEST_HAS_NATIVE_WCHAR
|
||||
#if !defined(__WCHAR_UNSIGNED__)
|
||||
EXPECT_EQ(0, BuiltInDefaultValue<wchar_t>::Get());
|
||||
#else
|
||||
@@ -299,7 +299,7 @@ TEST(BuiltInDefaultValueTest, ExistsForNumericTypes) {
|
||||
EXPECT_TRUE(BuiltInDefaultValue<unsigned char>::Exists());
|
||||
EXPECT_TRUE(BuiltInDefaultValue<signed char>::Exists());
|
||||
EXPECT_TRUE(BuiltInDefaultValue<char>::Exists());
|
||||
#if GMOCK_WCHAR_T_IS_NATIVE_
|
||||
#if GTEST_HAS_NATIVE_WCHAR
|
||||
EXPECT_TRUE(BuiltInDefaultValue<wchar_t>::Exists());
|
||||
#endif
|
||||
EXPECT_TRUE(BuiltInDefaultValue<unsigned short>::Exists()); // NOLINT
|
||||
@@ -1101,6 +1101,7 @@ TEST(SetArgPointeeTest, AcceptsStringLiteral) {
|
||||
EXPECT_STREQ("world", ptr);
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
TEST(SetArgPointeeTest, AcceptsWideStringLiteral) {
|
||||
typedef void MyFunction(const wchar_t**);
|
||||
Action<MyFunction> a = SetArgPointee<0>(L"world");
|
||||
@@ -1108,16 +1109,13 @@ TEST(SetArgPointeeTest, AcceptsWideStringLiteral) {
|
||||
a.Perform(std::make_tuple(&ptr));
|
||||
EXPECT_STREQ(L"world", ptr);
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
|
||||
typedef void MyStringFunction(std::wstring*);
|
||||
Action<MyStringFunction> a2 = SetArgPointee<0>(L"world");
|
||||
std::wstring str = L"";
|
||||
a2.Perform(std::make_tuple(&str));
|
||||
EXPECT_EQ(L"world", str);
|
||||
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// Tests that SetArgPointee<N>() accepts a char pointer.
|
||||
TEST(SetArgPointeeTest, AcceptsCharPointer) {
|
||||
|
||||
@@ -87,10 +87,10 @@ TEST(InitGoogleMockTest, ParsesSingleFlag) {
|
||||
|
||||
TEST(InitGoogleMockTest, ParsesMultipleFlags) {
|
||||
int old_default_behavior = GMOCK_FLAG_GET(default_mock_behavior);
|
||||
const wchar_t* argv[] = {L"foo.exe", L"--gmock_verbose=info",
|
||||
L"--gmock_default_mock_behavior=2", nullptr};
|
||||
const char* argv[] = {"foo.exe", "--gmock_verbose=info",
|
||||
"--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");
|
||||
EXPECT_EQ(2, GMOCK_FLAG_GET(default_mock_behavior));
|
||||
@@ -115,6 +115,8 @@ TEST(InitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
||||
TestInitGoogleMock(argv, new_argv, "error");
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
|
||||
TEST(WideInitGoogleMockTest, ParsesInvalidCommandLine) {
|
||||
const wchar_t* argv[] = {nullptr};
|
||||
|
||||
@@ -168,6 +170,7 @@ TEST(WideInitGoogleMockTest, ParsesGoogleMockFlagAndUnrecognizedFlag) {
|
||||
|
||||
TestInitGoogleMock(argv, new_argv, "error");
|
||||
}
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
#endif // !defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_)
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ When building GoogleTest as a standalone project, the typical workflow starts
|
||||
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.
|
||||
mkdir build # Create a directory to hold the build output.
|
||||
cd build
|
||||
|
||||
@@ -552,7 +552,7 @@ auto ConvertGenerator(Gen&& gen, Func&& f) {
|
||||
|
||||
#define INSTANTIATE_TEST_SUITE_P(prefix, test_suite_name, ...) \
|
||||
static ::testing::internal::ParamGenerator<test_suite_name::ParamType> \
|
||||
gtest_##prefix##test_suite_name##_EvalGenerator_() { \
|
||||
gtest_##prefix##test_suite_name##_EvalGenerator_() { \
|
||||
return GTEST_EXPAND_(GTEST_GET_FIRST_(__VA_ARGS__, DUMMY_PARAM_)); \
|
||||
} \
|
||||
static ::std::string gtest_##prefix##test_suite_name##_EvalGenerateName_( \
|
||||
@@ -562,7 +562,7 @@ auto ConvertGenerator(Gen&& gen, Func&& f) {
|
||||
__VA_ARGS__, \
|
||||
::testing::internal::DefaultParamName<test_suite_name::ParamType>, \
|
||||
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, \
|
||||
"Too Many Args!"); \
|
||||
} \
|
||||
|
||||
@@ -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(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.
|
||||
// Also see https://github.com/google/googletest/issues/4762.
|
||||
PrintTo(static_cast<char32_t>(c), os);
|
||||
}
|
||||
|
||||
// Overloads for the UTF-8 and UTF-16 code unit types. A code unit that
|
||||
// encodes a code point all by itself is printed with the U+XXXX notation;
|
||||
// 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
|
||||
inline 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);
|
||||
}
|
||||
GTEST_API_ void PrintTo(char8_t c, ::std::ostream* os);
|
||||
#endif
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// MSVC can be configured to define wchar_t as a typedef of unsigned
|
||||
// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native
|
||||
// type. When wchar_t is a typedef, defining an overload for const
|
||||
// wchar_t* would cause unsigned short* be printed as a wide string,
|
||||
// possibly causing invalid memory accesses.
|
||||
#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED)
|
||||
// Only add an overload for printing wchar_t* if:
|
||||
// 1. Wide string support is enabled.
|
||||
// 2. wchar_t is a distinct native type. (If it's a typedef, the overload could
|
||||
// cause a pointer to the underlying type to be mistakenly treated as a
|
||||
// string.)
|
||||
#if GTEST_HAS_STD_WSTRING && GTEST_HAS_NATIVE_WCHAR
|
||||
// Overloads for wide C strings
|
||||
GTEST_API_ void PrintTo(const 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 <>
|
||||
class [[nodiscard]] UniversalTersePrinter<wchar_t*> {
|
||||
public:
|
||||
static void Print(wchar_t* str, ::std::ostream* os) {
|
||||
UniversalTersePrinter<const wchar_t*>::Print(str, os);
|
||||
}
|
||||
};
|
||||
class [[nodiscard]] UniversalTersePrinter<wchar_t*>
|
||||
: public UniversalTersePrinter<const wchar_t*> {};
|
||||
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
template <typename T>
|
||||
void UniversalTersePrint(const T& value, ::std::ostream* os) {
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
#include "gtest/gtest-typed-test.h" // IWYU pragma: export
|
||||
#include "gtest/gtest_pred_impl.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"
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||
@@ -1514,6 +1514,8 @@ GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression,
|
||||
const char* s2_expression,
|
||||
const char* s1, const char* s2);
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
|
||||
// Helper function for *_STREQ on wide strings.
|
||||
//
|
||||
// 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 wchar_t* s1, const wchar_t* s2);
|
||||
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// 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* needle,
|
||||
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,
|
||||
const char* haystack_expr,
|
||||
const char* needle,
|
||||
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,
|
||||
const char* haystack_expr,
|
||||
const ::std::string& needle,
|
||||
@@ -1564,6 +1560,14 @@ GTEST_API_ AssertionResult IsNotSubstring(const char* needle_expr,
|
||||
const ::std::string& haystack);
|
||||
|
||||
#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,
|
||||
const char* haystack_expr,
|
||||
const ::std::wstring& needle,
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
#ifndef 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
|
||||
#include <stdlib.h>
|
||||
@@ -1516,8 +1516,9 @@ class [[nodiscard]] NeverThrown {
|
||||
parent_class>::GetSetUpCaseOrSuite(__FILE__, __LINE__), \
|
||||
::testing::internal::SuiteApiResolver< \
|
||||
parent_class>::GetTearDownCaseOrSuite(__FILE__, __LINE__), \
|
||||
new ::testing::internal::TestFactoryImpl<GTEST_TEST_CLASS_NAME_( \
|
||||
test_suite_name, test_name)>); \
|
||||
::std::make_unique<::testing::internal::TestFactoryImpl< \
|
||||
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)>>() \
|
||||
.release()); \
|
||||
void GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)::TestBody()
|
||||
|
||||
#endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_
|
||||
|
||||
@@ -500,22 +500,82 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
||||
#endif // defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
#endif // GTEST_HAS_EXCEPTIONS
|
||||
|
||||
#ifndef GTEST_HAS_STD_WSTRING
|
||||
// The user didn't tell us whether ::std::wstring is available, so we need
|
||||
// to figure it out.
|
||||
// Cygwin 1.7 and below doesn't support ::std::wstring.
|
||||
// Solaris' libc++ doesn't support it either. Android has
|
||||
// no support for it at least as recent as Froyo (2.2).
|
||||
#if (!(defined(GTEST_OS_LINUX_ANDROID) || 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 1
|
||||
// MSVC either defines wchar_t as a typedef of unsigned short, or as a native
|
||||
// type (in which case, it defines _NATIVE_WCHAR_T_DEFINED). When wchar_t is a
|
||||
// typedef, defining an overload for const wchar_t* would cause unsigned short*
|
||||
// be printed as a wide string, possibly causing invalid memory accesses, so we
|
||||
// omit wchar_t overloads in that case.
|
||||
#if defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED)
|
||||
#define GTEST_HAS_NATIVE_WCHAR 0
|
||||
#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 // GTEST_HAS_STD_WSTRING
|
||||
|
||||
#ifndef GTEST_HAS_FILE_SYSTEM
|
||||
// Most platforms support a file system.
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
#include <iomanip>
|
||||
#include <ios>
|
||||
#include <ostream> // NOLINT
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -285,6 +286,28 @@ void PrintTo(char32_t c, ::std::ostream* os) {
|
||||
<< 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
|
||||
#if defined(__SIZEOF_INT128__)
|
||||
void PrintTo(__uint128_t v, ::std::ostream* os) {
|
||||
@@ -422,6 +445,28 @@ void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) {
|
||||
|
||||
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.
|
||||
template <typename Char>
|
||||
void PrintCStringTo(const Char* s, ostream* os) {
|
||||
@@ -429,7 +474,7 @@ void PrintCStringTo(const Char* s, ostream* os) {
|
||||
*os << "NULL";
|
||||
} else {
|
||||
*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); }
|
||||
|
||||
// MSVC compiler can be configured to define whar_t as a typedef
|
||||
// of unsigned short. Defining an overload for const wchar_t* in that case
|
||||
// would cause pointers to unsigned shorts be printed as wide strings,
|
||||
// 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.
|
||||
#if GTEST_HAS_STD_WSTRING && GTEST_HAS_NATIVE_WCHAR
|
||||
void PrintTo(const wchar_t* s, ostream* os) { PrintCStringTo(s, os); }
|
||||
#endif // wchar_t is native
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
+15
-11
@@ -1876,11 +1876,13 @@ bool IsSubstringPred(const char* needle, const char* haystack) {
|
||||
return strstr(haystack, needle) != nullptr;
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) {
|
||||
if (needle == nullptr || haystack == nullptr) return needle == haystack;
|
||||
|
||||
return wcsstr(haystack, needle) != nullptr;
|
||||
}
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
// StringType here can be either ::std::string or ::std::wstring.
|
||||
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);
|
||||
}
|
||||
|
||||
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 char* needle,
|
||||
const char* 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,
|
||||
const ::std::string& needle,
|
||||
const ::std::string& haystack) {
|
||||
@@ -1953,6 +1944,17 @@ AssertionResult IsNotSubstring(const char* needle_expr,
|
||||
}
|
||||
|
||||
#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,
|
||||
const ::std::wstring& needle,
|
||||
const ::std::wstring& haystack) {
|
||||
@@ -2182,6 +2184,7 @@ bool String::WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs) {
|
||||
return wcscmp(lhs, rhs) == 0;
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
// Helper function for *_STREQ on wide strings.
|
||||
AssertionResult CmpHelperSTREQ(const char* lhs_expression,
|
||||
const char* rhs_expression, const wchar_t* lhs,
|
||||
@@ -2206,6 +2209,7 @@ AssertionResult CmpHelperSTRNE(const char* s1_expression,
|
||||
<< "Expected: (" << s1_expression << ") != (" << s2_expression
|
||||
<< "), 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
|
||||
// the same content.
|
||||
|
||||
@@ -396,12 +396,24 @@ TEST(PrintCharTest, UnsignedChar) {
|
||||
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')); }
|
||||
|
||||
#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
|
||||
|
||||
// Tests printing other simple, built-in types.
|
||||
@@ -456,7 +468,7 @@ TEST(PrintBuiltInTypeTest, Integer) {
|
||||
#ifdef __cpp_lib_char8_t
|
||||
EXPECT_EQ("U+0000",
|
||||
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
|
||||
#endif
|
||||
EXPECT_EQ("U+0000",
|
||||
@@ -648,13 +660,8 @@ TEST(PrintU32StringTest, EscapesProperly) {
|
||||
Print(p));
|
||||
}
|
||||
|
||||
// MSVC compiler can be configured to define whar_t as a typedef
|
||||
// of unsigned short. Defining an overload for const wchar_t* in that case
|
||||
// would cause pointers to unsigned shorts be printed as wide strings,
|
||||
// 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)
|
||||
#if GTEST_HAS_NATIVE_WCHAR
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
|
||||
// const wchar_t*.
|
||||
TEST(PrintWideCStringTest, Const) {
|
||||
@@ -685,7 +692,8 @@ TEST(PrintWideCStringTest, EscapesProperly) {
|
||||
"\\n\\r\\t\\v\\xD3\\x576\\x8D3\\xC74D a\"",
|
||||
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.
|
||||
|
||||
|
||||
@@ -2564,6 +2564,7 @@ TEST(StringAssertionTest, ASSERT_STRCASENE) {
|
||||
EXPECT_FATAL_FAILURE(ASSERT_STRCASENE("Hi", "hi"), "(ignoring case)");
|
||||
}
|
||||
|
||||
#if GTEST_HAS_STD_WSTRING
|
||||
// Tests *_STREQ on wide strings.
|
||||
TEST(StringAssertionTest, STREQ_Wide) {
|
||||
// NULL strings.
|
||||
@@ -2619,6 +2620,7 @@ TEST(StringAssertionTest, STRNE_Wide) {
|
||||
// The streaming variation.
|
||||
ASSERT_STRNE(L"abc\x8119", L"abc\x8120") << "This shouldn't happen";
|
||||
}
|
||||
#endif // GTEST_HAS_STD_WSTRING
|
||||
|
||||
// Tests for ::testing::IsSubstring().
|
||||
|
||||
@@ -2633,18 +2635,6 @@ TEST(IsSubstringTest, ReturnsCorrectResultForCString) {
|
||||
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
|
||||
// argument type is const char*.
|
||||
TEST(IsSubstringTest, GeneratesCorrectMessageForCString) {
|
||||
@@ -2665,6 +2655,18 @@ TEST(IsSubstringTest, ReturnsCorrectResultsForStdString) {
|
||||
}
|
||||
|
||||
#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
|
||||
// argument type is ::std::wstring.
|
||||
TEST(IsSubstringTest, ReturnsCorrectResultForStdWstring) {
|
||||
@@ -2696,25 +2698,6 @@ TEST(IsNotSubstringTest, ReturnsCorrectResultForCString) {
|
||||
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
|
||||
// argument type is ::std::string.
|
||||
TEST(IsNotSubstringTest, ReturnsCorrectResultsForStdString) {
|
||||
@@ -2736,6 +2719,25 @@ TEST(IsNotSubstringTest, GeneratesCorrectMessageForStdString) {
|
||||
|
||||
#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
|
||||
// argument type is ::std::wstring.
|
||||
TEST(IsNotSubstringTest, ReturnsCorrectResultForStdWstring) {
|
||||
|
||||
Reference in New Issue
Block a user