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