Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
googletest
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
googletest
Commits
b22d2366
Commit
b22d2366
authored
Nov 27, 2018
by
durandal
Committed by
Gennadiy Civil
Nov 28, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Googletest export
Accept gmock matchers in EXPECT_EXIT and friends to allow matches other than simple regex matches on death output. PiperOrigin-RevId: 223035409
parent
191f9336
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
335 additions
and
249 deletions
+335
-249
gmock-matchers.h
googlemock/include/gmock/gmock-matchers.h
+0
-149
gtest-matchers.h
googletest/include/gtest/gtest-matchers.h
+147
-1
gtest-death-test-internal.h
...letest/include/gtest/internal/gtest-death-test-internal.h
+74
-44
gtest-death-test.cc
googletest/src/gtest-death-test.cc
+46
-45
googletest-death-test-test.cc
googletest/test/googletest-death-test-test.cc
+68
-10
No files found.
googlemock/include/gmock/gmock-matchers.h
View file @
b22d2366
...
@@ -97,77 +97,6 @@ class StringMatchResultListener : public MatchResultListener {
...
@@ -97,77 +97,6 @@ class StringMatchResultListener : public MatchResultListener {
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
StringMatchResultListener
);
GTEST_DISALLOW_COPY_AND_ASSIGN_
(
StringMatchResultListener
);
};
};
// The PolymorphicMatcher class template makes it easy to implement a
// polymorphic matcher (i.e. a matcher that can match values of more
// than one type, e.g. Eq(n) and NotNull()).
//
// To define a polymorphic matcher, a user should provide an Impl
// class that has a DescribeTo() method and a DescribeNegationTo()
// method, and define a member function (or member function template)
//
// bool MatchAndExplain(const Value& value,
// MatchResultListener* listener) const;
//
// See the definition of NotNull() for a complete example.
template
<
class
Impl
>
class
PolymorphicMatcher
{
public
:
explicit
PolymorphicMatcher
(
const
Impl
&
an_impl
)
:
impl_
(
an_impl
)
{}
// Returns a mutable reference to the underlying matcher
// implementation object.
Impl
&
mutable_impl
()
{
return
impl_
;
}
// Returns an immutable reference to the underlying matcher
// implementation object.
const
Impl
&
impl
()
const
{
return
impl_
;
}
template
<
typename
T
>
operator
Matcher
<
T
>
()
const
{
return
Matcher
<
T
>
(
new
MonomorphicImpl
<
GTEST_REFERENCE_TO_CONST_
(
T
)
>
(
impl_
));
}
private
:
template
<
typename
T
>
class
MonomorphicImpl
:
public
MatcherInterface
<
T
>
{
public
:
explicit
MonomorphicImpl
(
const
Impl
&
impl
)
:
impl_
(
impl
)
{}
virtual
void
DescribeTo
(
::
std
::
ostream
*
os
)
const
{
impl_
.
DescribeTo
(
os
);
}
virtual
void
DescribeNegationTo
(
::
std
::
ostream
*
os
)
const
{
impl_
.
DescribeNegationTo
(
os
);
}
virtual
bool
MatchAndExplain
(
T
x
,
MatchResultListener
*
listener
)
const
{
return
impl_
.
MatchAndExplain
(
x
,
listener
);
}
private
:
const
Impl
impl_
;
GTEST_DISALLOW_ASSIGN_
(
MonomorphicImpl
);
};
Impl
impl_
;
GTEST_DISALLOW_ASSIGN_
(
PolymorphicMatcher
);
};
// Creates a polymorphic matcher from its implementation. This is
// easier to use than the PolymorphicMatcher<Impl> constructor as it
// doesn't require you to explicitly write the template argument, e.g.
//
// MakePolymorphicMatcher(foo);
// vs
// PolymorphicMatcher<TypeOfFoo>(foo);
template
<
class
Impl
>
inline
PolymorphicMatcher
<
Impl
>
MakePolymorphicMatcher
(
const
Impl
&
impl
)
{
return
PolymorphicMatcher
<
Impl
>
(
impl
);
}
// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION
// and MUST NOT BE USED IN USER CODE!!!
// and MUST NOT BE USED IN USER CODE!!!
namespace
internal
{
namespace
internal
{
...
@@ -976,62 +905,6 @@ class EndsWithMatcher {
...
@@ -976,62 +905,6 @@ class EndsWithMatcher {
GTEST_DISALLOW_ASSIGN_
(
EndsWithMatcher
);
GTEST_DISALLOW_ASSIGN_
(
EndsWithMatcher
);
};
};
// Implements polymorphic matchers MatchesRegex(regex) and
// ContainsRegex(regex), which can be used as a Matcher<T> as long as
// T can be converted to a string.
class
MatchesRegexMatcher
{
public
:
MatchesRegexMatcher
(
const
RE
*
regex
,
bool
full_match
)
:
regex_
(
regex
),
full_match_
(
full_match
)
{}
#if GTEST_HAS_ABSL
bool
MatchAndExplain
(
const
absl
::
string_view
&
s
,
MatchResultListener
*
listener
)
const
{
return
MatchAndExplain
(
string
(
s
),
listener
);
}
#endif // GTEST_HAS_ABSL
// Accepts pointer types, particularly:
// const char*
// char*
// const wchar_t*
// wchar_t*
template
<
typename
CharType
>
bool
MatchAndExplain
(
CharType
*
s
,
MatchResultListener
*
listener
)
const
{
return
s
!=
nullptr
&&
MatchAndExplain
(
std
::
string
(
s
),
listener
);
}
// Matches anything that can convert to std::string.
//
// This is a template, not just a plain function with const std::string&,
// because absl::string_view has some interfering non-explicit constructors.
template
<
class
MatcheeStringType
>
bool
MatchAndExplain
(
const
MatcheeStringType
&
s
,
MatchResultListener
*
/* listener */
)
const
{
const
std
::
string
&
s2
(
s
);
return
full_match_
?
RE
:
:
FullMatch
(
s2
,
*
regex_
)
:
RE
::
PartialMatch
(
s2
,
*
regex_
);
}
void
DescribeTo
(
::
std
::
ostream
*
os
)
const
{
*
os
<<
(
full_match_
?
"matches"
:
"contains"
)
<<
" regular expression "
;
UniversalPrinter
<
std
::
string
>::
Print
(
regex_
->
pattern
(),
os
);
}
void
DescribeNegationTo
(
::
std
::
ostream
*
os
)
const
{
*
os
<<
"doesn't "
<<
(
full_match_
?
"match"
:
"contain"
)
<<
" regular expression "
;
UniversalPrinter
<
std
::
string
>::
Print
(
regex_
->
pattern
(),
os
);
}
private
:
const
std
::
shared_ptr
<
const
RE
>
regex_
;
const
bool
full_match_
;
GTEST_DISALLOW_ASSIGN_
(
MatchesRegexMatcher
);
};
// Implements a matcher that compares the two fields of a 2-tuple
// Implements a matcher that compares the two fields of a 2-tuple
// using one of the ==, <=, <, etc, operators. The two fields being
// using one of the ==, <=, <, etc, operators. The two fields being
// compared don't have to have the same type.
// compared don't have to have the same type.
...
@@ -3935,28 +3808,6 @@ inline PolymorphicMatcher<internal::EndsWithMatcher<std::string> > EndsWith(
...
@@ -3935,28 +3808,6 @@ inline PolymorphicMatcher<internal::EndsWithMatcher<std::string> > EndsWith(
return
MakePolymorphicMatcher
(
internal
::
EndsWithMatcher
<
std
::
string
>
(
suffix
));
return
MakePolymorphicMatcher
(
internal
::
EndsWithMatcher
<
std
::
string
>
(
suffix
));
}
}
// Matches a string that fully matches regular expression 'regex'.
// The matcher takes ownership of 'regex'.
inline
PolymorphicMatcher
<
internal
::
MatchesRegexMatcher
>
MatchesRegex
(
const
internal
::
RE
*
regex
)
{
return
MakePolymorphicMatcher
(
internal
::
MatchesRegexMatcher
(
regex
,
true
));
}
inline
PolymorphicMatcher
<
internal
::
MatchesRegexMatcher
>
MatchesRegex
(
const
std
::
string
&
regex
)
{
return
MatchesRegex
(
new
internal
::
RE
(
regex
));
}
// Matches a string that contains regular expression 'regex'.
// The matcher takes ownership of 'regex'.
inline
PolymorphicMatcher
<
internal
::
MatchesRegexMatcher
>
ContainsRegex
(
const
internal
::
RE
*
regex
)
{
return
MakePolymorphicMatcher
(
internal
::
MatchesRegexMatcher
(
regex
,
false
));
}
inline
PolymorphicMatcher
<
internal
::
MatchesRegexMatcher
>
ContainsRegex
(
const
std
::
string
&
regex
)
{
return
ContainsRegex
(
new
internal
::
RE
(
regex
));
}
#if GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING
#if GTEST_HAS_GLOBAL_WSTRING || GTEST_HAS_STD_WSTRING
// Wide string matchers.
// Wide string matchers.
...
...
googletest/include/gtest/gtest-matchers.h
View file @
b22d2366
...
@@ -43,9 +43,9 @@
...
@@ -43,9 +43,9 @@
#include <ostream>
#include <ostream>
#include <string>
#include <string>
#include "gtest/gtest-printers.h"
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-port.h"
#include "gtest/gtest-printers.h"
GTEST_DISABLE_MSC_WARNINGS_PUSH_
(
GTEST_DISABLE_MSC_WARNINGS_PUSH_
(
4251
5046
/* class A needs to have dll-interface to be used by clients of
4251
5046
/* class A needs to have dll-interface to be used by clients of
...
@@ -508,6 +508,63 @@ std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {
...
@@ -508,6 +508,63 @@ std::ostream& operator<<(std::ostream& os, const Matcher<T>& matcher) {
return
os
;
return
os
;
}
}
// The PolymorphicMatcher class template makes it easy to implement a
// polymorphic matcher (i.e. a matcher that can match values of more
// than one type, e.g. Eq(n) and NotNull()).
//
// To define a polymorphic matcher, a user should provide an Impl
// class that has a DescribeTo() method and a DescribeNegationTo()
// method, and define a member function (or member function template)
//
// bool MatchAndExplain(const Value& value,
// MatchResultListener* listener) const;
//
// See the definition of NotNull() for a complete example.
template
<
class
Impl
>
class
PolymorphicMatcher
{
public
:
explicit
PolymorphicMatcher
(
const
Impl
&
an_impl
)
:
impl_
(
an_impl
)
{}
// Returns a mutable reference to the underlying matcher
// implementation object.
Impl
&
mutable_impl
()
{
return
impl_
;
}
// Returns an immutable reference to the underlying matcher
// implementation object.
const
Impl
&
impl
()
const
{
return
impl_
;
}
template
<
typename
T
>
operator
Matcher
<
T
>
()
const
{
return
Matcher
<
T
>
(
new
MonomorphicImpl
<
GTEST_REFERENCE_TO_CONST_
(
T
)
>
(
impl_
));
}
private
:
template
<
typename
T
>
class
MonomorphicImpl
:
public
MatcherInterface
<
T
>
{
public
:
explicit
MonomorphicImpl
(
const
Impl
&
impl
)
:
impl_
(
impl
)
{}
virtual
void
DescribeTo
(
::
std
::
ostream
*
os
)
const
{
impl_
.
DescribeTo
(
os
);
}
virtual
void
DescribeNegationTo
(
::
std
::
ostream
*
os
)
const
{
impl_
.
DescribeNegationTo
(
os
);
}
virtual
bool
MatchAndExplain
(
T
x
,
MatchResultListener
*
listener
)
const
{
return
impl_
.
MatchAndExplain
(
x
,
listener
);
}
private
:
const
Impl
impl_
;
GTEST_DISALLOW_ASSIGN_
(
MonomorphicImpl
);
};
Impl
impl_
;
GTEST_DISALLOW_ASSIGN_
(
PolymorphicMatcher
);
};
// Creates a matcher from its implementation. This is easier to use
// Creates a matcher from its implementation. This is easier to use
// than the Matcher<T> constructor as it doesn't require you to
// than the Matcher<T> constructor as it doesn't require you to
// explicitly write the template argument, e.g.
// explicitly write the template argument, e.g.
...
@@ -520,6 +577,18 @@ inline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) {
...
@@ -520,6 +577,18 @@ inline Matcher<T> MakeMatcher(const MatcherInterface<T>* impl) {
return
Matcher
<
T
>
(
impl
);
return
Matcher
<
T
>
(
impl
);
}
}
// Creates a polymorphic matcher from its implementation. This is
// easier to use than the PolymorphicMatcher<Impl> constructor as it
// doesn't require you to explicitly write the template argument, e.g.
//
// MakePolymorphicMatcher(foo);
// vs
// PolymorphicMatcher<TypeOfFoo>(foo);
template
<
class
Impl
>
inline
PolymorphicMatcher
<
Impl
>
MakePolymorphicMatcher
(
const
Impl
&
impl
)
{
return
PolymorphicMatcher
<
Impl
>
(
impl
);
}
namespace
internal
{
namespace
internal
{
// Implements a matcher that compares a given value with a
// Implements a matcher that compares a given value with a
// pre-supplied value using one of the ==, <=, <, etc, operators. The
// pre-supplied value using one of the ==, <=, <, etc, operators. The
...
@@ -613,8 +682,85 @@ class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> {
...
@@ -613,8 +682,85 @@ class GeMatcher : public ComparisonBase<GeMatcher<Rhs>, Rhs, AnyGe> {
static
const
char
*
Desc
()
{
return
"is >="
;
}
static
const
char
*
Desc
()
{
return
"is >="
;
}
static
const
char
*
NegatedDesc
()
{
return
"isn't >="
;
}
static
const
char
*
NegatedDesc
()
{
return
"isn't >="
;
}
};
};
// Implements polymorphic matchers MatchesRegex(regex) and
// ContainsRegex(regex), which can be used as a Matcher<T> as long as
// T can be converted to a string.
class
MatchesRegexMatcher
{
public
:
MatchesRegexMatcher
(
const
RE
*
regex
,
bool
full_match
)
:
regex_
(
regex
),
full_match_
(
full_match
)
{}
#if GTEST_HAS_ABSL
bool
MatchAndExplain
(
const
absl
::
string_view
&
s
,
MatchResultListener
*
listener
)
const
{
return
MatchAndExplain
(
string
(
s
),
listener
);
}
#endif // GTEST_HAS_ABSL
// Accepts pointer types, particularly:
// const char*
// char*
// const wchar_t*
// wchar_t*
template
<
typename
CharType
>
bool
MatchAndExplain
(
CharType
*
s
,
MatchResultListener
*
listener
)
const
{
return
s
!=
nullptr
&&
MatchAndExplain
(
std
::
string
(
s
),
listener
);
}
// Matches anything that can convert to std::string.
//
// This is a template, not just a plain function with const std::string&,
// because absl::string_view has some interfering non-explicit constructors.
template
<
class
MatcheeStringType
>
bool
MatchAndExplain
(
const
MatcheeStringType
&
s
,
MatchResultListener
*
/* listener */
)
const
{
const
std
::
string
&
s2
(
s
);
return
full_match_
?
RE
::
FullMatch
(
s2
,
*
regex_
)
:
RE
::
PartialMatch
(
s2
,
*
regex_
);
}
void
DescribeTo
(
::
std
::
ostream
*
os
)
const
{
*
os
<<
(
full_match_
?
"matches"
:
"contains"
)
<<
" regular expression "
;
UniversalPrinter
<
std
::
string
>::
Print
(
regex_
->
pattern
(),
os
);
}
void
DescribeNegationTo
(
::
std
::
ostream
*
os
)
const
{
*
os
<<
"doesn't "
<<
(
full_match_
?
"match"
:
"contain"
)
<<
" regular expression "
;
UniversalPrinter
<
std
::
string
>::
Print
(
regex_
->
pattern
(),
os
);
}
private
:
const
std
::
shared_ptr
<
const
RE
>
regex_
;
const
bool
full_match_
;
GTEST_DISALLOW_ASSIGN_
(
MatchesRegexMatcher
);
};
}
// namespace internal
}
// namespace internal
// Matches a string that fully matches regular expression 'regex'.
// The matcher takes ownership of 'regex'.
inline
PolymorphicMatcher
<
internal
::
MatchesRegexMatcher
>
MatchesRegex
(
const
internal
::
RE
*
regex
)
{
return
MakePolymorphicMatcher
(
internal
::
MatchesRegexMatcher
(
regex
,
true
));
}
inline
PolymorphicMatcher
<
internal
::
MatchesRegexMatcher
>
MatchesRegex
(
const
std
::
string
&
regex
)
{
return
MatchesRegex
(
new
internal
::
RE
(
regex
));
}
// Matches a string that contains regular expression 'regex'.
// The matcher takes ownership of 'regex'.
inline
PolymorphicMatcher
<
internal
::
MatchesRegexMatcher
>
ContainsRegex
(
const
internal
::
RE
*
regex
)
{
return
MakePolymorphicMatcher
(
internal
::
MatchesRegexMatcher
(
regex
,
false
));
}
inline
PolymorphicMatcher
<
internal
::
MatchesRegexMatcher
>
ContainsRegex
(
const
std
::
string
&
regex
)
{
return
ContainsRegex
(
new
internal
::
RE
(
regex
));
}
// Creates a polymorphic matcher that matches anything equal to x.
// Creates a polymorphic matcher that matches anything equal to x.
// Note: if the parameter of Eq() were declared as const T&, Eq("foo")
// Note: if the parameter of Eq() were declared as const T&, Eq("foo")
// wouldn't compile.
// wouldn't compile.
...
...
googletest/include/gtest/internal/gtest-death-test-internal.h
View file @
b22d2366
...
@@ -36,6 +36,7 @@
...
@@ -36,6 +36,7 @@
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_
#include "gtest/gtest-matchers.h"
#include "gtest/internal/gtest-internal.h"
#include "gtest/internal/gtest-internal.h"
#include <stdio.h>
#include <stdio.h>
...
@@ -79,7 +80,7 @@ class GTEST_API_ DeathTest {
...
@@ -79,7 +80,7 @@ class GTEST_API_ DeathTest {
// argument is set. If the death test should be skipped, the pointer
// argument is set. If the death test should be skipped, the pointer
// is set to NULL; otherwise, it is set to the address of a new concrete
// is set to NULL; otherwise, it is set to the address of a new concrete
// DeathTest object that controls the execution of the current test.
// DeathTest object that controls the execution of the current test.
static
bool
Create
(
const
char
*
statement
,
const
RE
*
regex
,
static
bool
Create
(
const
char
*
statement
,
Matcher
<
const
std
::
string
&>
matcher
,
const
char
*
file
,
int
line
,
DeathTest
**
test
);
const
char
*
file
,
int
line
,
DeathTest
**
test
);
DeathTest
();
DeathTest
();
virtual
~
DeathTest
()
{
}
virtual
~
DeathTest
()
{
}
...
@@ -145,21 +146,51 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
...
@@ -145,21 +146,51 @@ GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251
class
DeathTestFactory
{
class
DeathTestFactory
{
public
:
public
:
virtual
~
DeathTestFactory
()
{
}
virtual
~
DeathTestFactory
()
{
}
virtual
bool
Create
(
const
char
*
statement
,
const
RE
*
regex
,
virtual
bool
Create
(
const
char
*
statement
,
const
char
*
file
,
int
line
,
DeathTest
**
test
)
=
0
;
Matcher
<
const
std
::
string
&>
matcher
,
const
char
*
file
,
int
line
,
DeathTest
**
test
)
=
0
;
};
};
// A concrete DeathTestFactory implementation for normal use.
// A concrete DeathTestFactory implementation for normal use.
class
DefaultDeathTestFactory
:
public
DeathTestFactory
{
class
DefaultDeathTestFactory
:
public
DeathTestFactory
{
public
:
public
:
virtual
bool
Create
(
const
char
*
statement
,
const
RE
*
regex
,
virtual
bool
Create
(
const
char
*
statement
,
const
char
*
file
,
int
line
,
DeathTest
**
test
);
Matcher
<
const
std
::
string
&>
matcher
,
const
char
*
file
,
int
line
,
DeathTest
**
test
);
};
};
// Returns true if exit_status describes a process that was terminated
// Returns true if exit_status describes a process that was terminated
// by a signal, or exited normally with a nonzero exit code.
// by a signal, or exited normally with a nonzero exit code.
GTEST_API_
bool
ExitedUnsuccessfully
(
int
exit_status
);
GTEST_API_
bool
ExitedUnsuccessfully
(
int
exit_status
);
// A string passed to EXPECT_DEATH (etc.) is caught by one of these overloads
// and interpreted as a regex (rather than an Eq matcher) for legacy
// compatibility.
inline
Matcher
<
const
::
std
::
string
&>
MakeDeathTestMatcher
(
::
testing
::
internal
::
RE
regex
)
{
return
ContainsRegex
(
regex
.
pattern
());
}
inline
Matcher
<
const
::
std
::
string
&>
MakeDeathTestMatcher
(
const
char
*
regex
)
{
return
ContainsRegex
(
regex
);
}
inline
Matcher
<
const
::
std
::
string
&>
MakeDeathTestMatcher
(
const
::
std
::
string
&
regex
)
{
return
ContainsRegex
(
regex
);
}
#if GTEST_HAS_GLOBAL_STRING
inline
Matcher
<
const
::
std
::
string
&>
MakeDeathTestMatcher
(
const
::
string
&
regex
)
{
return
ContainsRegex
(
regex
);
}
#endif
// If a Matcher<const ::std::string&> is passed to EXPECT_DEATH (etc.), it's
// used directly.
inline
Matcher
<
const
::
std
::
string
&>
MakeDeathTestMatcher
(
Matcher
<
const
::
std
::
string
&>
matcher
)
{
return
matcher
;
}
// Traps C++ exceptions escaping statement and reports them as test
// Traps C++ exceptions escaping statement and reports them as test
// failures. Note that trapping SEH exceptions is not implemented here.
// failures. Note that trapping SEH exceptions is not implemented here.
# if GTEST_HAS_EXCEPTIONS
# if GTEST_HAS_EXCEPTIONS
...
@@ -187,37 +218,37 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
...
@@ -187,37 +218,37 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
// ASSERT_EXIT*, and EXPECT_EXIT*.
// ASSERT_EXIT*, and EXPECT_EXIT*.
#define GTEST_DEATH_TEST_(statement, predicate, regex
, fail)
\
#define GTEST_DEATH_TEST_(statement, predicate, regex
_or_matcher, fail)
\
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
GTEST_AMBIGUOUS_ELSE_BLOCKER_
\
if (::testing::internal::AlwaysTrue()) { \
if (::testing::internal::AlwaysTrue()) {
\
const ::testing::internal::RE& gtest_regex = (regex);
\
::testing::internal::DeathTest* gtest_dt;
\
::testing::internal::DeathTest* gtest_dt;
\
if (!::testing::internal::DeathTest::Create(
\
if (!::testing::internal::DeathTest::Create(
\
#statement,
\
#statement, >est_regex, __FILE__, __LINE__, >est_dt)) {
\
::testing::internal::MakeDeathTestMatcher(regex_or_matcher),
\
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__);
\
__FILE__, __LINE__, >est_dt)) {
\
}
\
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__);
\
if (gtest_dt != nullptr) {
\
}
\
std::unique_ptr< ::testing::internal::DeathTest>
\
if (gtest_dt != nullptr) {
\
gtest_dt_ptr(gtest_dt);
\
std::unique_ptr< ::testing::internal::DeathTest> gtest_dt_ptr(gtest_dt);
\
switch (gtest_dt->AssumeRole()) { \
switch (gtest_dt->AssumeRole()) {
\
case ::testing::internal::DeathTest::OVERSEE_TEST: \
case ::testing::internal::DeathTest::OVERSEE_TEST:
\
if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) {
\
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__);
\
} \
}
\
break; \
break;
\
case ::testing::internal::DeathTest::EXECUTE_TEST: { \
case ::testing::internal::DeathTest::EXECUTE_TEST: {
\
::testing::internal::DeathTest::ReturnSentinel gtest_sentinel( \
::testing::internal::DeathTest::ReturnSentinel gtest_sentinel(
\
gtest_dt); \
gtest_dt);
\
GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt);
\
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE);
\
break; \
break;
\
} \
}
\
default: \
default:
\
break; \
break;
\
} \
}
\
} \
}
\
} else \
} else
\
GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__) \
GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__)
\
: fail(::testing::internal::DeathTest::LastMessage())
: fail(::testing::internal::DeathTest::LastMessage())
// The symbol "fail" here expands to something into which a message
// The symbol "fail" here expands to something into which a message
// can be streamed.
// can be streamed.
...
@@ -227,14 +258,13 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
...
@@ -227,14 +258,13 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// must accept a streamed message even though the message is never printed.
// must accept a streamed message even though the message is never printed.
// The regex object is not evaluated, but it is used to prevent "unused"
// The regex object is not evaluated, but it is used to prevent "unused"
// warnings and to avoid an expression that doesn't compile in debug mode.
// warnings and to avoid an expression that doesn't compile in debug mode.
#define GTEST_EXECUTE_STATEMENT_(statement, regex) \
#define GTEST_EXECUTE_STATEMENT_(statement, regex_or_matcher) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
if (::testing::internal::AlwaysTrue()) { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} else if (!::testing::internal::AlwaysTrue()) { \
} else if (!::testing::internal::AlwaysTrue()) { \
const ::testing::internal::RE& gtest_regex = (regex); \
::testing::internal::MakeDeathTestMatcher(regex_or_matcher); \
static_cast<void>(gtest_regex); \
} else \
} else \
::testing::Message()
::testing::Message()
// A class representing the parsed contents of the
// A class representing the parsed contents of the
...
...
googletest/src/gtest-death-test.cc
View file @
b22d2366
...
@@ -31,6 +31,9 @@
...
@@ -31,6 +31,9 @@
// This file implements death tests.
// This file implements death tests.
#include "gtest/gtest-death-test.h"
#include "gtest/gtest-death-test.h"
#include <utility>
#include "gtest/internal/gtest-port.h"
#include "gtest/internal/gtest-port.h"
#include "gtest/internal/custom/gtest.h"
#include "gtest/internal/custom/gtest.h"
...
@@ -374,10 +377,11 @@ DeathTest::DeathTest() {
...
@@ -374,10 +377,11 @@ DeathTest::DeathTest() {
// Creates and returns a death test by dispatching to the current
// Creates and returns a death test by dispatching to the current
// death test factory.
// death test factory.
bool
DeathTest
::
Create
(
const
char
*
statement
,
const
RE
*
regex
,
bool
DeathTest
::
Create
(
const
char
*
statement
,
const
char
*
file
,
int
line
,
DeathTest
**
test
)
{
Matcher
<
const
std
::
string
&>
matcher
,
const
char
*
file
,
int
line
,
DeathTest
**
test
)
{
return
GetUnitTestImpl
()
->
death_test_factory
()
->
Create
(
return
GetUnitTestImpl
()
->
death_test_factory
()
->
Create
(
statement
,
regex
,
file
,
line
,
test
);
statement
,
std
::
move
(
matcher
)
,
file
,
line
,
test
);
}
}
const
char
*
DeathTest
::
LastMessage
()
{
const
char
*
DeathTest
::
LastMessage
()
{
...
@@ -393,9 +397,9 @@ std::string DeathTest::last_death_test_message_;
...
@@ -393,9 +397,9 @@ std::string DeathTest::last_death_test_message_;
// Provides cross platform implementation for some death functionality.
// Provides cross platform implementation for some death functionality.
class
DeathTestImpl
:
public
DeathTest
{
class
DeathTestImpl
:
public
DeathTest
{
protected
:
protected
:
DeathTestImpl
(
const
char
*
a_statement
,
const
RE
*
a_regex
)
DeathTestImpl
(
const
char
*
a_statement
,
Matcher
<
const
std
::
string
&>
matcher
)
:
statement_
(
a_statement
),
:
statement_
(
a_statement
),
regex_
(
a_regex
),
matcher_
(
std
::
move
(
matcher
)
),
spawned_
(
false
),
spawned_
(
false
),
status_
(
-
1
),
status_
(
-
1
),
outcome_
(
IN_PROGRESS
),
outcome_
(
IN_PROGRESS
),
...
@@ -409,7 +413,6 @@ class DeathTestImpl : public DeathTest {
...
@@ -409,7 +413,6 @@ class DeathTestImpl : public DeathTest {
virtual
bool
Passed
(
bool
status_ok
);
virtual
bool
Passed
(
bool
status_ok
);
const
char
*
statement
()
const
{
return
statement_
;
}
const
char
*
statement
()
const
{
return
statement_
;
}
const
RE
*
regex
()
const
{
return
regex_
;
}
bool
spawned
()
const
{
return
spawned_
;
}
bool
spawned
()
const
{
return
spawned_
;
}
void
set_spawned
(
bool
is_spawned
)
{
spawned_
=
is_spawned
;
}
void
set_spawned
(
bool
is_spawned
)
{
spawned_
=
is_spawned
;
}
int
status
()
const
{
return
status_
;
}
int
status
()
const
{
return
status_
;
}
...
@@ -434,9 +437,8 @@ class DeathTestImpl : public DeathTest {
...
@@ -434,9 +437,8 @@ class DeathTestImpl : public DeathTest {
// The textual content of the code this object is testing. This class
// The textual content of the code this object is testing. This class
// doesn't own this string and should not attempt to delete it.
// doesn't own this string and should not attempt to delete it.
const
char
*
const
statement_
;
const
char
*
const
statement_
;
// The regular expression which test output must match. DeathTestImpl
// A matcher that's expected to match the stderr output by the child process.
// doesn't own this object and should not attempt to delete it.
Matcher
<
const
std
::
string
&>
matcher_
;
const
RE
*
const
regex_
;
// True if the death test child process has been successfully spawned.
// True if the death test child process has been successfully spawned.
bool
spawned_
;
bool
spawned_
;
// The exit status of the child process.
// The exit status of the child process.
...
@@ -555,9 +557,8 @@ static ::std::string FormatDeathTestOutput(const ::std::string& output) {
...
@@ -555,9 +557,8 @@ static ::std::string FormatDeathTestOutput(const ::std::string& output) {
// in the format specified by wait(2). On Windows, this is the
// in the format specified by wait(2). On Windows, this is the
// value supplied to the ExitProcess() API or a numeric code
// value supplied to the ExitProcess() API or a numeric code
// of the exception that terminated the program.
// of the exception that terminated the program.
// regex: A regular expression object to be applied to
// matcher_: A matcher that's expected to match the stderr output by the child
// the test's captured standard error output; the death test
// process.
// fails if it does not match.
//
//
// Argument:
// Argument:
// status_ok: true if exit_status is acceptable in the context of
// status_ok: true if exit_status is acceptable in the context of
...
@@ -591,18 +592,15 @@ bool DeathTestImpl::Passed(bool status_ok) {
...
@@ -591,18 +592,15 @@ bool DeathTestImpl::Passed(bool status_ok) {
break
;
break
;
case
DIED
:
case
DIED
:
if
(
status_ok
)
{
if
(
status_ok
)
{
# if GTEST_USES_PCRE
if
(
matcher_
.
Matches
(
error_message
))
{
// PCRE regexes support embedded NULs.
const
bool
matched
=
RE
::
PartialMatch
(
error_message
,
*
regex
());
# else
const
bool
matched
=
RE
::
PartialMatch
(
error_message
.
c_str
(),
*
regex
());
# endif // GTEST_USES_PCRE
if
(
matched
)
{
success
=
true
;
success
=
true
;
}
else
{
}
else
{
std
::
ostringstream
stream
;
matcher_
.
DescribeTo
(
&
stream
);
buffer
<<
" Result: died but not with expected error.
\n
"
buffer
<<
" Result: died but not with expected error.
\n
"
<<
" Expected: "
<<
regex
()
->
pattern
()
<<
"
\n
"
<<
" Expected: "
<<
stream
.
str
()
<<
"
\n
"
<<
"Actual msg:
\n
"
<<
FormatDeathTestOutput
(
error_message
);
<<
"Actual msg:
\n
"
<<
FormatDeathTestOutput
(
error_message
);
}
}
}
else
{
}
else
{
buffer
<<
" Result: died but not with expected exit code:
\n
"
buffer
<<
" Result: died but not with expected exit code:
\n
"
...
@@ -651,11 +649,11 @@ bool DeathTestImpl::Passed(bool status_ok) {
...
@@ -651,11 +649,11 @@ bool DeathTestImpl::Passed(bool status_ok) {
//
//
class
WindowsDeathTest
:
public
DeathTestImpl
{
class
WindowsDeathTest
:
public
DeathTestImpl
{
public
:
public
:
WindowsDeathTest
(
const
char
*
a_statement
,
WindowsDeathTest
(
const
char
*
a_statement
,
Matcher
<
const
std
::
string
&>
matcher
,
const
RE
*
a_regex
,
const
char
*
file
,
int
line
)
const
char
*
file
,
:
DeathTestImpl
(
a_statement
,
std
::
move
(
matcher
))
,
int
line
)
file_
(
file
),
:
DeathTestImpl
(
a_statement
,
a_regex
),
file_
(
file
),
line_
(
line
)
{}
line_
(
line
)
{}
// All of these virtual functions are inherited from DeathTest.
// All of these virtual functions are inherited from DeathTest.
virtual
int
Wait
();
virtual
int
Wait
();
...
@@ -815,11 +813,11 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
...
@@ -815,11 +813,11 @@ DeathTest::TestRole WindowsDeathTest::AssumeRole() {
class
FuchsiaDeathTest
:
public
DeathTestImpl
{
class
FuchsiaDeathTest
:
public
DeathTestImpl
{
public
:
public
:
FuchsiaDeathTest
(
const
char
*
a_statement
,
FuchsiaDeathTest
(
const
char
*
a_statement
,
Matcher
<
const
std
::
string
&>
matcher
,
const
RE
*
a_regex
,
const
char
*
file
,
int
line
)
const
char
*
file
,
:
DeathTestImpl
(
a_statement
,
std
::
move
(
matcher
))
,
int
line
)
file_
(
file
),
:
DeathTestImpl
(
a_statement
,
a_regex
),
file_
(
file
),
line_
(
line
)
{}
line_
(
line
)
{}
// All of these virtual functions are inherited from DeathTest.
// All of these virtual functions are inherited from DeathTest.
int
Wait
()
override
;
int
Wait
()
override
;
...
@@ -1064,7 +1062,7 @@ std::string FuchsiaDeathTest::GetErrorLogs() {
...
@@ -1064,7 +1062,7 @@ std::string FuchsiaDeathTest::GetErrorLogs() {
// left undefined.
// left undefined.
class
ForkingDeathTest
:
public
DeathTestImpl
{
class
ForkingDeathTest
:
public
DeathTestImpl
{
public
:
public
:
ForkingDeathTest
(
const
char
*
statement
,
const
RE
*
regex
);
ForkingDeathTest
(
const
char
*
statement
,
Matcher
<
const
std
::
string
&>
matcher
);
// All of these virtual functions are inherited from DeathTest.
// All of these virtual functions are inherited from DeathTest.
virtual
int
Wait
();
virtual
int
Wait
();
...
@@ -1078,9 +1076,9 @@ class ForkingDeathTest : public DeathTestImpl {
...
@@ -1078,9 +1076,9 @@ class ForkingDeathTest : public DeathTestImpl {
};
};
// Constructs a ForkingDeathTest.
// Constructs a ForkingDeathTest.
ForkingDeathTest
::
ForkingDeathTest
(
const
char
*
a_statement
,
const
RE
*
a_regex
)
ForkingDeathTest
::
ForkingDeathTest
(
const
char
*
a_statement
,
:
DeathTestImpl
(
a_statement
,
a_regex
),
Matcher
<
const
std
::
string
&>
matcher
)
child_pid_
(
-
1
)
{}
:
DeathTestImpl
(
a_statement
,
std
::
move
(
matcher
)),
child_pid_
(
-
1
)
{}
// Waits for the child in a death test to exit, returning its exit
// Waits for the child in a death test to exit, returning its exit
// status, or 0 if no child process exists. As a side effect, sets the
// status, or 0 if no child process exists. As a side effect, sets the
...
@@ -1101,8 +1099,8 @@ int ForkingDeathTest::Wait() {
...
@@ -1101,8 +1099,8 @@ int ForkingDeathTest::Wait() {
// in the child process.
// in the child process.
class
NoExecDeathTest
:
public
ForkingDeathTest
{
class
NoExecDeathTest
:
public
ForkingDeathTest
{
public
:
public
:
NoExecDeathTest
(
const
char
*
a_statement
,
const
RE
*
a_regex
)
:
NoExecDeathTest
(
const
char
*
a_statement
,
Matcher
<
const
std
::
string
&>
matcher
)
ForkingDeathTest
(
a_statement
,
a_regex
)
{
}
:
ForkingDeathTest
(
a_statement
,
std
::
move
(
matcher
))
{
}
virtual
TestRole
AssumeRole
();
virtual
TestRole
AssumeRole
();
};
};
...
@@ -1156,9 +1154,11 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() {
...
@@ -1156,9 +1154,11 @@ DeathTest::TestRole NoExecDeathTest::AssumeRole() {
// only this specific death test to be run.
// only this specific death test to be run.
class
ExecDeathTest
:
public
ForkingDeathTest
{
class
ExecDeathTest
:
public
ForkingDeathTest
{
public
:
public
:
ExecDeathTest
(
const
char
*
a_statement
,
const
RE
*
a_regex
,
ExecDeathTest
(
const
char
*
a_statement
,
Matcher
<
const
std
::
string
&>
matcher
,
const
char
*
file
,
int
line
)
:
const
char
*
file
,
int
line
)
ForkingDeathTest
(
a_statement
,
a_regex
),
file_
(
file
),
line_
(
line
)
{
}
:
ForkingDeathTest
(
a_statement
,
std
::
move
(
matcher
)),
file_
(
file
),
line_
(
line
)
{}
virtual
TestRole
AssumeRole
();
virtual
TestRole
AssumeRole
();
private
:
private
:
static
::
std
::
vector
<
std
::
string
>
GetArgvsForDeathTestChildProcess
()
{
static
::
std
::
vector
<
std
::
string
>
GetArgvsForDeathTestChildProcess
()
{
...
@@ -1447,7 +1447,8 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
...
@@ -1447,7 +1447,8 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() {
// by the "test" argument to its address. If the test should be
// by the "test" argument to its address. If the test should be
// skipped, sets that pointer to NULL. Returns true, unless the
// skipped, sets that pointer to NULL. Returns true, unless the
// flag is set to an invalid value.
// flag is set to an invalid value.
bool
DefaultDeathTestFactory
::
Create
(
const
char
*
statement
,
const
RE
*
regex
,
bool
DefaultDeathTestFactory
::
Create
(
const
char
*
statement
,
Matcher
<
const
std
::
string
&>
matcher
,
const
char
*
file
,
int
line
,
const
char
*
file
,
int
line
,
DeathTest
**
test
)
{
DeathTest
**
test
)
{
UnitTestImpl
*
const
impl
=
GetUnitTestImpl
();
UnitTestImpl
*
const
impl
=
GetUnitTestImpl
();
...
@@ -1476,22 +1477,22 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
...
@@ -1476,22 +1477,22 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex,
if
(
GTEST_FLAG
(
death_test_style
)
==
"threadsafe"
||
if
(
GTEST_FLAG
(
death_test_style
)
==
"threadsafe"
||
GTEST_FLAG
(
death_test_style
)
==
"fast"
)
{
GTEST_FLAG
(
death_test_style
)
==
"fast"
)
{
*
test
=
new
WindowsDeathTest
(
statement
,
regex
,
file
,
line
);
*
test
=
new
WindowsDeathTest
(
statement
,
std
::
move
(
matcher
)
,
file
,
line
);
}
}
# elif GTEST_OS_FUCHSIA
# elif GTEST_OS_FUCHSIA
if
(
GTEST_FLAG
(
death_test_style
)
==
"threadsafe"
||
if
(
GTEST_FLAG
(
death_test_style
)
==
"threadsafe"
||
GTEST_FLAG
(
death_test_style
)
==
"fast"
)
{
GTEST_FLAG
(
death_test_style
)
==
"fast"
)
{
*
test
=
new
FuchsiaDeathTest
(
statement
,
regex
,
file
,
line
);
*
test
=
new
FuchsiaDeathTest
(
statement
,
std
::
move
(
matcher
)
,
file
,
line
);
}
}
# else
# else
if
(
GTEST_FLAG
(
death_test_style
)
==
"threadsafe"
)
{
if
(
GTEST_FLAG
(
death_test_style
)
==
"threadsafe"
)
{
*
test
=
new
ExecDeathTest
(
statement
,
regex
,
file
,
line
);
*
test
=
new
ExecDeathTest
(
statement
,
std
::
move
(
matcher
)
,
file
,
line
);
}
else
if
(
GTEST_FLAG
(
death_test_style
)
==
"fast"
)
{
}
else
if
(
GTEST_FLAG
(
death_test_style
)
==
"fast"
)
{
*
test
=
new
NoExecDeathTest
(
statement
,
regex
);
*
test
=
new
NoExecDeathTest
(
statement
,
std
::
move
(
matcher
)
);
}
}
# endif // GTEST_OS_WINDOWS
# endif // GTEST_OS_WINDOWS
...
...
googletest/test/googletest-death-test-test.cc
View file @
b22d2366
...
@@ -31,6 +31,8 @@
...
@@ -31,6 +31,8 @@
// Tests for death tests.
// Tests for death tests.
#include "gtest/gtest-death-test.h"
#include "gtest/gtest-death-test.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "gtest/gtest.h"
#include "gtest/internal/gtest-filepath.h"
#include "gtest/internal/gtest-filepath.h"
...
@@ -59,6 +61,8 @@ using testing::internal::AlwaysTrue;
...
@@ -59,6 +61,8 @@ using testing::internal::AlwaysTrue;
namespace
posix
=
::
testing
::
internal
::
posix
;
namespace
posix
=
::
testing
::
internal
::
posix
;
using
testing
::
HasSubstr
;
using
testing
::
Matcher
;
using
testing
::
Message
;
using
testing
::
Message
;
using
testing
::
internal
::
DeathTest
;
using
testing
::
internal
::
DeathTest
;
using
testing
::
internal
::
DeathTestFactory
;
using
testing
::
internal
::
DeathTestFactory
;
...
@@ -97,6 +101,8 @@ class ReplaceDeathTestFactory {
...
@@ -97,6 +101,8 @@ class ReplaceDeathTestFactory {
}
// namespace internal
}
// namespace internal
}
// namespace testing
}
// namespace testing
namespace
{
void
DieWithMessage
(
const
::
std
::
string
&
message
)
{
void
DieWithMessage
(
const
::
std
::
string
&
message
)
{
fprintf
(
stderr
,
"%s"
,
message
.
c_str
());
fprintf
(
stderr
,
"%s"
,
message
.
c_str
());
fflush
(
stderr
);
// Make sure the text is printed before the process exits.
fflush
(
stderr
);
// Make sure the text is printed before the process exits.
...
@@ -452,16 +458,12 @@ TEST_F(TestForDeathTest, MixedStyles) {
...
@@ -452,16 +458,12 @@ TEST_F(TestForDeathTest, MixedStyles) {
# if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD
# if GTEST_HAS_CLONE && GTEST_HAS_PTHREAD
namespace
{
bool
pthread_flag
;
bool
pthread_flag
;
void
SetPthreadFlag
()
{
void
SetPthreadFlag
()
{
pthread_flag
=
true
;
pthread_flag
=
true
;
}
}
}
// namespace
TEST_F
(
TestForDeathTest
,
DoesNotExecuteAtforkHooks
)
{
TEST_F
(
TestForDeathTest
,
DoesNotExecuteAtforkHooks
)
{
if
(
!
testing
::
GTEST_FLAG
(
death_test_use_fork
))
{
if
(
!
testing
::
GTEST_FLAG
(
death_test_use_fork
))
{
testing
::
GTEST_FLAG
(
death_test_style
)
=
"threadsafe"
;
testing
::
GTEST_FLAG
(
death_test_style
)
=
"threadsafe"
;
...
@@ -885,7 +887,7 @@ class MockDeathTestFactory : public DeathTestFactory {
...
@@ -885,7 +887,7 @@ class MockDeathTestFactory : public DeathTestFactory {
public
:
public
:
MockDeathTestFactory
();
MockDeathTestFactory
();
virtual
bool
Create
(
const
char
*
statement
,
virtual
bool
Create
(
const
char
*
statement
,
const
::
testing
::
internal
::
RE
*
regex
,
testing
::
Matcher
<
const
std
::
string
&>
matcher
,
const
char
*
file
,
int
line
,
DeathTest
**
test
);
const
char
*
file
,
int
line
,
DeathTest
**
test
);
// Sets the parameters for subsequent calls to Create.
// Sets the parameters for subsequent calls to Create.
...
@@ -1000,11 +1002,9 @@ void MockDeathTestFactory::SetParameters(bool create,
...
@@ -1000,11 +1002,9 @@ void MockDeathTestFactory::SetParameters(bool create,
// Sets test to NULL (if create_ is false) or to the address of a new
// Sets test to NULL (if create_ is false) or to the address of a new
// MockDeathTest object with parameters taken from the last call
// MockDeathTest object with parameters taken from the last call
// to SetParameters (if create_ is true). Always returns true.
// to SetParameters (if create_ is true). Always returns true.
bool
MockDeathTestFactory
::
Create
(
const
char
*
/*statement*/
,
bool
MockDeathTestFactory
::
Create
(
const
::
testing
::
internal
::
RE
*
/*regex*/
,
const
char
*
/*statement*/
,
testing
::
Matcher
<
const
std
::
string
&>
/*matcher*/
,
const
char
*
/*file*/
,
const
char
*
/*file*/
,
int
/*line*/
,
DeathTest
**
test
)
{
int
/*line*/
,
DeathTest
**
test
)
{
test_deleted_
=
false
;
test_deleted_
=
false
;
if
(
create_
)
{
if
(
create_
)
{
*
test
=
new
MockDeathTest
(
this
,
role_
,
status_
,
passed_
);
*
test
=
new
MockDeathTest
(
this
,
role_
,
status_
,
passed_
);
...
@@ -1326,8 +1326,60 @@ TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) {
...
@@ -1326,8 +1326,60 @@ TEST(InDeathTestChildDeathTest, ReportsDeathTestCorrectlyInThreadSafeStyle) {
},
"Inside"
);
},
"Inside"
);
}
}
void
DieWithMessage
(
const
char
*
message
)
{
fputs
(
message
,
stderr
);
fflush
(
stderr
);
// Make sure the text is printed before the process exits.
_exit
(
1
);
}
TEST
(
MatcherDeathTest
,
DoesNotBreakBareRegexMatching
)
{
// googletest tests this, of course; here we ensure that including googlemock
// has not broken it.
EXPECT_DEATH
(
DieWithMessage
(
"O, I die, Horatio."
),
"I d[aeiou]e"
);
}
TEST
(
MatcherDeathTest
,
MonomorphicMatcherMatches
)
{
EXPECT_DEATH
(
DieWithMessage
(
"Behind O, I am slain!"
),
Matcher
<
const
std
::
string
&>
(
HasSubstr
(
"I am slain"
)));
}
TEST
(
MatcherDeathTest
,
MonomorphicMatcherDoesNotMatch
)
{
EXPECT_NONFATAL_FAILURE
(
EXPECT_DEATH
(
DieWithMessage
(
"Behind O, I am slain!"
),
Matcher
<
const
std
::
string
&>
(
HasSubstr
(
"Ow, I am slain"
))),
"Expected: has substring
\"
Ow, I am slain
\"
"
);
}
TEST
(
MatcherDeathTest
,
PolymorphicMatcherMatches
)
{
EXPECT_DEATH
(
DieWithMessage
(
"The rest is silence."
),
HasSubstr
(
"rest is silence"
));
}
TEST
(
MatcherDeathTest
,
PolymorphicMatcherDoesNotMatch
)
{
EXPECT_NONFATAL_FAILURE
(
EXPECT_DEATH
(
DieWithMessage
(
"The rest is silence."
),
HasSubstr
(
"rest is science"
)),
"Expected: has substring
\"
rest is science
\"
"
);
}
TEST
(
MatcherDeathTest
,
CompositeMatcherMatches
)
{
EXPECT_DEATH
(
DieWithMessage
(
"Et tu, Brute! Then fall, Caesar."
),
AllOf
(
HasSubstr
(
"Et tu"
),
HasSubstr
(
"fall, Caesar"
)));
}
TEST
(
MatcherDeathTest
,
CompositeMatcherDoesNotMatch
)
{
EXPECT_NONFATAL_FAILURE
(
EXPECT_DEATH
(
DieWithMessage
(
"The rest is silence."
),
AnyOf
(
HasSubstr
(
"Eat two"
),
HasSubstr
(
"lol Caesar"
))),
"Expected: (has substring
\"
Eat two
\"
) or "
"(has substring
\"
lol Caesar
\"
)"
);
}
}
// namespace
#else // !GTEST_HAS_DEATH_TEST follows
#else // !GTEST_HAS_DEATH_TEST follows
namespace
{
using
testing
::
internal
::
CaptureStderr
;
using
testing
::
internal
::
CaptureStderr
;
using
testing
::
internal
::
GetCapturedStderr
;
using
testing
::
internal
::
GetCapturedStderr
;
...
@@ -1376,8 +1428,12 @@ TEST(ConditionalDeathMacrosTest, AssertDeatDoesNotReturnhIfUnsupported) {
...
@@ -1376,8 +1428,12 @@ TEST(ConditionalDeathMacrosTest, AssertDeatDoesNotReturnhIfUnsupported) {
EXPECT_EQ
(
1
,
n
);
EXPECT_EQ
(
1
,
n
);
}
}
}
// namespace
#endif // !GTEST_HAS_DEATH_TEST
#endif // !GTEST_HAS_DEATH_TEST
namespace
{
// Tests that the death test macros expand to code which may or may not
// Tests that the death test macros expand to code which may or may not
// be followed by operator<<, and that in either case the complete text
// be followed by operator<<, and that in either case the complete text
// comprises only a single C++ statement.
// comprises only a single C++ statement.
...
@@ -1428,3 +1484,5 @@ TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) {
...
@@ -1428,3 +1484,5 @@ TEST(ConditionalDeathMacrosSyntaxDeathTest, SwitchStatement) {
TEST
(
NotADeathTest
,
Test
)
{
TEST
(
NotADeathTest
,
Test
)
{
SUCCEED
();
SUCCEED
();
}
}
}
// namespace
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment