blob: fc09340a1591dc3dae9065b2f64e81709efa5ffc [file] [edit]
//===- ErrorMatchersTest.cpp ----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Tests for the Error / Expected<T> matchers in ErrorMatchers.h.
//
// Each matcher is exercised on a value it should match and on one it should
// not. The latter run inside gtest's own failure interception (gtest-spi.h) and
// assert on the reported text, since a matcher's diagnostic is most of what it
// is for.
//
//===----------------------------------------------------------------------===//
#include "ErrorMatchers.h"
#include "gtest/gtest-spi.h"
using namespace orc_rt;
using namespace orc_rt::test;
using ::testing::Gt;
using ::testing::HasSubstr;
using ::testing::Property;
namespace {
class CustomError : public ErrorExtends<CustomError, ErrorInfoBase> {
public:
static constexpr const char *RTTIName = "::CustomError";
CustomError(int Info) : Info(Info) {}
std::string toString() const noexcept override {
return "CustomError (" + std::to_string(Info) + ")";
}
int getInfo() const { return Info; }
protected:
int Info;
};
class OtherError : public ErrorExtends<OtherError, ErrorInfoBase> {
public:
static constexpr const char *RTTIName = "::OtherError";
std::string toString() const noexcept override { return "OtherError"; }
};
TEST(ErrorMatchersTest, SucceededMatchesSuccess) {
EXPECT_THAT_ERROR(Error::success(), Succeeded());
}
TEST(ErrorMatchersTest, SucceededRejectsFailure) {
EXPECT_NONFATAL_FAILURE(
EXPECT_THAT_ERROR(make_error<CustomError>(7), Succeeded()), "7");
}
TEST(ErrorMatchersTest, FailedMatchesFailure) {
EXPECT_THAT_ERROR(make_error<CustomError>(7), Failed());
}
TEST(ErrorMatchersTest, FailedRejectsSuccess) {
EXPECT_NONFATAL_FAILURE(EXPECT_THAT_ERROR(Error::success(), Failed()),
"Actual");
}
TEST(ErrorMatchersTest, LValueErrorIsHandedOverExplicitly) {
Error E = make_error<CustomError>(7);
EXPECT_THAT_ERROR(std::move(E), Failed());
}
TEST(ErrorMatchersTest, FailedOfTypeMatchesThatType) {
EXPECT_THAT_ERROR(make_error<CustomError>(7), Failed<CustomError>());
}
TEST(ErrorMatchersTest, FailedOfTypeNamesTheTypeItFound) {
// The point of the type matcher: on a mismatch it says what did turn up,
// rather than only that the expectation was not met.
EXPECT_NONFATAL_FAILURE(
EXPECT_THAT_ERROR(make_error<OtherError>(), Failed<CustomError>()),
"failed with ::OtherError: OtherError");
}
TEST(ErrorMatchersTest, FailedOfTypeRejectsSuccess) {
EXPECT_NONFATAL_FAILURE(
EXPECT_THAT_ERROR(Error::success(), Failed<CustomError>()), "succeeded");
}
TEST(ErrorMatchersTest, FailedOfTypeWithInnerMatcher) {
EXPECT_THAT_ERROR(
make_error<CustomError>(7),
Failed<CustomError>(Property("getInfo", &CustomError::getInfo, 7)));
}
TEST(ErrorMatchersTest, FailedOfTypeRejectsFailingInnerMatcher) {
EXPECT_NONFATAL_FAILURE(
EXPECT_THAT_ERROR(
make_error<CustomError>(7),
Failed<CustomError>(Property("getInfo", &CustomError::getInfo, 8))),
"getInfo");
}
TEST(ErrorMatchersTest, FailedWithMessageMatchesExactMessage) {
EXPECT_THAT_ERROR(make_error<CustomError>(7),
FailedWithMessage("CustomError (7)"));
}
TEST(ErrorMatchersTest, FailedWithMessageTakesAMatcher) {
// The reason to prefer a matcher: a message that embeds errno text, a path,
// or an address cannot be compared for equality across platforms.
EXPECT_THAT_ERROR(make_error<CustomError>(7),
FailedWithMessage(HasSubstr("(7)")));
}
TEST(ErrorMatchersTest, FailedWithMessageRejectsOtherMessage) {
EXPECT_NONFATAL_FAILURE(
EXPECT_THAT_ERROR(make_error<CustomError>(7),
FailedWithMessage("CustomError (8)")),
"CustomError (7)");
}
TEST(ErrorMatchersTest, FailedWithMessageRejectsSuccess) {
EXPECT_NONFATAL_FAILURE(
EXPECT_THAT_ERROR(Error::success(), FailedWithMessage("anything")),
"succeeded");
}
TEST(ErrorMatchersTest, AssertThatErrorIsFatal) {
EXPECT_FATAL_FAILURE(ASSERT_THAT_ERROR(Error::success(), Failed()), "Actual");
}
TEST(ExpectedMatchersTest, SucceededMatchesValue) {
EXPECT_THAT_EXPECTED(Expected<int>(42), Succeeded());
}
TEST(ExpectedMatchersTest, FailedMatchesFailure) {
Expected<int> V = make_error<CustomError>(7);
EXPECT_THAT_EXPECTED(V, Failed());
}
TEST(ExpectedMatchersTest, HasValueMatchesValue) {
EXPECT_THAT_EXPECTED(Expected<int>(42), HasValue(42));
}
TEST(ExpectedMatchersTest, HasValueTakesAMatcher) {
EXPECT_THAT_EXPECTED(Expected<int>(42), HasValue(Gt(40)));
}
TEST(ExpectedMatchersTest, HasValueRejectsOtherValue) {
EXPECT_NONFATAL_FAILURE(EXPECT_THAT_EXPECTED(Expected<int>(42), HasValue(43)),
"42");
}
TEST(ExpectedMatchersTest, HasValueRejectsFailureAndNamesTheError) {
EXPECT_NONFATAL_FAILURE(
EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(7)),
HasValue(42)),
"failed with ::CustomError: CustomError (7)");
}
TEST(ExpectedMatchersTest, FailedRejectsValue) {
EXPECT_NONFATAL_FAILURE(EXPECT_THAT_EXPECTED(Expected<int>(42), Failed()),
"Actual");
}
TEST(ExpectedMatchersTest, ValueSurvivesASucceededMatch) {
Expected<int> V(42);
ASSERT_THAT_EXPECTED(V, Succeeded());
EXPECT_EQ(*V, 42);
}
TEST(ExpectedMatchersTest, FailureLeavesExpectedDestructible) {
// The macro takes the Expected's error, which leaves it in a state where
// re-checking it would arm the abort in its destructor. Nothing in the
// matchers does that, so this scope exits cleanly rather than aborting.
Expected<int> V = make_error<CustomError>(7);
EXPECT_THAT_EXPECTED(V, Failed<CustomError>());
}
} // namespace