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
22 namespace panda::test::expected {
23
24 enum class ErrorCode { First, Second };
25
helper(int v)26 static 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
38 struct Default {
39 int v;
40 };
41
42 struct NonDefaultConstructible {
43 NonDefaultConstructible() = delete;
44 };
45
TEST(Expected, Unexpected)46 TEST(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
TEST(Expected, Ctor)55 TEST(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
TEST(Expected, Access)80 TEST(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
TEST(Expected, Assignment)92 TEST(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
TEST(Expected, Basic)104 TEST(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
TEST(Expected, ValueOr)117 TEST(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