private:
Optional<testing::Matcher<InfoT &>> Matcher;
};
+
+class ErrorMessageMatches
+ : public testing::MatcherInterface<const ErrorHolder &> {
+public:
+ explicit ErrorMessageMatches(
+ testing::Matcher<std::vector<std::string>> Matcher)
+ : Matcher(std::move(Matcher)) {}
+
+ bool MatchAndExplain(const ErrorHolder &Holder,
+ testing::MatchResultListener *listener) const override {
+ std::vector<std::string> Messages;
+ for (const std::shared_ptr<ErrorInfoBase> &Info: Holder.Infos)
+ Messages.push_back(Info->message());
+
+ return Matcher.MatchAndExplain(Messages, listener);
+ }
+
+ void DescribeTo(std::ostream *OS) const override {
+ *OS << "failed with Error whose message ";
+ Matcher.DescribeTo(OS);
+ }
+
+ void DescribeNegationTo(std::ostream *OS) const override {
+ *OS << "failed with an Error whose message ";
+ Matcher.DescribeNegationTo(OS);
+ }
+
+private:
+ testing::Matcher<std::vector<std::string>> Matcher;
+};
} // namespace detail
#define EXPECT_THAT_ERROR(Err, Matcher) \
testing::SafeMatcherCast<InfoT &>(Matcher)));
}
+template <typename... M>
+testing::Matcher<const detail::ErrorHolder &> FailedWithMessage(M... Matcher) {
+ static_assert(sizeof...(M) > 0, "");
+ return MakeMatcher(
+ new detail::ErrorMessageMatches(testing::ElementsAre(Matcher...)));
+}
+
+template <typename M>
+testing::Matcher<const detail::ErrorHolder &> FailedWithMessageArray(M Matcher) {
+ return MakeMatcher(new detail::ErrorMessageMatches(Matcher));
+}
+
template <typename M>
detail::ValueMatchesPoly<M> HasValue(M Matcher) {
return detail::ValueMatchesPoly<M>(Matcher);
" Actual: failed (CustomError {0})");
}
+TEST(Error, FailedWithMessageMatcher) {
+ EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)),
+ FailedWithMessage("CustomError {0}"));
+
+ EXPECT_NONFATAL_FAILURE(
+ EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(1)),
+ FailedWithMessage("CustomError {0}")),
+ "Expected: failed with Error whose message has 1 element that is equal "
+ "to \"CustomError {0}\"\n"
+ " Actual: failed (CustomError {1})");
+
+ EXPECT_NONFATAL_FAILURE(
+ EXPECT_THAT_EXPECTED(Expected<int>(0),
+ FailedWithMessage("CustomError {0}")),
+ "Expected: failed with Error whose message has 1 element that is equal "
+ "to \"CustomError {0}\"\n"
+ " Actual: succeeded with value 0");
+
+ EXPECT_NONFATAL_FAILURE(
+ EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)),
+ FailedWithMessage("CustomError {0}", "CustomError {0}")),
+ "Expected: failed with Error whose message has 2 elements where\n"
+ "element #0 is equal to \"CustomError {0}\",\n"
+ "element #1 is equal to \"CustomError {0}\"\n"
+ " Actual: failed (CustomError {0}), which has 1 element");
+
+ EXPECT_NONFATAL_FAILURE(
+ EXPECT_THAT_EXPECTED(
+ Expected<int>(joinErrors(make_error<CustomError>(0),
+ make_error<CustomError>(0))),
+ FailedWithMessage("CustomError {0}")),
+ "Expected: failed with Error whose message has 1 element that is equal "
+ "to \"CustomError {0}\"\n"
+ " Actual: failed (CustomError {0}; CustomError {0}), which has 2 elements");
+
+ EXPECT_THAT_ERROR(
+ joinErrors(make_error<CustomError>(0), make_error<CustomError>(0)),
+ FailedWithMessageArray(testing::SizeIs(2)));
+}
+
TEST(Error, C_API) {
EXPECT_THAT_ERROR(unwrap(wrap(Error::success())), Succeeded())
<< "Failed to round-trip Error success value via C API";