1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <lib/fit/result.h>
6 #include <unittest/unittest.h>
7
8 namespace {
9
10 struct Copyable {
11 int data;
12 };
13
14 struct MoveOnly {
15 MoveOnly(const MoveOnly&) = delete;
16 MoveOnly(MoveOnly&&) = default;
17 MoveOnly& operator=(const MoveOnly&) = delete;
18 MoveOnly& operator=(MoveOnly&&) = default;
19
20 int data;
21 };
22
states()23 bool states() {
24 BEGIN_TEST;
25
26 fit::result<> good = fit::ok();
27 EXPECT_EQ(fit::result_state::ok, good.state());
28 EXPECT_TRUE(good);
29 EXPECT_TRUE(good.is_ok());
30 EXPECT_FALSE(good.is_error());
31 EXPECT_FALSE(good.is_pending());
32
33 fit::result<> bad = fit::error();
34 EXPECT_EQ(fit::result_state::error, bad.state());
35 EXPECT_TRUE(bad);
36 EXPECT_FALSE(bad.is_ok());
37 EXPECT_TRUE(bad.is_error());
38 EXPECT_FALSE(bad.is_pending());
39
40 fit::result<> pending = fit::pending();
41 EXPECT_EQ(fit::result_state::pending, pending.state());
42 EXPECT_FALSE(pending);
43 EXPECT_FALSE(pending.is_ok());
44 EXPECT_FALSE(pending.is_error());
45 EXPECT_TRUE(pending.is_pending());
46
47 fit::result<> default_init;
48 EXPECT_EQ(fit::result_state::pending, default_init.state());
49 EXPECT_FALSE(default_init);
50 EXPECT_FALSE(default_init.is_ok());
51 EXPECT_FALSE(default_init.is_error());
52 EXPECT_TRUE(default_init.is_pending());
53
54 END_TEST;
55 }
56
void_value_and_error()57 bool void_value_and_error() {
58 BEGIN_TEST;
59
60 fit::result<> good = fit::ok();
61 EXPECT_EQ(fit::result_state::ok, good.state());
62
63 fit::result<> bad = fit::error();
64 EXPECT_EQ(fit::result_state::error, bad.state());
65
66 fit::result<> tmpcopy(good);
67 EXPECT_EQ(fit::result_state::ok, tmpcopy.state());
68 EXPECT_EQ(fit::result_state::ok, good.state());
69 tmpcopy = bad;
70 EXPECT_EQ(fit::result_state::error, tmpcopy.state());
71 EXPECT_EQ(fit::result_state::error, bad.state());
72
73 fit::result<> tmpmove(std::move(good));
74 EXPECT_EQ(fit::result_state::ok, tmpmove.state());
75 EXPECT_EQ(fit::result_state::pending, good.state());
76 tmpmove = std::move(bad);
77 EXPECT_EQ(fit::result_state::error, tmpmove.state());
78 EXPECT_EQ(fit::result_state::pending, bad.state());
79
80 fit::result<> tmpsrc = fit::ok();
81 fit::ok_result<> taken_ok_result = tmpsrc.take_ok_result();
82 EXPECT_EQ(fit::result_state::pending, tmpsrc.state());
83 (void)taken_ok_result;
84 tmpsrc = fit::error();
85 fit::error_result<> taken_error_result = tmpsrc.take_error_result();
86 EXPECT_EQ(fit::result_state::pending, tmpsrc.state());
87 (void)taken_error_result;
88
89 END_TEST;
90 }
91
copyable_value()92 bool copyable_value() {
93 BEGIN_TEST;
94
95 fit::result<Copyable> good = fit::ok<Copyable>({42});
96 EXPECT_EQ(fit::result_state::ok, good.state());
97 EXPECT_EQ(42, good.value().data);
98
99 fit::result<Copyable> bad = fit::error();
100 EXPECT_EQ(fit::result_state::error, bad.state());
101
102 fit::result<Copyable> tmpcopy(good);
103 EXPECT_EQ(fit::result_state::ok, tmpcopy.state());
104 EXPECT_EQ(42, tmpcopy.value().data);
105 EXPECT_EQ(fit::result_state::ok, good.state());
106 tmpcopy = bad;
107 EXPECT_EQ(fit::result_state::error, tmpcopy.state());
108 EXPECT_EQ(fit::result_state::error, bad.state());
109
110 fit::result<Copyable> tmpmove(std::move(good));
111 EXPECT_EQ(fit::result_state::ok, tmpmove.state());
112 EXPECT_EQ(fit::result_state::pending, good.state());
113 EXPECT_EQ(42, tmpmove.value().data);
114 tmpmove = std::move(bad);
115 EXPECT_EQ(fit::result_state::error, tmpmove.state());
116 EXPECT_EQ(fit::result_state::pending, bad.state());
117
118 fit::result<Copyable> tmpsrc = fit::ok<Copyable>({42});
119 Copyable taken_value = tmpsrc.take_value();
120 EXPECT_EQ(fit::result_state::pending, tmpsrc.state());
121 EXPECT_EQ(42, taken_value.data);
122 tmpsrc = fit::ok<Copyable>({42});
123 fit::ok_result<Copyable> taken_ok_result = tmpsrc.take_ok_result();
124 EXPECT_EQ(fit::result_state::pending, tmpsrc.state());
125 EXPECT_EQ(42, taken_ok_result.value.data);
126 tmpsrc = fit::error();
127 fit::error_result<> taken_error_result = tmpsrc.take_error_result();
128 EXPECT_EQ(fit::result_state::pending, tmpsrc.state());
129 (void)taken_error_result;
130
131 END_TEST;
132 }
133
copyable_error()134 bool copyable_error() {
135 BEGIN_TEST;
136
137 fit::result<void, Copyable> good = fit::ok();
138 EXPECT_EQ(fit::result_state::ok, good.state());
139
140 fit::result<void, Copyable> bad = fit::error<Copyable>({42});
141 EXPECT_EQ(fit::result_state::error, bad.state());
142 EXPECT_EQ(42, bad.error().data);
143
144 fit::result<void, Copyable> tmpcopy(good);
145 EXPECT_EQ(fit::result_state::ok, tmpcopy.state());
146 EXPECT_EQ(fit::result_state::ok, good.state());
147 tmpcopy = bad;
148 EXPECT_EQ(fit::result_state::error, tmpcopy.state());
149 EXPECT_EQ(fit::result_state::error, bad.state());
150 EXPECT_EQ(42, tmpcopy.error().data);
151
152 fit::result<void, Copyable> tmpmove(std::move(good));
153 EXPECT_EQ(fit::result_state::ok, tmpmove.state());
154 EXPECT_EQ(fit::result_state::pending, good.state());
155 tmpmove = std::move(bad);
156 EXPECT_EQ(fit::result_state::error, tmpmove.state());
157 EXPECT_EQ(fit::result_state::pending, bad.state());
158 EXPECT_EQ(42, tmpmove.error().data);
159
160 fit::result<void, Copyable> tmpsrc = fit::ok();
161 fit::ok_result<> taken_ok_result = tmpsrc.take_ok_result();
162 EXPECT_EQ(fit::result_state::pending, tmpsrc.state());
163 (void)taken_ok_result;
164 tmpsrc = fit::error<Copyable>({42});
165 Copyable taken_error = tmpsrc.take_error();
166 EXPECT_EQ(fit::result_state::pending, tmpsrc.state());
167 EXPECT_EQ(42, taken_error.data);
168 tmpsrc = fit::error<Copyable>({42});
169 fit::error_result<Copyable> taken_error_result = tmpsrc.take_error_result();
170 EXPECT_EQ(fit::result_state::pending, tmpsrc.state());
171 EXPECT_EQ(42, taken_error_result.error.data);
172
173 END_TEST;
174 }
175
moveonly_value()176 bool moveonly_value() {
177 BEGIN_TEST;
178
179 fit::result<MoveOnly> good = fit::ok<MoveOnly>({42});
180 EXPECT_EQ(fit::result_state::ok, good.state());
181 EXPECT_EQ(42, good.value().data);
182
183 fit::result<MoveOnly> bad = fit::error();
184 EXPECT_EQ(fit::result_state::error, bad.state());
185
186 fit::result<MoveOnly> tmpmove(std::move(good));
187 EXPECT_EQ(fit::result_state::ok, tmpmove.state());
188 EXPECT_EQ(42, tmpmove.value().data);
189 EXPECT_EQ(fit::result_state::pending, good.state());
190 tmpmove = std::move(bad);
191 EXPECT_EQ(fit::result_state::error, tmpmove.state());
192 EXPECT_EQ(fit::result_state::pending, bad.state());
193
194 fit::result<MoveOnly> tmpsrc = fit::ok<MoveOnly>({42});
195 MoveOnly taken_value = tmpsrc.take_value();
196 EXPECT_EQ(fit::result_state::pending, tmpsrc.state());
197 EXPECT_EQ(42, taken_value.data);
198 tmpsrc = fit::ok<MoveOnly>({42});
199 fit::ok_result<MoveOnly> taken_ok_result = tmpsrc.take_ok_result();
200 EXPECT_EQ(fit::result_state::pending, tmpsrc.state());
201 EXPECT_EQ(42, taken_ok_result.value.data);
202 tmpsrc = fit::error();
203 fit::error_result<> taken_error_result = tmpsrc.take_error_result();
204 EXPECT_EQ(fit::result_state::pending, tmpsrc.state());
205 (void)taken_error_result;
206
207 END_TEST;
208 }
209
moveonly_error()210 bool moveonly_error() {
211 BEGIN_TEST;
212
213 fit::result<void, MoveOnly> good = fit::ok();
214 EXPECT_EQ(fit::result_state::ok, good.state());
215
216 fit::result<void, MoveOnly> bad = fit::error<MoveOnly>({42});
217 EXPECT_EQ(fit::result_state::error, bad.state());
218 EXPECT_EQ(42, bad.error().data);
219
220 fit::result<void, MoveOnly> tmpmove(std::move(good));
221 EXPECT_EQ(fit::result_state::ok, tmpmove.state());
222 EXPECT_EQ(fit::result_state::pending, good.state());
223 tmpmove = std::move(bad);
224 EXPECT_EQ(fit::result_state::error, tmpmove.state());
225 EXPECT_EQ(fit::result_state::pending, bad.state());
226 EXPECT_EQ(42, tmpmove.error().data);
227
228 fit::result<void, MoveOnly> tmpsrc = fit::ok();
229 fit::ok_result<> taken_ok_result = tmpsrc.take_ok_result();
230 EXPECT_EQ(fit::result_state::pending, tmpsrc.state());
231 (void)taken_ok_result;
232 tmpsrc = fit::error<MoveOnly>({42});
233 MoveOnly taken_error = tmpsrc.take_error();
234 EXPECT_EQ(fit::result_state::pending, tmpsrc.state());
235 EXPECT_EQ(42, taken_error.data);
236 tmpsrc = fit::error<MoveOnly>({42});
237 fit::error_result<MoveOnly> taken_error_result = tmpsrc.take_error_result();
238 EXPECT_EQ(fit::result_state::pending, tmpsrc.state());
239 EXPECT_EQ(42, taken_error_result.error.data);
240
241 END_TEST;
242 }
243
swapping()244 bool swapping() {
245 BEGIN_TEST;
246
247 fit::result<int, char> a, b, c;
248 a = fit::ok(42);
249 b = fit::error('x');
250
251 a.swap(b);
252 EXPECT_EQ('x', a.error());
253 EXPECT_EQ(42, b.value());
254
255 swap(b, c);
256 EXPECT_EQ(42, c.value());
257 EXPECT_TRUE(b.is_pending());
258
259 swap(c, c);
260 EXPECT_EQ(42, c.value());
261
262 END_TEST;
263 }
264
265 // Test constexpr behavior.
266 namespace constexpr_test {
267 static_assert(fit::ok(1).value == 1, "");
268 static_assert(fit::error(1).error == 1, "");
269 static_assert(fit::result<>().state() == fit::result_state::pending, "");
270 static_assert(fit::result<>().is_pending(), "");
271 static_assert(!fit::result<>().is_ok(), "");
272 static_assert(!fit::result<>(), "");
273 static_assert(!fit::result<>().is_error(), "");
274 static_assert(fit::result<>(fit::pending()).state() == fit::result_state::pending, "");
275 static_assert(fit::result<>(fit::pending()).is_pending(), "");
276 static_assert(!fit::result<>(fit::pending()).is_ok(), "");
277 static_assert(!fit::result<>(fit::pending()), "");
278 static_assert(!fit::result<>(fit::pending()).is_error(), "");
279 static_assert(fit::result<>(fit::ok()).state() == fit::result_state::ok, "");
280 static_assert(!fit::result<>(fit::ok()).is_pending(), "");
281 static_assert(fit::result<>(fit::ok()).is_ok(), "");
282 static_assert(fit::result<>(fit::ok()), "");
283 static_assert(!fit::result<>(fit::ok()).is_error(), "");
284 static_assert(fit::result<int>(fit::ok(1)).state() == fit::result_state::ok, "");
285 static_assert(!fit::result<int>(fit::ok(1)).is_pending(), "");
286 static_assert(fit::result<int>(fit::ok(1)).is_ok(), "");
287 static_assert(fit::result<int>(fit::ok(1)), "");
288 static_assert(!fit::result<int>(fit::ok(1)).is_error(), "");
289 static_assert(fit::result<int>(fit::ok(1)).value() == 1, "");
290 static_assert(fit::result<>(fit::error()).state() == fit::result_state::error, "");
291 static_assert(!fit::result<>(fit::error()).is_pending(), "");
292 static_assert(!fit::result<>(fit::error()).is_ok(), "");
293 static_assert(fit::result<>(fit::error()), "");
294 static_assert(fit::result<>(fit::error()).is_error(), "");
295 static_assert(fit::result<void, int>(fit::error(1)).state() == fit::result_state::error, "");
296 static_assert(!fit::result<void, int>(fit::error(1)).is_pending(), "");
297 static_assert(!fit::result<void, int>(fit::error(1)).is_ok(), "");
298 static_assert(fit::result<void, int>(fit::error(1)), "");
299 static_assert(fit::result<void, int>(fit::error(1)).is_error(), "");
300 static_assert(fit::result<void, int>(fit::error(1)).error() == 1, "");
301 } // namespace constexpr_test
302 } // namespace
303
304 BEGIN_TEST_CASE(result_tests)
305 RUN_TEST(states)
306 RUN_TEST(void_value_and_error)
307 RUN_TEST(copyable_value)
308 RUN_TEST(copyable_error)
309 RUN_TEST(moveonly_value)
310 RUN_TEST(moveonly_error)
311 RUN_TEST(swapping)
312 END_TEST_CASE(result_tests)
313