blob: 0f0913aabe2aada6efa98d1880717e6219eb8b8c [file] [log] [blame]
// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "libhwsec-foundation/error/caller_info.h"
#include "libhwsec-foundation/error/error.h"
#include "libhwsec-foundation/error/error_message.h"
#include "libhwsec-foundation/error/testing_helper.h"
#include <sstream>
#include <type_traits>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
using ::hwsec_foundation::error::testing::TestForCreateError;
using ::hwsec_foundation::error::testing::TestForCreateErrorWrap;
namespace hwsec_foundation {
namespace error {
class TestingErrorTest : public ::testing::Test {
public:
TestingErrorTest() {}
~TestingErrorTest() override = default;
protected:
// Implement a test error object.
class TestingErrorObj : public ErrorBaseObj {
public:
explicit TestingErrorObj(int err1, double err2, std::string err3)
: err1_(err1), err2_(err2), err3_(err3) {}
virtual ~TestingErrorObj() = default;
std::string ToReadableString() const {
std::stringstream ss;
ss << err1_ << " " << err2_ << " " << err3_;
return ss.str();
}
hwsec_foundation::error::ErrorBase SelfCopy() const {
return std::make_unique<TestingErrorObj>(err1_, err2_, err3_);
}
protected:
TestingErrorObj(TestingErrorObj&&) = default;
private:
const int err1_;
const double err2_;
const std::string err3_;
};
using TestingError = std::unique_ptr<TestingErrorObj>;
};
TEST_F(TestingErrorTest, PrintErrorMessage) {
auto err = CreateError<TestingError>(87, 0.1234, "AAAA");
std::stringstream ss;
ss << *err;
EXPECT_EQ("87 0.1234 AAAA", ss.str());
}
TEST_F(TestingErrorTest, WrapErrors) {
auto err = CreateError<TestingError>(87, 0.1234, "AAAA");
auto err2 = CreateError<TestingError>(12, 0.56, "BBB");
err2->Wrap(std::move(err));
EXPECT_EQ(err, nullptr);
std::stringstream ss;
ss << *err2;
EXPECT_EQ("12 0.56 BBB: 87 0.1234 AAAA", ss.str());
auto err3 = CreateError<TestingError>(555, 9487, "CCC");
err3->Wrap(std::move(err2));
EXPECT_EQ(err2, nullptr);
ss = std::stringstream();
ss << *err3;
EXPECT_EQ("555 9487 CCC: 12 0.56 BBB: 87 0.1234 AAAA", ss.str());
}
TEST_F(TestingErrorTest, CreateWrappedError) {
auto err = CreateError<TestingError>(87, 0.1234, "AAAA");
auto err2 = CreateErrorWrap<TestingError>(std::move(err), 12, 0.56, "BBB");
EXPECT_EQ(err, nullptr);
std::stringstream ss;
ss << *err2;
EXPECT_EQ("12 0.56 BBB: 87 0.1234 AAAA", ss.str());
}
TEST_F(TestingErrorTest, UnWrappError) {
ErrorBase err = CreateError<TestingError>(87, 0.1234, "AAAA");
ErrorBase err2 =
CreateErrorWrap<TestingError>(std::move(err), 12, 0.56, "BBB");
EXPECT_EQ(err, nullptr);
err = err2->UnWrap();
std::stringstream ss;
ss << *err;
EXPECT_EQ("87 0.1234 AAAA", ss.str());
ss = std::stringstream();
ss << *err2;
EXPECT_EQ("12 0.56 BBB", ss.str());
}
TEST_F(TestingErrorTest, FullCopyError) {
ErrorBase err = CreateError<TestingError>(87, 0.1234, "AAAA");
ErrorBase err2 =
CreateErrorWrap<TestingError>(std::move(err), 12, 0.56, "BBB");
ErrorBase err3 = err2->FullCopy();
std::stringstream ss;
ss << *err2;
EXPECT_EQ("12 0.56 BBB: 87 0.1234 AAAA", ss.str());
ss = std::stringstream();
ss << *err3;
EXPECT_EQ("12 0.56 BBB: 87 0.1234 AAAA", ss.str());
err2->UnWrap();
ss = std::stringstream();
ss << *err3;
EXPECT_EQ("12 0.56 BBB: 87 0.1234 AAAA", ss.str());
err2.reset();
ss = std::stringstream();
ss << *err3;
EXPECT_EQ("12 0.56 BBB: 87 0.1234 AAAA", ss.str());
}
TEST_F(TestingErrorTest, TestForCreateError) {
EXPECT_FALSE((TestForCreateError<ErrorBase>::Check::value));
EXPECT_FALSE((TestForCreateError<ErrorBase, int>::Check::value));
EXPECT_FALSE((TestForCreateError<ErrorBase, int, double>::Check::value));
EXPECT_FALSE(
(TestForCreateError<ErrorBase, int, double, std::string>::Check::value));
EXPECT_FALSE(
(TestForCreateError<ErrorBase, int, int, std::string>::Check::value));
EXPECT_FALSE((TestForCreateError<ErrorBase, const int&, const int&,
std::string>::Check::value));
EXPECT_FALSE((TestForCreateError<ErrorBase, double, int&,
const std::string&>::Check::value));
EXPECT_FALSE(
(TestForCreateError<ErrorBase, int, int, std::string&&>::Check::value));
EXPECT_FALSE((TestForCreateError<ErrorBase, std::string, std::string,
std::string>::Check::value));
EXPECT_FALSE((TestForCreateError<ErrorBase, bool, bool, bool>::Check::value));
EXPECT_FALSE((TestForCreateError<ErrorBase, std::string>::Check::value));
EXPECT_FALSE((TestForCreateError<ErrorBase, char[]>::Check::value));
EXPECT_FALSE(
(TestForCreateError<ErrorBase, int, double, char[]>::Check::value));
EXPECT_FALSE((TestForCreateError<TestingError>::Check::value));
EXPECT_FALSE((TestForCreateError<TestingError, int>::Check::value));
EXPECT_FALSE((TestForCreateError<TestingError, int, double>::Check::value));
EXPECT_TRUE((TestForCreateError<TestingError, int, double,
std::string>::Check::value));
EXPECT_TRUE(
(TestForCreateError<TestingError, int, int, std::string>::Check::value));
EXPECT_TRUE((TestForCreateError<TestingError, const int&, const int&,
std::string>::Check::value));
EXPECT_TRUE((TestForCreateError<TestingError, double, int&,
const std::string&>::Check::value));
EXPECT_TRUE((
TestForCreateError<TestingError, int, int, std::string&&>::Check::value));
EXPECT_FALSE((TestForCreateError<TestingError, std::string, std::string,
std::string>::Check::value));
EXPECT_FALSE(
(TestForCreateError<TestingError, bool, bool, bool>::Check::value));
EXPECT_FALSE((TestForCreateError<TestingError, std::string>::Check::value));
EXPECT_FALSE((TestForCreateError<TestingError, char[]>::Check::value));
EXPECT_TRUE(
(TestForCreateError<TestingError, int, double, char[]>::Check::value));
EXPECT_FALSE((TestForCreateError<Error>::Check::value));
EXPECT_TRUE((TestForCreateError<Error, std::string>::Check::value));
EXPECT_TRUE((TestForCreateError<Error, std::string&&>::Check::value));
EXPECT_TRUE((TestForCreateError<Error, const std::string&>::Check::value));
EXPECT_TRUE((TestForCreateError<Error, std::string&>::Check::value));
EXPECT_TRUE((TestForCreateError<Error, char[]>::Check::value));
EXPECT_TRUE((TestForCreateError<Error, char*>::Check::value));
EXPECT_FALSE((TestForCreateError<Error, char>::Check::value));
EXPECT_FALSE((TestForCreateError<Error, int>::Check::value));
EXPECT_FALSE(
(TestForCreateError<Error, std::string, std::string>::Check::value));
using StringCallerError = CallerInfoError<Error>;
EXPECT_FALSE((TestForCreateError<StringCallerError>::Check::value));
EXPECT_FALSE(
(TestForCreateError<StringCallerError, std::string>::Check::value));
EXPECT_FALSE((TestForCreateError<StringCallerError, const char[],
const char[], int>::Check::value));
EXPECT_TRUE((TestForCreateError<StringCallerError, const char[], const char[],
int, std::string>::Check::value));
}
TEST_F(TestingErrorTest, TestForCreateErrorWrap) {
EXPECT_FALSE(
(TestForCreateErrorWrap<TestingError, ErrorBase, int>::Check::value));
EXPECT_FALSE((TestForCreateErrorWrap<TestingError, ErrorBase, int,
double>::Check::value));
EXPECT_TRUE((TestForCreateErrorWrap<TestingError, ErrorBase, int, double,
std::string>::Check::value));
EXPECT_TRUE((TestForCreateErrorWrap<TestingError, ErrorBase, int, int,
std::string>::Check::value));
EXPECT_TRUE((TestForCreateErrorWrap<TestingError, ErrorBase, const int&,
const int&, std::string>::Check::value));
EXPECT_TRUE((TestForCreateErrorWrap<TestingError, ErrorBase, double, int&,
const std::string&>::Check::value));
EXPECT_TRUE((TestForCreateErrorWrap<TestingError, ErrorBase, int, int,
std::string&&>::Check::value));
EXPECT_FALSE(
(TestForCreateErrorWrap<TestingError, ErrorBase, std::string, std::string,
std::string>::Check::value));
EXPECT_FALSE((TestForCreateErrorWrap<TestingError, ErrorBase, bool, bool,
bool>::Check::value));
EXPECT_FALSE((TestForCreateErrorWrap<TestingError, ErrorBase,
std::string>::Check::value));
EXPECT_FALSE(
(TestForCreateErrorWrap<TestingError, ErrorBase, char[]>::Check::value));
EXPECT_TRUE((TestForCreateErrorWrap<TestingError, ErrorBase, int, double,
char[]>::Check::value));
}
TEST_F(TestingErrorTest, Error) {
auto err = CreateError<Error>("Magic");
auto err2 = CreateErrorWrap<TestingError>(std::move(err), 12, 0.56, "BBB");
std::stringstream ss;
ss << *err2;
EXPECT_EQ("12 0.56 BBB: Magic", ss.str());
}
TEST_F(TestingErrorTest, AsIsCast) {
auto err = CreateError<Error>("Magic");
auto err2 = CreateErrorWrap<TestingError>(std::move(err), 12, 0.56, "BBB");
ErrorBase err3 = CreateErrorWrap<TestingError>(std::move(err2), 1, 0, "XD");
EXPECT_TRUE(err3->Is<TestingError>());
EXPECT_FALSE(err3->Is<Error>());
auto err4 = err3->As<Error>();
EXPECT_TRUE(err4->Is<Error>());
EXPECT_FALSE(err4->Is<TestingError>());
EXPECT_EQ("Magic", err4->ToFullReadableString());
auto err5 = err3->Cast<Error>();
EXPECT_EQ(nullptr, err5);
auto err6 = err3->Cast<TestingError>();
EXPECT_NE(nullptr, err6);
EXPECT_EQ("1 0 XD", err6->ToReadableString());
EXPECT_EQ("1 0 XD: 12 0.56 BBB: Magic", err6->ToFullReadableString());
}
TEST_F(TestingErrorTest, CallerInfoError) {
using StringCallerError = CallerInfoError<Error>;
auto err = CreateError<StringCallerError>(CALLER_INFO_ARGS, "Magic");
EXPECT_NE(err->ToFullReadableString().find("Magic"), std::string::npos);
auto err2 = err->FullCopy();
}
} // namespace error
} // namespace hwsec_foundation