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
af287b4f
Commit
af287b4f
authored
Jul 15, 2020
by
vslashg
Browse files
Merge pull request #2903 from AmatanHead:informative-exception-asserts
PiperOrigin-RevId: 320425648
parents
70b90929
0d2830b2
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
283 additions
and
41 deletions
+283
-41
googlemock/test/gmock-generated-matchers_nc.cc
googlemock/test/gmock-generated-matchers_nc.cc
+72
-0
googlemock/test/gmock_generated_matchers_nc_test.py
googlemock/test/gmock_generated_matchers_nc_test.py
+88
-0
googletest/include/gtest/internal/gtest-internal.h
googletest/include/gtest/internal/gtest-internal.h
+81
-32
googletest/test/gtest_unittest.cc
googletest/test/gtest_unittest.cc
+42
-9
No files found.
googlemock/test/gmock-generated-matchers_nc.cc
0 → 100644
View file @
af287b4f
// Copyright 2009, 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.
// Google Mock - a framework for writing C++ mock classes.
//
// This file contains negative compilation tests for script-generated
// Google Mock matchers.
#include "gmock/gmock.h"
#if defined(TEST_WRONG_ARG_TYPE_IN_MATCHER_MACRO)
// Tests using an MATCHER definition to match a value of an
// incompatible type.
MATCHER
(
WrongArgType
,
""
)
{
return
10
/
arg
>
2
;
}
void
Test
()
{
testing
::
Matcher
<
const
char
*>
m
=
WrongArgType
();
}
#elif defined(TEST_MATCHER_MACRO_IN_CLASS)
// Tests using MATCHER in a class scope.
class
Foo
{
public:
// This won't compile as C++ doesn't allow defining a method of a
// nested class out-of-line in the enclosing class.
MATCHER
(
Bar
,
""
)
{
return
arg
>
0
;
}
};
#elif defined(TEST_MATCHER_MACRO_IN_FUNCTION)
// Tests using MATCHER in a function body.
void
Test
()
{
// This won't compile as C++ doesn't allow member templates in local
// classes. We may want to revisit this when C++0x is widely
// implemented.
MATCHER
(
Bar
,
""
)
{
return
arg
>
0
;
}
}
#else
// Sanity check - this should compile.
#endif
googlemock/test/gmock_generated_matchers_nc_test.py
0 → 100755
View file @
af287b4f
#!/usr/bin/env python
#
# Copyright 2009, 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.
# Google Mock - a framework for writing C++ mock classes.
#
# This file drives the negative compilation tests for script-generated
# Google Mock matchers.
"""Driver for the NC tests for script-generated Google Mock matchers."""
import
os
import
sys
IS_LINUX
=
os
.
name
==
"posix"
and
os
.
uname
()[
0
]
==
"Linux"
if
not
IS_LINUX
:
sys
.
stderr
.
write
(
"WARNING: Negative compilation tests are not supported on this platform"
)
sys
.
exit
(
0
)
# Suppresses the 'Import not at the top of the file' lint complaint.
# pylint: disable-msg=C6204
from
google3.testing.pybase
import
fake_target_util
from
google3.testing.pybase
import
googletest
# pylint: enable-msg=C6204
class
GMockGeneratedMatcherTest
(
googletest
.
TestCase
):
"""Negative compilation tests for generated Google Mock matchers."""
def
testCompilerErrors
(
self
):
"""Verifies that erroneous code leads to expected compiler messages."""
# Defines a list of test specs, where each element is a tuple
# (test name, list of regexes for matching the compiler errors).
test_specs
=
[
(
"WRONG_ARG_TYPE_IN_MATCHER_MACRO"
,
[
r
"invalid operands"
,
]),
(
"MATCHER_MACRO_IN_CLASS"
,
[
r
"cannot define member function.*Bar.*within.*Foo"
,
# GCC
r
"MATCHER\(Bar, .*\)"
,
# Clang
]),
(
"MATCHER_MACRO_IN_FUNCTION"
,
[
r
"invalid declaration of member template in local class"
,
# GCC
r
"templates cannot be declared inside of a local class"
,
# Clang
]),
(
"SANITY"
,
None
),
]
fake_target_util
.
AssertCcCompilerErrors
(
self
,
# The current test case.
"google3/third_party/googletest/googlemock/test/"
"gmock-generated-matchers_nc"
,
# The fake target file.
"gmock-generated-matchers_nc.o"
,
# The sub-target to build.
test_specs
# List of test specs.
)
if
__name__
==
"__main__"
:
googletest
.
main
()
googletest/include/gtest/internal/gtest-internal.h
View file @
af287b4f
...
@@ -1291,41 +1291,90 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
...
@@ -1291,41 +1291,90 @@ constexpr bool InstantiateTypedTestCase_P_IsDeprecated() { return true; }
} else
/* NOLINT */
\
} else
/* NOLINT */
\
static_assert(true, "") // User must have a semicolon after expansion.
static_assert(true, "") // User must have a semicolon after expansion.
#define GTEST_TEST_THROW_(statement, expected_exception, fail) \
#if GTEST_HAS_EXCEPTIONS
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::ConstCharPtr gtest_msg = "") { \
namespace
testing
{
bool gtest_caught_expected = false; \
namespace
internal
{
try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
class
NeverThrown
{
} \
public:
catch (expected_exception const&) { \
const
char
*
what
()
const
noexcept
{
gtest_caught_expected = true; \
return
"this exception should never be thrown"
;
} \
}
catch (...) { \
};
gtest_msg.value = \
"Expected: " #statement " throws an exception of type " \
}
// namespace internal
#expected_exception ".\n Actual: it throws a different type."; \
}
// namespace testing
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
} \
#if GTEST_HAS_RTTI
if (!gtest_caught_expected) { \
gtest_msg.value = \
#define GTEST_EXCEPTION_TYPE_(e) ::testing::internal::GetTypeName(typeid(e))
"Expected: " #statement " throws an exception of type " \
#expected_exception ".\n Actual: it throws nothing."; \
#else // GTEST_HAS_RTTI
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
} \
#define GTEST_EXCEPTION_TYPE_(e) \
} else \
std::string { "an std::exception-derived error" }
GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \
fail(gtest_msg.value)
#endif // GTEST_HAS_RTTI
#define GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception) \
catch (typename std::conditional< \
std::is_same<typename std::remove_cv<typename std::remove_reference< \
expected_exception>::type>::type, \
std::exception>::value, \
const ::testing::internal::NeverThrown&, const std::exception&>::type \
e) { \
gtest_msg.value = "Expected: " #statement \
" throws an exception of type " #expected_exception \
".\n Actual: it throws "; \
gtest_msg.value += GTEST_EXCEPTION_TYPE_(e); \
gtest_msg.value += " with description \""; \
gtest_msg.value += e.what(); \
gtest_msg.value += "\"."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
}
#else // GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception)
#endif // GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_THROW_(statement, expected_exception, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::TrueWithString gtest_msg{}) { \
bool gtest_caught_expected = false; \
try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} catch (expected_exception const&) { \
gtest_caught_expected = true; \
} \
GTEST_TEST_THROW_CATCH_STD_EXCEPTION_(statement, expected_exception) \
catch (...) { \
gtest_msg.value = "Expected: " #statement \
" throws an exception of type " #expected_exception \
".\n Actual: it throws a different type."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
} \
if (!gtest_caught_expected) { \
gtest_msg.value = "Expected: " #statement \
" throws an exception of type " #expected_exception \
".\n Actual: it throws nothing."; \
goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \
} \
} else
/*NOLINT*/
\
GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__) \
: fail(gtest_msg.value.c_str())
#if GTEST_HAS_EXCEPTIONS
#if GTEST_HAS_EXCEPTIONS
#define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_() \
#define GTEST_TEST_NO_THROW_CATCH_STD_EXCEPTION_()
\
catch (std::exception const& e) { \
catch (std::exception const& e) {
\
gtest_msg.value =
(
\
gtest_msg.value =
"it throws ";
\
"it throws std::exception-derived exception with description: \""
\
gtest_msg.value += GTEST_EXCEPTION_TYPE_(e);
\
);
\
gtest_msg.value += " with description \"";
\
gtest_msg.value += e.what(); \
gtest_msg.value += e.what();
\
gtest_msg.value += "\"."; \
gtest_msg.value += "\".";
\
goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \
goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \
}
}
...
...
googletest/test/gtest_unittest.cc
View file @
af287b4f
...
@@ -3345,6 +3345,16 @@ TEST_F(SingleEvaluationTest, OtherCases) {
...
@@ -3345,6 +3345,16 @@ TEST_F(SingleEvaluationTest, OtherCases) {
#if GTEST_HAS_EXCEPTIONS
#if GTEST_HAS_EXCEPTIONS
#if GTEST_HAS_RTTI
#define ERROR_DESC "std::runtime_error"
#else // GTEST_HAS_RTTI
#define ERROR_DESC "an std::exception-derived error"
#endif // GTEST_HAS_RTTI
void
ThrowAnInteger
()
{
void
ThrowAnInteger
()
{
throw
1
;
throw
1
;
}
}
...
@@ -3368,31 +3378,38 @@ TEST_F(SingleEvaluationTest, ExceptionTests) {
...
@@ -3368,31 +3378,38 @@ TEST_F(SingleEvaluationTest, ExceptionTests) {
},
bool
),
"throws a different type"
);
},
bool
),
"throws a different type"
);
EXPECT_EQ
(
2
,
a_
);
EXPECT_EQ
(
2
,
a_
);
// failed EXPECT_THROW, throws runtime error
EXPECT_NONFATAL_FAILURE
(
EXPECT_THROW
({
// NOLINT
a_
++
;
ThrowRuntimeError
(
"A description"
);
},
bool
),
"throws "
ERROR_DESC
" with description
\"
A description
\"
"
);
EXPECT_EQ
(
3
,
a_
);
// failed EXPECT_THROW, throws nothing
// failed EXPECT_THROW, throws nothing
EXPECT_NONFATAL_FAILURE
(
EXPECT_THROW
(
a_
++
,
bool
),
"throws nothing"
);
EXPECT_NONFATAL_FAILURE
(
EXPECT_THROW
(
a_
++
,
bool
),
"throws nothing"
);
EXPECT_EQ
(
3
,
a_
);
EXPECT_EQ
(
4
,
a_
);
// successful EXPECT_NO_THROW
// successful EXPECT_NO_THROW
EXPECT_NO_THROW
(
a_
++
);
EXPECT_NO_THROW
(
a_
++
);
EXPECT_EQ
(
4
,
a_
);
EXPECT_EQ
(
5
,
a_
);
// failed EXPECT_NO_THROW
// failed EXPECT_NO_THROW
EXPECT_NONFATAL_FAILURE
(
EXPECT_NO_THROW
({
// NOLINT
EXPECT_NONFATAL_FAILURE
(
EXPECT_NO_THROW
({
// NOLINT
a_
++
;
a_
++
;
ThrowAnInteger
();
ThrowAnInteger
();
}),
"it throws"
);
}),
"it throws"
);
EXPECT_EQ
(
5
,
a_
);
EXPECT_EQ
(
6
,
a_
);
// successful EXPECT_ANY_THROW
// successful EXPECT_ANY_THROW
EXPECT_ANY_THROW
({
// NOLINT
EXPECT_ANY_THROW
({
// NOLINT
a_
++
;
a_
++
;
ThrowAnInteger
();
ThrowAnInteger
();
});
});
EXPECT_EQ
(
6
,
a_
);
EXPECT_EQ
(
7
,
a_
);
// failed EXPECT_ANY_THROW
// failed EXPECT_ANY_THROW
EXPECT_NONFATAL_FAILURE
(
EXPECT_ANY_THROW
(
a_
++
),
"it doesn't"
);
EXPECT_NONFATAL_FAILURE
(
EXPECT_ANY_THROW
(
a_
++
),
"it doesn't"
);
EXPECT_EQ
(
7
,
a_
);
EXPECT_EQ
(
8
,
a_
);
}
}
#endif // GTEST_HAS_EXCEPTIONS
#endif // GTEST_HAS_EXCEPTIONS
...
@@ -3812,6 +3829,12 @@ TEST(AssertionTest, ASSERT_THROW) {
...
@@ -3812,6 +3829,12 @@ TEST(AssertionTest, ASSERT_THROW) {
ASSERT_THROW
(
ThrowAnInteger
(),
bool
),
ASSERT_THROW
(
ThrowAnInteger
(),
bool
),
"Expected: ThrowAnInteger() throws an exception of type bool.
\n
"
"Expected: ThrowAnInteger() throws an exception of type bool.
\n
"
" Actual: it throws a different type."
);
" Actual: it throws a different type."
);
EXPECT_FATAL_FAILURE
(
ASSERT_THROW
(
ThrowRuntimeError
(
"A description"
),
std
::
logic_error
),
"Expected: ThrowRuntimeError(
\"
A description
\"
) "
"throws an exception of type std::logic_error.
\n
"
"Actual: it throws "
ERROR_DESC
" "
"with description
\"
A description
\"
."
);
# endif
# endif
EXPECT_FATAL_FAILURE
(
EXPECT_FATAL_FAILURE
(
...
@@ -3829,8 +3852,8 @@ TEST(AssertionTest, ASSERT_NO_THROW) {
...
@@ -3829,8 +3852,8 @@ TEST(AssertionTest, ASSERT_NO_THROW) {
EXPECT_FATAL_FAILURE
(
ASSERT_NO_THROW
(
ThrowRuntimeError
(
"A description"
)),
EXPECT_FATAL_FAILURE
(
ASSERT_NO_THROW
(
ThrowRuntimeError
(
"A description"
)),
"Expected: ThrowRuntimeError(
\"
A description
\"
) "
"Expected: ThrowRuntimeError(
\"
A description
\"
) "
"doesn't throw an exception.
\n
"
"doesn't throw an exception.
\n
"
"Actual: it throws
std::exception-derived exception
"
"Actual: it throws
"
ERROR_DESC
"
"
"with description
:
\"
A description
\"
."
);
"with description
\"
A description
\"
."
);
}
}
// Tests ASSERT_ANY_THROW.
// Tests ASSERT_ANY_THROW.
...
@@ -4140,6 +4163,10 @@ TEST(ExpectThrowTest, DoesNotGenerateUnreachableCodeWarning) {
...
@@ -4140,6 +4163,10 @@ TEST(ExpectThrowTest, DoesNotGenerateUnreachableCodeWarning) {
EXPECT_NONFATAL_FAILURE
(
EXPECT_ANY_THROW
(
n
++
),
""
);
EXPECT_NONFATAL_FAILURE
(
EXPECT_ANY_THROW
(
n
++
),
""
);
}
}
TEST
(
ExpectThrowTest
,
DoesNotGenerateDuplicateCatchClauseWarning
)
{
EXPECT_THROW
(
throw
std
::
exception
(),
std
::
exception
);
}
TEST
(
AssertionSyntaxTest
,
ExceptionAssertionsBehavesLikeSingleStatement
)
{
TEST
(
AssertionSyntaxTest
,
ExceptionAssertionsBehavesLikeSingleStatement
)
{
if
(
AlwaysFalse
())
if
(
AlwaysFalse
())
EXPECT_THROW
(
ThrowNothing
(),
bool
);
EXPECT_THROW
(
ThrowNothing
(),
bool
);
...
@@ -4550,6 +4577,12 @@ TEST(ExpectTest, EXPECT_THROW) {
...
@@ -4550,6 +4577,12 @@ TEST(ExpectTest, EXPECT_THROW) {
EXPECT_NONFATAL_FAILURE
(
EXPECT_THROW
(
ThrowAnInteger
(),
bool
),
EXPECT_NONFATAL_FAILURE
(
EXPECT_THROW
(
ThrowAnInteger
(),
bool
),
"Expected: ThrowAnInteger() throws an exception of "
"Expected: ThrowAnInteger() throws an exception of "
"type bool.
\n
Actual: it throws a different type."
);
"type bool.
\n
Actual: it throws a different type."
);
EXPECT_NONFATAL_FAILURE
(
EXPECT_THROW
(
ThrowRuntimeError
(
"A description"
),
std
::
logic_error
),
"Expected: ThrowRuntimeError(
\"
A description
\"
) "
"throws an exception of type std::logic_error.
\n
"
"Actual: it throws "
ERROR_DESC
" "
"with description
\"
A description
\"
."
);
EXPECT_NONFATAL_FAILURE
(
EXPECT_NONFATAL_FAILURE
(
EXPECT_THROW
(
ThrowNothing
(),
bool
),
EXPECT_THROW
(
ThrowNothing
(),
bool
),
"Expected: ThrowNothing() throws an exception of type bool.
\n
"
"Expected: ThrowNothing() throws an exception of type bool.
\n
"
...
@@ -4565,8 +4598,8 @@ TEST(ExpectTest, EXPECT_NO_THROW) {
...
@@ -4565,8 +4598,8 @@ TEST(ExpectTest, EXPECT_NO_THROW) {
EXPECT_NONFATAL_FAILURE
(
EXPECT_NO_THROW
(
ThrowRuntimeError
(
"A description"
)),
EXPECT_NONFATAL_FAILURE
(
EXPECT_NO_THROW
(
ThrowRuntimeError
(
"A description"
)),
"Expected: ThrowRuntimeError(
\"
A description
\"
) "
"Expected: ThrowRuntimeError(
\"
A description
\"
) "
"doesn't throw an exception.
\n
"
"doesn't throw an exception.
\n
"
"Actual: it throws
std::exception-derived exception
"
"Actual: it throws
"
ERROR_DESC
"
"
"with description
:
\"
A description
\"
."
);
"with description
\"
A description
\"
."
);
}
}
// Tests EXPECT_ANY_THROW.
// Tests EXPECT_ANY_THROW.
...
...
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