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 <functional>
6 
7 #include <lib/fit/promise.h>
8 #include <lib/fit/single_threaded_executor.h>
9 #include <unittest/unittest.h>
10 
11 #include "examples/utils.h"
12 #include "unittest_utils.h"
13 
14 namespace {
15 
16 class fake_context : public fit::context {
17 public:
executor() const18     fit::executor* executor() const override {
19         ASSERT_CRITICAL(false);
20     }
suspend_task()21     fit::suspended_task suspend_task() override {
22         ASSERT_CRITICAL(false);
23     }
24 };
25 
26 template <typename V = void, typename E = void>
27 class capture_result_wrapper {
28 public:
29     template <typename Promise>
wrap(Promise promise)30     decltype(auto) wrap(Promise promise) {
31         static_assert(std::is_same<V, typename Promise::value_type>::value, "");
32         static_assert(std::is_same<E, typename Promise::error_type>::value, "");
33         ASSERT_CRITICAL(promise);
34         return promise.then([this](fit::result<V, E>& result) {
35             last_result = std::move(result);
36         });
37     }
38 
39     fit::result<V, E> last_result;
40 };
41 
42 struct move_only {
43     move_only(const move_only&) = delete;
44     move_only(move_only&&) = default;
45     move_only& operator=(const move_only&) = delete;
46     move_only& operator=(move_only&&) = default;
47 };
48 
49 // Just a simple test to put the promise through its paces.
50 // Other tests go into more detail to cover the API surface.
basics()51 bool basics() {
52     BEGIN_TEST;
53 
54     for (int i = 0; i < 5; i++) {
55         // Make a promise that calculates half the square of a number.
56         // Produces an error if the square is odd.
57         auto promise =
58             fit::make_promise([i] {
59                 // Pretend that squaring numbers is hard and takes time
60                 // to finish...
61                 return utils::sleep_for_a_little_while()
62                     .then([i](fit::result<>) {
63                         return fit::ok(i * i);
64                     });
65             }).then([](fit::result<int> square) -> fit::result<int, const char*> {
66                 if (square.value() % 2 == 0)
67                     return fit::ok(square.value() / 2);
68                 return fit::error("square is odd");
69             });
70 
71         // Evaluate the promise.
72         fit::result<int, const char*> result =
73             fit::run_single_threaded(std::move(promise));
74         if (i % 2 == 0) {
75             EXPECT_TRUE(result.is_ok());
76             EXPECT_EQ(i * i / 2, result.value());
77         } else {
78             EXPECT_TRUE(result.is_error());
79             EXPECT_STR_EQ("square is odd", result.error());
80         }
81     }
82 
83     END_TEST;
84 }
85 
86 // An empty promise has no continuation.
87 // We can't do a lot with it but we can check for emptyness.
empty_promise()88 bool empty_promise() {
89     BEGIN_TEST;
90 
91     {
92         fit::promise<> promise;
93         EXPECT_FALSE(promise);
94     }
95 
96     {
97         fit::promise<> promise(nullptr);
98         EXPECT_FALSE(promise);
99     }
100 
101     {
102         fit::function<fit::result<>(fit::context&)> f;
103         fit::promise<> promise(std::move(f));
104         EXPECT_FALSE(promise);
105     }
106 
107     {
108         std::function<fit::result<>(fit::context&)> f;
109         fit::promise<> promise(std::move(f));
110         EXPECT_FALSE(promise);
111     }
112 
113     END_TEST;
114 }
115 
invocation()116 bool invocation() {
117     BEGIN_TEST;
118 
119     uint64_t run_count = 0;
120     fake_context fake_context;
121     fit::promise<> promise([&](fit::context& context) -> fit::result<> {
122         ASSERT_CRITICAL(&context == &fake_context);
123         if (++run_count == 2)
124             return fit::ok();
125         return fit::pending();
126     });
127     EXPECT_TRUE(promise);
128 
129     fit::result<> result = promise(fake_context);
130     EXPECT_EQ(1, run_count);
131     EXPECT_EQ(fit::result_state::pending, result.state());
132     EXPECT_TRUE(promise);
133 
134     result = promise(fake_context);
135     EXPECT_EQ(2, run_count);
136     EXPECT_EQ(fit::result_state::ok, result.state());
137     EXPECT_FALSE(promise);
138 
139     END_TEST;
140 }
141 
take_continuation()142 bool take_continuation() {
143     BEGIN_TEST;
144 
145     uint64_t run_count = 0;
146     fake_context fake_context;
147     fit::promise<> promise([&](fit::context& context) -> fit::result<> {
148         ASSERT_CRITICAL(&context == &fake_context);
149         run_count++;
150         return fit::pending();
151     });
152     EXPECT_TRUE(promise);
153 
154     fit::function<fit::result<>(fit::context&)> f = promise.take_continuation();
155     EXPECT_FALSE(promise);
156     EXPECT_EQ(0, run_count);
157 
158     fit::result<> result = f(fake_context);
159     EXPECT_EQ(1, run_count);
160     EXPECT_EQ(fit::result_state::pending, result.state());
161 
162     END_TEST;
163 }
164 
assignment_and_swap()165 bool assignment_and_swap() {
166     BEGIN_TEST;
167 
168     fake_context fake_context;
169 
170     fit::promise<> empty;
171     EXPECT_FALSE(empty);
172 
173     uint64_t run_count = 0;
174     fit::promise<> promise([&](fit::context& context) -> fit::result<> {
175         run_count++;
176         return fit::pending();
177     });
178     EXPECT_TRUE(promise);
179 
180     fit::promise<> x(std::move(empty));
181     EXPECT_FALSE(x);
182 
183     fit::promise<> y(std::move(promise));
184     EXPECT_TRUE(y);
185     y(fake_context);
186     EXPECT_EQ(1, run_count);
187 
188     x.swap(y);
189     EXPECT_TRUE(x);
190     EXPECT_FALSE(y);
191     x(fake_context);
192     EXPECT_EQ(2, run_count);
193 
194     x.swap(x);
195     EXPECT_TRUE(x);
196     x(fake_context);
197     EXPECT_EQ(3, run_count);
198 
199     y.swap(y);
200     EXPECT_FALSE(y);
201 
202     x = nullptr;
203     EXPECT_FALSE(x);
204 
205     y = [&](fit::context& context) -> fit::result<> {
206         run_count *= 2;
207         return fit::pending();
208     };
209     EXPECT_TRUE(y);
210     y(fake_context);
211     EXPECT_EQ(6, run_count);
212 
213     x = std::move(y);
214     EXPECT_TRUE(x);
215     EXPECT_FALSE(y);
216     x(fake_context);
217     EXPECT_EQ(12, run_count);
218 
219     x = std::move(y);
220     EXPECT_FALSE(x);
221 
222     END_TEST;
223 }
224 
comparison_with_nullptr()225 bool comparison_with_nullptr() {
226     BEGIN_TEST;
227 
228     {
229         fit::promise<> promise;
230         EXPECT_TRUE(promise == nullptr);
231         EXPECT_TRUE(nullptr == promise);
232         EXPECT_FALSE(promise != nullptr);
233         EXPECT_FALSE(nullptr != promise);
234     }
235 
236     {
237         fit::promise<> promise([&](fit::context& context) -> fit::result<> {
238             return fit::pending();
239         });
240         EXPECT_FALSE(promise == nullptr);
241         EXPECT_FALSE(nullptr == promise);
242         EXPECT_TRUE(promise != nullptr);
243         EXPECT_TRUE(nullptr != promise);
244     }
245 
246     END_TEST;
247 }
248 
make_promise()249 bool make_promise() {
250     BEGIN_TEST;
251 
252     fake_context fake_context;
253 
254     // Handler signature: void().
255     {
256         uint64_t run_count = 0;
257         auto p = fit::make_promise([&] {
258             run_count++;
259         });
260         static_assert(std::is_same<void, decltype(p)::value_type>::value, "");
261         static_assert(std::is_same<void, decltype(p)::error_type>::value, "");
262         fit::result<> result = p(fake_context);
263         EXPECT_EQ(1, run_count);
264         EXPECT_EQ(fit::result_state::ok, result.state());
265         EXPECT_FALSE(p);
266     }
267 
268     // Handler signature: fit::result<int, char>().
269     {
270         uint64_t run_count = 0;
271         auto p = fit::make_promise([&]() -> fit::result<int, char> {
272             run_count++;
273             return fit::ok(42);
274         });
275         static_assert(std::is_same<int, decltype(p)::value_type>::value, "");
276         static_assert(std::is_same<char, decltype(p)::error_type>::value, "");
277         fit::result<int, char> result = p(fake_context);
278         EXPECT_EQ(1, run_count);
279         EXPECT_EQ(fit::result_state::ok, result.state());
280         EXPECT_EQ(42, result.value());
281         EXPECT_FALSE(p);
282     }
283 
284     // Handler signature: fit::ok<int>().
285     {
286         uint64_t run_count = 0;
287         auto p = fit::make_promise([&] {
288             run_count++;
289             return fit::ok(42);
290         });
291         static_assert(std::is_same<int, decltype(p)::value_type>::value, "");
292         static_assert(std::is_same<void, decltype(p)::error_type>::value, "");
293         fit::result<int, void> result = p(fake_context);
294         EXPECT_EQ(1, run_count);
295         EXPECT_EQ(fit::result_state::ok, result.state());
296         EXPECT_EQ(42, result.value());
297         EXPECT_FALSE(p);
298     }
299 
300     // Handler signature: fit::error<int>().
301     {
302         uint64_t run_count = 0;
303         auto p = fit::make_promise([&] {
304             run_count++;
305             return fit::error(42);
306         });
307         static_assert(std::is_same<void, decltype(p)::value_type>::value, "");
308         static_assert(std::is_same<int, decltype(p)::error_type>::value, "");
309         fit::result<void, int> result = p(fake_context);
310         EXPECT_EQ(1, run_count);
311         EXPECT_EQ(fit::result_state::error, result.state());
312         EXPECT_EQ(42, result.error());
313         EXPECT_FALSE(p);
314     }
315 
316     // Handler signature: fit::pending().
317     {
318         uint64_t run_count = 0;
319         auto p = fit::make_promise([&] {
320             run_count++;
321             return fit::pending();
322         });
323         static_assert(std::is_same<void, decltype(p)::value_type>::value, "");
324         static_assert(std::is_same<void, decltype(p)::error_type>::value, "");
325         fit::result<> result = p(fake_context);
326         EXPECT_EQ(1, run_count);
327         EXPECT_EQ(fit::result_state::pending, result.state());
328         EXPECT_TRUE(p);
329     }
330 
331     // Handler signature: fit::promise_impl<...>.
332     {
333         uint64_t run_count = 0;
334         uint64_t run_count2 = 0;
335         auto p = fit::make_promise([&] {
336             run_count++;
337             return fit::make_promise([&]() -> fit::result<int, char> {
338                 if (++run_count2 == 2)
339                     return fit::ok(42);
340                 return fit::pending();
341             });
342         });
343         static_assert(std::is_same<int, decltype(p)::value_type>::value, "");
344         static_assert(std::is_same<char, decltype(p)::error_type>::value, "");
345         fit::result<int, char> result = p(fake_context);
346         EXPECT_EQ(1, run_count);
347         EXPECT_EQ(1, run_count2);
348         EXPECT_EQ(fit::result_state::pending, result.state());
349         EXPECT_TRUE(p);
350         result = p(fake_context);
351         EXPECT_EQ(1, run_count);
352         EXPECT_EQ(2, run_count2);
353         EXPECT_EQ(fit::result_state::ok, result.state());
354         EXPECT_EQ(42, result.value());
355         EXPECT_FALSE(p);
356     }
357 
358     // Handler signature: void(context&).
359     {
360         uint64_t run_count = 0;
361         auto p = fit::make_promise([&](fit::context& context) {
362             ASSERT_CRITICAL(&context == &fake_context);
363             run_count++;
364         });
365         static_assert(std::is_same<void, decltype(p)::value_type>::value, "");
366         static_assert(std::is_same<void, decltype(p)::error_type>::value, "");
367         fit::result<> result = p(fake_context);
368         EXPECT_EQ(1, run_count);
369         EXPECT_EQ(fit::result_state::ok, result.state());
370         EXPECT_FALSE(p);
371     }
372 
373     END_TEST;
374 }
375 
376 // This is a bit lower level than fit::make_promise() in that there's
377 // no automatic adaptation of the handler type.
make_promise_with_continuation()378 bool make_promise_with_continuation() {
379     BEGIN_TEST;
380 
381     uint64_t run_count = 0;
382     fake_context fake_context;
383     auto p = fit::make_promise_with_continuation(
384         [&](fit::context& context) -> fit::result<int, char> {
385             ASSERT_CRITICAL(&context == &fake_context);
386             run_count++;
387             return fit::ok(42);
388         });
389     static_assert(std::is_same<int, decltype(p)::value_type>::value, "");
390     static_assert(std::is_same<char, decltype(p)::error_type>::value, "");
391     EXPECT_TRUE(p);
392 
393     fit::result<int, char> result = p(fake_context);
394     EXPECT_EQ(1, run_count);
395     EXPECT_EQ(fit::result_state::ok, result.state());
396     EXPECT_EQ(42, result.value());
397     EXPECT_FALSE(p);
398 
399     END_TEST;
400 }
401 
make_ok_promise(int value)402 auto make_ok_promise(int value) {
403     return fit::make_promise([value, count = 0]() mutable -> fit::result<int, char> {
404         ASSERT_CRITICAL(count == 0);
405         ++count;
406         return fit::ok(value);
407     });
408 }
409 
make_error_promise(char error)410 auto make_error_promise(char error) {
411     return fit::make_promise([error, count = 0]() mutable -> fit::result<int, char> {
412         ASSERT_CRITICAL(count == 0);
413         ++count;
414         return fit::error(error);
415     });
416 }
417 
make_delayed_ok_promise(int value)418 auto make_delayed_ok_promise(int value) {
419     return fit::make_promise([value, count = 0]() mutable -> fit::result<int, char> {
420         ASSERT_CRITICAL(count <= 1);
421         if (++count == 2)
422             return fit::ok(value);
423         return fit::pending();
424     });
425 }
426 
make_delayed_error_promise(char error)427 auto make_delayed_error_promise(char error) {
428     return fit::make_promise([error, count = 0]() mutable -> fit::result<int, char> {
429         ASSERT_CRITICAL(count <= 1);
430         if (++count == 2)
431             return fit::error(error);
432         return fit::pending();
433     });
434 }
435 
436 // To keep these tests manageable, we only focus on argument type adaptation
437 // since return type adaptation logic is already covered by |make_promise()|
438 // and by the examples.
then_combinator()439 bool then_combinator() {
440     BEGIN_TEST;
441 
442     fake_context fake_context;
443 
444     // Chaining on OK.
445     // Handler signature: fit::result<>(fit::result<int, char>).
446     {
447         uint64_t run_count = 0;
448         auto p =
449             make_delayed_ok_promise(42)
450                 .then([&](fit::result<int, char> result) -> fit::result<> {
451                     ASSERT_CRITICAL(result.value() == 42);
452                     if (++run_count == 2)
453                         return fit::ok();
454                     return fit::pending();
455                 });
456 
457         fit::result<> result = p(fake_context);
458         EXPECT_TRUE(p);
459         EXPECT_EQ(0, run_count);
460         EXPECT_EQ(fit::result_state::pending, result.state());
461 
462         result = p(fake_context);
463         EXPECT_TRUE(p);
464         EXPECT_EQ(1, run_count);
465         EXPECT_EQ(fit::result_state::pending, result.state());
466 
467         result = p(fake_context);
468         EXPECT_FALSE(p);
469         EXPECT_EQ(2, run_count);
470         EXPECT_EQ(fit::result_state::ok, result.state());
471     }
472 
473     // Chaining on ERROR.
474     // Handler signature: fit::result<>(fit::result<int, char>).
475     {
476         uint64_t run_count = 0;
477         auto p =
478             make_delayed_error_promise('x')
479                 .then([&](fit::result<int, char> result) -> fit::result<> {
480                     ASSERT_CRITICAL(result.error() == 'x');
481                     if (++run_count == 2)
482                         return fit::ok();
483                     return fit::pending();
484                 });
485 
486         fit::result<> result = p(fake_context);
487         EXPECT_TRUE(p);
488         EXPECT_EQ(0, run_count);
489         EXPECT_EQ(fit::result_state::pending, result.state());
490 
491         result = p(fake_context);
492         EXPECT_TRUE(p);
493         EXPECT_EQ(1, run_count);
494         EXPECT_EQ(fit::result_state::pending, result.state());
495 
496         result = p(fake_context);
497         EXPECT_FALSE(p);
498         EXPECT_EQ(2, run_count);
499         EXPECT_EQ(fit::result_state::ok, result.state());
500     }
501 
502     // Cover all handler argument signatures, more briefly.
503     {
504         uint64_t run_count = 0;
505         auto p =
506             make_ok_promise(42)
507                 .then([&](fit::result<int, char> result)
508                           -> fit::result<int, char> {
509                     run_count++;
510                     return fit::ok(result.value() + 1);
511                 })
512                 .then([&](fit::result<int, char>& result)
513                           -> fit::result<int, char> {
514                     run_count++;
515                     return fit::ok(result.value() + 1);
516                 })
517                 .then([&](const fit::result<int, char>& result)
518                           -> fit::result<int, char> {
519                     run_count++;
520                     return fit::ok(result.value() + 1);
521                 })
522                 .then([&](fit::context& context, fit::result<int, char> result)
523                           -> fit::result<int, char> {
524                     ASSERT_CRITICAL(&context == &fake_context);
525                     run_count++;
526                     return fit::ok(result.value() + 1);
527                 })
528                 .then([&](fit::context& context, fit::result<int, char>& result)
529                           -> fit::result<int, char> {
530                     ASSERT_CRITICAL(&context == &fake_context);
531                     run_count++;
532                     return fit::ok(result.value() + 1);
533                 })
534                 .then([&](fit::context& context, const fit::result<int, char>& result)
535                           -> fit::result<int, char> {
536                     ASSERT_CRITICAL(&context == &fake_context);
537                     run_count++;
538                     return fit::ok(result.value() + 1);
539                 });
540 
541         fit::result<int, char> result = p(fake_context);
542         EXPECT_FALSE(p);
543         EXPECT_EQ(6, run_count);
544         EXPECT_EQ(fit::result_state::ok, result.state());
545         EXPECT_EQ(48, result.value());
546     }
547 
548     END_TEST;
549 }
550 
and_then_combinator()551 bool and_then_combinator() {
552     BEGIN_TEST;
553 
554     fake_context fake_context;
555 
556     // Chaining on OK.
557     // Handler signature: fit::result<>(int).
558     {
559         uint64_t run_count = 0;
560         auto p =
561             make_delayed_ok_promise(42)
562                 .and_then([&](int value) -> fit::result<void, char> {
563                     ASSERT_CRITICAL(value == 42);
564                     if (++run_count == 2)
565                         return fit::error('y');
566                     return fit::pending();
567                 });
568 
569         fit::result<void, char> result = p(fake_context);
570         EXPECT_TRUE(p);
571         EXPECT_EQ(0, run_count);
572         EXPECT_EQ(fit::result_state::pending, result.state());
573 
574         result = p(fake_context);
575         EXPECT_TRUE(p);
576         EXPECT_EQ(1, run_count);
577         EXPECT_EQ(fit::result_state::pending, result.state());
578 
579         result = p(fake_context);
580         EXPECT_FALSE(p);
581         EXPECT_EQ(2, run_count);
582         EXPECT_EQ(fit::result_state::error, result.state());
583         EXPECT_EQ('y', result.error());
584     }
585 
586     // Chaining on ERROR.
587     // Handler signature: fit::result<>(int).
588     {
589         uint64_t run_count = 0;
590         auto p =
591             make_delayed_error_promise('x')
592                 .and_then([&](int value) -> fit::result<void, char> {
593                     run_count++;
594                     return fit::pending();
595                 });
596 
597         fit::result<void, char> result = p(fake_context);
598         EXPECT_TRUE(p);
599         EXPECT_EQ(0, run_count);
600         EXPECT_EQ(fit::result_state::pending, result.state());
601 
602         result = p(fake_context);
603         EXPECT_FALSE(p);
604         EXPECT_EQ(0, run_count);
605         EXPECT_EQ(fit::result_state::error, result.state());
606         EXPECT_EQ('x', result.error());
607     }
608 
609     // Cover all handler argument signatures, more briefly.
610     {
611         uint64_t run_count = 0;
612         auto p =
613             make_ok_promise(42)
614                 .and_then([&](int value)
615                               -> fit::result<int, char> {
616                     run_count++;
617                     return fit::ok(value + 1);
618                 })
619                 .and_then([&](int& value)
620                               -> fit::result<int, char> {
621                     run_count++;
622                     return fit::ok(value + 1);
623                 })
624                 .and_then([&](const int& value)
625                               -> fit::result<int, char> {
626                     run_count++;
627                     return fit::ok(value + 1);
628                 })
629                 .and_then([&](fit::context& context, int value)
630                               -> fit::result<int, char> {
631                     ASSERT_CRITICAL(&context == &fake_context);
632                     run_count++;
633                     return fit::ok(value + 1);
634                 })
635                 .and_then([&](fit::context& context, int& value)
636                               -> fit::result<int, char> {
637                     ASSERT_CRITICAL(&context == &fake_context);
638                     run_count++;
639                     return fit::ok(value + 1);
640                 })
641                 .and_then([&](fit::context& context, const int& value)
642                               -> fit::result<int, char> {
643                     ASSERT_CRITICAL(&context == &fake_context);
644                     run_count++;
645                     return fit::ok(value + 1);
646                 });
647 
648         fit::result<int, char> result = p(fake_context);
649         EXPECT_EQ(6, run_count);
650         EXPECT_EQ(fit::result_state::ok, result.state());
651         EXPECT_EQ(48, result.value());
652         EXPECT_FALSE(p);
653     }
654 
655     END_TEST;
656 }
657 
or_else_combinator()658 bool or_else_combinator() {
659     BEGIN_TEST;
660 
661     fake_context fake_context;
662 
663     // Chaining on OK.
664     // Handler signature: fit::result<>(char).
665     {
666         uint64_t run_count = 0;
667         auto p =
668             make_delayed_ok_promise(42)
669                 .or_else([&](char error) -> fit::result<int> {
670                     run_count++;
671                     return fit::pending();
672                 });
673 
674         fit::result<int> result = p(fake_context);
675         EXPECT_TRUE(p);
676         EXPECT_EQ(0, run_count);
677         EXPECT_EQ(fit::result_state::pending, result.state());
678 
679         result = p(fake_context);
680         EXPECT_FALSE(p);
681         EXPECT_EQ(0, run_count);
682         EXPECT_EQ(fit::result_state::ok, result.state());
683         EXPECT_EQ(42, result.value());
684     }
685 
686     // Chaining on ERROR.
687     // Handler signature: fit::result<>(char).
688     {
689         uint64_t run_count = 0;
690         auto p =
691             make_delayed_error_promise('x')
692                 .or_else([&](char error) -> fit::result<int> {
693                     ASSERT_CRITICAL(error == 'x');
694                     if (++run_count == 2)
695                         return fit::ok(43);
696                     return fit::pending();
697                 });
698 
699         fit::result<int> result = p(fake_context);
700         EXPECT_TRUE(p);
701         EXPECT_EQ(0, run_count);
702         EXPECT_EQ(fit::result_state::pending, result.state());
703 
704         result = p(fake_context);
705         EXPECT_TRUE(p);
706         EXPECT_EQ(1, run_count);
707         EXPECT_EQ(fit::result_state::pending, result.state());
708 
709         result = p(fake_context);
710         EXPECT_FALSE(p);
711         EXPECT_EQ(2, run_count);
712         EXPECT_EQ(fit::result_state::ok, result.state());
713         EXPECT_EQ(43, result.value());
714     }
715 
716     // Cover all handler argument signatures, more briefly.
717     {
718         uint64_t run_count = 0;
719         auto p =
720             make_error_promise('a')
721                 .or_else([&](char error)
722                              -> fit::result<int, char> {
723                     run_count++;
724                     return fit::error(error + 1);
725                 })
726                 .or_else([&](char& error)
727                              -> fit::result<int, char> {
728                     run_count++;
729                     return fit::error(error + 1);
730                 })
731                 .or_else([&](const char& error)
732                              -> fit::result<int, char> {
733                     run_count++;
734                     return fit::error(error + 1);
735                 })
736                 .or_else([&](fit::context& context, char error)
737                              -> fit::result<int, char> {
738                     ASSERT_CRITICAL(&context == &fake_context);
739                     run_count++;
740                     return fit::error(error + 1);
741                 })
742                 .or_else([&](fit::context& context, char& error)
743                              -> fit::result<int, char> {
744                     ASSERT_CRITICAL(&context == &fake_context);
745                     run_count++;
746                     return fit::error(error + 1);
747                 })
748                 .or_else([&](fit::context& context, const char& error)
749                              -> fit::result<int, char> {
750                     ASSERT_CRITICAL(&context == &fake_context);
751                     run_count++;
752                     return fit::error(error + 1);
753                 });
754 
755         fit::result<int, char> result = p(fake_context);
756         EXPECT_EQ(6, run_count);
757         EXPECT_EQ(fit::result_state::error, result.state());
758         EXPECT_EQ('g', result.error());
759         EXPECT_FALSE(p);
760     }
761 
762     END_TEST;
763 }
764 
inspect_combinator()765 bool inspect_combinator() {
766     BEGIN_TEST;
767 
768     fake_context fake_context;
769 
770     // Chaining on OK.
771     // Handler signature: void(fit::result<int, char>).
772     {
773         uint64_t run_count = 0;
774         auto p =
775             make_delayed_ok_promise(42)
776                 .inspect([&](fit::result<int, char> result) {
777                     ASSERT_CRITICAL(result.value() == 42);
778                     run_count++;
779                 });
780 
781         fit::result<int, char> result = p(fake_context);
782         EXPECT_TRUE(p);
783         EXPECT_EQ(0, run_count);
784         EXPECT_EQ(fit::result_state::pending, result.state());
785 
786         result = p(fake_context);
787         EXPECT_FALSE(p);
788         EXPECT_EQ(1, run_count);
789         EXPECT_EQ(fit::result_state::ok, result.state());
790         EXPECT_EQ(42, result.value());
791     }
792 
793     // Chaining on ERROR.
794     // Handler signature: void(fit::result<int, char>).
795     {
796         uint64_t run_count = 0;
797         auto p =
798             make_delayed_error_promise('x')
799                 .inspect([&](fit::result<int, char> result) {
800                     ASSERT_CRITICAL(result.error() == 'x');
801                     run_count++;
802                 });
803 
804         fit::result<int, char> result = p(fake_context);
805         EXPECT_TRUE(p);
806         EXPECT_EQ(0, run_count);
807         EXPECT_EQ(fit::result_state::pending, result.state());
808 
809         result = p(fake_context);
810         EXPECT_FALSE(p);
811         EXPECT_EQ(1, run_count);
812         EXPECT_EQ(fit::result_state::error, result.state());
813         EXPECT_EQ('x', result.error());
814     }
815 
816     // Cover all handler argument signatures, more briefly.
817     {
818         uint64_t run_count = 0;
819         auto p =
820             make_ok_promise(42)
821                 .inspect([&](fit::result<int, char> result) {
822                     ASSERT_CRITICAL(result.value() == 42);
823                     run_count++;
824                 })
825                 .inspect([&](fit::result<int, char>& result) {
826                     ASSERT_CRITICAL(result.value() == 42);
827                     run_count++;
828                     result = fit::ok(result.value() + 1);
829                 })
830                 .inspect([&](const fit::result<int, char>& result) {
831                     ASSERT_CRITICAL(result.value() == 43);
832                     run_count++;
833                 })
834                 .inspect([&](fit::context& context, fit::result<int, char> result) {
835                     ASSERT_CRITICAL(result.value() == 43);
836                     ASSERT_CRITICAL(&context == &fake_context);
837                     run_count++;
838                 })
839                 .inspect([&](fit::context& context, fit::result<int, char>& result) {
840                     ASSERT_CRITICAL(result.value() == 43);
841                     ASSERT_CRITICAL(&context == &fake_context);
842                     run_count++;
843                     result = fit::ok(result.value() + 1);
844                 })
845                 .inspect([&](fit::context& context, const fit::result<int, char>& result) {
846                     ASSERT_CRITICAL(result.value() == 44);
847                     ASSERT_CRITICAL(&context == &fake_context);
848                     run_count++;
849                 });
850 
851         fit::result<int, char> result = p(fake_context);
852         EXPECT_FALSE(p);
853         EXPECT_EQ(6, run_count);
854         EXPECT_EQ(fit::result_state::ok, result.state());
855         EXPECT_EQ(44, result.value());
856     }
857 
858     END_TEST;
859 }
860 
discard_result_combinator()861 bool discard_result_combinator() {
862     BEGIN_TEST;
863 
864     fake_context fake_context;
865 
866     // Chaining on OK.
867     {
868         auto p = make_delayed_ok_promise(42).discard_result();
869         static_assert(std::is_same<void, decltype(p)::value_type>::value, "");
870         static_assert(std::is_same<void, decltype(p)::error_type>::value, "");
871 
872         fit::result<> result = p(fake_context);
873         EXPECT_TRUE(p);
874         EXPECT_EQ(fit::result_state::pending, result.state());
875 
876         result = p(fake_context);
877         EXPECT_FALSE(p);
878         EXPECT_EQ(fit::result_state::ok, result.state());
879     }
880 
881     // Chaining on ERROR.
882     {
883         auto p = make_delayed_error_promise('x').discard_result();
884         static_assert(std::is_same<void, decltype(p)::value_type>::value, "");
885         static_assert(std::is_same<void, decltype(p)::error_type>::value, "");
886 
887         fit::result<> result = p(fake_context);
888         EXPECT_TRUE(p);
889         EXPECT_EQ(fit::result_state::pending, result.state());
890 
891         result = p(fake_context);
892         EXPECT_FALSE(p);
893         EXPECT_EQ(fit::result_state::ok, result.state());
894     }
895 
896     END_TEST;
897 }
898 
wrap_with_combinator()899 bool wrap_with_combinator() {
900     BEGIN_TEST;
901 
902     fake_context fake_context;
903     capture_result_wrapper<int, char> wrapper;
904     uint64_t successor_run_count = 0;
905 
906     // Apply a wrapper which steals a promise's result th
907     auto p = make_delayed_ok_promise(42)
908                  .wrap_with(wrapper)
909                  .then([&](fit::result<>) { successor_run_count++; });
910     static_assert(std::is_same<void, decltype(p)::value_type>::value, "");
911     static_assert(std::is_same<void, decltype(p)::error_type>::value, "");
912 
913     fit::result<> result = p(fake_context);
914     EXPECT_TRUE(p);
915     EXPECT_EQ(fit::result_state::pending, result.state());
916     EXPECT_EQ(fit::result_state::pending, wrapper.last_result.state());
917     EXPECT_EQ(0, successor_run_count);
918 
919     result = p(fake_context);
920     EXPECT_FALSE(p);
921     EXPECT_EQ(fit::result_state::ok, result.state());
922     EXPECT_EQ(fit::result_state::ok, wrapper.last_result.state());
923     EXPECT_EQ(42, wrapper.last_result.value());
924     EXPECT_EQ(1, successor_run_count);
925 
926     END_TEST;
927 }
928 
box_combinator()929 bool box_combinator() {
930     BEGIN_TEST;
931 
932     fake_context fake_context;
933 
934     auto p = fit::make_promise([&]() -> fit::result<int, char> {
935         return fit::ok(42);
936     });
937     static_assert(!std::is_same<fit::promise<int, char>, decltype(p)>::value, "");
938 
939     auto q = p.box();
940     static_assert(std::is_same<fit::promise<int, char>, decltype(q)>::value, "");
941     EXPECT_TRUE(q);
942     EXPECT_FALSE(p);
943 
944     fit::result<int, char> result = q(fake_context);
945     EXPECT_FALSE(q);
946     EXPECT_EQ(fit::result_state::ok, result.state());
947     EXPECT_EQ(42, result.value());
948 
949     END_TEST;
950 }
951 
join_combinator()952 bool join_combinator() {
953     BEGIN_TEST;
954 
955     fake_context fake_context;
956 
957     auto p = fit::join_promises(
958         make_ok_promise(42),
959         make_error_promise('x').or_else([](char error) {
960             return fit::error('y');
961         }),
962         make_delayed_ok_promise(55));
963     EXPECT_TRUE(p);
964 
965     fit::result<std::tuple<
966         fit::result<int, char>,
967         fit::result<int, char>,
968         fit::result<int, char>>>
969         result = p(fake_context);
970     EXPECT_TRUE(p);
971     EXPECT_EQ(fit::result_state::pending, result.state());
972 
973     result = p(fake_context);
974     EXPECT_FALSE(p);
975     EXPECT_EQ(fit::result_state::ok, result.state());
976     EXPECT_EQ(42, std::get<0>(result.value()).value());
977     EXPECT_EQ('y', std::get<1>(result.value()).error());
978     EXPECT_EQ(55, std::get<2>(result.value()).value());
979 
980     END_TEST;
981 }
982 
983 // Ensure that fit::promise is considered nullable so that a promise can be
984 // directly stored as the continuation of another promise without any
985 // additional wrappers, similar to fit::function.
986 static_assert(fit::is_nullable<fit::promise<>>::value, "");
987 
988 // Test return type adapation performed by handler invokers.
989 // These tests verify that the necessary specializations can be produced
990 // in all cases for handlers with various signatures.
991 namespace handler_invoker_test {
992 
993 // handler returning void...
994 static_assert(std::is_same<
995                   fit::result<>,
996                   fit::internal::result_handler_invoker<
997                       void (*)(fit::result<int, double>&),
998                       fit::result<int, double>>::result_type>::value,
999               "");
1000 static_assert(std::is_same<
1001                   fit::result<void, double>,
1002                   fit::internal::value_handler_invoker<
1003                       void (*)(int&),
1004                       fit::result<int, double>>::result_type>::value,
1005               "");
1006 static_assert(std::is_same<
1007                   fit::result<int, void>,
1008                   fit::internal::error_handler_invoker<
1009                       void (*)(double&),
1010                       fit::result<int, double>>::result_type>::value,
1011               "");
1012 
1013 // handler returning fit::pending_result...
1014 static_assert(std::is_same<
1015                   fit::result<>,
1016                   fit::internal::result_handler_invoker<
1017                       fit::pending_result (*)(fit::result<int, double>&),
1018                       fit::result<int, double>>::result_type>::value,
1019               "");
1020 static_assert(std::is_same<
1021                   fit::result<void, double>,
1022                   fit::internal::value_handler_invoker<
1023                       fit::pending_result (*)(int&),
1024                       fit::result<int, double>>::result_type>::value,
1025               "");
1026 static_assert(std::is_same<
1027                   fit::result<int, void>,
1028                   fit::internal::error_handler_invoker<
1029                       fit::pending_result (*)(double&),
1030                       fit::result<int, double>>::result_type>::value,
1031               "");
1032 
1033 // handler returning fit::ok_result...
1034 static_assert(std::is_same<
1035                   fit::result<unsigned, void>,
1036                   fit::internal::result_handler_invoker<
1037                       fit::ok_result<unsigned> (*)(fit::result<int, double>&),
1038                       fit::result<int, double>>::result_type>::value,
1039               "");
1040 static_assert(std::is_same<
1041                   fit::result<unsigned, double>,
1042                   fit::internal::value_handler_invoker<
1043                       fit::ok_result<unsigned> (*)(int&),
1044                       fit::result<int, double>>::result_type>::value,
1045               "");
1046 static_assert(std::is_same<
1047                   fit::result<int, void>,
1048                   fit::internal::error_handler_invoker<
1049                       fit::ok_result<int> (*)(double&),
1050                       fit::result<int, double>>::result_type>::value,
1051               "");
1052 
1053 // handler returning fit::error_result...
1054 static_assert(std::is_same<
1055                   fit::result<void, float>,
1056                   fit::internal::result_handler_invoker<
1057                       fit::error_result<float> (*)(fit::result<int, double>&),
1058                       fit::result<int, double>>::result_type>::value,
1059               "");
1060 static_assert(std::is_same<
1061                   fit::result<void, double>,
1062                   fit::internal::value_handler_invoker<
1063                       fit::error_result<double> (*)(int&),
1064                       fit::result<int, double>>::result_type>::value,
1065               "");
1066 static_assert(std::is_same<
1067                   fit::result<int, float>,
1068                   fit::internal::error_handler_invoker<
1069                       fit::error_result<float> (*)(double&),
1070                       fit::result<int, double>>::result_type>::value,
1071               "");
1072 
1073 // handler returning fit::result...
1074 static_assert(std::is_same<
1075                   fit::result<unsigned, float>,
1076                   fit::internal::result_handler_invoker<
1077                       fit::result<unsigned, float> (*)(fit::result<int, double>&),
1078                       fit::result<int, double>>::result_type>::value,
1079               "");
1080 static_assert(std::is_same<
1081                   fit::result<unsigned, float>,
1082                   fit::internal::value_handler_invoker<
1083                       fit::result<unsigned, float> (*)(int&),
1084                       fit::result<int, double>>::result_type>::value,
1085               "");
1086 static_assert(std::is_same<
1087                   fit::result<unsigned, float>,
1088                   fit::internal::error_handler_invoker<
1089                       fit::result<unsigned, float> (*)(double&),
1090                       fit::result<int, double>>::result_type>::value,
1091               "");
1092 
1093 // handler returning fit::promise...
1094 static_assert(std::is_same<
1095                   fit::result<unsigned, float>,
1096                   fit::internal::result_handler_invoker<
1097                       fit::promise<unsigned, float> (*)(fit::result<int, double>&),
1098                       fit::result<int, double>>::result_type>::value,
1099               "");
1100 static_assert(std::is_same<
1101                   fit::result<unsigned, double>,
1102                   fit::internal::value_handler_invoker<
1103                       fit::promise<unsigned, double> (*)(int&),
1104                       fit::result<int, double>>::result_type>::value,
1105               "");
1106 static_assert(std::is_same<
1107                   fit::result<int, float>,
1108                   fit::internal::error_handler_invoker<
1109                       fit::promise<int, float> (*)(double&),
1110                       fit::result<int, double>>::result_type>::value,
1111               "");
1112 
1113 // handler returning lambda...
1114 auto result_continuation_lambda = [](fit::result<int, double>&)
__anon5af905b73b02(fit::result<int, double>&) 1115     -> fit::result<unsigned, float> { return fit::pending(); };
1116 auto value_continuation_lambda = [](int&)
__anon5af905b73c02(int&) 1117     -> fit::result<unsigned, double> { return fit::pending(); };
1118 auto error_continuation_lambda = [](double&)
__anon5af905b73d02(double&) 1119     -> fit::result<int, float> { return fit::pending(); };
1120 static_assert(std::is_same<
1121                   fit::result<unsigned, float>,
1122                   fit::internal::result_handler_invoker<
1123                       decltype(result_continuation_lambda),
1124                       fit::result<int, double>>::result_type>::value,
1125               "");
1126 static_assert(std::is_same<
1127                   fit::result<unsigned, double>,
1128                   fit::internal::value_handler_invoker<
1129                       decltype(value_continuation_lambda),
1130                       fit::result<int, double>>::result_type>::value,
1131               "");
1132 static_assert(std::is_same<
1133                   fit::result<int, float>,
1134                   fit::internal::error_handler_invoker<
1135                       decltype(error_continuation_lambda),
1136                       fit::result<int, double>>::result_type>::value,
1137               "");
1138 
1139 } // namespace handler_invoker_test
1140 
1141 // Test predicate which is used interally to improve the quality of
1142 // compilation errors when an invalid continuation type is encountered.
1143 namespace is_continuation_test {
1144 
1145 static_assert(fit::internal::is_continuation<
1146                   fit::function<fit::result<>(fit::context&)>>::value,
1147               "");
1148 static_assert(!fit::internal::is_continuation<
1149                   fit::function<void(fit::context&)>>::value,
1150               "");
1151 static_assert(!fit::internal::is_continuation<
1152                   fit::function<fit::result<>()>>::value,
1153               "");
1154 static_assert(!fit::internal::is_continuation<
1155                   void>::value,
1156               "");
1157 
1158 auto continuation_lambda = [](fit::context&)
__anon5af905b73e02(fit::context&) 1159     -> fit::result<> { return fit::pending(); };
__anon5af905b73f02null1160 auto invalid_lambda = [] {};
1161 
1162 static_assert(fit::internal::is_continuation<
1163                   decltype(continuation_lambda)>::value,
1164               "");
1165 static_assert(!fit::internal::is_continuation<
1166                   decltype(invalid_lambda)>::value,
1167               "");
1168 
1169 } // namespace is_continuation_test
1170 } // namespace
1171 
1172 // These are compile-time diagnostic tests.
1173 // We expect the following tests to fail at compile time and produce helpful
1174 // static assertions when enabled manually.
1175 #if 0
1176 void diagnose_handler_with_invalid_return_type() {
1177     // Doesn't work because result isn't fit::result<>, fit::ok_result<>,
1178     // fit::error_result<>, fit::pending_result, a continuation, or void.
1179     fit::make_promise([]() -> int { return 0; });
1180 }
1181 #endif
1182 #if 0
1183 void diagnose_handler_with_too_few_arguments() {
1184     // Expected between 1 and 2 arguments, got 0.
1185     fit::make_promise([] {})
1186         .then([]() {});
1187 }
1188 #endif
1189 #if 0
1190 void diagnose_handler_with_too_many_arguments() {
1191     // Expected between 1 and 2 arguments, got 3.
1192     fit::make_promise([] {})
1193         .then([](fit::context&, fit::result<>, int excess) {});
1194 }
1195 #endif
1196 #if 0
1197 void diagnose_handler_with_invalid_context_arg() {
1198     // When there are two argument, the first must be fit::context&.
1199     fit::make_promise([] {})
1200         .then([](fit::result<>, int excess) {});
1201 }
1202 #endif
1203 #if 0
1204 void diagnose_handler_with_invalid_result_arg() {
1205     // The result type must match that produced by the prior.
1206     fit::make_promise([] {})
1207         .then([](fit::result<int>& result) {});
1208 }
1209 #endif
1210 #if 0
1211 void diagnose_handler_with_invalid_move_only_result_arg() {
1212     // Move-only types must be passed by reference not by value.
1213     fit::make_promise([] { return fit::ok(move_only{}); })
1214         .then([](fit::result<move_only> result) {});
1215 }
1216 #endif
1217 #if 0
1218 void diagnose_handler_with_invalid_value_arg() {
1219     // The value type must match that produced by the prior.
1220     fit::make_promise([] { return fit::ok(3.2f); })
1221         .and_then([](int value) {});
1222 }
1223 #endif
1224 #if 0
1225 void diagnose_handler_with_invalid_move_only_value_arg() {
1226     // The value type must match that produced by the prior.
1227     fit::make_promise([] { return fit::ok(move_only{}); })
1228         .and_then([](move_only value) {});
1229 }
1230 #endif
1231 #if 0
1232 void diagnose_handler_with_invalid_error_arg() {
1233     // The error type must match that produced by the prior.
1234     fit::make_promise([] { return fit::error(3.2f); })
1235         .or_else([](int error) {});
1236 }
1237 #endif
1238 #if 0
1239 void diagnose_handler_with_invalid_move_only_error_arg() {
1240     // The error type must match that produced by the prior.
1241     fit::make_promise([] { return fit::error(move_only{}); })
1242         .or_else([](move_only error) {});
1243 }
1244 #endif
1245 
1246 BEGIN_TEST_CASE(promise_tests)
1247 RUN_TEST(basics)
1248 RUN_TEST(empty_promise)
1249 RUN_TEST(invocation)
1250 RUN_TEST(take_continuation)
1251 RUN_TEST(assignment_and_swap)
1252 RUN_TEST(comparison_with_nullptr)
1253 RUN_TEST(make_promise)
1254 RUN_TEST(make_promise_with_continuation)
1255 RUN_TEST(then_combinator)
1256 RUN_TEST(and_then_combinator)
1257 RUN_TEST(or_else_combinator)
1258 RUN_TEST(inspect_combinator)
1259 RUN_TEST(discard_result_combinator)
1260 RUN_TEST(wrap_with_combinator)
1261 RUN_TEST(box_combinator)
1262 RUN_TEST(join_combinator)
1263 
1264 // suppress -Wunneeded-internal-declaration
1265 (void)handler_invoker_test::result_continuation_lambda;
1266 (void)handler_invoker_test::value_continuation_lambda;
1267 (void)handler_invoker_test::error_continuation_lambda;
1268 (void)is_continuation_test::continuation_lambda;
1269 (void)is_continuation_test::invalid_lambda;
1270 END_TEST_CASE(promise_tests)
1271