#include #include "utils/result.hpp" using cpptrace::detail::Result; namespace { // A simple custom error type that behaves like a standard exception. struct error { int x; const char* what() const { return "error..."; } }; class ResultFixture : public testing::Test { public: ResultFixture() { cpptrace::absorb_trace_exceptions(true); } ~ResultFixture() override { cpptrace::absorb_trace_exceptions(false); } }; TEST_F(ResultFixture, ConstructWithValueRValue) { cpptrace::detail::Result result("test"); EXPECT_TRUE(result.has_value()); EXPECT_FALSE(result.is_error()); EXPECT_TRUE(static_cast(result)); EXPECT_EQ(result.unwrap_value(), "test"); EXPECT_FALSE(result.error().has_value()); } TEST_F(ResultFixture, ConstructWithValueLValue) { std::string s = "test"; cpptrace::detail::Result result(s); EXPECT_TRUE(result.has_value()); EXPECT_FALSE(result.is_error()); EXPECT_EQ(result.unwrap_value(), "test"); s = "x"; EXPECT_EQ(result.unwrap_value(), "test"); cpptrace::detail::Result r2(s); EXPECT_EQ(r2.unwrap_value(), "x"); s = "y"; EXPECT_EQ(r2.unwrap_value(), "y"); } TEST_F(ResultFixture, ConstructWithErrorRValue) { cpptrace::detail::Result result(error{1}); EXPECT_FALSE(result.has_value()); EXPECT_TRUE(result.is_error()); EXPECT_FALSE(static_cast(result)); EXPECT_EQ(result.unwrap_error().x, 1); // Check that value() returns nullopt in this scenario EXPECT_FALSE(result.value().has_value()); } TEST_F(ResultFixture, ConstructWithErrorLValue) { error e{1}; cpptrace::detail::Result result(e); EXPECT_FALSE(result.has_value()); EXPECT_TRUE(result.is_error()); EXPECT_EQ(result.unwrap_error().x, 1); } TEST_F(ResultFixture, MoveConstructorValue) { cpptrace::detail::Result original(std::string("move")); cpptrace::detail::Result moved(std::move(original)); EXPECT_TRUE(moved.has_value()); EXPECT_EQ(moved.unwrap_value(), "move"); EXPECT_TRUE(original.has_value()); std::string s = "test"; cpptrace::detail::Result r1(s); cpptrace::detail::Result r2(std::move(r1)); EXPECT_TRUE(r2.has_value()); EXPECT_EQ(r2.unwrap_value(), "test"); s = "foo"; EXPECT_EQ(r2.unwrap_value(), "foo"); EXPECT_TRUE(r2.has_value()); } TEST_F(ResultFixture, MoveConstructorError) { cpptrace::detail::Result original(error{1}); cpptrace::detail::Result moved(std::move(original)); EXPECT_TRUE(moved.is_error()); EXPECT_EQ(moved.unwrap_error().x, 1); EXPECT_TRUE(original.is_error()); } TEST_F(ResultFixture, ValueOr) { { cpptrace::detail::Result res_with_value(42); EXPECT_EQ(res_with_value.value_or(-1), 42); EXPECT_EQ(std::move(res_with_value).value_or(-1), 42); } { cpptrace::detail::Result res_with_error(error{}); EXPECT_EQ(res_with_error.value_or(-1), -1); EXPECT_EQ(std::move(res_with_error).value_or(-1), -1); } { int x = 2; int y = 3; cpptrace::detail::Result res_with_value(x); EXPECT_EQ(res_with_value.value_or(y), 2); EXPECT_EQ(std::move(res_with_value).value_or(y), 2); } { int x = 2; cpptrace::detail::Result res_with_error(error{}); EXPECT_EQ(res_with_error.value_or(x), 2); EXPECT_EQ(&res_with_error.value_or(x), &x); EXPECT_EQ(std::move(res_with_error).value_or(x), 2); } } }