summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuilherme Iscaro <iscaro@profusion.mobi>2017-08-08 18:11:23 -0300
committerGuilherme Iscaro <iscaro@profusion.mobi>2017-08-25 20:42:23 -0300
commitc35e929713da501d9e9323613f8708436dbc596b (patch)
tree960617d0b8cb0d0a48863e8b6d8db88d53d7e24a
parent0dd2c1a53018e1c0a7f4c695782fd453bd03a362 (diff)
Add new Future/Promise API.
Summary: Eina: Add Eina_Promise/Eina_Future. This commit adds a new promise/future API which aims to replace efl_future. Efl_Object: Add integration with Eina_Future. This commit adds the EO support for the new future infra. From now on there's no need to efl_future_link()/efl_future_unlink() object and futures since the new API already handles that internally. Eina_Promise/Eina_Future: Add example and tests. Subscribers: cedric, jpeg Differential Revision: https://phab.enlightenment.org/D5131
-rw-r--r--src/Makefile_Ecore.am1
-rw-r--r--src/examples/ecore/Makefile.am5
-rw-r--r--src/examples/ecore/ecore_promise2_example.c385
-rw-r--r--src/tests/ecore/ecore_suite.c1
-rw-r--r--src/tests/ecore/ecore_suite.h1
-rw-r--r--src/tests/ecore/ecore_test_promise2.c852
6 files changed, 1245 insertions, 0 deletions
diff --git a/src/Makefile_Ecore.am b/src/Makefile_Ecore.am
index c5be098bf7..4158ae5185 100644
--- a/src/Makefile_Ecore.am
+++ b/src/Makefile_Ecore.am
@@ -226,6 +226,7 @@ tests/ecore/ecore_test_ecore_thread_eina_thread_queue.c \
226tests/ecore/ecore_test_ecore_input.c \ 226tests/ecore/ecore_test_ecore_input.c \
227tests/ecore/ecore_test_ecore_file.c \ 227tests/ecore/ecore_test_ecore_file.c \
228tests/ecore/ecore_test_promise.c \ 228tests/ecore/ecore_test_promise.c \
229tests/ecore/ecore_test_promise2.c \
229tests/ecore/ecore_test_job.c \ 230tests/ecore/ecore_test_job.c \
230tests/ecore/ecore_test_args.c \ 231tests/ecore/ecore_test_args.c \
231tests/ecore/ecore_suite.h 232tests/ecore/ecore_suite.h
diff --git a/src/examples/ecore/Makefile.am b/src/examples/ecore/Makefile.am
index e10dfc7827..9ab288c594 100644
--- a/src/examples/ecore/Makefile.am
+++ b/src/examples/ecore/Makefile.am
@@ -76,6 +76,7 @@ ecore_idler_example \
76ecore_imf_example \ 76ecore_imf_example \
77ecore_job_example \ 77ecore_job_example \
78ecore_poller_example \ 78ecore_poller_example \
79ecore_promise2_example \
79ecore_server_bench \ 80ecore_server_bench \
80ecore_thread_example \ 81ecore_thread_example \
81ecore_time_functions_example \ 82ecore_time_functions_example \
@@ -292,6 +293,9 @@ endif
292ecore_poller_example_SOURCES = ecore_poller_example.c 293ecore_poller_example_SOURCES = ecore_poller_example.c
293ecore_poller_example_LDADD = $(ECORE_COMMON_LDADD) 294ecore_poller_example_LDADD = $(ECORE_COMMON_LDADD)
294 295
296ecore_promise2_example_SOURCES = ecore_promise2_example.c
297ecore_promise2_example_LDADD = $(ECORE_COMMON_LDADD)
298
295ecore_server_bench_SOURCES = ecore_server_bench.c 299ecore_server_bench_SOURCES = ecore_server_bench.c
296ecore_server_bench_LDADD = $(ECORE_CON_COMMON_LDADD) 300ecore_server_bench_LDADD = $(ECORE_CON_COMMON_LDADD)
297 301
@@ -425,6 +429,7 @@ ecore_job_example.c \
425ecore_pipe_gstreamer_example.c \ 429ecore_pipe_gstreamer_example.c \
426ecore_pipe_simple_example.c \ 430ecore_pipe_simple_example.c \
427ecore_poller_example.c \ 431ecore_poller_example.c \
432ecore_promise2_example.c \
428ecore_server_bench.c \ 433ecore_server_bench.c \
429ecore_thread_example.c \ 434ecore_thread_example.c \
430ecore_time_functions_example.c \ 435ecore_time_functions_example.c \
diff --git a/src/examples/ecore/ecore_promise2_example.c b/src/examples/ecore/ecore_promise2_example.c
new file mode 100644
index 0000000000..34fffc0759
--- /dev/null
+++ b/src/examples/ecore/ecore_promise2_example.c
@@ -0,0 +1,385 @@
1#define EFL_EO_API_SUPPORT 1
2#define EFL_BETA_API_SUPPORT 1
3
4#include <Ecore.h>
5#include <Eina.h>
6#include <stdlib.h>
7#include <errno.h>
8
9typedef struct _Ctx {
10 Eina_Promise *p;
11 Eina_Bool should_fail;
12 Ecore_Timer *timer;
13 Eina_Value *value;
14} Ctx;
15
16typedef struct _Inner_Promise_Ctx {
17 Eina_Future *future;
18 Eina_Promise *promise;
19} Inner_Promise_Ctx;
20
21#define DEFAULT_MSG "the simple example is working!"
22
23#define VALUE_TYPE_CHECK(_v, _type) \
24 if (_v.type != _type) \
25 { \
26 fprintf(stderr, "Value type is not '%s' - received '%s'\n", \
27 _type->name, _v.type->name); \
28 return _v; \
29 }
30
31static Eina_Bool
32_timeout(void *data)
33{
34 Ctx *ctx = data;
35 if (ctx->should_fail) eina_promise_reject(ctx->p, ENETDOWN);
36 else
37 {
38 Eina_Value v;
39 eina_value_copy(ctx->value, &v);
40 eina_promise_resolve(ctx->p, v);
41 eina_value_free(ctx->value);
42 }
43 free(ctx);
44 return EINA_FALSE;
45}
46
47static void
48_promise_cancel(void *data, const Eina_Promise *dead EINA_UNUSED)
49{
50 Ctx *ctx = data;
51 if (ctx->timer) ecore_timer_del(ctx->timer);
52 eina_value_free(ctx->value);
53 free(ctx);
54}
55
56static Eina_Future_Scheduler *
57_future_scheduler_get(void)
58{
59 return efl_loop_future_scheduler_get(ecore_main_loop_get());
60}
61
62static Ctx *
63_promise_ctx_new(Eina_Value *v)
64{
65 Ctx *ctx;
66 ctx = calloc(1, sizeof(Ctx));
67 EINA_SAFETY_ON_NULL_GOTO(ctx, err_ctx);
68 ctx->p = eina_promise_new(_future_scheduler_get(), _promise_cancel, ctx);
69 EINA_SAFETY_ON_NULL_GOTO(ctx->p, err_timer);
70 ctx->value = v;
71 return ctx;
72 err_timer:
73 free(ctx);
74 err_ctx:
75 eina_value_free(v);
76 return NULL;
77}
78
79static Eina_Future *
80_future_get(Ctx *ctx)
81{
82 Eina_Future *f;
83
84 f = eina_future_new(ctx->p);
85 EINA_SAFETY_ON_NULL_GOTO(f, err_future);
86 ctx->timer = ecore_timer_add(0.1, _timeout, ctx);
87 EINA_SAFETY_ON_NULL_GOTO(ctx->timer, err_timer);
88 return f;
89
90 err_timer:
91 eina_future_cancel(f);
92 err_future:
93 return NULL;
94}
95
96static Eina_Future *
97_fail_future_get(void)
98{
99 Ctx *ctx = _promise_ctx_new(NULL);
100 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
101 ctx->should_fail = EINA_TRUE;
102 return _future_get(ctx);
103}
104
105static Eina_Future *
106_str_future_get(void)
107{
108 Eina_Value *v = eina_value_util_string_new(DEFAULT_MSG);
109 EINA_SAFETY_ON_NULL_RETURN_VAL(v, NULL);
110 Ctx *ctx = _promise_ctx_new(v);
111 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
112 return _future_get(ctx);
113}
114
115static Eina_Future *
116_int_future_get(void)
117{
118 Eina_Value *v= eina_value_util_int_new(0);
119 EINA_SAFETY_ON_NULL_RETURN_VAL(v, NULL);
120 Ctx *ctx = _promise_ctx_new(v);
121 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, NULL);
122 return _future_get(ctx);
123}
124
125static Eina_Value
126_simple_ok(void *data EINA_UNUSED, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
127{
128 VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_STRING);
129 return v;
130}
131
132static Eina_Value
133_alternate_error_cb(void *data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
134{
135 Eina_Bool *should_fail = data;
136 Eina_Value new_v = EINA_VALUE_EMPTY;
137
138 if (*should_fail)
139 {
140 *should_fail = EINA_FALSE;
141 eina_value_setup(&new_v, EINA_VALUE_TYPE_ERROR);
142 eina_value_set(&new_v, ENETDOWN);
143 printf("Received succes from the previous future - Generating error for the next future...\n");
144 }
145 else
146 {
147 *should_fail = EINA_TRUE;
148 Eina_Error err;
149 VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_ERROR);
150 eina_value_get(&v, &err);
151 printf("Received error from the previous future - value: %s. Send success\n",
152 eina_error_msg_get(err));
153 }
154 return new_v;
155}
156
157static void
158_alternate_error(void)
159{
160 static Eina_Bool should_fail = EINA_TRUE;
161
162 eina_future_chain(_str_future_get(),
163 {.cb = _alternate_error_cb, .data = &should_fail},
164 {.cb = _alternate_error_cb, .data = &should_fail},
165 {.cb = _alternate_error_cb, .data = &should_fail},
166 {.cb = _alternate_error_cb, .data = &should_fail});
167
168}
169
170static Eina_Value
171_simple_err(void *data EINA_UNUSED, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
172{
173 VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_ERROR);
174 return v;
175}
176
177static void
178_simple(void)
179{
180 eina_future_chain(_str_future_get(),
181 eina_future_cb_console("Expecting the following message: "DEFAULT_MSG ". Got: ", NULL),
182 { .cb = _simple_ok, .data = NULL });
183 eina_future_chain(_fail_future_get(),
184 eina_future_cb_console("Expectig network down error. Got: ", NULL),
185 { .cb = _simple_err, .data = NULL });
186}
187
188static Eina_Value
189_chain_no_errors_cb(void *data EINA_UNUSED, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
190{
191 int count;
192 Eina_Value new_v;
193
194 eina_value_setup(&new_v, EINA_VALUE_TYPE_INT);
195 if (!v.type)
196 count = 1;
197 else
198 {
199 VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_INT);
200 eina_value_get(&v, &count);
201 }
202 eina_value_set(&new_v, count * 2);
203 return new_v;
204}
205
206static void
207_chain_no_errors(void)
208{
209 eina_future_chain(_int_future_get(),
210 eina_future_cb_console("Expecting no value. Got: ", NULL),
211 {.cb = _chain_no_errors_cb, .data = NULL},
212 eina_future_cb_console("Expecting number 2. Got: ", NULL),
213 {.cb = _chain_no_errors_cb, .data = NULL},
214 eina_future_cb_console("Expecting number 4. Got: ", NULL),
215 {.cb = _chain_no_errors_cb, .data = NULL},
216 eina_future_cb_console("Expecting number 8. Got: ", NULL),
217 {.cb = _chain_no_errors_cb, .data = NULL},
218 eina_future_cb_console("Expecting number 16. Got: ", NULL));
219}
220
221static Eina_Value
222_chain_with_error_cb(void *data EINA_UNUSED, const Eina_Value v EINA_UNUSED, const Eina_Future *dead_future EINA_UNUSED)
223{
224 Eina_Value err;
225 eina_value_setup(&err, EINA_VALUE_TYPE_ERROR);
226 eina_value_set(&err, E2BIG);
227 return err;
228}
229
230static void
231_chain_with_error(void)
232{
233 eina_future_chain(_int_future_get(),
234 { _chain_with_error_cb, NULL },
235 eina_future_cb_console("Expecting argument list too long. Got: ", NULL),
236 { .cb = _simple_err, .data = NULL });
237}
238
239static Eina_Value
240_delayed_resolve(void *data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
241{
242 Inner_Promise_Ctx *ctx = data;
243 Eina_Value new_v;
244 eina_value_setup(&new_v, EINA_VALUE_TYPE_STRING);
245 eina_value_set(&new_v, "Hello from inner future");
246 eina_promise_resolve(ctx->promise, new_v);
247 free(ctx);
248 return v;
249}
250
251static Eina_Value
252_delayed_reject(void *data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
253{
254 Inner_Promise_Ctx *ctx = data;
255 eina_promise_reject(ctx->promise, ENETDOWN);
256 free(ctx);
257 return v;
258}
259
260static void
261_inner_promise_cancel(void *data, const Eina_Promise *dead EINA_UNUSED)
262{
263 Inner_Promise_Ctx *ctx = data;
264 eina_future_cancel(ctx->future);
265 free(ctx);
266}
267
268static Eina_Value
269_chain_inner_cb(void *data, const Eina_Value v EINA_UNUSED, const Eina_Future *dead_future EINA_UNUSED)
270{
271 Inner_Promise_Ctx *ctx;
272 Eina_Value r;
273
274 ctx = calloc(1, sizeof(Inner_Promise_Ctx));
275 EINA_SAFETY_ON_NULL_GOTO(ctx, err);
276 ctx->promise = eina_promise_new(_future_scheduler_get(), _inner_promise_cancel, ctx);
277 EINA_SAFETY_ON_NULL_GOTO(ctx->promise, err);
278
279 printf("Creating a new promise inside the future cb\n");
280 ctx->future = eina_future_then(_int_future_get(),
281 !data ? _delayed_resolve : _delayed_reject,
282 ctx);
283 return eina_promise_as_value(ctx->promise);
284
285 err:
286 eina_value_setup(&r, EINA_VALUE_TYPE_ERROR);
287 eina_value_set(&r, ENOMEM);
288 free(ctx);
289 return r;
290}
291
292static Eina_Value
293_chain_inner_last_cb(void *data EINA_UNUSED, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
294{
295 VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_STRING);
296 return v;
297}
298
299static void
300_chain_inner_no_errors(void)
301{
302 eina_future_chain(_int_future_get(),
303 { .cb = _chain_inner_cb, .data = NULL },
304 eina_future_cb_console("Expecting message: 'Hello from inner future'. Got: ", NULL),
305 { .cb = _chain_inner_last_cb, .data = NULL });
306}
307
308static Eina_Value
309_err_inner_chain(void *data EINA_UNUSED, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
310{
311 VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_ERROR);
312 ecore_main_loop_quit();
313 return v;
314}
315
316static void
317_chain_inner_errors(void)
318{
319
320 eina_future_chain(_int_future_get(),
321 { .cb = _chain_inner_cb, .data = (void *)1 },
322 eina_future_cb_console("Expection network down error. Got: ", NULL),
323 { .cb = _err_inner_chain, .data = NULL });
324}
325
326static Eina_Value
327_canceled_cb(void *data EINA_UNUSED, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
328{
329 VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_ERROR);
330 return v;
331}
332
333static void
334_future_cancel(void)
335{
336 Eina_Future *f;
337
338 f = eina_future_chain(_int_future_get(),
339 eina_future_cb_console("Expecting cancelled operation error. Got: ", NULL),
340 { .cb = _canceled_cb, .data = NULL },
341 eina_future_cb_console("Expecting cancelled operation error. Got: ", NULL),
342 { .cb = _canceled_cb, .data = NULL },
343 eina_future_cb_console("Expecting cancelled operation error. Got: ", NULL),
344 { .cb = _canceled_cb, .data = NULL },
345 eina_future_cb_console("Expecting cancelled operation error. Got: ", NULL),
346 { .cb = _canceled_cb, .data = NULL },
347 eina_future_cb_console("Expecting cancelled operation error. Got: ", NULL),
348 { .cb = _canceled_cb, .data = NULL },
349 eina_future_cb_console("Expecting cancelled operation error. Got: ", NULL));
350 eina_future_cancel(f);
351}
352
353int
354main(int argc EINA_UNUSED, char *argv[] EINA_UNUSED)
355{
356 if (!eina_init())
357 {
358 fprintf(stderr, "Could not init eina\n");
359 return EXIT_FAILURE;
360 }
361
362 if (!ecore_init())
363 {
364 fprintf(stderr, "Could not init ecore\n");
365 goto err_ecore;
366 }
367
368 _simple();
369 _alternate_error();
370 _chain_no_errors();
371 _chain_with_error();
372 _chain_inner_no_errors();
373 _chain_inner_errors();
374 _future_cancel();
375
376 ecore_main_loop_begin();
377
378 eina_shutdown();
379 ecore_shutdown();
380 return EXIT_SUCCESS;
381
382 err_ecore:
383 eina_shutdown();
384 return EXIT_FAILURE;
385}
diff --git a/src/tests/ecore/ecore_suite.c b/src/tests/ecore/ecore_suite.c
index 76656c4de7..eb81132366 100644
--- a/src/tests/ecore/ecore_suite.c
+++ b/src/tests/ecore/ecore_suite.c
@@ -29,6 +29,7 @@ static const Efl_Test_Case etc[] = {
29 { "Ecore_Promise", ecore_test_ecore_promise }, 29 { "Ecore_Promise", ecore_test_ecore_promise },
30 { "Ecore_Job", ecore_test_ecore_job }, 30 { "Ecore_Job", ecore_test_ecore_job },
31 { "Ecore_Args", ecore_test_ecore_args }, 31 { "Ecore_Args", ecore_test_ecore_args },
32 { "Ecore_Promise2", ecore_test_ecore_promise2 },
32 { NULL, NULL } 33 { NULL, NULL }
33}; 34};
34 35
diff --git a/src/tests/ecore/ecore_suite.h b/src/tests/ecore/ecore_suite.h
index 31ca43d421..50df87f154 100644
--- a/src/tests/ecore/ecore_suite.h
+++ b/src/tests/ecore/ecore_suite.h
@@ -18,5 +18,6 @@ void ecore_test_ecore_file(TCase *tc);
18void ecore_test_ecore_promise(TCase *tc); 18void ecore_test_ecore_promise(TCase *tc);
19void ecore_test_ecore_job(TCase *tc); 19void ecore_test_ecore_job(TCase *tc);
20void ecore_test_ecore_args(TCase *tc); 20void ecore_test_ecore_args(TCase *tc);
21void ecore_test_ecore_promise2(TCase *tc);
21 22
22#endif /* _ECORE_SUITE_H */ 23#endif /* _ECORE_SUITE_H */
diff --git a/src/tests/ecore/ecore_test_promise2.c b/src/tests/ecore/ecore_test_promise2.c
new file mode 100644
index 0000000000..f71fa07c0e
--- /dev/null
+++ b/src/tests/ecore/ecore_test_promise2.c
@@ -0,0 +1,852 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include <Ecore.h>
6#include <Eina.h>
7#include <stdlib.h>
8#include <errno.h>
9#include <time.h>
10#include <Eo.h>
11#include "ecore_suite.h"
12
13#define CHAIN_SIZE (3)
14#define DEFAULT_ERROR (EFBIG)
15#define DEFAULT_MSG ("Future resolve is working!")
16#define DEFAULT_INT_VALUE (5466)
17#define DEFAULT_INT_VALUE_AS_STRING ("5466")
18#define DEFAULT_TIMEOUT (0.1)
19
20#define VALUE_TYPE_CHECK(_v, _type) \
21 do { \
22 ck_assert_ptr_eq(_v.type, _type); \
23} while(0)
24
25#define ERROR_CHECK(_v, _errno) \
26 do { \
27 Eina_Error _err; \
28 VALUE_TYPE_CHECK(_v, EINA_VALUE_TYPE_ERROR); \
29 fail_if(!eina_value_get(&_v, &_err)); \
30 ck_assert_int_eq(_err, _errno); \
31 } while (0)
32
33typedef struct _PromiseCtx {
34 Eina_Promise *p;
35 Ecore_Timer *t;
36 Eina_Bool fail;
37 Eina_Value *value;
38} PromiseCtx;
39
40typedef struct _Easy_Ctx {
41 Eina_Bool success_called;
42 Eina_Bool error_called;
43 Eina_Bool free_called;
44 Eina_Bool stop_loop;
45} Easy_Ctx;
46
47typedef struct _Race_Ctx {
48 Eina_Value value;
49 unsigned int success_idx;
50 unsigned int failed;
51 unsigned int success;
52} Race_Ctx;
53
54typedef struct _Race_Future_Ctx {
55 Race_Ctx *race_ctx;
56 unsigned int idx;
57 int value;
58} Race_Future_Ctx;
59
60static void
61_cancel(void *data, const Eina_Promise *dead_ptr EINA_UNUSED)
62{
63 PromiseCtx *ctx = data;
64 if (ctx->t) ecore_timer_del(ctx->t);
65 ctx->t = NULL;
66 eina_value_free(ctx->value);
67 free(ctx);
68}
69
70static void
71_promise_cancel_test(void *data, const Eina_Promise *dead_ptr EINA_UNUSED)
72{
73 Eina_Bool *cancel_called = data;
74 *cancel_called = EINA_TRUE;
75}
76
77static Eina_Bool
78_simple_timeout(void *data)
79{
80 PromiseCtx *ctx = data;
81
82 if (ctx->fail) eina_promise_reject(ctx->p, DEFAULT_ERROR);
83 else
84 {
85 Eina_Value v;
86
87 fail_if(!eina_value_copy(ctx->value, &v));
88 eina_promise_resolve(ctx->p, v);
89 eina_value_free(ctx->value);
90 }
91 free(ctx);
92 return EINA_FALSE;
93}
94
95static Eina_Future_Scheduler *
96_future_scheduler_get(void)
97{
98 return efl_loop_future_scheduler_get(ecore_main_loop_get());
99}
100
101static PromiseCtx *
102_promise_ctx_new(void)
103{
104 PromiseCtx *ctx;
105 ctx = calloc(1, sizeof(PromiseCtx));
106 fail_if(!ctx);
107 ctx->p = eina_promise_new(_future_scheduler_get(), _cancel, ctx);
108 fail_if(!ctx->p);
109 return ctx;
110}
111
112static Eina_Future *
113_future_get(PromiseCtx *ctx, double timeout)
114{
115 Eina_Future *f;
116
117 f = eina_future_new(ctx->p);
118 fail_if(!f);
119 ctx->t = ecore_timer_add(timeout, _simple_timeout, ctx);
120 fail_if(!ctx->t);
121 return f;
122}
123
124static Eina_Future *
125_fail_future_get(void)
126{
127 PromiseCtx *ctx = _promise_ctx_new();
128 ctx->fail = EINA_TRUE;
129 return _future_get(ctx, DEFAULT_TIMEOUT);
130}
131
132static Eina_Future *
133_int_future_with_value_and_timeout(int value, double timeout)
134{
135 PromiseCtx *ctx = _promise_ctx_new();
136 ctx->value = eina_value_util_int_new(value);
137 fail_if(!ctx->value);
138 return _future_get(ctx, timeout);
139}
140
141static Eina_Future *
142_int_future_get(void)
143{
144 return _int_future_with_value_and_timeout(DEFAULT_INT_VALUE, DEFAULT_TIMEOUT);
145}
146
147static Eina_Future *
148_str_future_get(void)
149{
150 PromiseCtx *ctx = _promise_ctx_new();
151 ctx->value = eina_value_util_string_new(DEFAULT_MSG);
152 fail_if(!ctx->value);
153 return _future_get(ctx, DEFAULT_TIMEOUT);
154}
155
156static Eina_Value
157_simple_err(void *data EINA_UNUSED, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
158{
159 ERROR_CHECK(v, DEFAULT_ERROR);
160 ecore_main_loop_quit();
161 return v;
162}
163
164static Eina_Value
165_simple_ok(void *data EINA_UNUSED, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
166{
167 const char *msg;
168
169 VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_STRING);
170 fail_if(!eina_value_get(&v, &msg));
171 ck_assert_str_eq(DEFAULT_MSG, msg);
172 ecore_main_loop_quit();
173 return v;
174}
175
176static Eina_Value
177_chain_stop(void *data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
178{
179 int *i = data;
180 fail_if(*i != CHAIN_SIZE);
181 ecore_main_loop_quit();
182 return v;
183}
184
185static Eina_Value
186_chain_no_error(void *data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
187{
188 Eina_Value new_v;
189 static int count = DEFAULT_INT_VALUE;
190 int current_i;
191 int *i = data;
192
193 VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_INT);
194 fail_if(!eina_value_get(&v, &current_i));
195 fail_if(current_i != count++);
196 fail_if(!eina_value_setup(&new_v, EINA_VALUE_TYPE_INT));
197 fail_if(!eina_value_set(&new_v, count));
198 (*i)++;
199 return new_v;
200}
201
202static Eina_Value
203_chain_error(void *data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
204{
205 int *i = data;
206
207 ERROR_CHECK(v, DEFAULT_ERROR);
208 (*i)++;
209 return v;
210}
211
212static Eina_Value
213_cancel_cb(void *data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
214{
215 Eina_Value new_v;
216 int *cancel_count = data;
217
218 fail_if(!eina_value_setup(&new_v, EINA_VALUE_TYPE_INT));
219 ERROR_CHECK(v, ECANCELED);
220 (*cancel_count)++;
221 /* Although this function returns an INT Eina_Value, the next
222 _cancel_cb must receive a EINA_VALYE_TYPE_ERROR as ECANCELED */
223 return new_v;
224}
225
226static Eina_Value
227_inner_resolve(void *data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
228{
229 Eina_Value new_v;
230 fail_if(!eina_value_setup(&new_v, EINA_VALUE_TYPE_STRING));
231 fail_if(!eina_value_set(&new_v, DEFAULT_MSG));
232 eina_promise_resolve(data, new_v);
233 return v;
234}
235
236static Eina_Value
237_inner_fail(void *data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
238{
239 eina_promise_reject(data, DEFAULT_ERROR);
240 return v;
241}
242
243static void
244_inner_promise_cancel(void *data EINA_UNUSED, const Eina_Promise *dead_ptr EINA_UNUSED)
245{
246 //This must never happen...
247 fail_if(EINA_FALSE);
248}
249
250static Eina_Value
251_future_promise_create(void *data, const Eina_Value v EINA_UNUSED, const Eina_Future *dead_future EINA_UNUSED)
252{
253 Eina_Promise *p;
254
255 p = eina_promise_new(_future_scheduler_get(), _inner_promise_cancel, NULL);
256 fail_if(!p);
257 eina_future_then(_str_future_get(),
258 data ? _inner_fail : _inner_resolve,
259 p);
260 return eina_promise_as_value(p);
261}
262
263static Eina_Value
264_inner_future_last(void *data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
265{
266 if (data)
267 ERROR_CHECK(v, DEFAULT_ERROR);
268 else
269 {
270 const char *msg;
271 VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_STRING);
272 fail_if(!eina_value_get(&v, &msg));
273 ck_assert_str_eq(DEFAULT_MSG, msg);
274 }
275 ecore_main_loop_quit();
276 return v;
277}
278
279static Eina_Value
280_convert_check(void *data EINA_UNUSED, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
281{
282 const char *number;
283 VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_STRING);
284 fail_if(!eina_value_get(&v, &number));
285 ck_assert_str_eq(DEFAULT_INT_VALUE_AS_STRING, number);
286 ecore_main_loop_quit();
287 return v;
288}
289
290static Eina_Value
291_easy_success(void *data, const Eina_Value v)
292{
293 Easy_Ctx *ctx = data;
294 const char *msg;
295
296 ctx->success_called = EINA_TRUE;
297 VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_STRING);
298 fail_if(!eina_value_get(&v, &msg));
299 ck_assert_str_eq(DEFAULT_MSG, msg);
300 return v;
301}
302
303static Eina_Value
304_easy_error(void *data, const Eina_Error err)
305{
306 Eina_Value v;
307 Easy_Ctx *ctx = data;
308 fail_if(err != EINVAL);
309 fail_if(!eina_value_setup(&v, EINA_VALUE_TYPE_ERROR));
310 fail_if(!eina_value_set(&v, err));
311 ctx->error_called = EINA_TRUE;
312 return v;
313}
314
315static void
316_easy_free(void *data, const Eina_Future *dead_future EINA_UNUSED)
317{
318 Easy_Ctx *ctx = data;
319 ctx->free_called = EINA_TRUE;
320 if (ctx->stop_loop) ecore_main_loop_quit();
321}
322
323static Eina_Value
324_all_cb(void *data, const Eina_Value array, const Eina_Future *dead EINA_UNUSED)
325{
326 unsigned int len, i, *expected_len = data;
327
328 VALUE_TYPE_CHECK(array, EINA_VALUE_TYPE_ARRAY);
329 len = eina_value_array_count(&array);
330 fail_if(len != *expected_len);
331
332 for (i = 0; i < len; i++)
333 {
334 Eina_Value v;
335
336 fail_if(!eina_value_array_get(&array, i, &v));
337 if (i % 2 == 0)
338 {
339 const char *msg;
340 VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_STRING);
341 fail_if(!eina_value_get(&v, &msg));
342 ck_assert_str_eq(DEFAULT_MSG, msg);
343 }
344 else
345 {
346 int ivalue = 0;
347 VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_INT);
348 fail_if(!eina_value_get(&v, &ivalue));
349 fail_if(ivalue != DEFAULT_INT_VALUE);
350 }
351 eina_value_flush(&v);
352 }
353 ecore_main_loop_quit();
354 return array;
355}
356
357static Eina_Value
358_future_all_count(void *data, const Eina_Value v, const Eina_Future *dead EINA_UNUSED)
359{
360 unsigned int *futures_called = data;
361 (*futures_called)++;
362 return v;
363}
364
365static Eina_Value
366_race_cb(void *data, const Eina_Value v, const Eina_Future *dead EINA_UNUSED)
367{
368 Race_Future_Ctx *future_ctx = data;
369 Race_Ctx *ctx = future_ctx->race_ctx;
370
371 if (v.type == EINA_VALUE_TYPE_ERROR)
372 {
373 Eina_Error err;
374 eina_value_get(&v, &err);
375 fail_if(err != ECANCELED);
376 ctx->failed++;
377 }
378 else if (v.type == EINA_VALUE_TYPE_INT)
379 {
380 int i;
381 fail_if(!eina_value_get(&v, &i));
382 fail_if(future_ctx->value != i);
383 ctx->success++;
384 ctx->success_idx = future_ctx->idx;
385 fail_if(!eina_value_copy(&v, &ctx->value));
386 }
387 else fail_if(EINA_TRUE); //This is not supposed to happen!
388 free(future_ctx);
389 return v;
390}
391
392static Eina_Value
393_race_end_cb(void *data, const Eina_Value v, const Eina_Future *dead EINA_UNUSED)
394{
395 Race_Ctx *ctx = data;
396 unsigned int idx;
397 Eina_Value_Struct *st;
398 Eina_Value r;
399
400 VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_STRUCT);
401
402 st = eina_value_memory_get(&v);
403 fail_if(!st);
404 fail_if(st->desc != EINA_PROMISE_RACE_STRUCT_DESC);
405 fail_if(!eina_value_struct_get(&v, "index", &idx));
406 fail_if(idx != ctx->success_idx);
407 fail_if(!eina_value_struct_get(&v, "value", &r));
408 fail_if(eina_value_compare(&r, &ctx->value));
409 eina_value_flush(&r);
410 ecore_main_loop_quit();
411 return v;
412}
413
414START_TEST(efl_test_promise_future_success)
415{
416 Eina_Future *f;
417 fail_if(!ecore_init());
418 f = eina_future_then(_str_future_get(),
419 _simple_ok, NULL);
420 fail_if(!f);
421 ecore_main_loop_begin();
422 ecore_shutdown();
423}
424END_TEST
425
426START_TEST(efl_test_promise_future_failure)
427{
428 Eina_Future *f;
429 fail_if(!ecore_init());
430 f = eina_future_then(_fail_future_get(),
431 _simple_err, NULL);
432 fail_if(!f);
433 ecore_main_loop_begin();
434 ecore_shutdown();
435}
436END_TEST
437
438START_TEST(efl_test_promise_future_chain_no_error)
439{
440 Eina_Future *f;
441 static int i = 0;
442
443 fail_if(!ecore_init());
444 f = eina_future_chain(_int_future_get(),
445 {.cb = _chain_no_error, .data = &i},
446 {.cb = _chain_no_error, .data = &i},
447 {.cb = _chain_no_error, .data = &i},
448 {.cb = _chain_stop, .data = &i});
449 fail_if(!f);
450 ecore_main_loop_begin();
451 ecore_shutdown();
452}
453END_TEST
454
455START_TEST(efl_test_promise_future_chain_error)
456{
457 Eina_Future *f;
458 static int i = 0;
459
460 fail_if(!ecore_init());
461 f = eina_future_chain(_fail_future_get(),
462 {.cb = _chain_error, .data = &i},
463 {.cb = _chain_error, .data = &i},
464 {.cb = _chain_error, .data = &i},
465 {.cb = _chain_stop, .data = &i});
466 fail_if(!f);
467 ecore_main_loop_begin();
468 ecore_shutdown();
469}
470END_TEST
471
472START_TEST(efl_test_promise_future_cancel)
473{
474 fail_if(!ecore_init());
475 int i;
476
477 for (i = 0; i < 3; i++)
478 {
479 Eina_Promise *p;
480 Eina_Future *first, *last, *middle;
481 int cancel_count = 0;
482 Eina_Bool cancel_called = EINA_FALSE;
483
484 p = eina_promise_new(_future_scheduler_get(), _promise_cancel_test, &cancel_called);
485 fail_if(!p);
486 first = eina_future_new(p);
487 fail_if(!first);
488 if (i == 2)
489 {
490 Eina_Future *f;
491 last = NULL;
492 f = eina_future_then(first, _cancel_cb, &cancel_count);
493 fail_if(!f);
494 middle = eina_future_then(f, _cancel_cb, &cancel_count);
495 fail_if(!middle);
496 f = eina_future_then(middle, _cancel_cb, &cancel_count);
497 fail_if(!f);
498 }
499 else
500 {
501 middle = NULL;
502 last = eina_future_chain(first,
503 {.cb = _cancel_cb, .data = &cancel_count},
504 {.cb = _cancel_cb, .data = &cancel_count},
505 {.cb = _cancel_cb, .data = &cancel_count});
506 fail_if(!last);
507 }
508 if (i == 0)
509 eina_future_cancel(last);
510 else if (i == 1)
511 eina_future_cancel(first);
512 else
513 eina_future_cancel(middle);
514 fail_if(cancel_count != CHAIN_SIZE);
515 fail_if(!cancel_called);
516 }
517 ecore_shutdown();
518}
519END_TEST
520
521START_TEST(efl_test_promise_future_inner_promise)
522{
523 Eina_Future *f;
524
525 fail_if(!ecore_init());
526 f = eina_future_chain(_str_future_get(),
527 {.cb = _future_promise_create, .data = NULL},
528 {.cb = _inner_future_last, .data = NULL});
529 fail_if(!f);
530 ecore_main_loop_begin();
531 ecore_shutdown();
532}
533END_TEST
534
535START_TEST(efl_test_promise_future_inner_promise_fail)
536{
537 Eina_Future *f;
538 void *data =(void *) 0x01;
539
540 fail_if(!ecore_init());
541 f = eina_future_chain(_str_future_get(),
542 {.cb = _future_promise_create, .data = data},
543 {.cb = _inner_future_last, .data = data});
544 fail_if(!f);
545 ecore_main_loop_begin();
546 ecore_shutdown();
547}
548END_TEST
549
550START_TEST(efl_test_promise_future_implicit_cancel)
551{
552 Eina_Promise *p;
553 Eina_Future *f;
554 int cancel_count = 0;
555 Eina_Bool cancel_called = EINA_FALSE;
556 Eina_Value v = EINA_VALUE_EMPTY;
557
558 fail_if(!ecore_init());
559
560 p = eina_promise_new(_future_scheduler_get(), _promise_cancel_test, &cancel_called);
561 fail_if(!p);
562 f = eina_future_new(p);
563 fail_if(!f);
564 f = eina_future_chain(f,
565 {.cb = _cancel_cb, .data = &cancel_count},
566 {.cb = _cancel_cb, .data = &cancel_count},
567 {.cb = _cancel_cb, .data = &cancel_count});
568 fail_if(!f);
569 eina_promise_resolve(p, v);
570 /*
571 The promise was resolved, but the mainloop is not running.
572 Since ecore_shutdown() will be called all the futures must be cancelled
573 */
574 ecore_shutdown();
575 //All the futures were cancelled at this point
576 fail_if(cancel_count != CHAIN_SIZE);
577 //Cancel should not be called, since we called eina_promise_resolve()
578 fail_if(cancel_called);
579}
580END_TEST
581
582START_TEST(efl_test_promise_future_convert)
583{
584 Eina_Future *f;
585
586 fail_if(!ecore_init());
587 f = eina_future_chain(_int_future_get(),
588 eina_future_cb_convert_to(EINA_VALUE_TYPE_STRING),
589 { .cb = _convert_check, .data = NULL });
590 fail_if(!f);
591 ecore_main_loop_begin();
592 ecore_shutdown();
593
594}
595END_TEST
596
597START_TEST(efl_test_promise_future_easy)
598{
599 Eina_Future *f;
600 Easy_Ctx easy1 = { 0 };
601 Easy_Ctx easy2 = { 0 };
602 Easy_Ctx easy3 = { 0 };
603
604 easy3.stop_loop = EINA_TRUE;
605 fail_if(!ecore_init());
606 f = eina_future_then_from_desc(_str_future_get(),
607 eina_future_cb_easy(_easy_success,
608 _easy_error,
609 _easy_free,
610 EINA_VALUE_TYPE_STRING,
611 &easy1));
612 fail_if(!f);
613 f = eina_future_then_easy(f, _easy_success, _easy_error,
614 _easy_free, NULL, &easy2);
615 fail_if(!f);
616 f = eina_future_chain_easy(f, {_easy_success, _easy_error,
617 _easy_free, EINA_VALUE_TYPE_INT, &easy3});
618 fail_if(!f);
619 ecore_main_loop_begin();
620 ecore_shutdown();
621 fail_if(!(easy1.success_called && !easy1.error_called && easy1.free_called));
622 fail_if(!(easy2.success_called && !easy2.error_called && easy2.free_called));
623 fail_if(!(!easy3.success_called && easy3.error_called && easy3.free_called));
624}
625END_TEST
626
627START_TEST(efl_test_promise_future_all)
628{
629 Eina_Future *futures[11];
630 unsigned int i, futures_called = 0, len = EINA_C_ARRAY_LENGTH(futures);
631
632 fail_if(!ecore_init());
633 for (i = 0; i < len - 1; i++)
634 {
635 Eina_Future *f;
636 if (i % 2 == 0)
637 f = _str_future_get();
638 else
639 f = _int_future_get();
640 fail_if(!f);
641 futures[i] = eina_future_then(f, _future_all_count, &futures_called);
642 fail_if(!futures[i]);
643 }
644
645 futures[--len] = NULL;
646 fail_if(!eina_future_then(eina_future_all_array(futures), _all_cb, &len));
647 ecore_main_loop_begin();
648 ecore_shutdown();
649 fail_if(futures_called != len);
650}
651END_TEST
652
653START_TEST(efl_test_promise_future_race)
654{
655 Race_Ctx ctx = { 0 };
656 Eina_Future *futures[11];
657 unsigned int i, len = EINA_C_ARRAY_LENGTH(futures);
658 double timeouts[10] = {
659 2.0, 1.0, 0.5, 0.1, 4.5, 2.3, 5.6, 1.0, 0.5, 0.3
660 };
661
662 srand(time(NULL));
663 fail_if(!ecore_init());
664 for (i = 0; i < len - 1; i++)
665 {
666 Race_Future_Ctx *future_ctx = calloc(1, sizeof(Race_Future_Ctx));
667 fail_if(!future_ctx);
668 future_ctx->race_ctx = &ctx;
669 future_ctx->idx = i;
670 future_ctx->value = rand() % RAND_MAX;
671 futures[i] = eina_future_then(_int_future_with_value_and_timeout(future_ctx->value, timeouts[i]),
672 _race_cb, future_ctx);
673 fail_if(!futures[i]);
674 }
675
676 futures[--len] = NULL;
677 fail_if(!eina_future_then(eina_future_race_array(futures),
678 _race_end_cb, &ctx));
679 ecore_main_loop_begin();
680 eina_value_flush(&ctx.value);
681 ecore_shutdown();
682 fail_if(ctx.success != 1);
683 fail_if(ctx.failed != (len - 1));
684}
685END_TEST
686
687static Eina_Value
688_eo_future1_ok(Eo *eo EINA_UNUSED, const Eina_Value v)
689{
690 const char *number;
691
692 VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_STRING);
693 fail_if(!eina_value_get(&v, &number));
694 ck_assert_str_eq(DEFAULT_INT_VALUE_AS_STRING, number);
695 return v;
696}
697
698static Eina_Value
699_eo_future1_err(Eo *eo EINA_UNUSED, Eina_Error err EINA_UNUSED)
700{
701 //Should not happen
702 fail_if(EINA_TRUE);
703}
704
705static Eina_Value
706_eo_future2_ok(Eo *eo EINA_UNUSED, const Eina_Value v)
707{
708 //Should not happen
709 fail_if(EINA_TRUE);
710 return v;
711}
712
713static Eina_Value
714_eo_future2_err(Eo *eo EINA_UNUSED, Eina_Error err)
715{
716 Eina_Value v;
717
718 fail_if(err != EINVAL);
719 fail_if(!eina_value_setup(&v, EINA_VALUE_TYPE_INT));
720 fail_if(!eina_value_set(&v, DEFAULT_INT_VALUE));
721 return v;
722}
723
724static void
725_eo_future_free(Eo *eo, const Eina_Future *dead EINA_UNUSED)
726{
727 int *free_called = efl_key_data_get(eo, "free_called");
728 (*free_called)++;
729}
730
731static Eina_Value
732_eo_chain_stop(void *data EINA_UNUSED, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
733{
734 int ivalue = 0;
735 VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_INT);
736 fail_if(!eina_value_get(&v, &ivalue));
737 ck_assert_int_eq(ivalue, DEFAULT_INT_VALUE);
738 ecore_main_loop_quit();
739 return v;
740}
741
742START_TEST(efl_test_promise_eo)
743{
744 Eina_Future *f;
745 Eo *obj;
746 int free_called = 0;
747
748 fail_if(!efl_object_init());
749 fail_if(!ecore_init());
750
751 //Use a random object..
752 obj = efl_add(EFL_IO_BUFFER_CLASS, NULL);
753 fail_if(!obj);
754 efl_key_data_set(obj, "free_called", &free_called);
755 f = eina_future_chain(_int_future_get(),
756 eina_future_cb_convert_to(EINA_VALUE_TYPE_STRING),
757 efl_future_cb(obj, _eo_future1_ok, _eo_future1_err, _eo_future_free, EINA_VALUE_TYPE_STRING),
758 efl_future_cb(obj, _eo_future2_ok, _eo_future2_err, _eo_future_free, EINA_VALUE_TYPE_INT),
759 { .cb = _eo_chain_stop });
760 fail_if(!f);
761 ecore_main_loop_begin();
762 efl_unref(obj);
763 ecore_shutdown();
764 efl_object_shutdown();
765 ck_assert_int_eq(free_called, 2);
766}
767END_TEST
768
769static Eina_Value
770_eo_future_link_success(Eo *eo EINA_UNUSED, const Eina_Value v)
771{
772 //This should never happen
773 fail_if(EINA_TRUE);
774 return v;
775}
776
777static Eina_Value
778_eo_future_link_err(Eo *eo, Eina_Error err)
779{
780 int *err_called = efl_key_data_get(eo, "err_called");
781 Eina_Value v;
782
783 fail_if(!err_called);
784 ck_assert_int_eq(err, ECANCELED);
785 fail_if(!eina_value_setup(&v, EINA_VALUE_TYPE_ERROR));
786 fail_if(!eina_value_set(&v, err));
787 (*err_called)++;
788 return v;
789}
790
791static Eina_Value
792_eo_link_chain_end(void *data EINA_UNUSED, const Eina_Value v, const Eina_Future *dead EINA_UNUSED)
793{
794 int *err_called = data;
795 VALUE_TYPE_CHECK(v, EINA_VALUE_TYPE_ERROR);
796 ERROR_CHECK(v, ECANCELED);
797 (*err_called)++;
798 return v;
799}
800
801START_TEST(efl_test_promise_eo_link)
802{
803 Eina_Future *f;
804 Eo *obj;
805 int err_called = 0;
806
807 fail_if(!efl_object_init());
808 fail_if(!ecore_init());
809
810 //Use a random object..
811 obj = efl_add(EFL_IO_BUFFER_CLASS, NULL);
812 fail_if(!obj);
813
814 efl_key_data_set(obj, "err_called", &err_called);
815 fail_if(!efl_key_data_get(obj, "err_called"));
816 f = efl_future_chain(obj, _int_future_get(),
817 {.success = _eo_future_link_success, .error = _eo_future_link_err},
818 {.success = _eo_future_link_success, .error = _eo_future_link_err},
819 {.success = _eo_future_link_success, .error = _eo_future_link_err},
820 {.success = _eo_future_link_success, .error = _eo_future_link_err},
821 {.success = _eo_future_link_success, .error = _eo_future_link_err});
822 fail_if(!f);
823 f = eina_future_then(f, _eo_link_chain_end, &err_called);
824 fail_if(!f);
825 /*
826 Since the mainloop is not running and the object is deleted the whole chain must be cancelled.
827 */
828 efl_unref(obj);
829 ecore_shutdown();
830 efl_object_shutdown();
831 ck_assert_int_eq(err_called, 6);
832}
833END_TEST
834
835void ecore_test_ecore_promise2(TCase *tc)
836{
837 tcase_add_test(tc, efl_test_promise_future_success);
838 tcase_add_test(tc, efl_test_promise_future_failure);
839 tcase_add_test(tc, efl_test_promise_future_chain_no_error);
840 tcase_add_test(tc, efl_test_promise_future_chain_error);
841 tcase_add_test(tc, efl_test_promise_future_cancel);
842 tcase_add_test(tc, efl_test_promise_future_implicit_cancel);
843 tcase_add_test(tc, efl_test_promise_future_inner_promise);
844 tcase_add_test(tc, efl_test_promise_future_inner_promise_fail);
845 tcase_add_test(tc, efl_test_promise_future_convert);
846 tcase_add_test(tc, efl_test_promise_future_easy);
847 tcase_add_test(tc, efl_test_promise_future_all);
848 tcase_add_test(tc, efl_test_promise_future_race);
849 //FIXME: We should move this to EO tests, however they depend on Ecore...
850 tcase_add_test(tc, efl_test_promise_eo);
851 tcase_add_test(tc, efl_test_promise_eo_link);
852}