mirror of
https://github.com/google/googletest.git
synced 2026-10-28 18:07:18 +08:00
Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd8e73f067 | ||
|
|
b66cffcd5f | ||
|
|
988ea2c179 | ||
|
|
bc548fd273 | ||
|
|
3ca3771f9c | ||
|
|
5a4a3c968b | ||
|
|
4267679b68 | ||
|
|
f840327b0f | ||
|
|
8eff9e3366 | ||
|
|
dd0a37b843 | ||
|
|
7e91a413e8 | ||
|
|
283c17563f | ||
|
|
efbef50b59 | ||
|
|
8ecdd89c69 | ||
|
|
b769fc08a4 | ||
|
|
5f31f20eda | ||
|
|
3b49a56fe3 | ||
|
|
c3e1e7fe8e | ||
|
|
defb708946 | ||
|
|
4957858705 | ||
|
|
c06edf0146 | ||
|
|
d94a7326e9 | ||
|
|
36ba75f0ad | ||
|
|
938220d0f6 | ||
|
|
e273a2d81e | ||
|
|
bfff9fc387 | ||
|
|
7260682388 | ||
|
|
0daf775f8c | ||
|
|
1a447fdce7 | ||
|
|
91c99b6ffe | ||
|
|
7358557f03 | ||
|
|
71edd0ef29 | ||
|
|
a2118f6587 | ||
|
|
49495eacfd | ||
|
|
aa1eefe02c | ||
|
|
002d14757f | ||
|
|
02e50550c6 | ||
|
|
963dd8ea18 | ||
|
|
806b89cf63 |
13
BUILD.bazel
13
BUILD.bazel
@ -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({
|
||||
|
||||
@ -32,7 +32,7 @@
|
||||
|
||||
module(
|
||||
name = "googletest",
|
||||
version = "1.18.0",
|
||||
version = "head",
|
||||
compatibility_level = 1,
|
||||
)
|
||||
|
||||
|
||||
@ -69,7 +69,7 @@ IF EXIST "%KOKORO_GFILE_DIR%\distdir\googletest_vendor.tar.gz" (
|
||||
--keep_going ^
|
||||
--per_file_copt=external/.*@/w ^
|
||||
--test_output=errors ^
|
||||
--test_tag_filters=-no_test_msvc2017 ^
|
||||
--test_tag_filters=-no_test_msvc2022 ^
|
||||
%VENDOR_FLAG%
|
||||
IF %errorlevel% neq 0 EXIT /B 1
|
||||
|
||||
@ -84,6 +84,6 @@ IF %errorlevel% neq 0 EXIT /B 1
|
||||
--keep_going ^
|
||||
--per_file_copt=external/.*@/w ^
|
||||
--test_output=errors ^
|
||||
--test_tag_filters=-no_test_msvc2017 ^
|
||||
--test_tag_filters=-no_test_msvc2022 ^
|
||||
%VENDOR_FLAG%
|
||||
IF %errorlevel% neq 0 EXIT /B 1
|
||||
|
||||
@ -416,41 +416,16 @@ systems (Linux, Cygwin, Mac), GoogleTest uses the
|
||||
syntax. To learn about POSIX syntax, you may want to read this
|
||||
[Wikipedia entry](https://en.wikipedia.org/wiki/Regular_expression#POSIX_extended).
|
||||
|
||||
On Windows, GoogleTest uses its own simple regular expression implementation. It
|
||||
lacks many features. For example, we don't support union (`"x|y"`), grouping
|
||||
(`"(xy)"`), brackets (`"[xy]"`), and repetition count (`"x{5,7}"`), among
|
||||
others. Below is what we do support (`A` denotes a literal character, period
|
||||
(`.`), 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`
|
||||
Otherwise (e.g. on Windows), GoogleTest uses the
|
||||
[`std::regex`](https://en.cppreference.com/w/cpp/regex) implementation from the
|
||||
C++ standard library with the
|
||||
[ECMAScript](https://en.cppreference.com/w/cpp/regex/ecmascript) syntax.
|
||||
|
||||
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:
|
||||
`GTEST_USES_SIMPLE_RE=1` or `GTEST_USES_POSIX_RE=1`. If you want your death
|
||||
tests to work in all cases, you can either `#if` on these macros or use the more
|
||||
limited syntax only.
|
||||
`GTEST_USES_RE2=1`, `GTEST_USES_POSIX_RE=1`, or `GTEST_USES_STD_RE=1`. If you
|
||||
want your death tests to work in all cases, you can either `#if` on these macros
|
||||
or use regular expressions supported by all engines.
|
||||
|
||||
## Death Tests
|
||||
|
||||
|
||||
@ -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_;
|
||||
};
|
||||
|
||||
|
||||
@ -277,13 +277,6 @@
|
||||
#include "gtest/gtest.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
|
||||
namespace proto2 {
|
||||
namespace internal {
|
||||
@ -323,8 +316,8 @@ T* DynamicCastMessageForGtest(proto2::MessageLite* msg) {
|
||||
#endif // GTEST_HAS_RTTI
|
||||
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(
|
||||
4251 GMOCK_MAYBE_5046_ /* 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
|
||||
4251 5046
|
||||
/* Symbol involving type with internal linkage not defined */)
|
||||
|
||||
namespace testing {
|
||||
@ -3971,8 +3964,8 @@ class [[nodiscard]] UnorderedElementsAreMatcherImpl
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename ElementIter>
|
||||
MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIter elem_last,
|
||||
template <typename ElementIter, typename ElementIterEnd>
|
||||
MatchMatrix AnalyzeElements(ElementIter elem_first, ElementIterEnd elem_last,
|
||||
::std::vector<std::string>* element_printouts,
|
||||
MatchResultListener* listener) const {
|
||||
element_printouts->clear();
|
||||
@ -4157,7 +4150,8 @@ class [[nodiscard]] UnorderedElementsAreMatcher {
|
||||
template <typename Container>
|
||||
operator Matcher<Container>() const {
|
||||
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;
|
||||
MatcherVec matchers;
|
||||
matchers.reserve(::std::tuple_size<MatcherTuple>::value);
|
||||
@ -4538,7 +4532,7 @@ class [[nodiscard]] ArgsMatcherImpl : public MatcherInterface<ArgsTuple> {
|
||||
|
||||
bool MatchAndExplain(ArgsTuple args,
|
||||
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;
|
||||
const SelectedArgs& selected_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) {
|
||||
*os << "whose fields (";
|
||||
const char* sep = "";
|
||||
// Workaround spurious C4189 on MSVC<=15.7 when k is empty.
|
||||
// Workaround spurious GCC warning when k is empty.
|
||||
(void)sep;
|
||||
// The static_cast to void is needed to silence Clang's -Wcomma warning.
|
||||
// This pattern looks suspiciously like we may have mismatched parentheses
|
||||
|
||||
@ -50,11 +50,6 @@ namespace testing {
|
||||
// Silence C4100 (unreferenced formal
|
||||
// parameter) for MSVC
|
||||
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 {
|
||||
|
||||
@ -123,9 +118,6 @@ MATCHER(IsFalse, negation ? "is true" : "is false") {
|
||||
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
|
||||
|
||||
} // namespace testing
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -62,10 +62,11 @@
|
||||
#include "absl/flags/flag.h"
|
||||
#endif
|
||||
|
||||
// For MS Visual C++, check the compiler version. At least VS 2015 is
|
||||
// required to compile Google Mock.
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
#error "At least Visual C++ 2015 (14.0) is required to compile Google Mock."
|
||||
// For MS Visual C++, check the compiler version. At least VS 2022 is
|
||||
// required to compile Google Mock (_MSC_VER >= 1930). We use a slightly lower
|
||||
// version for internal toolchains lagging behind.
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1925
|
||||
#error "At least Visual C++ 2022 (17.0) is required to compile Google Mock."
|
||||
#endif
|
||||
|
||||
// Macro for referencing flags. This is public as we want the user to
|
||||
|
||||
@ -56,12 +56,6 @@
|
||||
#include <qurt_event.h>
|
||||
#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 internal {
|
||||
|
||||
@ -786,7 +780,3 @@ InSequence::~InSequence() {
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER == 1900)
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4800
|
||||
#endif
|
||||
|
||||
@ -74,8 +74,7 @@ py_test(
|
||||
":gmock_test_utils",
|
||||
],
|
||||
tags = [
|
||||
"no_test_msvc2015",
|
||||
"no_test_msvc2017",
|
||||
"no_test_msvc2022",
|
||||
],
|
||||
)
|
||||
|
||||
@ -105,8 +104,7 @@ py_test(
|
||||
":gmock_output_test_golden.txt",
|
||||
],
|
||||
tags = [
|
||||
"no_test_msvc2015",
|
||||
"no_test_msvc2017",
|
||||
"no_test_msvc2022",
|
||||
],
|
||||
deps = [":gmock_test_utils"],
|
||||
)
|
||||
|
||||
@ -53,11 +53,6 @@
|
||||
// Silence C4100 (unreferenced formal parameter) and C4503 (decorated name
|
||||
// length exceeded) for MSVC.
|
||||
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 {
|
||||
@ -270,7 +265,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 +294,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 +1096,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 +1104,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) {
|
||||
@ -2219,7 +2212,4 @@ TEST(ActionMacro, LargeArity) {
|
||||
} // namespace
|
||||
} // namespace testing
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER == 1900)
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4800
|
||||
#endif
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_() // 4100 4503
|
||||
|
||||
@ -1046,12 +1046,7 @@ struct MoveHelper {
|
||||
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) {
|
||||
#endif
|
||||
MoveOnly m{0};
|
||||
MoveHelper helper;
|
||||
|
||||
|
||||
@ -78,6 +78,52 @@ TEST(ContainsTest, WorksWithMoveOnly) {
|
||||
|
||||
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
|
||||
TEST(ElementsAreTest, HugeMatcher) {
|
||||
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)));
|
||||
}
|
||||
|
||||
// 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
|
||||
TEST(ElementsAreTest, HugeMatcherStr) {
|
||||
vector<std::string> test_vector{
|
||||
@ -105,6 +158,13 @@ TEST(ElementsAreTest, HugeMatcherUnordered) {
|
||||
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
|
||||
// matches the matcher.
|
||||
TEST(MatcherAssertionTest, WorksWhenMatcherIsSatisfied) {
|
||||
@ -2228,6 +2288,13 @@ TEST_F(UnorderedElementsAreTest, WorksWithUncopyable) {
|
||||
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) {
|
||||
const int a[] = {1, 2, 3};
|
||||
std::vector<int> s(std::begin(a), std::end(a));
|
||||
|
||||
@ -1088,22 +1088,16 @@ TEST(UnexpectedCallTest, UnsatisfiedPrerequisites) {
|
||||
|
||||
// Verifies that the failure message contains the two unsatisfied
|
||||
// pre-requisites but not the satisfied one.
|
||||
#ifdef GTEST_USES_POSIX_RE
|
||||
EXPECT_THAT(r.message(),
|
||||
ContainsRegex(
|
||||
// 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"
|
||||
"(.|\n)*: pre-requisite #0\n"
|
||||
"(.|\n)*: pre-requisite #1"));
|
||||
#else
|
||||
// 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]*: pre-requisite #0\n"
|
||||
"[^\b]*: pre-requisite #1"))
|
||||
<< r.message();
|
||||
|
||||
b.DoB(1);
|
||||
b.DoB(3);
|
||||
|
||||
@ -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_)
|
||||
|
||||
|
||||
@ -226,13 +226,10 @@ if (gtest_build_tests)
|
||||
############################################################
|
||||
# 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}"
|
||||
src/gtest-all.cc)
|
||||
cxx_library(gtest_main_no_exception "${cxx_no_exception}"
|
||||
src/gtest-all.cc src/gtest_main.cc)
|
||||
endif()
|
||||
cxx_library(gtest_no_exception "${cxx_no_exception}"
|
||||
src/gtest-all.cc)
|
||||
cxx_library(gtest_main_no_exception "${cxx_no_exception}"
|
||||
src/gtest-all.cc src/gtest_main.cc)
|
||||
cxx_library(gtest_main_no_rtti "${cxx_no_rtti}"
|
||||
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_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(
|
||||
googletest-catch-exceptions-no-ex-test_
|
||||
"${cxx_no_exception}"
|
||||
gtest_main_no_exception
|
||||
test/googletest-catch-exceptions-test_.cc)
|
||||
endif()
|
||||
cxx_executable_with_flags(
|
||||
googletest-catch-exceptions-no-ex-test_
|
||||
"${cxx_no_exception}"
|
||||
gtest_main_no_exception
|
||||
test/googletest-catch-exceptions-test_.cc)
|
||||
|
||||
cxx_executable_with_flags(
|
||||
googletest-catch-exceptions-ex-test_
|
||||
@ -301,14 +295,11 @@ if (gtest_build_tests)
|
||||
cxx_executable(googletest-shuffle-test_ test gtest)
|
||||
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)
|
||||
set_target_properties(googletest-throw-on-failure-test_
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "${cxx_no_exception}")
|
||||
py_test(googletest-throw-on-failure-test)
|
||||
endif()
|
||||
cxx_executable(googletest-throw-on-failure-test_ test gtest_no_exception)
|
||||
set_target_properties(googletest-throw-on-failure-test_
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "${cxx_no_exception}")
|
||||
py_test(googletest-throw-on-failure-test)
|
||||
|
||||
cxx_executable(googletest-uninitialized-test_ test gtest)
|
||||
py_test(googletest-uninitialized-test)
|
||||
|
||||
@ -113,39 +113,12 @@ macro(config_compiler_and_linker)
|
||||
endif()
|
||||
endif()
|
||||
elseif (CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(cxx_base_flags "-Wall -Wshadow -Wundef")
|
||||
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_base_flags "-Wall -Wshadow -Wundef -Wno-error=dangling-else")
|
||||
set(cxx_exception_flags "-fexceptions")
|
||||
set(cxx_no_exception_flags "-fno-exceptions")
|
||||
# Until version 4.3.2, GCC doesn't define a macro to indicate
|
||||
# whether RTTI is enabled. Therefore we define GTEST_HAS_RTTI
|
||||
# explicitly.
|
||||
set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0")
|
||||
set(cxx_no_rtti_flags "-fno-rtti")
|
||||
set(cxx_strict_flags
|
||||
"-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()
|
||||
|
||||
# The pthreads library is available and allowed?
|
||||
|
||||
@ -143,13 +143,9 @@ class GTEST_API_ [[nodiscard]] AssertionResult {
|
||||
// Used in EXPECT_TRUE/FALSE(assertion_result).
|
||||
AssertionResult(const AssertionResult& other);
|
||||
|
||||
// C4800 is a level 3 warning in Visual Studio 2015 and earlier.
|
||||
// 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.
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)
|
||||
// C4800 is off by default starting in Visual Studio 2019 but can be
|
||||
// enabled with command-line options.
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */)
|
||||
#endif
|
||||
|
||||
// Used in the EXPECT_TRUE/FALSE(bool_expression).
|
||||
//
|
||||
@ -171,9 +167,7 @@ class GTEST_API_ [[nodiscard]] AssertionResult {
|
||||
int> = 0>
|
||||
explicit AssertionResult(const T& success) : success_(success) {}
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1910 || _MSC_VER >= 1920)
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
||||
#endif
|
||||
|
||||
// Assignment operator.
|
||||
AssertionResult& operator=(AssertionResult other) {
|
||||
|
||||
@ -105,54 +105,10 @@ GTEST_API_ bool InDeathTestChild();
|
||||
//
|
||||
// On the regular expressions used in death tests:
|
||||
//
|
||||
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
|
||||
// which uses the POSIX extended regex syntax.
|
||||
//
|
||||
// On other platforms (e.g. Windows or Mac), we only support a simple regex
|
||||
// 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.
|
||||
// Depending on the platform, this may use RE2, the POSIX <regex.h> library,
|
||||
// the C++11 standard library's <regex> engine with ECMAScript syntax, or
|
||||
// another similar engine. Regular expressions should be simple and portable
|
||||
// enough to work across the engines of interest.
|
||||
//
|
||||
// Known caveats:
|
||||
//
|
||||
|
||||
@ -52,16 +52,9 @@
|
||||
#include "gtest/internal/gtest-internal.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_(
|
||||
4251 GTEST_MAYBE_5046_ /* 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
|
||||
4251 5046
|
||||
/* Symbol involving type with internal linkage not defined */)
|
||||
|
||||
namespace testing {
|
||||
|
||||
@ -510,9 +510,9 @@ auto ConvertGenerator(Gen&& gen, Func&& f) {
|
||||
private ::testing::internal::GTestNonCopyable { \
|
||||
public: \
|
||||
GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \
|
||||
void TestBody() override; \
|
||||
\
|
||||
private: \
|
||||
void TestBody() override; \
|
||||
static int AddToRegistry() { \
|
||||
::testing::UnitTest::GetInstance() \
|
||||
->parameterized_test_registry() \
|
||||
@ -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!"); \
|
||||
} \
|
||||
|
||||
@ -104,6 +104,8 @@
|
||||
#ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||
#define GOOGLETEST_INCLUDE_GTEST_GTEST_PRINTERS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <any>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
@ -279,15 +281,13 @@ struct ProtobufPrinter {
|
||||
|
||||
struct ConvertibleToIntegerPrinter {
|
||||
// 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
|
||||
// case printing it as an integer is the desired behavior. In case
|
||||
// T is not an enum, printing it as an integer is the best we can do
|
||||
// given that it has no user-defined printer.
|
||||
static void PrintValue(internal::BiggestInt value, ::std::ostream* os) {
|
||||
*os << value;
|
||||
}
|
||||
static void PrintValue(intmax_t value, ::std::ostream* os) { *os << value; }
|
||||
};
|
||||
|
||||
struct ConvertibleToStringViewPrinter {
|
||||
@ -347,7 +347,7 @@ struct FindFirstPrinter<
|
||||
// - Print object pointers.
|
||||
// - Print protocol buffers.
|
||||
// - Use the stream operator, if available.
|
||||
// - Print types convertible to BiggestInt.
|
||||
// - Print types convertible to intmax_t.
|
||||
// - Print types convertible to StringView, if available.
|
||||
// - Fallback to printing the raw bytes of the object.
|
||||
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(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) {
|
||||
|
||||
@ -256,8 +256,11 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
||||
// The variables defined in the type-parameterized test macros are
|
||||
// static as typically these macros are used in a .h file that can be
|
||||
// #included in multiple translation units linked together.
|
||||
#define TYPED_TEST_SUITE_P(SuiteName) \
|
||||
static ::testing::internal::TypedTestSuitePState \
|
||||
// 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) \
|
||||
[[maybe_unused]] static ::testing::internal::TypedTestSuitePState \
|
||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName)
|
||||
|
||||
// Legacy API is deprecated but still available
|
||||
@ -267,22 +270,24 @@ INSTANTIATE_TYPED_TEST_SUITE_P(My, FooTest, MyTypes);
|
||||
TYPED_TEST_SUITE_P
|
||||
#endif // GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
|
||||
#define TYPED_TEST_P(SuiteName, TestName) \
|
||||
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class TestName : public SuiteName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef SuiteName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
void TestBody() override; \
|
||||
}; \
|
||||
[[maybe_unused]] static bool gtest_##TestName##_defined_ = \
|
||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTestName( \
|
||||
__FILE__, __LINE__, GTEST_STRINGIFY_(SuiteName), \
|
||||
GTEST_STRINGIFY_(TestName)); \
|
||||
} \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_SUITE_NAMESPACE_( \
|
||||
#define TYPED_TEST_P(SuiteName, TestName) \
|
||||
namespace GTEST_SUITE_NAMESPACE_(SuiteName) { \
|
||||
template <typename gtest_TypeParam_> \
|
||||
class TestName : public SuiteName<gtest_TypeParam_> { \
|
||||
private: \
|
||||
typedef SuiteName<gtest_TypeParam_> TestFixture; \
|
||||
typedef gtest_TypeParam_ TypeParam; \
|
||||
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_ = \
|
||||
GTEST_TYPED_TEST_SUITE_P_STATE_(SuiteName).AddTest( \
|
||||
>est_##TestName##_registered_test_, GTEST_STRINGIFY_(SuiteName)); \
|
||||
} \
|
||||
template <typename gtest_TypeParam_> \
|
||||
void GTEST_SUITE_NAMESPACE_( \
|
||||
SuiteName)::TestName<gtest_TypeParam_>::TestBody()
|
||||
|
||||
// Note: this won't work correctly if the trailing arguments are macros.
|
||||
|
||||
@ -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 \
|
||||
@ -1419,14 +1419,14 @@ class [[nodiscard]] EqHelper {
|
||||
}
|
||||
|
||||
// With this overloaded version, we allow anonymous enums to be used
|
||||
// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous
|
||||
// enums can be implicitly cast to BiggestInt.
|
||||
// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums can be
|
||||
// implicitly cast to intmax_t.
|
||||
//
|
||||
// Even though its body looks the same as the above version, we
|
||||
// cannot merge the two, as it will make anonymous enums unhappy.
|
||||
static AssertionResult Compare(const char* lhs_expression,
|
||||
const char* rhs_expression, BiggestInt lhs,
|
||||
BiggestInt rhs) {
|
||||
const char* rhs_expression, intmax_t lhs,
|
||||
intmax_t 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* 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>
|
||||
@ -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 */)
|
||||
|
||||
// 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 {
|
||||
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
|
||||
// if the test suite hasn't been registered; otherwise aborts the
|
||||
// program.
|
||||
bool AddTestName(const char* file, int line, const char* case_name,
|
||||
const char* test_name) {
|
||||
constexpr TypedTestSuitePState() = default;
|
||||
|
||||
// Adds the given test to registered_tests_ and returns true if the test
|
||||
// suite hasn't been registered; otherwise aborts the program.
|
||||
bool AddTest(RegisteredTest* test, const char* case_name) {
|
||||
if (registered_) {
|
||||
fprintf(stderr,
|
||||
"%s Test %s must be defined before "
|
||||
"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);
|
||||
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 = ®istered_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;
|
||||
}
|
||||
|
||||
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 {
|
||||
RegisteredTestsMap::const_iterator it = registered_tests_.find(test_name);
|
||||
GTEST_CHECK_(it != registered_tests_.end());
|
||||
return it->second;
|
||||
CodeLocation GetCodeLocation(const std::string& test_name) const {
|
||||
const RegisteredTest* test = FindTest(test_name);
|
||||
GTEST_CHECK_(test != nullptr);
|
||||
return CodeLocation(test->file, test->line);
|
||||
}
|
||||
|
||||
// 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.
|
||||
const char* VerifyRegisteredTestNames(const char* test_suite_name,
|
||||
const char* file, int line,
|
||||
const char* registered_tests);
|
||||
|
||||
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_;
|
||||
RegisteredTestsMap registered_tests_;
|
||||
bool registered_ = false;
|
||||
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
|
||||
#ifndef GTEST_REMOVE_LEGACY_TEST_CASEAPI_
|
||||
using TypedTestCasePState = TypedTestSuitePState;
|
||||
@ -1516,8 +1552,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_
|
||||
|
||||
@ -601,7 +601,7 @@ class [[nodiscard]] ParameterizedTestSuiteInfo
|
||||
|
||||
MakeAndRegisterTestInfo(
|
||||
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,
|
||||
GetTestSuiteTypeId(),
|
||||
SuiteApiResolver<TestSuite>::GetSetUpCaseOrSuite(file, line),
|
||||
|
||||
@ -176,7 +176,7 @@
|
||||
// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with
|
||||
// GTEST_HAS_POSIX_RE (see above) which users can
|
||||
// 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.
|
||||
// GTEST_HAS_ABSL - Google Test is compiled with Abseil.
|
||||
|
||||
@ -236,7 +236,6 @@
|
||||
// Integer types:
|
||||
// TypeWithSize - maps an integer to a int type.
|
||||
// TimeInMillis - integers of known sizes.
|
||||
// BiggestInt - the biggest signed integer type.
|
||||
//
|
||||
// Command-line utilities:
|
||||
// GetInjectableArgvs() - returns the command line as a vector of strings.
|
||||
@ -342,13 +341,6 @@
|
||||
#define GTEST_INIT_GOOGLE_TEST_NAME_ "testing::InitGoogleTest"
|
||||
#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.
|
||||
//
|
||||
// GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 4385)
|
||||
@ -446,8 +438,9 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
||||
#include <regex.h> // NOLINT
|
||||
#define GTEST_USES_POSIX_RE 1
|
||||
#else
|
||||
// Use our own simple regex implementation.
|
||||
#define GTEST_USES_SIMPLE_RE 1
|
||||
// Use std::regex from the C++ standard library.
|
||||
#include <regex> // NOLINT
|
||||
#define GTEST_USES_STD_RE 1
|
||||
#endif
|
||||
|
||||
#ifndef GTEST_HAS_EXCEPTIONS
|
||||
@ -456,14 +449,6 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
||||
#if defined(_MSC_VER) && defined(_CPPUNWIND)
|
||||
// MSVC defines _CPPUNWIND to 1 if and only if exceptions are enabled.
|
||||
#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__)
|
||||
// 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,
|
||||
@ -481,41 +466,89 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
||||
#elif defined(__GNUC__) && defined(__EXCEPTIONS) && __EXCEPTIONS
|
||||
// gcc defines __EXCEPTIONS to 1 if and only if exceptions are enabled.
|
||||
#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
|
||||
// For other compilers, we assume exceptions are disabled to be
|
||||
// conservative.
|
||||
#define GTEST_HAS_EXCEPTIONS 0
|
||||
#endif // defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
#endif // defined(_MSC_VER) && defined(_CPPUNWIND)
|
||||
#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.
|
||||
@ -561,16 +594,6 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
||||
|
||||
#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
|
||||
|
||||
// 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,
|
||||
// Sun Pro CC, IBM Visual Age, and HP aCC support.
|
||||
#if defined(__GNUC__) || defined(_MSC_VER) || defined(__SUNPRO_CC) || \
|
||||
defined(__IBMCPP__) || defined(__HP_aCC)
|
||||
#if defined(__GNUC__) || defined(_MSC_VER)
|
||||
#define GTEST_HAS_TYPED_TEST 1
|
||||
#define GTEST_HAS_TYPED_TEST_P 1
|
||||
#endif
|
||||
@ -807,8 +829,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
||||
#ifndef GTEST_HAS_SEH
|
||||
// The user didn't tell us, so we need to figure it out.
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
// These two compilers are known to support SEH.
|
||||
#ifdef _MSC_VER
|
||||
#define GTEST_HAS_SEH 1
|
||||
#else
|
||||
// Assume no SEH.
|
||||
@ -972,12 +993,11 @@ class GTEST_API_ [[nodiscard]] RE {
|
||||
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 \
|
||||
/* 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
|
||||
// Regular Expression syntax.
|
||||
// A simple C++ wrapper for <regex.h> or <regex>.
|
||||
class GTEST_API_ [[nodiscard]] RE {
|
||||
public:
|
||||
// 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 partial_regex_; // For PartialMatch().
|
||||
|
||||
#else // GTEST_USES_SIMPLE_RE
|
||||
#else // GTEST_USES_STD_RE
|
||||
|
||||
std::string full_pattern_; // For FullMatch();
|
||||
std::regex regex_;
|
||||
|
||||
#endif
|
||||
};
|
||||
@ -1735,14 +1755,16 @@ class [[nodiscard]] MutexBase {
|
||||
#define GTEST_DECLARE_STATIC_MUTEX_(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.
|
||||
// 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) \
|
||||
::testing::internal::MutexBase mutex = {PTHREAD_MUTEX_INITIALIZER, false, 0}
|
||||
#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
|
||||
::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
|
||||
// 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 __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) || \
|
||||
defined(GTEST_OS_IOS) || defined(GTEST_OS_WINDOWS_PHONE) || \
|
||||
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) {
|
||||
return _stricmp(s1, s2);
|
||||
}
|
||||
#endif // __BORLANDC__
|
||||
|
||||
#else
|
||||
|
||||
@ -2136,7 +2151,13 @@ GTEST_DISABLE_DEPRECATED_PUSH_()
|
||||
!defined(GTEST_OS_WINDOWS_RT) && !defined(GTEST_OS_WINDOWS_GAMES) && \
|
||||
!defined(GTEST_OS_ESP8266) && !defined(GTEST_OS_XTENSA) && \
|
||||
!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
|
||||
inline FILE* FOpen(const char* path, const char* mode) {
|
||||
#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) {
|
||||
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
|
||||
inline int FClose(FILE* fp) { return fclose(fp); }
|
||||
#if !defined(GTEST_OS_WINDOWS_MOBILE) && !defined(GTEST_OS_QURT)
|
||||
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));
|
||||
#endif
|
||||
}
|
||||
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));
|
||||
#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_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.
|
||||
static_cast<void>(name); // To prevent 'unused argument' warning.
|
||||
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
|
||||
return getenv(name);
|
||||
#endif
|
||||
@ -2217,14 +2253,6 @@ GTEST_DISABLE_DEPRECATED_POP_()
|
||||
#define GTEST_SNPRINTF_ snprintf
|
||||
#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
|
||||
// type. It maps a size in bytes to a primitive type with that
|
||||
// size. e.g.
|
||||
|
||||
@ -43,11 +43,6 @@
|
||||
#ifndef 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 <cstdint>
|
||||
|
||||
@ -47,8 +47,6 @@
|
||||
// libstdc++ (which is where cxxabi.h comes from).
|
||||
#if GTEST_HAS_CXXABI_H_
|
||||
#include <cxxabi.h>
|
||||
#elif defined(__HP_aCC)
|
||||
#include <acxx_demangle.h>
|
||||
#endif // GTEST_HASH_CXXABI_H_
|
||||
|
||||
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.
|
||||
inline std::string GetTypeName(const std::type_info& type) {
|
||||
const char* const name = type.name();
|
||||
#if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC)
|
||||
#if GTEST_HAS_CXXABI_H_
|
||||
int status = 0;
|
||||
// gcc's implementation of typeid(T).name() mangles the type name,
|
||||
// so we have to demangle it.
|
||||
#if GTEST_HAS_CXXABI_H_
|
||||
using abi::__cxa_demangle;
|
||||
#endif // GTEST_HAS_CXXABI_H_
|
||||
char* const readable_name = __cxa_demangle(name, nullptr, nullptr, &status);
|
||||
const std::string name_str(status == 0 ? readable_name : name);
|
||||
free(readable_name);
|
||||
@ -117,7 +113,7 @@ inline std::string GetTypeName(const std::type_info& type) {
|
||||
return s;
|
||||
#else
|
||||
return name;
|
||||
#endif // GTEST_HAS_CXXABI_H_ || __HP_aCC
|
||||
#endif // GTEST_HAS_CXXABI_H_
|
||||
}
|
||||
#endif // GTEST_HAS_RTTI
|
||||
|
||||
|
||||
@ -325,7 +325,7 @@ FilePath FilePath::GenerateUniqueFileName(const FilePath& directory,
|
||||
// This does NOT check that a directory (or file) actually exists.
|
||||
bool FilePath::IsDirectory() const {
|
||||
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
|
||||
|
||||
@ -980,26 +980,7 @@ inline UnitTestImpl* GetUnitTestImpl() {
|
||||
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
|
||||
// other parts of Google Test.
|
||||
|
||||
@ -766,249 +766,46 @@ void RE::Init(const char* regex) {
|
||||
delete[] full_pattern;
|
||||
}
|
||||
|
||||
#elif defined(GTEST_USES_SIMPLE_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.
|
||||
#elif defined(GTEST_USES_STD_RE)
|
||||
|
||||
RE::~RE() = default;
|
||||
|
||||
// Returns true if and only if regular expression re matches the entire str.
|
||||
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
|
||||
// str (including str itself).
|
||||
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.
|
||||
void RE::Init(const char* regex) {
|
||||
full_pattern_.clear();
|
||||
pattern_.clear();
|
||||
pattern_ = regex == nullptr ? "" : regex;
|
||||
is_valid_ = false;
|
||||
|
||||
if (regex != nullptr) {
|
||||
pattern_ = regex;
|
||||
}
|
||||
|
||||
is_valid_ = ValidateRegex(regex);
|
||||
if (!is_valid_) {
|
||||
// No need to calculate the full pattern when the regex is invalid.
|
||||
if (regex == nullptr) {
|
||||
ADD_FAILURE() << "NULL is not a valid regular expression.";
|
||||
return;
|
||||
}
|
||||
|
||||
// Reserves enough bytes to hold the regular expression used for a
|
||||
// full match: we need space to prepend a '^' and append a '$'.
|
||||
full_pattern_.reserve(pattern_.size() + 2);
|
||||
|
||||
if (pattern_.empty() || pattern_.front() != '^') {
|
||||
full_pattern_.push_back('^'); // Makes sure full_pattern_ starts with '^'.
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
try {
|
||||
regex_ = std::regex(regex, std::regex_constants::ECMAScript);
|
||||
} catch (const std::regex_error& e) {
|
||||
ADD_FAILURE() << "Regular expression \"" << regex
|
||||
<< "\" is not a valid regular expression: " << e.what();
|
||||
return;
|
||||
}
|
||||
#else
|
||||
regex_ = std::regex(regex, std::regex_constants::ECMAScript);
|
||||
#endif
|
||||
|
||||
full_pattern_.append(pattern_);
|
||||
|
||||
if (pattern_.empty() || pattern_.back() != '$') {
|
||||
full_pattern_.push_back('$'); // Makes sure full_pattern_ ends with '$'.
|
||||
}
|
||||
is_valid_ = true;
|
||||
}
|
||||
|
||||
#endif // GTEST_USES_POSIX_RE
|
||||
@ -1085,7 +882,14 @@ bool EndsWithPathSeparator(const std::string& path) {
|
||||
class CapturedStream {
|
||||
public:
|
||||
// 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
|
||||
char temp_dir_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)
|
||||
<< "Failed to create temporary file in " << temp_dir_path
|
||||
<< " 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)
|
||||
<< "Failed to open temporary file " << temp_file_path << " with error "
|
||||
<< ::GetLastError();
|
||||
@ -1167,8 +971,12 @@ class CapturedStream {
|
||||
filename_ = std::move(name_template);
|
||||
#endif // GTEST_OS_WINDOWS
|
||||
fflush(nullptr);
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
_dup2(captured_fd, fd_);
|
||||
#else
|
||||
dup2(captured_fd, fd_);
|
||||
close(captured_fd);
|
||||
#endif
|
||||
posix::Close(captured_fd);
|
||||
}
|
||||
|
||||
~CapturedStream() { remove(filename_.c_str()); }
|
||||
@ -1177,8 +985,12 @@ class CapturedStream {
|
||||
if (uncaptured_fd_ != -1) {
|
||||
// Restores the original stream.
|
||||
fflush(nullptr);
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
_dup2(uncaptured_fd_, fd_);
|
||||
#else
|
||||
dup2(uncaptured_fd_, fd_);
|
||||
close(uncaptured_fd_);
|
||||
#endif
|
||||
posix::Close(uncaptured_fd_);
|
||||
uncaptured_fd_ = -1;
|
||||
}
|
||||
|
||||
@ -1227,14 +1039,14 @@ static std::string GetCapturedStream(CapturedStream** captured_stream) {
|
||||
return content;
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
// MSVC and C++Builder do not provide a definition of STDERR_FILENO.
|
||||
#if defined(_MSC_VER)
|
||||
// MSVC does not provide a definition of STDERR_FILENO.
|
||||
const int kStdOutFileno = 1;
|
||||
const int kStdErrFileno = 2;
|
||||
#else
|
||||
const int kStdOutFileno = STDOUT_FILENO;
|
||||
const int kStdErrFileno = STDERR_FILENO;
|
||||
#endif // defined(_MSC_VER) || defined(__BORLANDC__)
|
||||
#endif // defined(_MSC_VER)
|
||||
|
||||
// Starts capturing stdout.
|
||||
void CaptureStdout() {
|
||||
@ -1331,7 +1143,7 @@ static std::string FlagToEnvVar(const char* flag) {
|
||||
|
||||
Message env_var;
|
||||
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();
|
||||
|
||||
@ -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 {
|
||||
|
||||
|
||||
@ -62,7 +62,6 @@ const char* TypedTestSuitePState::VerifyRegisteredTestNames(
|
||||
const char* registered_tests) {
|
||||
RegisterTypeParameterizedTestSuite(test_suite_name, CodeLocation(file, line));
|
||||
|
||||
typedef RegisteredTestsMap::const_iterator RegisteredTestIter;
|
||||
registered_ = true;
|
||||
|
||||
std::vector<std::string> name_vec = SplitIntoTestNames(registered_tests);
|
||||
@ -78,7 +77,7 @@ const char* TypedTestSuitePState::VerifyRegisteredTestNames(
|
||||
continue;
|
||||
}
|
||||
|
||||
if (registered_tests_.count(name) != 0) {
|
||||
if (TestExists(name)) {
|
||||
tests.insert(name);
|
||||
} else {
|
||||
errors << "No test named " << name
|
||||
@ -86,10 +85,10 @@ const char* TypedTestSuitePState::VerifyRegisteredTestNames(
|
||||
}
|
||||
}
|
||||
|
||||
for (RegisteredTestIter it = registered_tests_.begin();
|
||||
it != registered_tests_.end(); ++it) {
|
||||
if (tests.count(it->first) == 0) {
|
||||
errors << "You forgot to list test " << it->first << ".\n";
|
||||
for (const RegisteredTest* it = registered_tests_; it != nullptr;
|
||||
it = it->next) {
|
||||
if (tests.count(it->name) == 0) {
|
||||
errors << "You forgot to list test " << it->name << ".\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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.
|
||||
@ -4644,7 +4648,7 @@ std::string JsonUnitTestResultPrinter::EscapeJson(const std::string& str) {
|
||||
m << "\\r";
|
||||
break;
|
||||
default:
|
||||
if (ch < ' ') {
|
||||
if (static_cast<unsigned char>(ch) < ' ' || ch == '\x7F') {
|
||||
m << "\\u00" << String::FormatByte(static_cast<unsigned char>(ch));
|
||||
} else {
|
||||
m << ch;
|
||||
@ -5285,17 +5289,8 @@ void TestEventListeners::SuppressEventForwarding(bool suppress) {
|
||||
// call this before main() starts, from which point on the return
|
||||
// value will never change.
|
||||
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;
|
||||
return &instance;
|
||||
#endif // defined(__BORLANDC__)
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// 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.
|
||||
template <typename CharType>
|
||||
void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
|
||||
std::string flagfile_value;
|
||||
for (int i = 1; i < *argc; i++) {
|
||||
const std::string arg_string = StreamableToString(argv[i]);
|
||||
const char* const arg = arg_string.c_str();
|
||||
@ -6880,9 +6884,7 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) {
|
||||
if (ParseGoogleTestFlag(arg)) {
|
||||
remove_flag = true;
|
||||
#if GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM
|
||||
} else if (ParseFlag(arg, "flagfile", &flagfile_value)) {
|
||||
GTEST_FLAG_SET(flagfile, flagfile_value);
|
||||
LoadFlagsFromFile(flagfile_value);
|
||||
} else if (ParseFlagFileFlag(arg)) {
|
||||
remove_flag = true;
|
||||
#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM
|
||||
} else if (arg_string == "--help" || HasGoogleTestFlagPrefix(arg)) {
|
||||
|
||||
@ -611,8 +611,7 @@ py_test(
|
||||
srcs = ["googletest-param-test-invalid-name1-test.py"],
|
||||
data = [":googletest-param-test-invalid-name1-test_"],
|
||||
tags = [
|
||||
"no_test_msvc2015",
|
||||
"no_test_msvc2017",
|
||||
"no_test_msvc2022",
|
||||
],
|
||||
deps = [":gtest_test_utils"],
|
||||
)
|
||||
@ -623,8 +622,7 @@ py_test(
|
||||
srcs = ["googletest-param-test-invalid-name2-test.py"],
|
||||
data = [":googletest-param-test-invalid-name2-test_"],
|
||||
tags = [
|
||||
"no_test_msvc2015",
|
||||
"no_test_msvc2017",
|
||||
"no_test_msvc2022",
|
||||
],
|
||||
deps = [":gtest_test_utils"],
|
||||
)
|
||||
|
||||
@ -1362,11 +1362,8 @@ void DieWithMessage(const char* message) {
|
||||
TEST(MatcherDeathTest, DoesNotBreakBareRegexMatching) {
|
||||
// googletest tests this, of course; here we ensure that including googlemock
|
||||
// has not broken it.
|
||||
#ifdef GTEST_USES_POSIX_RE
|
||||
EXPECT_DEATH(DieWithMessage("O, I die, Horatio."), "I d[aeiou]e");
|
||||
#else
|
||||
EXPECT_DEATH(DieWithMessage("O, I die, Horatio."), "I di?e");
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(MatcherDeathTest, MonomorphicMatcherMatches) {
|
||||
|
||||
@ -336,7 +336,7 @@ EXPECTED_NON_EMPTY = {
|
||||
'time': '*',
|
||||
'timestamp': '*',
|
||||
'classname': 'PropertyRecordingTest',
|
||||
'key_1': '1',
|
||||
'key_1': '\u007f!caf\u00e9 \u4e2d',
|
||||
},
|
||||
{
|
||||
'name': 'IntValuedProperty',
|
||||
@ -878,7 +878,7 @@ class GTestJsonOutputUnitTest(gtest_test_utils.TestCase):
|
||||
'the expected exit code %s.'
|
||||
% (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)
|
||||
return actual
|
||||
|
||||
|
||||
@ -395,11 +395,11 @@ TEST(RegexEngineSelectionTest, SelectsCorrectRegexEngine) {
|
||||
#elif GTEST_HAS_POSIX_RE
|
||||
EXPECT_TRUE(GTEST_USES_POSIX_RE);
|
||||
#else
|
||||
EXPECT_TRUE(GTEST_USES_SIMPLE_RE);
|
||||
EXPECT_TRUE(GTEST_USES_STD_RE);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef GTEST_USES_POSIX_RE
|
||||
#if defined(GTEST_USES_POSIX_RE) || defined(GTEST_USES_STD_RE)
|
||||
|
||||
template <typename Str>
|
||||
class RETest : public ::testing::Test {};
|
||||
@ -424,9 +424,15 @@ TYPED_TEST(RETest, ImplicitConstructorWorks) {
|
||||
|
||||
// Tests that RE's constructors reject invalid regular expressions.
|
||||
TYPED_TEST(RETest, RejectsInvalidRegex) {
|
||||
#ifdef GTEST_USES_POSIX_RE
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
{ const RE invalid(TypeParam("?")); },
|
||||
"\"?\" 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().
|
||||
@ -456,467 +462,7 @@ TYPED_TEST(RETest, PartialMatchWorks) {
|
||||
EXPECT_FALSE(RE::PartialMatch(TypeParam("zza"), re));
|
||||
}
|
||||
|
||||
#elif defined(GTEST_USES_SIMPLE_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
|
||||
#endif // GTEST_USES_POSIX_RE || GTEST_USES_STD_RE
|
||||
|
||||
#ifndef GTEST_OS_WINDOWS_MOBILE
|
||||
|
||||
|
||||
@ -95,10 +95,12 @@ void PrintTo(EnumWithPrintTo e, std::ostream* os) {
|
||||
*os << (e == kEWPT1 ? "kEWPT1" : "invalid");
|
||||
}
|
||||
|
||||
// A class implicitly convertible to BiggestInt.
|
||||
// A class implicitly convertible to intmax_t.
|
||||
class BiggestIntConvertible {
|
||||
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
|
||||
@ -356,7 +358,7 @@ TEST(PrintEnumTest, EnumWithPrintTo) {
|
||||
TEST(PrintClassTest, AbslStringify) { EXPECT_EQ("(10, 20)", Print(Point())); }
|
||||
#endif
|
||||
|
||||
// Tests printing a class implicitly convertible to BiggestInt.
|
||||
// Tests printing a class implicitly convertible to intmax_t.
|
||||
|
||||
TEST(PrintClassTest, BiggestIntConvertible) {
|
||||
EXPECT_EQ("42", Print(BiggestIntConvertible()));
|
||||
@ -396,12 +398,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 +470,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 +662,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 +694,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.
|
||||
|
||||
@ -765,7 +775,7 @@ TEST(PrintPointerTest, NonMemberFunctionPointer) {
|
||||
// pointers to objects, and some compilers (e.g. GCC 3.4) enforce
|
||||
// this limitation.
|
||||
EXPECT_EQ(PrintPointer(reinterpret_cast<const void*>(
|
||||
reinterpret_cast<internal::BiggestInt>(&MyFunction))),
|
||||
reinterpret_cast<intmax_t>(&MyFunction))),
|
||||
Print(&MyFunction));
|
||||
int (*p)(bool) = NULL; // NOLINT
|
||||
EXPECT_EQ("NULL", Print(p));
|
||||
@ -1466,8 +1476,8 @@ TEST(PrintReferenceTest, HandlesFunctionPointer) {
|
||||
// standard disallows casting between pointers to functions and
|
||||
// pointers to objects, and some compilers (e.g. GCC 3.4) enforce
|
||||
// this limitation.
|
||||
const std::string fp_string = PrintPointer(reinterpret_cast<const void*>(
|
||||
reinterpret_cast<internal::BiggestInt>(fp)));
|
||||
const std::string fp_string = PrintPointer(
|
||||
reinterpret_cast<const void*>(reinterpret_cast<intmax_t>(fp)));
|
||||
EXPECT_EQ("@" + fp_pointer_string + " " + fp_string, PrintByRef(fp));
|
||||
}
|
||||
|
||||
|
||||
@ -200,12 +200,15 @@ using testing::internal::TypedTestSuitePState;
|
||||
class TypedTestSuitePStateTest : public Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
state_.AddTestName("foo.cc", 0, "FooTest", "A");
|
||||
state_.AddTestName("foo.cc", 0, "FooTest", "B");
|
||||
state_.AddTestName("foo.cc", 0, "FooTest", "C");
|
||||
state_.AddTest(&test_a_, "FooTest");
|
||||
state_.AddTest(&test_b_, "FooTest");
|
||||
state_.AddTest(&test_c_, "FooTest");
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -246,8 +249,9 @@ TEST_F(TypedTestSuitePStateDeathTest, DetectsMissedTest) {
|
||||
// a run-time error if the test case has been registered.
|
||||
TEST_F(TypedTestSuitePStateDeathTest, DetectsTestAfterRegistration) {
|
||||
state_.VerifyRegisteredTestNames("Suite", "foo.cc", 1, "A, B, C");
|
||||
TypedTestSuitePState::RegisteredTest test_d = {"D", "foo.cc", 2, nullptr};
|
||||
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"
|
||||
"\\(FooTest, \\.\\.\\.\\)\\.");
|
||||
}
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
|
||||
// Verifies that the command line flag variables can be accessed in
|
||||
// code once "gtest.h" has been #included.
|
||||
@ -484,9 +485,11 @@ class FormatEpochTimeInMillisAsIso8601Test : public Test {
|
||||
const std::string env_var =
|
||||
std::string("TZ=") + (time_zone ? time_zone : "");
|
||||
_putenv(env_var.c_str());
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996 /* deprecated function */)
|
||||
#if defined(GTEST_OS_WINDOWS)
|
||||
_tzset();
|
||||
#else
|
||||
tzset();
|
||||
GTEST_DISABLE_MSC_WARNINGS_POP_()
|
||||
#endif
|
||||
#else
|
||||
#if defined(GTEST_OS_LINUX_ANDROID) && __ANDROID_API__ < 21
|
||||
// Work around KitKat bug in tzset by setting "UTC" before setting "UTC+00".
|
||||
@ -534,11 +537,6 @@ TEST_F(FormatEpochTimeInMillisAsIso8601Test, PrintsEpochStart) {
|
||||
|
||||
#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
|
||||
// when the RHS is a pointer type.
|
||||
TEST(NullLiteralTest, LHSAllowsNullLiterals) {
|
||||
@ -595,10 +593,8 @@ TEST(NullLiteralTest, ImplicitConversion) {
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#if __has_warning("-Wzero-as-null-pointer-constant")
|
||||
#pragma clang diagnostic error "-Wzero-as-null-pointer-constant"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
TEST(NullLiteralTest, NoConversionNoWarning) {
|
||||
// Test that gtests detection and handling of null pointer constants
|
||||
@ -611,11 +607,6 @@ TEST(NullLiteralTest, NoConversionNoWarning) {
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
// Restores warnings after previous "#pragma option push" suppressed them.
|
||||
#pragma option pop
|
||||
#endif
|
||||
|
||||
//
|
||||
// Tests CodePointToUtf8().
|
||||
|
||||
@ -1275,11 +1266,6 @@ TEST_F(ExpectFatalFailureTest, CatchesFatalFailureOnAllThreads) {
|
||||
"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
|
||||
// function even when the statement in it contains ASSERT_*.
|
||||
|
||||
@ -1303,11 +1289,6 @@ void DoesNotAbortHelper(bool* aborted) {
|
||||
*aborted = false;
|
||||
}
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
// Restores warnings after previous "#pragma option push" suppressed them.
|
||||
#pragma option pop
|
||||
#endif
|
||||
|
||||
TEST_F(ExpectFatalFailureTest, DoesNotAbort) {
|
||||
bool aborted = true;
|
||||
DoesNotAbortHelper(&aborted);
|
||||
@ -1322,15 +1303,12 @@ static int global_var = 0;
|
||||
#define GTEST_USE_UNPROTECTED_COMMA_ global_var++, global_var++
|
||||
|
||||
TEST_F(ExpectFatalFailureTest, AcceptsMacroThatExpandsToUnprotectedComma) {
|
||||
#ifndef __BORLANDC__
|
||||
// ICE's in C++Builder.
|
||||
EXPECT_FATAL_FAILURE(
|
||||
{
|
||||
GTEST_USE_UNPROTECTED_COMMA_;
|
||||
AddFatalFailure();
|
||||
},
|
||||
"");
|
||||
#endif
|
||||
|
||||
EXPECT_FATAL_FAILURE_ON_ALL_THREADS(
|
||||
{
|
||||
@ -1711,26 +1689,6 @@ static void SetEnv(const char* name, const char* value) {
|
||||
#ifdef GTEST_OS_WINDOWS_MOBILE
|
||||
// Environment variables are not supported on Windows CE.
|
||||
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.
|
||||
_putenv((Message() << name << "=" << value).GetString().c_str());
|
||||
#else
|
||||
@ -2564,6 +2522,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 +2578,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 +2593,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 +2613,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 +2656,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 +2677,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) {
|
||||
@ -3706,11 +3666,6 @@ TEST(AssertionTest, AppendUserMessage) {
|
||||
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.
|
||||
TEST(AssertionTest, ASSERT_TRUE) {
|
||||
ASSERT_TRUE(2 > 1); // NOLINT
|
||||
@ -3729,13 +3684,10 @@ TEST(AssertionTest, ASSERT_TRUE) {
|
||||
// Tests ASSERT_TRUE(predicate) for predicates returning AssertionResult.
|
||||
TEST(AssertionTest, AssertTrueWithAssertionResult) {
|
||||
ASSERT_TRUE(ResultIsEven(2));
|
||||
#ifndef __BORLANDC__
|
||||
// ICE's in C++Builder.
|
||||
EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEven(3)),
|
||||
"Value of: ResultIsEven(3)\n"
|
||||
" Actual: false (3 is odd)\n"
|
||||
"Expected: true");
|
||||
#endif
|
||||
ASSERT_TRUE(ResultIsEvenNoExplanation(2));
|
||||
EXPECT_FATAL_FAILURE(ASSERT_TRUE(ResultIsEvenNoExplanation(3)),
|
||||
"Value of: ResultIsEvenNoExplanation(3)\n"
|
||||
@ -3764,13 +3716,10 @@ TEST(AssertionTest, ASSERT_FALSE) {
|
||||
// Tests ASSERT_FALSE(predicate) for predicates returning AssertionResult.
|
||||
TEST(AssertionTest, AssertFalseWithAssertionResult) {
|
||||
ASSERT_FALSE(ResultIsEven(3));
|
||||
#ifndef __BORLANDC__
|
||||
// ICE's in C++Builder.
|
||||
EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEven(2)),
|
||||
"Value of: ResultIsEven(2)\n"
|
||||
" Actual: true (2 is even)\n"
|
||||
"Expected: false");
|
||||
#endif
|
||||
ASSERT_FALSE(ResultIsEvenNoExplanation(3));
|
||||
EXPECT_FATAL_FAILURE(ASSERT_FALSE(ResultIsEvenNoExplanation(2)),
|
||||
"Value of: ResultIsEvenNoExplanation(2)\n"
|
||||
@ -3778,11 +3727,6 @@ TEST(AssertionTest, AssertFalseWithAssertionResult) {
|
||||
"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
|
||||
// sure that the specialization we did for integer and anonymous enums
|
||||
// isn't used for double arguments.
|
||||
@ -3873,9 +3817,6 @@ void ThrowNothing() {}
|
||||
TEST(AssertionTest, ASSERT_THROW) {
|
||||
ASSERT_THROW(ThrowAnInteger(), int);
|
||||
|
||||
#ifndef __BORLANDC__
|
||||
|
||||
// ICE's in C++Builder 2007 and 2009.
|
||||
EXPECT_FATAL_FAILURE(
|
||||
ASSERT_THROW(ThrowAnInteger(), bool),
|
||||
"Expected: ThrowAnInteger() throws an exception of type bool.\n"
|
||||
@ -3887,7 +3828,6 @@ TEST(AssertionTest, ASSERT_THROW) {
|
||||
"Actual: it throws " ERROR_DESC
|
||||
" "
|
||||
"with description \"A description\".");
|
||||
#endif
|
||||
|
||||
EXPECT_FATAL_FAILURE(
|
||||
ASSERT_THROW(ThrowNothing(), bool),
|
||||
@ -4007,9 +3947,6 @@ TEST(AssertionTest, NamedEnum) {
|
||||
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.
|
||||
enum {
|
||||
kCaseA = -1,
|
||||
@ -4025,7 +3962,7 @@ enum {
|
||||
// On Linux, kCaseB and kCaseA have the same value when truncated to
|
||||
// int size. We want to test whether this will confuse the
|
||||
// assertions.
|
||||
kCaseB = testing::internal::kMaxBiggestInt,
|
||||
kCaseB = (std::numeric_limits<intmax_t>::max)(),
|
||||
|
||||
#else
|
||||
|
||||
@ -4059,18 +3996,12 @@ TEST(AssertionTest, AnonymousEnum) {
|
||||
ASSERT_GT(kCaseB, 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, kCaseC), "\n Which is: 42");
|
||||
#endif
|
||||
|
||||
EXPECT_FATAL_FAILURE(ASSERT_EQ(kCaseA, kCaseC), "\n Which is: -1");
|
||||
}
|
||||
|
||||
#endif // !GTEST_OS_MAC && !defined(__SUNPRO_CC)
|
||||
|
||||
#ifdef GTEST_OS_WINDOWS
|
||||
|
||||
static HRESULT UnexpectedHRESULTFailure() { return E_UNEXPECTED; }
|
||||
@ -4115,13 +4046,9 @@ TEST(HRESULTAssertionTest, EXPECT_HRESULT_FAILED) {
|
||||
TEST(HRESULTAssertionTest, ASSERT_HRESULT_FAILED) {
|
||||
ASSERT_HRESULT_FAILED(E_UNEXPECTED);
|
||||
|
||||
#ifndef __BORLANDC__
|
||||
|
||||
// ICE's in C++Builder 2007 and 2009.
|
||||
EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(OkHRESULTSuccess()),
|
||||
"Expected: (OkHRESULTSuccess()) fails.\n"
|
||||
" Actual: 0x0");
|
||||
#endif
|
||||
|
||||
EXPECT_FATAL_FAILURE(ASSERT_HRESULT_FAILED(FalseHRESULTSuccess()),
|
||||
"Expected: (FalseHRESULTSuccess()) fails.\n"
|
||||
@ -4139,13 +4066,9 @@ TEST(HRESULTAssertionTest, Streaming) {
|
||||
<< "expected failure",
|
||||
"expected failure");
|
||||
|
||||
#ifndef __BORLANDC__
|
||||
|
||||
// ICE's in C++Builder 2007 and 2009.
|
||||
EXPECT_FATAL_FAILURE(ASSERT_HRESULT_SUCCEEDED(E_UNEXPECTED)
|
||||
<< "expected failure",
|
||||
"expected failure");
|
||||
#endif
|
||||
|
||||
EXPECT_NONFATAL_FAILURE(EXPECT_HRESULT_FAILED(S_OK) << "expected failure",
|
||||
"expected failure");
|
||||
@ -4523,11 +4446,6 @@ TEST(ExpectTest, ExpectFalseWithAssertionResult) {
|
||||
"Expected: false");
|
||||
}
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
// Restores warnings after previous "#pragma option push" suppressed them
|
||||
#pragma option pop
|
||||
#endif
|
||||
|
||||
// Tests EXPECT_EQ.
|
||||
TEST(ExpectTest, EXPECT_EQ) {
|
||||
EXPECT_EQ(5, 2 + 3);
|
||||
@ -5040,13 +4958,10 @@ TEST(ComparisonAssertionTest, AcceptsUnprintableArgs) {
|
||||
|
||||
// Code tested by EXPECT_FATAL_FAILURE cannot reference local
|
||||
// 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')),
|
||||
"1-byte object <78>");
|
||||
EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')),
|
||||
"1-byte object <78>");
|
||||
#endif
|
||||
EXPECT_FATAL_FAILURE(ASSERT_LE(UnprintableChar('y'), UnprintableChar('x')),
|
||||
"1-byte object <79>");
|
||||
EXPECT_FATAL_FAILURE(ASSERT_GE(UnprintableChar('x'), UnprintableChar('y')),
|
||||
@ -6539,11 +6454,6 @@ TEST(StreamingAssertionsTest, Unconditional) {
|
||||
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) {
|
||||
EXPECT_TRUE(true) << "unexpected failure";
|
||||
ASSERT_TRUE(true) << "unexpected failure";
|
||||
@ -6562,11 +6472,6 @@ TEST(StreamingAssertionsTest, Truth2) {
|
||||
"expected failure");
|
||||
}
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
// Restores warnings after previous "#pragma option push" suppressed them
|
||||
#pragma option pop
|
||||
#endif
|
||||
|
||||
TEST(StreamingAssertionsTest, IntegerEquals) {
|
||||
EXPECT_EQ(1, 1) << "unexpected failure";
|
||||
ASSERT_EQ(1, 1) << "unexpected failure";
|
||||
@ -7490,10 +7395,8 @@ TEST(CopyArrayTest, WorksForDegeneratedArrays) {
|
||||
TEST(CopyArrayTest, WorksForOneDimensionalArrays) {
|
||||
const char a[3] = "hi";
|
||||
int b[3];
|
||||
#ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions.
|
||||
CopyArray(a, &b);
|
||||
EXPECT_TRUE(ArrayEq(a, b));
|
||||
#endif
|
||||
|
||||
int c[3];
|
||||
CopyArray(a, 3, c);
|
||||
@ -7503,10 +7406,8 @@ TEST(CopyArrayTest, WorksForOneDimensionalArrays) {
|
||||
TEST(CopyArrayTest, WorksForTwoDimensionalArrays) {
|
||||
const int a[2][3] = {{0, 1, 2}, {3, 4, 5}};
|
||||
int b[2][3];
|
||||
#ifndef __BORLANDC__ // C++Builder cannot compile some array size deductions.
|
||||
CopyArray(a, &b);
|
||||
EXPECT_TRUE(ArrayEq(a, b));
|
||||
#endif
|
||||
|
||||
int c[2][3];
|
||||
CopyArray(a, 2, c);
|
||||
|
||||
@ -144,7 +144,7 @@ It is good practice to tell why you skip a test.
|
||||
</properties>
|
||||
<testcase name="OneProperty" file="gtest_xml_output_unittest_.cc" line="125" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest">
|
||||
<properties>
|
||||
<property name="key_1" value="1"/>
|
||||
<property name="key_1" value="\u007f!caf\u00e9 \u4e2d"/>
|
||||
</properties>
|
||||
</testcase>
|
||||
<testcase name="IntValuedProperty" file="gtest_xml_output_unittest_.cc" line="129" status="run" result="completed" time="*" timestamp="*" classname="PropertyRecordingTest">
|
||||
|
||||
@ -123,7 +123,7 @@ class PropertyRecordingTest : public Test {
|
||||
};
|
||||
|
||||
TEST_F(PropertyRecordingTest, OneProperty) {
|
||||
RecordProperty("key_1", "1");
|
||||
RecordProperty("key_1", "\x7F!caf\xC3\xA9 \xE4\xB8\xAD");
|
||||
}
|
||||
|
||||
TEST_F(PropertyRecordingTest, IntValuedProperty) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user