Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Oneflow-Inc
googletest
提交
aa4cbcdc
G
googletest
项目概览
Oneflow-Inc
/
googletest
9 个月 前同步成功
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
googletest
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
aa4cbcdc
编写于
8月 23, 2020
作者:
V
vslashg
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #2904 from AmatanHead:throw-matchers
PiperOrigin-RevId: 327294137
上级
fc1e7788
7f1c8bb4
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
353 addition
and
0 deletion
+353
-0
googlemock/include/gmock/gmock-matchers.h
googlemock/include/gmock/gmock-matchers.h
+169
-0
googlemock/test/gmock-matchers_test.cc
googlemock/test/gmock-matchers_test.cc
+184
-0
未找到文件。
googlemock/include/gmock/gmock-matchers.h
浏览文件 @
aa4cbcdc
...
...
@@ -4725,6 +4725,175 @@ PolymorphicMatcher<internal::variant_matcher::VariantMatcher<T> > VariantWith(
internal
::
variant_matcher
::
VariantMatcher
<
T
>
(
matcher
));
}
#if GTEST_HAS_EXCEPTIONS
// Anything inside the `internal` namespace is internal to the implementation
// and must not be used in user code!
namespace
internal
{
class
WithWhatMatcherImpl
{
public:
WithWhatMatcherImpl
(
Matcher
<
std
::
string
>
matcher
)
:
matcher_
(
std
::
move
(
matcher
))
{}
void
DescribeTo
(
std
::
ostream
*
os
)
const
{
*
os
<<
"contains .what() that "
;
matcher_
.
DescribeTo
(
os
);
}
void
DescribeNegationTo
(
std
::
ostream
*
os
)
const
{
*
os
<<
"contains .what() that does not "
;
matcher_
.
DescribeTo
(
os
);
}
template
<
typename
Err
>
bool
MatchAndExplain
(
const
Err
&
err
,
MatchResultListener
*
listener
)
const
{
*
listener
<<
"which contains .what() that "
;
return
matcher_
.
MatchAndExplain
(
err
.
what
(),
listener
);
}
private:
const
Matcher
<
std
::
string
>
matcher_
;
};
inline
PolymorphicMatcher
<
WithWhatMatcherImpl
>
WithWhat
(
Matcher
<
std
::
string
>
m
)
{
return
MakePolymorphicMatcher
(
WithWhatMatcherImpl
(
std
::
move
(
m
)));
}
template
<
typename
Err
>
class
ExceptionMatcherImpl
{
class
NeverThrown
{
public:
const
char
*
what
()
const
noexcept
{
return
"this exception should never be thrown"
;
}
};
// If the matchee raises an exception of a wrong type, we'd like to
// catch it and print its message and type. To do that, we add an additional
// catch clause:
//
// try { ... }
// catch (const Err&) { /* an expected exception */ }
// catch (const std::exception&) { /* exception of a wrong type */ }
//
// However, if the `Err` itself is `std::exception`, we'd end up with two
// identical `catch` clauses:
//
// try { ... }
// catch (const std::exception&) { /* an expected exception */ }
// catch (const std::exception&) { /* exception of a wrong type */ }
//
// This can cause a warning or an error in some compilers. To resolve
// the issue, we use a fake error type whenever `Err` is `std::exception`:
//
// try { ... }
// catch (const std::exception&) { /* an expected exception */ }
// catch (const NeverThrown&) { /* exception of a wrong type */ }
using
DefaultExceptionType
=
typename
std
::
conditional
<
std
::
is_same
<
typename
std
::
remove_cv
<
typename
std
::
remove_reference
<
Err
>::
type
>::
type
,
std
::
exception
>::
value
,
const
NeverThrown
&
,
const
std
::
exception
&>::
type
;
public:
ExceptionMatcherImpl
(
Matcher
<
const
Err
&>
matcher
)
:
matcher_
(
std
::
move
(
matcher
))
{}
void
DescribeTo
(
std
::
ostream
*
os
)
const
{
*
os
<<
"throws an exception which is a "
<<
GetTypeName
<
Err
>
();
*
os
<<
" which "
;
matcher_
.
DescribeTo
(
os
);
}
void
DescribeNegationTo
(
std
::
ostream
*
os
)
const
{
*
os
<<
"throws an exception which is not a "
<<
GetTypeName
<
Err
>
();
*
os
<<
" which "
;
matcher_
.
DescribeNegationTo
(
os
);
}
template
<
typename
T
>
bool
MatchAndExplain
(
T
&&
x
,
MatchResultListener
*
listener
)
const
{
try
{
(
void
)(
std
::
forward
<
T
>
(
x
)());
}
catch
(
const
Err
&
err
)
{
*
listener
<<
"throws an exception which is a "
<<
GetTypeName
<
Err
>
();
*
listener
<<
" "
;
return
matcher_
.
MatchAndExplain
(
err
,
listener
);
}
catch
(
DefaultExceptionType
err
)
{
#if GTEST_HAS_RTTI
*
listener
<<
"throws an exception of type "
<<
GetTypeName
(
typeid
(
err
));
*
listener
<<
" "
;
#else
*
listener
<<
"throws an std::exception-derived type "
;
#endif
*
listener
<<
"with description
\"
"
<<
err
.
what
()
<<
"
\"
"
;
return
false
;
}
catch
(...)
{
*
listener
<<
"throws an exception of an unknown type"
;
return
false
;
}
*
listener
<<
"does not throw any exception"
;
return
false
;
}
private:
const
Matcher
<
const
Err
&>
matcher_
;
};
}
// namespace internal
// Throws()
// Throws(exceptionMatcher)
// ThrowsMessage(messageMatcher)
//
// This matcher accepts a callable and verifies that when invoked, it throws
// an exception with the given type and properties.
//
// Examples:
//
// EXPECT_THAT(
// []() { throw std::runtime_error("message"); },
// Throws<std::runtime_error>());
//
// EXPECT_THAT(
// []() { throw std::runtime_error("message"); },
// ThrowsMessage<std::runtime_error>(HasSubstr("message")));
//
// EXPECT_THAT(
// []() { throw std::runtime_error("message"); },
// Throws<std::runtime_error>(
// Property(&std::runtime_error::what, HasSubstr("message"))));
template
<
typename
Err
>
PolymorphicMatcher
<
internal
::
ExceptionMatcherImpl
<
Err
>>
Throws
()
{
return
MakePolymorphicMatcher
(
internal
::
ExceptionMatcherImpl
<
Err
>
(
A
<
const
Err
&>
()));
}
template
<
typename
Err
,
typename
ExceptionMatcher
>
PolymorphicMatcher
<
internal
::
ExceptionMatcherImpl
<
Err
>>
Throws
(
const
ExceptionMatcher
&
exception_matcher
)
{
// Using matcher cast allows users to pass a matcher of a more broad type.
// For example user may want to pass Matcher<std::exception>
// to Throws<std::runtime_error>, or Matcher<int64> to Throws<int32>.
return
MakePolymorphicMatcher
(
internal
::
ExceptionMatcherImpl
<
Err
>
(
SafeMatcherCast
<
const
Err
&>
(
exception_matcher
)));
}
template
<
typename
Err
,
typename
MessageMatcher
>
PolymorphicMatcher
<
internal
::
ExceptionMatcherImpl
<
Err
>>
ThrowsMessage
(
MessageMatcher
&&
message_matcher
)
{
static_assert
(
std
::
is_base_of
<
std
::
exception
,
Err
>::
value
,
"expected an std::exception-derived type"
);
return
Throws
<
Err
>
(
internal
::
WithWhat
(
MatcherCast
<
std
::
string
>
(
std
::
forward
<
MessageMatcher
>
(
message_matcher
))));
}
#endif // GTEST_HAS_EXCEPTIONS
// These macros allow using matchers to check values in Google Test
// tests. ASSERT_THAT(value, matcher) and EXPECT_THAT(value, matcher)
// succeed if and only if the value matches the matcher. If the assertion
...
...
googlemock/test/gmock-matchers_test.cc
浏览文件 @
aa4cbcdc
...
...
@@ -8117,6 +8117,190 @@ TEST(MatcherPMacroTest, WorksOnMoveOnlyType) {
EXPECT_THAT
(
p
,
Not
(
UniquePointee
(
2
)));
}
#if GTEST_HAS_EXCEPTIONS
// std::function<void()> is used below for compatibility with older copies of
// GCC. Normally, a raw lambda is all that is needed.
// Test that examples from documentation compile
TEST
(
ThrowsTest
,
Examples
)
{
EXPECT_THAT
(
std
::
function
<
void
()
>
([]()
{
throw
std
::
runtime_error
(
"message"
);
}),
Throws
<
std
::
runtime_error
>
());
EXPECT_THAT
(
std
::
function
<
void
()
>
([]()
{
throw
std
::
runtime_error
(
"message"
);
}),
ThrowsMessage
<
std
::
runtime_error
>
(
HasSubstr
(
"message"
)));
}
TEST
(
ThrowsTest
,
DoesNotGenerateDuplicateCatchClauseWarning
)
{
EXPECT_THAT
(
std
::
function
<
void
()
>
([]()
{
throw
std
::
exception
();
}),
Throws
<
std
::
exception
>
());
}
TEST
(
ThrowsTest
,
CallableExecutedExactlyOnce
)
{
size_t
a
=
0
;
EXPECT_THAT
(
std
::
function
<
void
()
>
([
&
a
]()
{
a
++
;
throw
10
;
}),
Throws
<
int
>
());
EXPECT_EQ
(
a
,
1u
);
EXPECT_THAT
(
std
::
function
<
void
()
>
([
&
a
]()
{
a
++
;
throw
std
::
runtime_error
(
"message"
);
}),
Throws
<
std
::
runtime_error
>
());
EXPECT_EQ
(
a
,
2u
);
EXPECT_THAT
(
std
::
function
<
void
()
>
([
&
a
]()
{
a
++
;
throw
std
::
runtime_error
(
"message"
);
}),
ThrowsMessage
<
std
::
runtime_error
>
(
HasSubstr
(
"message"
)));
EXPECT_EQ
(
a
,
3u
);
EXPECT_THAT
(
std
::
function
<
void
()
>
([
&
a
]()
{
a
++
;
throw
std
::
runtime_error
(
"message"
);
}),
Throws
<
std
::
runtime_error
>
(
Property
(
&
std
::
runtime_error
::
what
,
HasSubstr
(
"message"
))));
EXPECT_EQ
(
a
,
4u
);
}
TEST
(
ThrowsTest
,
Describe
)
{
Matcher
<
std
::
function
<
void
()
>>
matcher
=
Throws
<
std
::
runtime_error
>
();
std
::
stringstream
ss
;
matcher
.
DescribeTo
(
&
ss
);
auto
explanation
=
ss
.
str
();
EXPECT_THAT
(
explanation
,
HasSubstr
(
"std::runtime_error"
));
}
TEST
(
ThrowsTest
,
Success
)
{
Matcher
<
std
::
function
<
void
()
>>
matcher
=
Throws
<
std
::
runtime_error
>
();
StringMatchResultListener
listener
;
EXPECT_TRUE
(
matcher
.
MatchAndExplain
(
[]()
{
throw
std
::
runtime_error
(
"error message"
);
},
&
listener
));
EXPECT_THAT
(
listener
.
str
(),
HasSubstr
(
"std::runtime_error"
));
}
TEST
(
ThrowsTest
,
FailWrongType
)
{
Matcher
<
std
::
function
<
void
()
>>
matcher
=
Throws
<
std
::
runtime_error
>
();
StringMatchResultListener
listener
;
EXPECT_FALSE
(
matcher
.
MatchAndExplain
(
[]()
{
throw
std
::
logic_error
(
"error message"
);
},
&
listener
));
EXPECT_THAT
(
listener
.
str
(),
HasSubstr
(
"std::logic_error"
));
EXPECT_THAT
(
listener
.
str
(),
HasSubstr
(
"
\"
error message
\"
"
));
}
TEST
(
ThrowsTest
,
FailWrongTypeNonStd
)
{
Matcher
<
std
::
function
<
void
()
>>
matcher
=
Throws
<
std
::
runtime_error
>
();
StringMatchResultListener
listener
;
EXPECT_FALSE
(
matcher
.
MatchAndExplain
([]()
{
throw
10
;
},
&
listener
));
EXPECT_THAT
(
listener
.
str
(),
HasSubstr
(
"throws an exception of an unknown type"
));
}
TEST
(
ThrowsTest
,
FailNoThrow
)
{
Matcher
<
std
::
function
<
void
()
>>
matcher
=
Throws
<
std
::
runtime_error
>
();
StringMatchResultListener
listener
;
EXPECT_FALSE
(
matcher
.
MatchAndExplain
([]()
{
(
void
)
0
;
},
&
listener
));
EXPECT_THAT
(
listener
.
str
(),
HasSubstr
(
"does not throw any exception"
));
}
class
ThrowsPredicateTest
:
public
TestWithParam
<
Matcher
<
std
::
function
<
void
()
>>>
{};
TEST_P
(
ThrowsPredicateTest
,
Describe
)
{
Matcher
<
std
::
function
<
void
()
>>
matcher
=
GetParam
();
std
::
stringstream
ss
;
matcher
.
DescribeTo
(
&
ss
);
auto
explanation
=
ss
.
str
();
EXPECT_THAT
(
explanation
,
HasSubstr
(
"std::runtime_error"
));
EXPECT_THAT
(
explanation
,
HasSubstr
(
"error message"
));
}
TEST_P
(
ThrowsPredicateTest
,
Success
)
{
Matcher
<
std
::
function
<
void
()
>>
matcher
=
GetParam
();
StringMatchResultListener
listener
;
EXPECT_TRUE
(
matcher
.
MatchAndExplain
(
[]()
{
throw
std
::
runtime_error
(
"error message"
);
},
&
listener
));
EXPECT_THAT
(
listener
.
str
(),
HasSubstr
(
"std::runtime_error"
));
}
TEST_P
(
ThrowsPredicateTest
,
FailWrongType
)
{
Matcher
<
std
::
function
<
void
()
>>
matcher
=
GetParam
();
StringMatchResultListener
listener
;
EXPECT_FALSE
(
matcher
.
MatchAndExplain
(
[]()
{
throw
std
::
logic_error
(
"error message"
);
},
&
listener
));
EXPECT_THAT
(
listener
.
str
(),
HasSubstr
(
"std::logic_error"
));
EXPECT_THAT
(
listener
.
str
(),
HasSubstr
(
"
\"
error message
\"
"
));
}
TEST_P
(
ThrowsPredicateTest
,
FailWrongTypeNonStd
)
{
Matcher
<
std
::
function
<
void
()
>>
matcher
=
GetParam
();
StringMatchResultListener
listener
;
EXPECT_FALSE
(
matcher
.
MatchAndExplain
([]()
{
throw
10
;
},
&
listener
));
EXPECT_THAT
(
listener
.
str
(),
HasSubstr
(
"throws an exception of an unknown type"
));
}
TEST_P
(
ThrowsPredicateTest
,
FailWrongMessage
)
{
Matcher
<
std
::
function
<
void
()
>>
matcher
=
GetParam
();
StringMatchResultListener
listener
;
EXPECT_FALSE
(
matcher
.
MatchAndExplain
(
[]()
{
throw
std
::
runtime_error
(
"wrong message"
);
},
&
listener
));
EXPECT_THAT
(
listener
.
str
(),
HasSubstr
(
"std::runtime_error"
));
EXPECT_THAT
(
listener
.
str
(),
Not
(
HasSubstr
(
"wrong message"
)));
}
TEST_P
(
ThrowsPredicateTest
,
FailNoThrow
)
{
Matcher
<
std
::
function
<
void
()
>>
matcher
=
GetParam
();
StringMatchResultListener
listener
;
EXPECT_FALSE
(
matcher
.
MatchAndExplain
([]()
{},
&
listener
));
EXPECT_THAT
(
listener
.
str
(),
HasSubstr
(
"does not throw any exception"
));
}
INSTANTIATE_TEST_SUITE_P
(
AllMessagePredicates
,
ThrowsPredicateTest
,
Values
(
Matcher
<
std
::
function
<
void
()
>>
(
ThrowsMessage
<
std
::
runtime_error
>
(
HasSubstr
(
"error message"
)))));
// Tests that Throws<E1>(Matcher<E2>{}) compiles even when E2 != const E1&.
TEST
(
ThrowsPredicateCompilesTest
,
ExceptionMatcherAcceptsBroadType
)
{
{
Matcher
<
std
::
function
<
void
()
>>
matcher
=
ThrowsMessage
<
std
::
runtime_error
>
(
HasSubstr
(
"error message"
));
EXPECT_TRUE
(
matcher
.
Matches
([]()
{
throw
std
::
runtime_error
(
"error message"
);
}));
EXPECT_FALSE
(
matcher
.
Matches
([]()
{
throw
std
::
runtime_error
(
"wrong message"
);
}));
}
{
Matcher
<
uint64_t
>
inner
=
Eq
(
10
);
Matcher
<
std
::
function
<
void
()
>>
matcher
=
Throws
<
uint32_t
>
(
inner
);
EXPECT_TRUE
(
matcher
.
Matches
([]()
{
throw
(
uint32_t
)
10
;
}));
EXPECT_FALSE
(
matcher
.
Matches
([]()
{
throw
(
uint32_t
)
11
;
}));
}
}
// Tests that ThrowsMessage("message") is equivalent
// to ThrowsMessage(Eq<std::string>("message")).
TEST
(
ThrowsPredicateCompilesTest
,
MessageMatcherAcceptsNonMatcher
)
{
Matcher
<
std
::
function
<
void
()
>>
matcher
=
ThrowsMessage
<
std
::
runtime_error
>
(
"error message"
);
EXPECT_TRUE
(
matcher
.
Matches
([]()
{
throw
std
::
runtime_error
(
"error message"
);
}));
EXPECT_FALSE
(
matcher
.
Matches
(
[]()
{
throw
std
::
runtime_error
(
"wrong error message"
);
}));
}
#endif // GTEST_HAS_EXCEPTIONS
}
// namespace
}
// namespace gmock_matchers_test
}
// namespace testing
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录