1/** 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "utils/expected.h" 17 18#include <gtest/gtest.h> 19 20#include <type_traits> 21 22namespace panda::test::expected { 23 24enum class ErrorCode { First, Second }; 25 26static Expected<int, ErrorCode> helper(int v) 27{ 28 switch (v) { 29 case 0: 30 return Unexpected {ErrorCode::First}; 31 case 1: 32 return {42}; 33 default: 34 return Unexpected {ErrorCode::Second}; 35 } 36} 37 38struct Default { 39 int v; 40}; 41 42struct NonDefaultConstructible { 43 NonDefaultConstructible() = delete; 44}; 45 46TEST(Expected, Unexpected) 47{ 48 int e = 1; 49 auto u = Unexpected(e); 50 EXPECT_EQ(Unexpected<int>(1).Value(), 1); 51 EXPECT_EQ(u.Value(), 1); 52 EXPECT_EQ(static_cast<const Unexpected<int> &>(u).Value(), 1); 53} 54 55TEST(Expected, Ctor) 56{ 57 int v = 1; 58 auto e = Expected<int, ErrorCode>(v); 59 EXPECT_TRUE(e); 60 EXPECT_EQ(e.Value(), 1); 61 EXPECT_EQ(*e, 1); 62 63 auto e0 = Expected<int, ErrorCode>(); 64 EXPECT_EQ(*e0, 0); 65 66 auto e1 = Expected<int, ErrorCode>(2); 67 EXPECT_EQ(e1.Value(), 2); 68 69 auto e2 = Expected<int, ErrorCode>(Unexpected(ErrorCode::First)); 70 auto u = Unexpected(ErrorCode::Second); 71 auto e3 = Expected<int, ErrorCode>(u); 72 EXPECT_FALSE(e2); 73 EXPECT_EQ(e2.Error(), ErrorCode::First); 74 EXPECT_EQ(e3.Error(), ErrorCode::Second); 75 76 // Default constructor is only enabled if T is default constructible. 77 EXPECT_FALSE((std::is_default_constructible_v<Expected<NonDefaultConstructible, ErrorCode>>)); 78} 79 80TEST(Expected, Access) 81{ 82 const auto e1 = Expected<int, ErrorCode>(Unexpected(ErrorCode::First)); 83 EXPECT_EQ(e1.Error(), ErrorCode::First); 84 EXPECT_EQ((Expected<int, ErrorCode>(Unexpected(ErrorCode::Second)).Error()), ErrorCode::Second); 85 const auto e2 = Expected<int, ErrorCode>(1); 86 EXPECT_EQ(e2.Value(), 1); 87 EXPECT_EQ(*e2, 1); 88 EXPECT_EQ((*Expected<int, ErrorCode>(2)), 2); 89 EXPECT_EQ((Expected<int, ErrorCode>(3).Value()), 3); 90} 91 92TEST(Expected, Assignment) 93{ 94 auto d = Default {1}; 95 Expected<Default, ErrorCode> t = d; 96 t.Value() = Default {2}; 97 EXPECT_TRUE(t); 98 EXPECT_EQ((*t).v, 2); 99 t = Unexpected(ErrorCode::First); 100 EXPECT_FALSE(t); 101 EXPECT_EQ(t.Error(), ErrorCode::First); 102} 103 104TEST(Expected, Basic) 105{ 106 auto res1 = helper(0); 107 auto res2 = helper(1); 108 auto res3 = helper(2); 109 EXPECT_FALSE(res1); 110 EXPECT_TRUE(res2); 111 EXPECT_FALSE(res3); 112 EXPECT_EQ(res1.Error(), ErrorCode::First); 113 EXPECT_EQ(*res2, 42); 114 EXPECT_EQ(res3.Error(), ErrorCode::Second); 115} 116 117TEST(Expected, ValueOr) 118{ 119 auto res1 = helper(0).ValueOr(1); 120 auto res2 = helper(res1).ValueOr(res1); 121 auto e = Expected<int, ErrorCode>(1); 122 EXPECT_EQ(res1, 1); 123 EXPECT_EQ(res2, 42); 124 EXPECT_EQ(e.ValueOr(0), 1); 125} 126} // namespace panda::test::expected 127