Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
yangql
googletest
Commits
ebb2fca5
Unverified
Commit
ebb2fca5
authored
Aug 27, 2018
by
Gennadiy Civil
Committed by
GitHub
Aug 27, 2018
Browse files
Merge branch 'master' into fix-1764_CMake-errors-in-googlemock
parents
b19292e6
641e7a37
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
387 additions
and
109 deletions
+387
-109
CONTRIBUTING.md
CONTRIBUTING.md
+1
-2
googlemock/include/gmock/gmock-matchers.h
googlemock/include/gmock/gmock-matchers.h
+35
-34
googlemock/test/gmock-matchers_test.cc
googlemock/test/gmock-matchers_test.cc
+18
-0
googletest/src/gtest.cc
googletest/src/gtest.cc
+139
-71
googletest/test/gtest_list_output_unittest.py
googletest/test/gtest_list_output_unittest.py
+141
-0
googletest/test/gtest_list_output_unittest_.cc
googletest/test/gtest_list_output_unittest_.cc
+51
-0
googletest/test/gtest_unittest.cc
googletest/test/gtest_unittest.cc
+2
-2
No files found.
CONTRIBUTING.md
View file @
ebb2fca5
...
@@ -20,8 +20,7 @@ instructions for how to sign and return it. Once we receive it, we'll be able to
...
@@ -20,8 +20,7 @@ instructions for how to sign and return it. Once we receive it, we'll be able to
accept your pull requests.
accept your pull requests.
## Are you a Googler?
## Are you a Googler?
If you are a Googler, please create an internal change and
If you are a Googler, you can either create an internal change or work on GitHub directly.
have it reviewed and submitted. The maintainers will normally be in position to upstream the changes.
## Contributing A Patch
## Contributing A Patch
...
...
googlemock/include/gmock/gmock-matchers.h
View file @
ebb2fca5
...
@@ -2602,16 +2602,20 @@ class PropertyMatcher {
...
@@ -2602,16 +2602,20 @@ class PropertyMatcher {
// Type traits specifying various features of different functors for ResultOf.
// Type traits specifying various features of different functors for ResultOf.
// The default template specifies features for functor objects.
// The default template specifies features for functor objects.
// Functor classes have to typedef argument_type and result_type
// to be compatible with ResultOf.
template
<
typename
Functor
>
template
<
typename
Functor
>
struct
CallableTraits
{
struct
CallableTraits
{
typedef
typename
Functor
::
result_type
ResultType
;
typedef
Functor
StorageType
;
typedef
Functor
StorageType
;
static
void
CheckIsValid
(
Functor
/* functor */
)
{}
static
void
CheckIsValid
(
Functor
/* functor */
)
{}
#if GTEST_LANG_CXX11
template
<
typename
T
>
static
auto
Invoke
(
Functor
f
,
T
arg
)
->
decltype
(
f
(
arg
))
{
return
f
(
arg
);
}
#else
typedef
typename
Functor
::
result_type
ResultType
;
template
<
typename
T
>
template
<
typename
T
>
static
ResultType
Invoke
(
Functor
f
,
T
arg
)
{
return
f
(
arg
);
}
static
ResultType
Invoke
(
Functor
f
,
T
arg
)
{
return
f
(
arg
);
}
#endif
};
};
// Specialization for function pointers.
// Specialization for function pointers.
...
@@ -2632,13 +2636,11 @@ struct CallableTraits<ResType(*)(ArgType)> {
...
@@ -2632,13 +2636,11 @@ struct CallableTraits<ResType(*)(ArgType)> {
// Implements the ResultOf() matcher for matching a return value of a
// Implements the ResultOf() matcher for matching a return value of a
// unary function of an object.
// unary function of an object.
template
<
typename
Callable
>
template
<
typename
Callable
,
typename
InnerMatcher
>
class
ResultOfMatcher
{
class
ResultOfMatcher
{
public:
public:
typedef
typename
CallableTraits
<
Callable
>::
ResultType
ResultType
;
ResultOfMatcher
(
Callable
callable
,
InnerMatcher
matcher
)
:
callable_
(
internal
::
move
(
callable
)),
matcher_
(
internal
::
move
(
matcher
))
{
ResultOfMatcher
(
Callable
callable
,
const
Matcher
<
ResultType
>&
matcher
)
:
callable_
(
callable
),
matcher_
(
matcher
)
{
CallableTraits
<
Callable
>::
CheckIsValid
(
callable_
);
CallableTraits
<
Callable
>::
CheckIsValid
(
callable_
);
}
}
...
@@ -2652,9 +2654,17 @@ class ResultOfMatcher {
...
@@ -2652,9 +2654,17 @@ class ResultOfMatcher {
template
<
typename
T
>
template
<
typename
T
>
class
Impl
:
public
MatcherInterface
<
T
>
{
class
Impl
:
public
MatcherInterface
<
T
>
{
#if GTEST_LANG_CXX11
using
ResultType
=
decltype
(
CallableTraits
<
Callable
>::
template
Invoke
<
T
>
(
std
::
declval
<
CallableStorageType
>
(),
std
::
declval
<
T
>
()));
#else
typedef
typename
CallableTraits
<
Callable
>::
ResultType
ResultType
;
#endif
public:
public:
Impl
(
CallableStorageType
callable
,
const
Matcher
<
ResultType
>&
matcher
)
template
<
typename
M
>
:
callable_
(
callable
),
matcher_
(
matcher
)
{}
Impl
(
const
CallableStorageType
&
callable
,
const
M
&
matcher
)
:
callable_
(
callable
),
matcher_
(
MatcherCast
<
ResultType
>
(
matcher
))
{}
virtual
void
DescribeTo
(
::
std
::
ostream
*
os
)
const
{
virtual
void
DescribeTo
(
::
std
::
ostream
*
os
)
const
{
*
os
<<
"is mapped by the given callable to a value that "
;
*
os
<<
"is mapped by the given callable to a value that "
;
...
@@ -2668,8 +2678,10 @@ class ResultOfMatcher {
...
@@ -2668,8 +2678,10 @@ class ResultOfMatcher {
virtual
bool
MatchAndExplain
(
T
obj
,
MatchResultListener
*
listener
)
const
{
virtual
bool
MatchAndExplain
(
T
obj
,
MatchResultListener
*
listener
)
const
{
*
listener
<<
"which is mapped by the given callable to "
;
*
listener
<<
"which is mapped by the given callable to "
;
// Cannot pass the return value (for example, int) to
// Cannot pass the return value directly to MatchPrintAndExplain, which
// MatchPrintAndExplain, which takes a non-const reference as argument.
// takes a non-const reference as argument.
// Also, specifying template argument explicitly is needed because T could
// be a non-const reference (e.g. Matcher<Uncopyable&>).
ResultType
result
=
ResultType
result
=
CallableTraits
<
Callable
>::
template
Invoke
<
T
>
(
callable_
,
obj
);
CallableTraits
<
Callable
>::
template
Invoke
<
T
>
(
callable_
,
obj
);
return
MatchPrintAndExplain
(
result
,
matcher_
,
listener
);
return
MatchPrintAndExplain
(
result
,
matcher_
,
listener
);
...
@@ -2679,7 +2691,7 @@ class ResultOfMatcher {
...
@@ -2679,7 +2691,7 @@ class ResultOfMatcher {
// Functors often define operator() as non-const method even though
// Functors often define operator() as non-const method even though
// they are actually stateless. But we need to use them even when
// they are actually stateless. But we need to use them even when
// 'this' is a const pointer. It's the user's responsibility not to
// 'this' is a const pointer. It's the user's responsibility not to
// use stateful callables with ResultOf(), which does't guarantee
// use stateful callables with ResultOf(), which does
n
't guarantee
// how many times the callable will be invoked.
// how many times the callable will be invoked.
mutable
CallableStorageType
callable_
;
mutable
CallableStorageType
callable_
;
const
Matcher
<
ResultType
>
matcher_
;
const
Matcher
<
ResultType
>
matcher_
;
...
@@ -2688,7 +2700,7 @@ class ResultOfMatcher {
...
@@ -2688,7 +2700,7 @@ class ResultOfMatcher {
};
// class Impl
};
// class Impl
const
CallableStorageType
callable_
;
const
CallableStorageType
callable_
;
const
Matcher
<
ResultType
>
matcher_
;
const
Inner
Matcher
matcher_
;
GTEST_DISALLOW_ASSIGN_
(
ResultOfMatcher
);
GTEST_DISALLOW_ASSIGN_
(
ResultOfMatcher
);
};
};
...
@@ -4554,26 +4566,15 @@ Property(const std::string& property_name,
...
@@ -4554,26 +4566,15 @@ Property(const std::string& property_name,
// For example,
// For example,
// ResultOf(f, StartsWith("hi"))
// ResultOf(f, StartsWith("hi"))
// matches a Foo object x iff f(x) starts with "hi".
// matches a Foo object x iff f(x) starts with "hi".
// callable parameter can be a function, function pointer, or a functor.
// `callable` parameter can be a function, function pointer, or a functor. It is
// Callable has to satisfy the following conditions:
// required to keep no state affecting the results of the calls on it and make
// * It is required to keep no state affecting the results of
// no assumptions about how many calls will be made. Any state it keeps must be
// the calls on it and make no assumptions about how many calls
// protected from the concurrent access.
// will be made. Any state it keeps must be protected from the
template
<
typename
Callable
,
typename
InnerMatcher
>
// concurrent access.
internal
::
ResultOfMatcher
<
Callable
,
InnerMatcher
>
ResultOf
(
// * If it is a function object, it has to define type result_type.
Callable
callable
,
InnerMatcher
matcher
)
{
// We recommend deriving your functor classes from std::unary_function.
return
internal
::
ResultOfMatcher
<
Callable
,
InnerMatcher
>
(
//
internal
::
move
(
callable
),
internal
::
move
(
matcher
));
template
<
typename
Callable
,
typename
ResultOfMatcher
>
internal
::
ResultOfMatcher
<
Callable
>
ResultOf
(
Callable
callable
,
const
ResultOfMatcher
&
matcher
)
{
return
internal
::
ResultOfMatcher
<
Callable
>
(
callable
,
MatcherCast
<
typename
internal
::
CallableTraits
<
Callable
>::
ResultType
>
(
matcher
));
// The call to MatcherCast() is required for supporting inner
// matchers of compatible types. For example, it allows
// ResultOf(Function, m)
// to compile where Function() returns an int32 and m is a matcher for int64.
}
}
// String matchers.
// String matchers.
...
...
googlemock/test/gmock-matchers_test.cc
View file @
ebb2fca5
...
@@ -4597,6 +4597,7 @@ struct PolymorphicFunctor {
...
@@ -4597,6 +4597,7 @@ struct PolymorphicFunctor {
typedef
int
result_type
;
typedef
int
result_type
;
int
operator
()(
int
n
)
{
return
n
;
}
int
operator
()(
int
n
)
{
return
n
;
}
int
operator
()(
const
char
*
s
)
{
return
static_cast
<
int
>
(
strlen
(
s
));
}
int
operator
()(
const
char
*
s
)
{
return
static_cast
<
int
>
(
strlen
(
s
));
}
std
::
string
operator
()(
int
*
p
)
{
return
p
?
"good ptr"
:
"null"
;
}
};
};
TEST
(
ResultOfTest
,
WorksForPolymorphicFunctors
)
{
TEST
(
ResultOfTest
,
WorksForPolymorphicFunctors
)
{
...
@@ -4611,6 +4612,23 @@ TEST(ResultOfTest, WorksForPolymorphicFunctors) {
...
@@ -4611,6 +4612,23 @@ TEST(ResultOfTest, WorksForPolymorphicFunctors) {
EXPECT_FALSE
(
matcher_string
.
Matches
(
"shrt"
));
EXPECT_FALSE
(
matcher_string
.
Matches
(
"shrt"
));
}
}
#if GTEST_LANG_CXX11
TEST
(
ResultOfTest
,
WorksForPolymorphicFunctorsIgnoringResultType
)
{
Matcher
<
int
*>
matcher
=
ResultOf
(
PolymorphicFunctor
(),
"good ptr"
);
int
n
=
0
;
EXPECT_TRUE
(
matcher
.
Matches
(
&
n
));
EXPECT_FALSE
(
matcher
.
Matches
(
nullptr
));
}
TEST
(
ResultOfTest
,
WorksForLambdas
)
{
Matcher
<
int
>
matcher
=
ResultOf
([](
int
str_len
)
{
return
std
::
string
(
str_len
,
'x'
);
},
"xxx"
);
EXPECT_TRUE
(
matcher
.
Matches
(
3
));
EXPECT_FALSE
(
matcher
.
Matches
(
1
));
}
#endif
const
int
*
ReferencingFunction
(
const
int
&
n
)
{
return
&
n
;
}
const
int
*
ReferencingFunction
(
const
int
&
n
)
{
return
&
n
;
}
struct
ReferencingFunctor
{
struct
ReferencingFunctor
{
...
...
googletest/src/gtest.cc
View file @
ebb2fca5
...
@@ -194,6 +194,21 @@ const char kStackTraceMarker[] = "\nStack trace:\n";
...
@@ -194,6 +194,21 @@ const char kStackTraceMarker[] = "\nStack trace:\n";
// specified on the command line.
// specified on the command line.
bool
g_help_flag
=
false
;
bool
g_help_flag
=
false
;
// Utilty function to Open File for Writing
static
FILE
*
OpenFileForWriting
(
const
std
::
string
&
output_file
)
{
FILE
*
fileout
=
NULL
;
FilePath
output_file_path
(
output_file
);
FilePath
output_dir
(
output_file_path
.
RemoveFileName
());
if
(
output_dir
.
CreateDirectoriesRecursively
())
{
fileout
=
posix
::
FOpen
(
output_file
.
c_str
(),
"w"
);
}
if
(
fileout
==
NULL
)
{
GTEST_LOG_
(
FATAL
)
<<
"Unable to open file
\"
"
<<
output_file
<<
"
\"
"
;
}
return
fileout
;
}
}
// namespace internal
}
// namespace internal
// Bazel passes in the argument to '--test_filter' via the TESTBRIDGE_TEST_ONLY
// Bazel passes in the argument to '--test_filter' via the TESTBRIDGE_TEST_ONLY
...
@@ -454,6 +469,7 @@ std::string UnitTestOptions::GetOutputFormat() {
...
@@ -454,6 +469,7 @@ std::string UnitTestOptions::GetOutputFormat() {
// Returns the name of the requested output file, or the default if none
// Returns the name of the requested output file, or the default if none
// was explicitly specified.
// was explicitly specified.
// FIXME Remove GetAbsolutePathToOutputFile checking gtest_output_flag == NULL
std
::
string
UnitTestOptions
::
GetAbsolutePathToOutputFile
()
{
std
::
string
UnitTestOptions
::
GetAbsolutePathToOutputFile
()
{
const
char
*
const
gtest_output_flag
=
GTEST_FLAG
(
output
).
c_str
();
const
char
*
const
gtest_output_flag
=
GTEST_FLAG
(
output
).
c_str
();
if
(
gtest_output_flag
==
NULL
)
if
(
gtest_output_flag
==
NULL
)
...
@@ -2130,13 +2146,8 @@ static const char* const kReservedTestSuiteAttributes[] = {
...
@@ -2130,13 +2146,8 @@ static const char* const kReservedTestSuiteAttributes[] = {
// The list of reserved attributes used in the <testcase> element of XML output.
// The list of reserved attributes used in the <testcase> element of XML output.
static
const
char
*
const
kReservedTestCaseAttributes
[]
=
{
static
const
char
*
const
kReservedTestCaseAttributes
[]
=
{
"classname"
,
"classname"
,
"name"
,
"status"
,
"time"
,
"name"
,
"type_param"
,
"value_param"
,
"file"
,
"line"
};
"status"
,
"time"
,
"type_param"
,
"value_param"
};
template
<
int
kSize
>
template
<
int
kSize
>
std
::
vector
<
std
::
string
>
ArrayAsVector
(
const
char
*
const
(
&
array
)[
kSize
])
{
std
::
vector
<
std
::
string
>
ArrayAsVector
(
const
char
*
const
(
&
array
)[
kSize
])
{
...
@@ -3414,6 +3425,11 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener {
...
@@ -3414,6 +3425,11 @@ class XmlUnitTestResultPrinter : public EmptyTestEventListener {
explicit
XmlUnitTestResultPrinter
(
const
char
*
output_file
);
explicit
XmlUnitTestResultPrinter
(
const
char
*
output_file
);
virtual
void
OnTestIterationEnd
(
const
UnitTest
&
unit_test
,
int
iteration
);
virtual
void
OnTestIterationEnd
(
const
UnitTest
&
unit_test
,
int
iteration
);
void
ListTestsMatchingFilter
(
const
std
::
vector
<
TestCase
*>&
test_cases
);
// Prints an XML summary of all unit tests.
static
void
PrintXmlTestsList
(
std
::
ostream
*
stream
,
const
std
::
vector
<
TestCase
*>&
test_cases
);
private:
private:
// Is c a whitespace character that is normalized to a space character
// Is c a whitespace character that is normalized to a space character
...
@@ -3497,33 +3513,22 @@ XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
...
@@ -3497,33 +3513,22 @@ XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file)
// Called after the unit test ends.
// Called after the unit test ends.
void
XmlUnitTestResultPrinter
::
OnTestIterationEnd
(
const
UnitTest
&
unit_test
,
void
XmlUnitTestResultPrinter
::
OnTestIterationEnd
(
const
UnitTest
&
unit_test
,
int
/*iteration*/
)
{
int
/*iteration*/
)
{
FILE
*
xmlout
=
NULL
;
FILE
*
xmlout
=
OpenFileForWriting
(
output_file_
);
FilePath
output_file
(
output_file_
);
FilePath
output_dir
(
output_file
.
RemoveFileName
());
if
(
output_dir
.
CreateDirectoriesRecursively
())
{
xmlout
=
posix
::
FOpen
(
output_file_
.
c_str
(),
"w"
);
}
if
(
xmlout
==
NULL
)
{
// FIXME: report the reason of the failure.
//
// We don't do it for now as:
//
// 1. There is no urgent need for it.
// 2. It's a bit involved to make the errno variable thread-safe on
// all three operating systems (Linux, Windows, and Mac OS).
// 3. To interpret the meaning of errno in a thread-safe way,
// we need the strerror_r() function, which is not available on
// Windows.
GTEST_LOG_
(
FATAL
)
<<
"Unable to open file
\"
"
<<
output_file_
<<
"
\"
"
;
}
std
::
stringstream
stream
;
std
::
stringstream
stream
;
PrintXmlUnitTest
(
&
stream
,
unit_test
);
PrintXmlUnitTest
(
&
stream
,
unit_test
);
fprintf
(
xmlout
,
"%s"
,
StringStreamToString
(
&
stream
).
c_str
());
fprintf
(
xmlout
,
"%s"
,
StringStreamToString
(
&
stream
).
c_str
());
fclose
(
xmlout
);
fclose
(
xmlout
);
}
}
void
XmlUnitTestResultPrinter
::
ListTestsMatchingFilter
(
const
std
::
vector
<
TestCase
*>&
test_cases
)
{
FILE
*
xmlout
=
OpenFileForWriting
(
output_file_
);
std
::
stringstream
stream
;
PrintXmlTestsList
(
&
stream
,
test_cases
);
fprintf
(
xmlout
,
"%s"
,
StringStreamToString
(
&
stream
).
c_str
());
fclose
(
xmlout
);
}
// Returns an XML-escaped copy of the input string str. If is_attribute
// Returns an XML-escaped copy of the input string str. If is_attribute
// is true, the text is meant to appear as an attribute value, and
// is true, the text is meant to appear as an attribute value, and
// normalizable whitespace is preserved by replacing it with character
// normalizable whitespace is preserved by replacing it with character
...
@@ -3706,6 +3711,13 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
...
@@ -3706,6 +3711,13 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream,
if
(
test_info
.
type_param
()
!=
NULL
)
{
if
(
test_info
.
type_param
()
!=
NULL
)
{
OutputXmlAttribute
(
stream
,
kTestcase
,
"type_param"
,
test_info
.
type_param
());
OutputXmlAttribute
(
stream
,
kTestcase
,
"type_param"
,
test_info
.
type_param
());
}
}
if
(
GTEST_FLAG
(
list_tests
))
{
OutputXmlAttribute
(
stream
,
kTestcase
,
"file"
,
test_info
.
file
());
OutputXmlAttribute
(
stream
,
kTestcase
,
"line"
,
StreamableToString
(
test_info
.
line
()));
*
stream
<<
" />
\n
"
;
return
;
}
OutputXmlAttribute
(
stream
,
kTestcase
,
"status"
,
OutputXmlAttribute
(
stream
,
kTestcase
,
"status"
,
test_info
.
should_run
()
?
"run"
:
"notrun"
);
test_info
.
should_run
()
?
"run"
:
"notrun"
);
...
@@ -3752,17 +3764,18 @@ void XmlUnitTestResultPrinter::PrintXmlTestCase(std::ostream* stream,
...
@@ -3752,17 +3764,18 @@ void XmlUnitTestResultPrinter::PrintXmlTestCase(std::ostream* stream,
OutputXmlAttribute
(
stream
,
kTestsuite
,
"name"
,
test_case
.
name
());
OutputXmlAttribute
(
stream
,
kTestsuite
,
"name"
,
test_case
.
name
());
OutputXmlAttribute
(
stream
,
kTestsuite
,
"tests"
,
OutputXmlAttribute
(
stream
,
kTestsuite
,
"tests"
,
StreamableToString
(
test_case
.
reportable_test_count
()));
StreamableToString
(
test_case
.
reportable_test_count
()));
OutputXmlAttribute
(
stream
,
kTestsuite
,
"failures"
,
if
(
!
GTEST_FLAG
(
list_tests
))
{
StreamableToString
(
test_case
.
failed_test_count
()));
OutputXmlAttribute
(
stream
,
kTestsuite
,
"failures"
,
OutputXmlAttribute
(
StreamableToString
(
test_case
.
failed_test_count
()));
stream
,
kTestsuite
,
"disabled"
,
OutputXmlAttribute
(
StreamableToString
(
test_case
.
reportable_disabled_test_count
()));
stream
,
kTestsuite
,
"disabled"
,
OutputXmlAttribute
(
stream
,
kTestsuite
,
"errors"
,
"0"
);
StreamableToString
(
test_case
.
reportable_disabled_test_count
()));
OutputXmlAttribute
(
stream
,
kTestsuite
,
"time"
,
OutputXmlAttribute
(
stream
,
kTestsuite
,
"errors"
,
"0"
);
FormatTimeInMillisAsSeconds
(
test_case
.
elapsed_time
()));
OutputXmlAttribute
(
stream
,
kTestsuite
,
"time"
,
*
stream
<<
TestPropertiesAsXmlAttributes
(
test_case
.
ad_hoc_test_result
())
FormatTimeInMillisAsSeconds
(
test_case
.
elapsed_time
()));
<<
">
\n
"
;
*
stream
<<
TestPropertiesAsXmlAttributes
(
test_case
.
ad_hoc_test_result
());
}
*
stream
<<
">
\n
"
;
for
(
int
i
=
0
;
i
<
test_case
.
total_test_count
();
++
i
)
{
for
(
int
i
=
0
;
i
<
test_case
.
total_test_count
();
++
i
)
{
if
(
test_case
.
GetTestInfo
(
i
)
->
is_reportable
())
if
(
test_case
.
GetTestInfo
(
i
)
->
is_reportable
())
OutputXmlTestInfo
(
stream
,
test_case
.
name
(),
*
test_case
.
GetTestInfo
(
i
));
OutputXmlTestInfo
(
stream
,
test_case
.
name
(),
*
test_case
.
GetTestInfo
(
i
));
...
@@ -3808,6 +3821,28 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream,
...
@@ -3808,6 +3821,28 @@ void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream,
*
stream
<<
"</"
<<
kTestsuites
<<
">
\n
"
;
*
stream
<<
"</"
<<
kTestsuites
<<
">
\n
"
;
}
}
void
XmlUnitTestResultPrinter
::
PrintXmlTestsList
(
std
::
ostream
*
stream
,
const
std
::
vector
<
TestCase
*>&
test_cases
)
{
const
std
::
string
kTestsuites
=
"testsuites"
;
*
stream
<<
"<?xml version=
\"
1.0
\"
encoding=
\"
UTF-8
\"
?>
\n
"
;
*
stream
<<
"<"
<<
kTestsuites
;
int
total_tests
=
0
;
for
(
size_t
i
=
0
;
i
<
test_cases
.
size
();
++
i
)
{
total_tests
+=
test_cases
[
i
]
->
total_test_count
();
}
OutputXmlAttribute
(
stream
,
kTestsuites
,
"tests"
,
StreamableToString
(
total_tests
));
OutputXmlAttribute
(
stream
,
kTestsuites
,
"name"
,
"AllTests"
);
*
stream
<<
">
\n
"
;
for
(
size_t
i
=
0
;
i
<
test_cases
.
size
();
++
i
)
{
PrintXmlTestCase
(
stream
,
*
test_cases
[
i
]);
}
*
stream
<<
"</"
<<
kTestsuites
<<
">
\n
"
;
}
// Produces a string representing the test properties in a result as space
// Produces a string representing the test properties in a result as space
// delimited XML attributes based on the property key="value" pairs.
// delimited XML attributes based on the property key="value" pairs.
std
::
string
XmlUnitTestResultPrinter
::
TestPropertiesAsXmlAttributes
(
std
::
string
XmlUnitTestResultPrinter
::
TestPropertiesAsXmlAttributes
(
...
@@ -3843,7 +3878,6 @@ void XmlUnitTestResultPrinter::OutputXmlTestProperties(
...
@@ -3843,7 +3878,6 @@ void XmlUnitTestResultPrinter::OutputXmlTestProperties(
// End XmlUnitTestResultPrinter
// End XmlUnitTestResultPrinter
// This class generates an JSON output file.
// This class generates an JSON output file.
class
JsonUnitTestResultPrinter
:
public
EmptyTestEventListener
{
class
JsonUnitTestResultPrinter
:
public
EmptyTestEventListener
{
public:
public:
...
@@ -3851,6 +3885,10 @@ class JsonUnitTestResultPrinter : public EmptyTestEventListener {
...
@@ -3851,6 +3885,10 @@ class JsonUnitTestResultPrinter : public EmptyTestEventListener {
virtual
void
OnTestIterationEnd
(
const
UnitTest
&
unit_test
,
int
iteration
);
virtual
void
OnTestIterationEnd
(
const
UnitTest
&
unit_test
,
int
iteration
);
// Prints an JSON summary of all unit tests.
static
void
PrintJsonTestList
(
::
std
::
ostream
*
stream
,
const
std
::
vector
<
TestCase
*>&
test_cases
);
private:
private:
// Returns an JSON-escaped copy of the input string str.
// Returns an JSON-escaped copy of the input string str.
static
std
::
string
EscapeJson
(
const
std
::
string
&
str
);
static
std
::
string
EscapeJson
(
const
std
::
string
&
str
);
...
@@ -3904,27 +3942,7 @@ JsonUnitTestResultPrinter::JsonUnitTestResultPrinter(const char* output_file)
...
@@ -3904,27 +3942,7 @@ JsonUnitTestResultPrinter::JsonUnitTestResultPrinter(const char* output_file)
void
JsonUnitTestResultPrinter
::
OnTestIterationEnd
(
const
UnitTest
&
unit_test
,
void
JsonUnitTestResultPrinter
::
OnTestIterationEnd
(
const
UnitTest
&
unit_test
,
int
/*iteration*/
)
{
int
/*iteration*/
)
{
FILE
*
jsonout
=
NULL
;
FILE
*
jsonout
=
OpenFileForWriting
(
output_file_
);
FilePath
output_file
(
output_file_
);
FilePath
output_dir
(
output_file
.
RemoveFileName
());
if
(
output_dir
.
CreateDirectoriesRecursively
())
{
jsonout
=
posix
::
FOpen
(
output_file_
.
c_str
(),
"w"
);
}
if
(
jsonout
==
NULL
)
{
// FIXME: report the reason of the failure.
//
// We don't do it for now as:
//
// 1. There is no urgent need for it.
// 2. It's a bit involved to make the errno variable thread-safe on
// all three operating systems (Linux, Windows, and Mac OS).
// 3. To interpret the meaning of errno in a thread-safe way,
// we need the strerror_r() function, which is not available on
// Windows.
GTEST_LOG_
(
FATAL
)
<<
"Unable to open file
\"
"
<<
output_file_
<<
"
\"
"
;
}
std
::
stringstream
stream
;
std
::
stringstream
stream
;
PrintJsonUnitTest
(
&
stream
,
unit_test
);
PrintJsonUnitTest
(
&
stream
,
unit_test
);
fprintf
(
jsonout
,
"%s"
,
StringStreamToString
(
&
stream
).
c_str
());
fprintf
(
jsonout
,
"%s"
,
StringStreamToString
(
&
stream
).
c_str
());
...
@@ -4059,6 +4077,12 @@ void JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream,
...
@@ -4059,6 +4077,12 @@ void JsonUnitTestResultPrinter::OutputJsonTestInfo(::std::ostream* stream,
OutputJsonKey
(
stream
,
kTestcase
,
"type_param"
,
test_info
.
type_param
(),
OutputJsonKey
(
stream
,
kTestcase
,
"type_param"
,
test_info
.
type_param
(),
kIndent
);
kIndent
);
}
}
if
(
GTEST_FLAG
(
list_tests
))
{
OutputJsonKey
(
stream
,
kTestcase
,
"file"
,
test_info
.
file
(),
kIndent
);
OutputJsonKey
(
stream
,
kTestcase
,
"line"
,
test_info
.
line
(),
kIndent
,
false
);
*
stream
<<
"
\n
"
<<
Indent
(
8
)
<<
"}"
;
return
;
}
OutputJsonKey
(
stream
,
kTestcase
,
"status"
,
OutputJsonKey
(
stream
,
kTestcase
,
"status"
,
test_info
.
should_run
()
?
"RUN"
:
"NOTRUN"
,
kIndent
);
test_info
.
should_run
()
?
"RUN"
:
"NOTRUN"
,
kIndent
);
...
@@ -4101,16 +4125,18 @@ void JsonUnitTestResultPrinter::PrintJsonTestCase(std::ostream* stream,
...
@@ -4101,16 +4125,18 @@ void JsonUnitTestResultPrinter::PrintJsonTestCase(std::ostream* stream,
OutputJsonKey
(
stream
,
kTestsuite
,
"name"
,
test_case
.
name
(),
kIndent
);
OutputJsonKey
(
stream
,
kTestsuite
,
"name"
,
test_case
.
name
(),
kIndent
);
OutputJsonKey
(
stream
,
kTestsuite
,
"tests"
,
test_case
.
reportable_test_count
(),
OutputJsonKey
(
stream
,
kTestsuite
,
"tests"
,
test_case
.
reportable_test_count
(),
kIndent
);
kIndent
);
OutputJsonKey
(
stream
,
kTestsuite
,
"failures"
,
test_case
.
failed_test_count
(),
if
(
!
GTEST_FLAG
(
list_tests
))
{
kIndent
);
OutputJsonKey
(
stream
,
kTestsuite
,
"failures"
,
test_case
.
failed_test_count
(),
OutputJsonKey
(
stream
,
kTestsuite
,
"disabled"
,
kIndent
);
test_case
.
reportable_disabled_test_count
(),
kIndent
);
OutputJsonKey
(
stream
,
kTestsuite
,
"disabled"
,
OutputJsonKey
(
stream
,
kTestsuite
,
"errors"
,
0
,
kIndent
);
test_case
.
reportable_disabled_test_count
(),
kIndent
);
OutputJsonKey
(
stream
,
kTestsuite
,
"time"
,
OutputJsonKey
(
stream
,
kTestsuite
,
"errors"
,
0
,
kIndent
);
FormatTimeInMillisAsDuration
(
test_case
.
elapsed_time
()),
kIndent
,
OutputJsonKey
(
stream
,
kTestsuite
,
"time"
,
false
);
FormatTimeInMillisAsDuration
(
test_case
.
elapsed_time
()),
*
stream
<<
TestPropertiesAsJson
(
test_case
.
ad_hoc_test_result
(),
kIndent
)
kIndent
,
false
);
<<
",
\n
"
;
*
stream
<<
TestPropertiesAsJson
(
test_case
.
ad_hoc_test_result
(),
kIndent
)
<<
",
\n
"
;
}
*
stream
<<
kIndent
<<
"
\"
"
<<
kTestsuite
<<
"
\"
: [
\n
"
;
*
stream
<<
kIndent
<<
"
\"
"
<<
kTestsuite
<<
"
\"
: [
\n
"
;
...
@@ -4174,6 +4200,31 @@ void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream,
...
@@ -4174,6 +4200,31 @@ void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream,
*
stream
<<
"
\n
"
<<
kIndent
<<
"]
\n
"
<<
"}
\n
"
;
*
stream
<<
"
\n
"
<<
kIndent
<<
"]
\n
"
<<
"}
\n
"
;
}
}
void
JsonUnitTestResultPrinter
::
PrintJsonTestList
(
std
::
ostream
*
stream
,
const
std
::
vector
<
TestCase
*>&
test_cases
)
{
const
std
::
string
kTestsuites
=
"testsuites"
;
const
std
::
string
kIndent
=
Indent
(
2
);
*
stream
<<
"{
\n
"
;
int
total_tests
=
0
;
for
(
size_t
i
=
0
;
i
<
test_cases
.
size
();
++
i
)
{
total_tests
+=
test_cases
[
i
]
->
total_test_count
();
}
OutputJsonKey
(
stream
,
kTestsuites
,
"tests"
,
total_tests
,
kIndent
);
OutputJsonKey
(
stream
,
kTestsuites
,
"name"
,
"AllTests"
,
kIndent
);
*
stream
<<
kIndent
<<
"
\"
"
<<
kTestsuites
<<
"
\"
: [
\n
"
;
for
(
size_t
i
=
0
;
i
<
test_cases
.
size
();
++
i
)
{
if
(
i
!=
0
)
{
*
stream
<<
",
\n
"
;
}
PrintJsonTestCase
(
stream
,
*
test_cases
[
i
]);
}
*
stream
<<
"
\n
"
<<
kIndent
<<
"]
\n
"
<<
"}
\n
"
;
}
// Produces a string representing the test properties in a result as
// Produces a string representing the test properties in a result as
// a JSON dictionary.
// a JSON dictionary.
std
::
string
JsonUnitTestResultPrinter
::
TestPropertiesAsJson
(
std
::
string
JsonUnitTestResultPrinter
::
TestPropertiesAsJson
(
...
@@ -5394,6 +5445,23 @@ void UnitTestImpl::ListTestsMatchingFilter() {
...
@@ -5394,6 +5445,23 @@ void UnitTestImpl::ListTestsMatchingFilter() {
}
}
}
}
fflush
(
stdout
);
fflush
(
stdout
);
const
std
::
string
&
output_format
=
UnitTestOptions
::
GetOutputFormat
();
if
(
output_format
==
"xml"
||
output_format
==
"json"
)
{
FILE
*
fileout
=
OpenFileForWriting
(
UnitTestOptions
::
GetAbsolutePathToOutputFile
().
c_str
());
std
::
stringstream
stream
;
if
(
output_format
==
"xml"
)
{
XmlUnitTestResultPrinter
(
UnitTestOptions
::
GetAbsolutePathToOutputFile
().
c_str
())
.
PrintXmlTestsList
(
&
stream
,
test_cases_
);
}
else
if
(
output_format
==
"json"
)
{
JsonUnitTestResultPrinter
(
UnitTestOptions
::
GetAbsolutePathToOutputFile
().
c_str
())
.
PrintJsonTestList
(
&
stream
,
test_cases_
);
}
fprintf
(
fileout
,
"%s"
,
StringStreamToString
(
&
stream
).
c_str
());
fclose
(
fileout
);
}
}
}
// Sets the OS stack trace getter.
// Sets the OS stack trace getter.
...
...
googletest/test/gtest_list_output_unittest.py
0 → 100644
View file @
ebb2fca5
#!/usr/bin/env python
#
# Copyright 2006, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Unit test for Google Test's --gtest_list_tests flag.
A user can ask Google Test to list all tests by specifying the
--gtest_list_tests flag. If output is requested, via --gtest_output=xml
or --gtest_output=json, the tests are listed, with extra information in the
output file.
This script tests such functionality by invoking gtest_list_output_unittest_
(a program written with Google Test) the command line flags.
"""
import
os
import
re
import
gtest_test_utils
GTEST_LIST_TESTS_FLAG
=
'--gtest_list_tests'
GTEST_OUTPUT_FLAG
=
'--gtest_output'
EXPECTED_XML
=
"""<\?xml version="1.0" encoding="UTF-8"\?>
<testsuites tests="2" name="AllTests">
<testsuite name="FooTest" tests="2">
<testcase name="Test1" file=".*gtest_list_output_unittest_.cc" line="43" />
<testcase name="Test2" file=".*gtest_list_output_unittest_.cc" line="45" />
</testsuite>
</testsuites>
"""
EXPECTED_JSON
=
"""{
"tests": 2,
"name": "AllTests",
"testsuites": \[
{
"name": "FooTest",
"tests": 2,
"testsuite": \[
{
"name": "Test1",
"file": ".*gtest_list_output_unittest_.cc",
"line": 43
},
{
"name": "Test2",
"file": ".*gtest_list_output_unittest_.cc",
"line": 45
}
\]
}
\]
}
"""
class
GTestListTestsOutputUnitTest
(
gtest_test_utils
.
TestCase
):
"""Unit test for Google Test's list tests with output to file functionality.
"""
def
testXml
(
self
):
"""Verifies XML output for listing tests in a Google Test binary.
Runs a test program that generates an empty XML output, and
tests that the XML output is expected.
"""
self
.
_TestOutput
(
'xml'
,
EXPECTED_XML
)
def
testJSON
(
self
):
"""Verifies XML output for listing tests in a Google Test binary.
Runs a test program that generates an empty XML output, and
tests that the XML output is expected.
"""
self
.
_TestOutput
(
'json'
,
EXPECTED_JSON
)
def
_GetOutput
(
self
,
out_format
):
file_path
=
os
.
path
.
join
(
gtest_test_utils
.
GetTempDir
(),
'test_out.'
+
out_format
)
gtest_prog_path
=
gtest_test_utils
.
GetTestExecutablePath
(
'gtest_list_output_unittest_'
)
command
=
([
gtest_prog_path
,
'%s=%s:%s'
%
(
GTEST_OUTPUT_FLAG
,
out_format
,
file_path
),
'--gtest_list_tests'
])
environ_copy
=
os
.
environ
.
copy
()
p
=
gtest_test_utils
.
Subprocess
(
command
,
env
=
environ_copy
,
working_dir
=
gtest_test_utils
.
GetTempDir
())
self
.
assert_
(
p
.
exited
)
self
.
assertEquals
(
0
,
p
.
exit_code
)
with
open
(
file_path
)
as
f
:
result
=
f
.
read
()
return
result
def
_TestOutput
(
self
,
test_format
,
expected_output
):
actual
=
self
.
_GetOutput
(
test_format
)
actual_lines
=
actual
.
splitlines
()
expected_lines
=
expected_output
.
splitlines
()
line_count
=
0
for
actual_line
in
actual_lines
:
expected_line
=
expected_lines
[
line_count
]
expected_line_re
=
re
.
compile
(
expected_line
.
strip
())
self
.
assert_
(
expected_line_re
.
match
(
actual_line
.
strip
()),
(
'actual output of "%s",
\n
'
'which does not match expected regex of "%s"
\n
'
'on line %d'
%
(
actual
,
expected_output
,
line_count
)))
line_count
=
line_count
+
1
if
__name__
==
'__main__'
:
os
.
environ
[
'GTEST_STACK_TRACE_DEPTH'
]
=
'1'
gtest_test_utils
.
Main
()
googletest/test/gtest_list_output_unittest_.cc
0 → 100644
View file @
ebb2fca5
// Copyright 2018, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Author: david.schuldenfrei@gmail.com (David Schuldenfrei)
// Unit test for Google Test's --gtest_list_tests and --gtest_output flag.
//
// A user can ask Google Test to list all tests that will run,
// and have the output saved in a Json/Xml file.
// The tests will not be run after listing.
//
// This program will be invoked from a Python unit test.
// Don't run it directly.
#include "gtest/gtest.h"
TEST
(
FooTest
,
Test1
)
{}
TEST
(
FooTest
,
Test2
)
{}
int
main
(
int
argc
,
char
**
argv
)
{
::
testing
::
InitGoogleTest
(
&
argc
,
argv
);
return
RUN_ALL_TESTS
();
}
googletest/test/gtest_unittest.cc
View file @
ebb2fca5
...
@@ -2090,8 +2090,8 @@ TEST_F(UnitTestRecordPropertyTest,
...
@@ -2090,8 +2090,8 @@ TEST_F(UnitTestRecordPropertyTest,
AddRecordWithReservedKeysGeneratesCorrectPropertyList
)
{
AddRecordWithReservedKeysGeneratesCorrectPropertyList
)
{
EXPECT_NONFATAL_FAILURE
(
EXPECT_NONFATAL_FAILURE
(
Test
::
RecordProperty
(
"name"
,
"1"
),
Test
::
RecordProperty
(
"name"
,
"1"
),
"'classname', 'name', 'status', 'time', 'type_param',
and
'value_param'"
"'classname', 'name', 'status', 'time', 'type_param', 'value_param'
,
"
" are reserved"
);
"
'file', and 'line'
are reserved"
);
}
}
class
UnitTestRecordPropertyTestEnvironment
:
public
Environment
{
class
UnitTestRecordPropertyTestEnvironment
:
public
Environment
{
...
...
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