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/promise.h>
6 #include <unittest/unittest.h>
7 
8 #include "unittest_utils.h"
9 
10 namespace {
11 
12 class fake_context : public fit::context {
13 public:
executor() const14     fit::executor* executor() const override {
15         ASSERT_CRITICAL(false);
16     }
suspend_task()17     fit::suspended_task suspend_task() override {
18         ASSERT_CRITICAL(false);
19     }
20 };
21 
empty_task()22 bool empty_task() {
23     BEGIN_TEST;
24 
25     fake_context context;
26 
27     {
28         fit::pending_task empty;
29         EXPECT_FALSE(empty);
30         EXPECT_FALSE(empty.take_promise());
31     }
32 
33     {
34         fit::pending_task empty(fit::promise<>(nullptr));
35         EXPECT_FALSE(empty);
36         EXPECT_FALSE(empty.take_promise());
37     }
38 
39     {
40         fit::pending_task empty(fit::promise<double, int>(nullptr));
41         EXPECT_FALSE(empty);
42         EXPECT_FALSE(empty.take_promise());
43     }
44 
45     END_TEST;
46 }
47 
non_empty_task()48 bool non_empty_task() {
49     BEGIN_TEST;
50 
51     fake_context context;
52 
53     {
54         uint64_t run_count = 0;
55         fit::pending_task task(fit::make_promise([&]() -> fit::result<> {
56             if (++run_count == 3)
57                 return fit::ok();
58             return fit::pending();
59         }));
60         EXPECT_TRUE(task);
61 
62         EXPECT_FALSE(task(context));
63         EXPECT_EQ(1, run_count);
64         EXPECT_TRUE(task);
65 
66         EXPECT_FALSE(task(context));
67         EXPECT_EQ(2, run_count);
68         EXPECT_TRUE(task);
69 
70         EXPECT_TRUE(task(context));
71         EXPECT_EQ(3, run_count);
72         EXPECT_FALSE(task);
73         EXPECT_FALSE(task.take_promise());
74     }
75 
76     {
77         uint64_t run_count = 0;
78         fit::pending_task task(fit::make_promise([&]() -> fit::result<int> {
79             if (++run_count == 2)
80                 return fit::ok(0);
81             return fit::pending();
82         }));
83         EXPECT_TRUE(task);
84 
85         fit::pending_task task_move(std::move(task));
86         EXPECT_TRUE(task_move);
87         EXPECT_FALSE(task);
88 
89         fit::pending_task task_movemove;
90         task_movemove = std::move(task_move);
91         EXPECT_TRUE(task_movemove);
92         EXPECT_FALSE(task_move);
93 
94         fit::promise<> promise = task_movemove.take_promise();
95         EXPECT_TRUE(promise);
96         EXPECT_EQ(fit::result_state::pending, promise(context).state());
97         EXPECT_EQ(1, run_count);
98 
99         EXPECT_EQ(fit::result_state::ok, promise(context).state());
100         EXPECT_EQ(2, run_count);
101         EXPECT_FALSE(promise);
102     }
103 
104     END_TEST;
105 }
106 
107 } // namespace
108 
109 BEGIN_TEST_CASE(pending_task_tests)
110 RUN_TEST(empty_task)
111 RUN_TEST(non_empty_task)
112 END_TEST_CASE(pending_task_tests)
113