Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: components/scheduler/promises/promise_unittest.cc

Issue 1401553002: NOT INTENDED FOR LANDING: A promises demo (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Support for rejectatble promises! Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium 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 <queue>
6
7 #include "base/bind.h"
8 #include "components/scheduler/promises/promise_executor.h"
9 #include "testing/gmock/include/gmock/gmock.h"
10
11 using testing::ElementsAre;
12 using testing::WhenSorted;
13
14 namespace promise {
15
16 class PromiseTest : public testing::Test {
17 public:
18 PromiseTest() {}
19 ~PromiseTest() override {}
20
21 void SetUp() override { executor_.reset(new internal::PromiseExecutor()); }
22
23 scoped_ptr<internal::PromiseExecutor> executor_;
24 };
25
26 namespace {
27 bool ReturnTrue() {
28 return true;
29 }
30
31 int ReturnOne() {
32 return 1;
33 }
34
35 int ReturnTwo() {
36 return 2;
37 }
38
39 int ReturnTen() {
40 return 10;
41 }
42
43 int Add(int i, int j) {
44 return i + j;
45 }
46
47 int CondTimesThree(int i, bool do_smth) {
48 if (do_smth)
49 return i * 3;
50 return i;
51 }
52
53 int ReturnZero() {
54 return 0;
55 }
56
57 void RecordParam(int* out, int in) {
58 *out = in;
59 }
60
61 Promise<int> Choose(Promise<int> p1, Promise<int> p2, int i) {
62 return i ? p1 : p2;
63 }
64
65 void RecordOrder(int value, std::vector<int>* out_result) {
66 out_result->push_back(value);
67 }
68
69 } // namespace
70
71 TEST_F(PromiseTest, NonVoidPromise) {
72 Promise<int> promise(promise::Create(base::Bind(&ReturnOne)));
73
74 executor_->StartResolve(promise);
75 executor_->RunUntilIdle();
76 EXPECT_EQ(1, promise.GetResolved());
77 }
78
79 TEST_F(PromiseTest, AssignPromise) {
80 Promise<int> promise = promise::Create(base::Bind(&ReturnOne));
81
82 executor_->StartResolve(promise);
83 executor_->RunUntilIdle();
84 EXPECT_EQ(1, promise.GetResolved());
85 }
86
87 TEST_F(PromiseTest, Then) {
88 Promise<int> promise(
89 promise::Create(base::Bind(&ReturnOne)).Then(base::Bind(&Add, 1)));
90
91 executor_->StartResolve(promise);
92 executor_->RunUntilIdle();
93 EXPECT_EQ(2, promise.GetResolved());
94 }
95
96 TEST_F(PromiseTest, AssignThen) {
97 Promise<int> promise =
98 promise::Create(base::Bind(&ReturnOne)).Then(base::Bind(&Add, 1));
99
100 executor_->StartResolve(promise);
101 executor_->RunUntilIdle();
102 EXPECT_EQ(2, promise.GetResolved());
103 }
104
105 TEST_F(PromiseTest, ThenVoid) {
106 int value = 0;
107 Promise<void> promise(promise::Create(base::Bind(&ReturnOne))
108 .Then(base::Bind(&RecordParam, &value)));
109
110 executor_->StartResolve(promise);
111 executor_->RunUntilIdle();
112 EXPECT_EQ(1, value);
113 }
114
115 TEST_F(PromiseTest, VoidThenVoid) {
116 int value = 0;
117 int value2 = 0;
118 Promise<void> promise(promise::Create(base::Bind(&RecordParam, &value, 1))
119 .Then(base::Bind(&RecordParam, &value2, 2)));
120
121 executor_->StartResolve(promise);
122 executor_->RunUntilIdle();
123 EXPECT_EQ(1, value);
124 EXPECT_EQ(2, value2);
125 }
126
127 TEST_F(PromiseTest, VoidThenInt) {
128 int value = 0;
129 Promise<int> promise(promise::Create(base::Bind(&RecordParam, &value, 2))
130 .Then(base::Bind(&ReturnOne)));
131
132 executor_->StartResolve(promise);
133 executor_->RunUntilIdle();
134 EXPECT_EQ(2, value);
135 EXPECT_EQ(1, promise.GetResolved());
136 }
137
138 TEST_F(PromiseTest, ThenChaining) {
139 Promise<int> promise(promise::Create(base::Bind(&ReturnOne))
140 .Then(base::Bind(&Add, 1))
141 .Then(base::Bind(&Add, 1))
142 .Then(base::Bind(&Add, 1)));
143
144 executor_->StartResolve(promise);
145 executor_->RunUntilIdle();
146 EXPECT_EQ(4, promise.GetResolved());
147 }
148
149 TEST_F(PromiseTest, PromiseReuse) {
150 Promise<int> promise10(promise::Create(base::Bind(&ReturnTen)));
151 Promise<int> promise11(promise10.Then(base::Bind(&Add, 1)));
152 Promise<int> promise12(promise10.Then(base::Bind(&Add, 2)));
153 Promise<int> promise13(promise10.Then(base::Bind(&Add, 3)));
154 Promise<int> promise14(promise10.Then(base::Bind(&Add, 4)));
155
156 executor_->StartResolve(promise11);
157 executor_->StartResolve(promise12);
158 executor_->StartResolve(promise13);
159 executor_->StartResolve(promise14);
160 executor_->RunUntilIdle();
161
162 EXPECT_EQ(11, promise11.GetResolved());
163 EXPECT_EQ(12, promise12.GetResolved());
164 EXPECT_EQ(13, promise13.GetResolved());
165 EXPECT_EQ(14, promise14.GetResolved());
166 }
167
168 TEST_F(PromiseTest, PromiseReuseResolvedPromise_TypeOne) {
169 Promise<int> promise10(promise::Create(10));
170 Promise<int> promise11(promise10.Then(base::Bind(&Add, 1)));
171 Promise<int> promise12(promise10.Then(base::Bind(&Add, 2)));
172 Promise<int> promise13(promise10.Then(base::Bind(&Add, 3)));
173 Promise<int> promise14(promise10.Then(base::Bind(&Add, 4)));
174
175 executor_->StartResolve(promise11);
176 executor_->StartResolve(promise12);
177 executor_->StartResolve(promise13);
178 executor_->StartResolve(promise14);
179 executor_->RunUntilIdle();
180
181 EXPECT_EQ(11, promise11.GetResolved());
182 EXPECT_EQ(12, promise12.GetResolved());
183 EXPECT_EQ(13, promise13.GetResolved());
184 EXPECT_EQ(14, promise14.GetResolved());
185 }
186
187 TEST_F(PromiseTest, PromiseReuseResolvedPromise_TypeTwo) {
188 Promise<int> promise10(promise::Create(10));
189 Promise<int> promise11(promise10.Then(base::Bind(&Add, 1)));
190 Promise<int> promise12(promise10.Then(base::Bind(&Add, 2)));
191 Promise<int> promise13(promise10.Then(base::Bind(&Add, 3)));
192 Promise<int> promise14(promise10.Then(base::Bind(&Add, 4)));
193
194 executor_->StartResolve(promise10);
195 executor_->RunUntilIdle();
196
197 executor_->StartResolve(promise11);
198 executor_->StartResolve(promise12);
199 executor_->StartResolve(promise13);
200 executor_->StartResolve(promise14);
201 executor_->RunUntilIdle();
202
203 EXPECT_EQ(11, promise11.GetResolved());
204 EXPECT_EQ(12, promise12.GetResolved());
205 EXPECT_EQ(13, promise13.GetResolved());
206 EXPECT_EQ(14, promise14.GetResolved());
207 }
208
209 TEST_F(PromiseTest, AllThen) {
210 Promise<int> promise(promise::All(promise::Create(base::Bind(&ReturnOne)),
211 promise::Create(base::Bind(&ReturnTrue)))
212 .Then(base::Bind(&CondTimesThree)));
213
214 executor_->StartResolve(promise);
215 executor_->RunUntilIdle();
216 EXPECT_EQ(3, promise.GetResolved());
217 }
218
219 TEST_F(PromiseTest, AssignAllThen) {
220 Promise<int> promise = promise::All(promise::Create(base::Bind(&ReturnOne)),
221 promise::Create(base::Bind(&ReturnTrue)))
222 .Then(base::Bind(&CondTimesThree));
223
224 executor_->StartResolve(promise);
225 executor_->RunUntilIdle();
226 EXPECT_EQ(3, promise.GetResolved());
227 }
228
229 TEST_F(PromiseTest, EagerTasksExecutedFirst) {
230 std::vector<int> run_order;
231
232 Promise<void> promiseA(
233 promise::Create(base::Bind(&RecordOrder, 0, &run_order))
234 .Then(base::Bind(&RecordOrder, 1, &run_order))
235 .Then(base::Bind(&RecordOrder, 2, &run_order))
236 .Then(base::Bind(&RecordOrder, 3, &run_order))
237 .Then(base::Bind(&RecordOrder, 4, &run_order)));
238
239 Promise<void> promiseB(
240 promise::Create(base::Bind(&RecordOrder, 10, &run_order))
241 .Then(base::Bind(&RecordOrder, 11, &run_order))
242 .Then(base::Bind(&RecordOrder, 12, &run_order))
243 .Then(base::Bind(&RecordOrder, 13, &run_order))
244 .Then(base::Bind(&RecordOrder, 14, &run_order)));
245
246 promiseB.SetEager(true);
247
248 executor_->StartResolve(promiseA);
249 executor_->StartResolve(promiseB);
250 executor_->RunUntilIdle();
251
252 EXPECT_THAT(run_order, ElementsAre(10, 11, 12, 13, 14, 0, 1, 2, 3, 4));
253 }
254
255 TEST_F(PromiseTest, DynamicChangingOfEagerness) {
256 std::vector<int> run_order;
257
258 Promise<void> promiseA(
259 promise::Create(base::Bind(&RecordOrder, 0, &run_order))
260 .Then(base::Bind(&RecordOrder, 1, &run_order))
261 .Then(base::Bind(&RecordOrder, 2, &run_order))
262 .Then(base::Bind(&RecordOrder, 3, &run_order))
263 .Then(base::Bind(&RecordOrder, 4, &run_order)));
264
265 Promise<void> promiseB(
266 promise::Create(base::Bind(&RecordOrder, 10, &run_order))
267 .Then(base::Bind(&RecordOrder, 11, &run_order))
268 .Then(base::Bind(&RecordOrder, 12, &run_order))
269 .Then(base::Bind(&RecordOrder, 13, &run_order))
270 .Then(base::Bind(&RecordOrder, 14, &run_order)));
271
272 promiseB.SetEager(true);
273
274 executor_->StartResolve(promiseA);
275 executor_->StartResolve(promiseB);
276
277 executor_->ResolveOnePromise();
278
279 promiseB.SetEager(false);
280 promiseA.SetEager(true);
281
282 executor_->RunUntilIdle();
283
284 EXPECT_THAT(run_order, ElementsAre(10, 0, 1, 2, 3, 4, 11, 12, 13, 14));
285 }
286
287 TEST_F(PromiseTest, MultipleThens) {
288 std::vector<int> run_order;
289
290 Promise<void> promiseA(
291 promise::Create(base::Bind(&RecordOrder, 0, &run_order))
292 .Then(base::Bind(&RecordOrder, 1, &run_order)));
293
294 Promise<void> promiseB(promiseA.Then(base::Bind(&RecordOrder, 2, &run_order))
295 .Then(base::Bind(&RecordOrder, 3, &run_order)));
296
297 Promise<void> promiseC(promiseA.Then(base::Bind(&RecordOrder, 4, &run_order))
298 .Then(base::Bind(&RecordOrder, 5, &run_order)));
299
300 executor_->StartResolve(promiseB);
301 executor_->StartResolve(promiseC);
302 executor_->RunUntilIdle();
303
304 // The interleaving of promiseB and promiseC execution is undefined.
305 EXPECT_THAT(run_order, WhenSorted(ElementsAre(0, 1, 2, 3, 4, 5)));
306 }
307
308 TEST_F(PromiseTest, Cancel) {
309 std::vector<int> run_order;
310
311 Promise<void> promise(
312 promise::Create(base::Bind(&RecordOrder, 1, &run_order)));
313
314 executor_->StartResolve(promise);
315 promise.Cancel();
316
317 executor_->RunUntilIdle();
318
319 EXPECT_TRUE(run_order.empty());
320 }
321
322 TEST_F(PromiseTest, CancelChainOfTasks) {
323 std::vector<int> run_order;
324
325 Promise<void> promiseA(
326 promise::Create(base::Bind(&RecordOrder, 0, &run_order))
327 .Then(base::Bind(&RecordOrder, 1, &run_order))
328 .Then(base::Bind(&RecordOrder, 2, &run_order))
329 .Then(base::Bind(&RecordOrder, 3, &run_order))
330 .Then(base::Bind(&RecordOrder, 4, &run_order)));
331
332 Promise<void> promiseB(
333 promise::Create(base::Bind(&RecordOrder, 10, &run_order))
334 .Then(base::Bind(&RecordOrder, 11, &run_order))
335 .Then(base::Bind(&RecordOrder, 12, &run_order))
336 .Then(base::Bind(&RecordOrder, 13, &run_order))
337 .Then(base::Bind(&RecordOrder, 14, &run_order)));
338
339 executor_->StartResolve(promiseA);
340 executor_->StartResolve(promiseB);
341
342 promiseB.Cancel();
343
344 executor_->RunUntilIdle();
345
346 EXPECT_THAT(run_order, ElementsAre(0, 1, 2, 3, 4));
347 }
348
349 TEST_F(PromiseTest, CancelOneBranch) {
350 std::vector<int> run_order;
351
352 Promise<void> promiseA(
353 promise::Create(base::Bind(&RecordOrder, 0, &run_order))
354 .Then(base::Bind(&RecordOrder, 1, &run_order)));
355
356 Promise<void> promiseB(promiseA.Then(base::Bind(&RecordOrder, 2, &run_order))
357 .Then(base::Bind(&RecordOrder, 3, &run_order)));
358
359 Promise<void> promiseC(promiseA.Then(base::Bind(&RecordOrder, 4, &run_order))
360 .Then(base::Bind(&RecordOrder, 5, &run_order)));
361
362 executor_->StartResolve(promiseB);
363 executor_->StartResolve(promiseC);
364
365 promiseB.Cancel();
366
367 executor_->RunUntilIdle();
368
369 EXPECT_THAT(run_order, ElementsAre(0, 1, 4, 5));
370 }
371
372 TEST_F(PromiseTest, CancelAndReresolve) {
373 std::vector<int> run_order;
374
375 Promise<void> promise(
376 promise::Create(base::Bind(&RecordOrder, 1, &run_order)));
377
378 executor_->StartResolve(promise);
379 promise.Cancel();
380
381 executor_->RunUntilIdle();
382
383 EXPECT_TRUE(run_order.empty());
384
385 executor_->StartResolve(promise);
386 executor_->RunUntilIdle();
387
388 EXPECT_THAT(run_order, ElementsAre(1));
389 }
390
391 TEST_F(PromiseTest, CancelChainOfTasksAndReresolve) {
392 std::vector<int> run_order;
393
394 Promise<void> promiseA(
395 promise::Create(base::Bind(&RecordOrder, 0, &run_order))
396 .Then(base::Bind(&RecordOrder, 1, &run_order))
397 .Then(base::Bind(&RecordOrder, 2, &run_order))
398 .Then(base::Bind(&RecordOrder, 3, &run_order))
399 .Then(base::Bind(&RecordOrder, 4, &run_order)));
400
401 Promise<void> promiseB(
402 promise::Create(base::Bind(&RecordOrder, 10, &run_order))
403 .Then(base::Bind(&RecordOrder, 11, &run_order))
404 .Then(base::Bind(&RecordOrder, 12, &run_order))
405 .Then(base::Bind(&RecordOrder, 13, &run_order))
406 .Then(base::Bind(&RecordOrder, 14, &run_order)));
407
408 executor_->StartResolve(promiseA);
409 executor_->StartResolve(promiseB);
410
411 promiseB.Cancel();
412
413 executor_->RunUntilIdle();
414
415 EXPECT_THAT(run_order, ElementsAre(0, 1, 2, 3, 4));
416
417 executor_->StartResolve(promiseB);
418 executor_->RunUntilIdle();
419
420 EXPECT_THAT(run_order, ElementsAre(0, 1, 2, 3, 4, 10, 11, 12, 13, 14));
421 }
422
423 TEST_F(PromiseTest, CancelOneBranchAndReresolve) {
424 std::vector<int> run_order;
425
426 Promise<void> promiseA(
427 promise::Create(base::Bind(&RecordOrder, 0, &run_order))
428 .Then(base::Bind(&RecordOrder, 1, &run_order)));
429
430 Promise<void> promiseB(promiseA.Then(base::Bind(&RecordOrder, 2, &run_order))
431 .Then(base::Bind(&RecordOrder, 3, &run_order)));
432
433 Promise<void> promiseC(promiseA.Then(base::Bind(&RecordOrder, 4, &run_order))
434 .Then(base::Bind(&RecordOrder, 5, &run_order)));
435
436 executor_->StartResolve(promiseB);
437 executor_->StartResolve(promiseC);
438
439 promiseB.Cancel();
440
441 executor_->RunUntilIdle();
442
443 EXPECT_THAT(run_order, ElementsAre(0, 1, 4, 5));
444
445 executor_->StartResolve(promiseB);
446 executor_->RunUntilIdle();
447
448 EXPECT_THAT(run_order, ElementsAre(0, 1, 4, 5, 2, 3));
449 }
450
451 TEST_F(PromiseTest, Choose) {
452 Promise<int> promise_two(promise::Create(base::Bind(&ReturnTwo)));
453 Promise<int> promise_ten(promise::Create(base::Bind(&ReturnTen)));
454 Promise<int> promiseA(
455 promise::Create(base::Bind(&ReturnZero))
456 .Then(base::Bind(&Choose, promise_two, promise_ten)));
457
458 Promise<int> promiseB(
459 promise::Create(base::Bind(&ReturnOne))
460 .Then(base::Bind(&Choose, promise_two, promise_ten)));
461
462 executor_->StartResolve(promiseA);
463 executor_->StartResolve(promiseB);
464 executor_->RunUntilIdle();
465 EXPECT_EQ(10, promiseA.GetResolved());
466 EXPECT_EQ(2, promiseB.GetResolved());
467 }
468
469 TEST_F(PromiseTest, ChooseAndAddOne) {
470 Promise<int> promise_two(promise::Create(base::Bind(&ReturnTwo)));
471 Promise<int> promise_ten(promise::Create(base::Bind(&ReturnTen)));
472 Promise<int> promiseA(promise::Create(base::Bind(&ReturnZero))
473 .Then(base::Bind(&Choose, promise_two, promise_ten))
474 .Then(base::Bind(&Add, 1)));
475
476 Promise<int> promiseB(promise::Create(base::Bind(&ReturnOne))
477 .Then(base::Bind(&Choose, promise_two, promise_ten))
478 .Then(base::Bind(&Add, 1)));
479
480 executor_->StartResolve(promiseA);
481 executor_->StartResolve(promiseB);
482 executor_->RunUntilIdle();
483 EXPECT_EQ(11, promiseA.GetResolved());
484 EXPECT_EQ(3, promiseB.GetResolved());
485 }
486
487 TEST_F(PromiseTest, ChooseResolved) {
488 Promise<int> promise_two(promise::Create(2));
489 Promise<int> promise_ten(promise::Create(10));
490 Promise<int> promiseA(
491 promise::Create(base::Bind(&ReturnZero))
492 .Then(base::Bind(&Choose, promise_two, promise_ten)));
493
494 Promise<int> promiseB(
495 promise::Create(base::Bind(&ReturnOne))
496 .Then(base::Bind(&Choose, promise_two, promise_ten)));
497
498 executor_->StartResolve(promiseA);
499 executor_->StartResolve(promiseB);
500 executor_->RunUntilIdle();
501 EXPECT_EQ(10, promiseA.GetResolved());
502 EXPECT_EQ(2, promiseB.GetResolved());
503 }
504
505 TEST_F(PromiseTest, ChooseResolvedAndAddOne) {
506 Promise<int> promise_two(promise::Create<int>(2));
507 Promise<int> promise_ten(promise::Create<int>(10));
508 Promise<int> promiseA(promise::Create(base::Bind(&ReturnZero))
509 .Then(base::Bind(&Choose, promise_two, promise_ten))
510 .Then(base::Bind(&Add, 1)));
511
512 Promise<int> promiseB(promise::Create(base::Bind(&ReturnOne))
513 .Then(base::Bind(&Choose, promise_two, promise_ten))
514 .Then(base::Bind(&Add, 1)));
515
516 executor_->StartResolve(promiseA);
517 executor_->StartResolve(promiseB);
518 executor_->RunUntilIdle();
519 EXPECT_EQ(11, promiseA.GetResolved());
520 EXPECT_EQ(3, promiseB.GetResolved());
521 }
522
523 namespace {
524 class BlockingResolveFixture {
525 public:
526 void Root() { run_order_.push_back("Root"); }
527
528 void L() { run_order_.push_back("L"); }
529
530 void LL() { run_order_.push_back("LL"); }
531
532 void LR() { run_order_.push_back("LR"); }
533
534 void R() { run_order_.push_back("R"); }
535
536 void RL() { run_order_.push_back("RL"); }
537
538 void RR() { run_order_.push_back("RL"); }
539
540 std::vector<std::string> run_order_;
541 };
542 } // namespace
543
544 TEST_F(PromiseTest, BlockingResolve) {
545 BlockingResolveFixture fixture;
546
547 Promise<void> promise_l(
548 promise::All(promise::Create(base::Bind(&BlockingResolveFixture::LL,
549 base::Unretained(&fixture))),
550 promise::Create(base::Bind(&BlockingResolveFixture::LR,
551 base::Unretained(&fixture))))
552 .Then(base::Bind(&BlockingResolveFixture::L,
553 base::Unretained(&fixture))));
554
555 Promise<void> blocking_promise(promise::Create<void>());
556
557 Promise<void> promise_r(
558 promise::All(promise::Create(base::Bind(&BlockingResolveFixture::RL,
559 base::Unretained(&fixture))),
560 promise::Create(base::Bind(&BlockingResolveFixture::RR,
561 base::Unretained(&fixture))),
562 blocking_promise)
563 .Then(base::Bind(&BlockingResolveFixture::R,
564 base::Unretained(&fixture))));
565
566 Promise<void> promise_root(promise::All(promise_l, promise_r)
567 .Then(base::Bind(&BlockingResolveFixture::Root,
568 base::Unretained(&fixture))));
569
570 executor_->StartResolve(promise_root);
571 executor_->RunUntilIdle();
572 EXPECT_THAT(fixture.run_order_,
573 WhenSorted(ElementsAre(std::string("L"), std::string("LL"),
574 std::string("LR"), std::string("RL"),
575 std::string("RL"))));
576
577 fixture.run_order_.clear();
578 blocking_promise.Resolve();
579 executor_->RunUntilIdle();
580 EXPECT_THAT(fixture.run_order_,
581 ElementsAre(std::string("R"), std::string("Root")));
582 }
583
584 TEST_F(PromiseTest, AnyIntToInt) {
585 Promise<int> promiseA(promise::Create<int>());
586 Promise<int> promiseB(promise::Create<int>());
587 Promise<int> promiseC(promise::Create<int>());
588 Promise<int> promiseD(promise::Create<int>());
589
590 Promise<int> promise = promise::Race(promiseA, promiseB, promiseC, promiseD)
591 .Then(base::Bind(&Add, 1));
592
593 executor_->StartResolve(promise);
594
595 promiseB.Resolve(10);
596 executor_->RunUntilIdle();
597
598 EXPECT_EQ(11, promise.GetResolved());
599 }
600
601 TEST_F(PromiseTest, AnyIntToVoid) {
602 Promise<int> promiseA(promise::Create<int>());
603 Promise<int> promiseB(promise::Create<int>());
604 Promise<int> promiseC(promise::Create<int>());
605
606 int chosen = 0;
607 Promise<void> promise(promise::Race(promiseA, promiseB, promiseC)
608 .Then(base::Bind(&RecordParam, &chosen)));
609
610 executor_->StartResolve(promise);
611
612 promiseB.Resolve(10);
613 executor_->RunUntilIdle();
614
615 EXPECT_EQ(10, chosen);
616 }
617
618 TEST_F(PromiseTest, AnyAllVoid) {
619 Promise<void> promiseA(promise::Create<void>());
620 Promise<void> promiseB(promise::Create<void>());
621 Promise<void> promiseC(promise::Create<void>());
622
623 int chosen = 0;
624 Promise<void> promise(promise::Race(promiseA, promiseB, promiseC)
625 .Then(base::Bind(&RecordParam, &chosen, 1)));
626
627 executor_->StartResolve(promise);
628
629 promiseB.Resolve();
630 executor_->RunUntilIdle();
631
632 EXPECT_EQ(1, chosen);
633 }
634
635 namespace {
636 Promise<int> ReturnAPromise(int value) {
637 return promise::Create(value + 1);
638 }
639 }
640
641 TEST_F(PromiseTest, AnyIntToIntPromise) {
642 Promise<int> promiseA(promise::Create<int>());
643 Promise<int> promiseB(promise::Create<int>());
644 Promise<int> promiseC(promise::Create<int>());
645 Promise<int> promiseD(promise::Create<int>());
646
647 Promise<int> promise(promise::Race(promiseA, promiseB, promiseC, promiseD)
648 .Then(base::Bind(&ReturnAPromise)));
649
650 executor_->StartResolve(promise);
651
652 promiseD.Resolve(10);
653 executor_->RunUntilIdle();
654
655 EXPECT_EQ(11, promise.GetResolved());
656 }
657
658 TEST_F(PromiseTest, FirstPromiseRegisteredWins) {
659 Promise<int> promiseA(promise::Create<int>());
660 Promise<int> promiseB(promise::Create<int>());
661 Promise<int> promiseC(promise::Create<int>());
662 Promise<int> promiseD(promise::Create<int>());
663
664 Promise<int> promise(promise::Race(promiseA, promiseB, promiseC, promiseD)
665 .Then(base::Bind(&ReturnAPromise)));
666
667 executor_->StartResolve(promise);
668
669 promiseD.Resolve(0);
670 promiseC.Resolve(10);
671 promiseB.Resolve(100);
672 promiseA.Resolve(1000);
673
674 executor_->RunUntilIdle();
675
676 EXPECT_EQ(1001, promise.GetResolved());
677 }
678
679 namespace {
680 Promise<void> ReturnAVoidPromise(int* out_value, int value) {
681 return promise::Create(base::Bind(&RecordParam, out_value, value));
682 }
683 }
684
685 TEST_F(PromiseTest, AnyIntToVoidPromise) {
686 Promise<int> promiseA(promise::Create<int>());
687 Promise<int> promiseB(promise::Create<int>());
688 Promise<int> promiseC(promise::Create<int>());
689 Promise<int> promiseD(promise::Create<int>());
690
691 int value = 0;
692 Promise<void> promise(promise::Race(promiseA, promiseB, promiseC, promiseD)
693 .Then(base::Bind(&ReturnAVoidPromise, &value)));
694
695 executor_->StartResolve(promise);
696
697 promiseD.Resolve(15);
698 executor_->RunUntilIdle();
699
700 EXPECT_EQ(15, value);
701 }
702
703 TEST_F(PromiseTest, AnyVoidToIntPromise) {
704 Promise<void> promiseA(promise::Create<void>());
705 Promise<void> promiseB(promise::Create<void>());
706 Promise<void> promiseC(promise::Create<void>());
707 Promise<void> promiseD(promise::Create<void>());
708
709 Promise<int> promise(promise::Race(promiseA, promiseB, promiseC, promiseD)
710 .Then(base::Bind(&ReturnAPromise, 8)));
711
712 executor_->StartResolve(promise);
713
714 promiseD.Resolve();
715 executor_->RunUntilIdle();
716
717 EXPECT_EQ(9, promise.GetResolved());
718 }
719
720 TEST_F(PromiseTest, AnyVoidToVoidPromise) {
721 Promise<void> promiseA(promise::Create<void>());
722 Promise<void> promiseB(promise::Create<void>());
723 Promise<void> promiseC(promise::Create<void>());
724 Promise<void> promiseD(promise::Create<void>());
725
726 int value;
727 Promise<void> promise(promise::Race(promiseA, promiseB, promiseC, promiseD)
728 .Then(base::Bind(&ReturnAVoidPromise, &value, 8)));
729
730 executor_->StartResolve(promise);
731
732 promiseD.Resolve();
733 executor_->RunUntilIdle();
734
735 EXPECT_EQ(8, value);
736 }
737
738 namespace {
739 Promise<void> GenerateNewTask(std::vector<int>* out_result) {
740 out_result->push_back(1);
741
742 return promise::Create(base::Bind(&RecordOrder, 2, out_result))
743 .Then(base::Bind(&RecordOrder, 3, out_result));
744 }
745 } // namespace
746
747 TEST_F(PromiseTest, NewPromiseFromWithinPromise) {
748 std::vector<int> run_order;
749
750 Promise<void> promise(promise::Create(base::Bind(&RecordOrder, 0, &run_order))
751 .Then(base::Bind(&GenerateNewTask, &run_order))
752 .Then(base::Bind(&RecordOrder, 4, &run_order)));
753
754 executor_->StartResolve(promise);
755
756 executor_->RunUntilIdle();
757
758 EXPECT_THAT(run_order, ElementsAre(0, 1, 2, 3, 4));
759 }
760
761 TEST_F(PromiseTest, ResolvePromiseWithAPromise) {
762 Promise<int> promise(promise::Create<int>());
763
764 promise.Resolve(promise::Create(base::Bind(&ReturnTen)));
765
766 executor_->StartResolve(promise);
767 executor_->RunUntilIdle();
768
769 EXPECT_EQ(10, promise.GetResolved());
770 }
771
772 TEST_F(PromiseTest, ResolvePromiseWithAVoidPromise) {
773 Promise<void> promise(promise::Create<void>());
774
775 int value = 0;
776 promise.Resolve(promise::Create(base::Bind(&RecordParam, &value, 5)));
777
778 executor_->StartResolve(promise);
779 executor_->RunUntilIdle();
780
781 EXPECT_EQ(5, value);
782 }
783
784 namespace {
785 class MoveOnlyType {
786 public:
787 MoveOnlyType() {}
788 MoveOnlyType(MoveOnlyType&& other) {}
789
790 void operator=(MoveOnlyType&& other) {}
791
792 private:
793 DISALLOW_COPY_AND_ASSIGN(MoveOnlyType);
794 };
795 } // namespace
796
797 TEST_F(PromiseTest, MoveOnlyType_ResolvedPromise_ViaMove) {
798 MoveOnlyType src;
799 Promise<MoveOnlyType> promise = promise::Create(std::move(src));
800
801 executor_->StartResolve(promise);
802 executor_->RunUntilIdle();
803
804 MoveOnlyType dest = std::move(promise.GetResolved());
805 }
806
807 TEST_F(PromiseTest, MoveOnlyType_ResolvedPromise_Constructed) {
808 Promise<MoveOnlyType> promise = promise::Create(MoveOnlyType());
809
810 executor_->StartResolve(promise);
811 executor_->RunUntilIdle();
812
813 MoveOnlyType dest = std::move(promise.GetResolved());
814 }
815
816 TEST_F(PromiseTest, MoveOnlyType_ManuallyResolved) {
817 Promise<MoveOnlyType> promise = promise::Create<MoveOnlyType>();
818
819 MoveOnlyType src;
820 promise.Resolve(std::move(src));
821
822 MoveOnlyType dest = std::move(promise.GetResolved());
823 }
824
825 namespace {
826 MoveOnlyType ReturnMoveOnlyType() {
827 return MoveOnlyType();
828 }
829 } // namespace
830
831 TEST_F(PromiseTest, MoveOnlyType_ReturnedFromClosure) {
832 Promise<MoveOnlyType> promise =
833 promise::Create(base::Bind(&ReturnMoveOnlyType));
834
835 executor_->StartResolve(promise);
836 executor_->RunUntilIdle();
837 MoveOnlyType dest = std::move(promise.GetResolved());
838 }
839
840 namespace {
841 void TakeMoveOnlyType(MoveOnlyType type) {
842 MoveOnlyType dest = std::move(type);
843 }
844 } // namespace
845
846 TEST_F(PromiseTest, MoveOnlyType_PassedToThenClosure) {
847 Promise<void> promise = promise::Create(base::Bind(&ReturnMoveOnlyType))
848 .Then(base::Bind(&TakeMoveOnlyType));
849
850 executor_->StartResolve(promise);
851 executor_->RunUntilIdle();
852 }
853
854 namespace {
855 MoveOnlyType PassMoveOnlyType(MoveOnlyType type) {
856 return type;
857 }
858 } // namespace
859
860 TEST_F(PromiseTest, MoveOnlyType_PassedToAndReturnedFromThenClosure) {
861 Promise<MoveOnlyType> promise =
862 promise::Create(base::Bind(&ReturnMoveOnlyType))
863 .Then(base::Bind(&PassMoveOnlyType));
864
865 executor_->StartResolve(promise);
866 executor_->RunUntilIdle();
867
868 MoveOnlyType dest = std::move(promise.GetResolved());
869 }
870
871 TEST_F(PromiseTest, MoveOnlyType_AnyThen) {
872 Promise<MoveOnlyType> promise =
873 promise::Race(promise::Create(base::Bind(&ReturnMoveOnlyType)),
874 promise::Create(base::Bind(&ReturnMoveOnlyType)),
875 promise::Create(base::Bind(&ReturnMoveOnlyType)))
876 .Then(base::Bind(&PassMoveOnlyType));
877
878 executor_->StartResolve(promise);
879 executor_->RunUntilIdle();
880
881 MoveOnlyType dest = std::move(promise.GetResolved());
882 }
883
884 namespace {
885 MoveOnlyType PassFirstMoveOnlyType(MoveOnlyType type,
886 MoveOnlyType type2,
887 MoveOnlyType type3) {
888 return type;
889 }
890 } // namespace
891
892 TEST_F(PromiseTest, MoveOnlyType_AllThen) {
893 Promise<MoveOnlyType> promise =
894 promise::All(promise::Create(base::Bind(&ReturnMoveOnlyType)),
895 promise::Create(base::Bind(&ReturnMoveOnlyType)),
896 promise::Create(base::Bind(&ReturnMoveOnlyType)))
897 .Then(base::Bind(&PassFirstMoveOnlyType));
898
899 executor_->StartResolve(promise);
900 executor_->RunUntilIdle();
901
902 MoveOnlyType dest = std::move(promise.GetResolved());
903 }
904
905 namespace {
906 Rejectable<int, bool> ReturnIntResolve() {
907 return Resolve(10);
908 }
909
910 Rejectable<int, bool> ReturnBoolReject() {
911 return Reject(true);
912 }
913 } // namespace
914
915 TEST_F(PromiseTest, IntBoolRejectable_Resolve) {
916 Rejectable<int, bool> rejectable = ReturnIntResolve();
917
918 EXPECT_TRUE(rejectable.is_resolved());
919 EXPECT_EQ(10, rejectable.resolved());
920 }
921
922 TEST_F(PromiseTest, IntBoolRejectable_Reject) {
923 Rejectable<int, bool> rejectable = ReturnBoolReject();
924
925 EXPECT_FALSE(rejectable.is_resolved());
926 EXPECT_TRUE(rejectable.reject_reason());
927 }
928
929 namespace {
930 Rejectable<void, void> ReturnVoidResolve() {
931 return Resolve();
932 }
933
934 Rejectable<void, void> ReturnVoidReject() {
935 return Reject();
936 }
937 } // namespace
938
939 TEST_F(PromiseTest, VoidVoidRejectable_Resolve) {
940 Rejectable<void, void> rejectable = ReturnVoidResolve();
941
942 EXPECT_TRUE(rejectable.is_resolved());
943 }
944
945 TEST_F(PromiseTest, VoidVoidRejectable_Reject) {
946 Rejectable<void, void> rejectable = ReturnVoidReject();
947
948 EXPECT_FALSE(rejectable.is_resolved());
949 }
950
951 TEST_F(PromiseTest, RejectablePromise_Resolve) {
952 Promise<Rejectable<int, bool>> promise(
953 promise::Create<Rejectable<int, bool>>());
954
955 promise.Resolve(10);
956
957 EXPECT_TRUE(promise.is_resolved());
958 EXPECT_FALSE(promise.is_rejected());
959 EXPECT_EQ(10, promise.GetResolved().resolved());
960 }
961
962 TEST_F(PromiseTest, RejectablePromise_Reject) {
963 Promise<Rejectable<int, bool>> promise(
964 promise::Create<Rejectable<int, bool>>());
965
966 promise.Reject(true);
967
968 EXPECT_FALSE(promise.is_resolved());
969 EXPECT_TRUE(promise.is_rejected());
970 EXPECT_TRUE(promise.GetResolved().reject_reason());
971 }
972
973 namespace {
974 Rejectable<int, int> ResolveWithTenFunc() {
975 return Resolve(10);
976 }
977
978 Rejectable<int, int> RejectWithTwentyFunc() {
979 return Reject(20);
980 }
981 }
982
983 TEST_F(PromiseTest, RejectableFunction_Resolve) {
984 Promise<Rejectable<int, int>> promise(
985 promise::Create(base::Bind(&ResolveWithTenFunc)));
986 executor_->StartResolve(promise);
987 executor_->RunUntilIdle();
988
989 EXPECT_TRUE(promise.is_resolved());
990 EXPECT_FALSE(promise.is_rejected());
991 EXPECT_EQ(10, promise.GetResolved().resolved());
992 }
993
994 TEST_F(PromiseTest, RejectableFunction_Reject) {
995 Promise<Rejectable<int, int>> promise(
996 promise::Create(base::Bind(&RejectWithTwentyFunc)));
997 executor_->StartResolve(promise);
998 executor_->RunUntilIdle();
999
1000 EXPECT_FALSE(promise.is_resolved());
1001 EXPECT_TRUE(promise.is_rejected());
1002 EXPECT_EQ(20, promise.GetResolved().reject_reason());
1003 }
1004
1005 TEST_F(PromiseTest, RejectablePromise_ResolveWithPromiseThatResolves) {
1006 Promise<Rejectable<int, int>> promise =
1007 promise::Create<Rejectable<int, int>>();
1008 executor_->StartResolve(promise);
1009
1010 promise.Resolve(promise::Create(base::Bind(&ResolveWithTenFunc)));
1011
1012 executor_->RunUntilIdle();
1013
1014 EXPECT_TRUE(promise.is_resolved());
1015 EXPECT_FALSE(promise.is_rejected());
1016 EXPECT_EQ(10, promise.GetResolved().resolved());
1017 }
1018
1019 TEST_F(PromiseTest, RejectablePromise_ResolveWithPromiseThatRejects) {
1020 Promise<Rejectable<int, int>> promise =
1021 promise::Create<Rejectable<int, int>>();
1022 executor_->StartResolve(promise);
1023
1024 promise.Resolve(promise::Create(base::Bind(&RejectWithTwentyFunc)));
1025
1026 executor_->RunUntilIdle();
1027
1028 EXPECT_FALSE(promise.is_resolved());
1029 EXPECT_TRUE(promise.is_rejected());
1030 EXPECT_EQ(20, promise.GetResolved().reject_reason());
1031 }
1032
1033 TEST_F(PromiseTest, RejectablePromise_ResolveWithResolvedPromise) {
1034 Promise<Rejectable<int, int>> rejected_promise =
1035 promise::Create<Rejectable<int, int>>();
1036
1037 rejected_promise.Resolve(1337);
1038
1039 Promise<Rejectable<int, int>> promise =
1040 promise::Create<Rejectable<int, int>>();
1041 executor_->StartResolve(promise);
1042
1043 promise.Resolve(rejected_promise);
1044
1045 EXPECT_TRUE(promise.is_resolved());
1046 EXPECT_FALSE(promise.is_rejected());
1047 EXPECT_EQ(1337, promise.GetResolved().resolved());
1048 }
1049
1050 TEST_F(PromiseTest, RejectablePromise_ResolveWithRectedPromise) {
1051 Promise<Rejectable<int, int>> rejected_promise =
1052 promise::Create<Rejectable<int, int>>();
1053
1054 rejected_promise.Reject(123);
1055
1056 Promise<Rejectable<int, int>> promise =
1057 promise::Create<Rejectable<int, int>>();
1058 executor_->StartResolve(promise);
1059
1060 promise.Resolve(rejected_promise);
1061
1062 EXPECT_FALSE(promise.is_resolved());
1063 EXPECT_TRUE(promise.is_rejected());
1064 EXPECT_EQ(123, promise.GetResolved().reject_reason());
1065 }
1066
1067 namespace {
1068 void OnRejectableIntBool(bool* was_rejected,
1069 int* resolved_result,
1070 bool* reject_reason,
1071 Rejectable<int, bool> result) {
1072 *was_rejected = result.is_rejected();
1073 if (result.is_rejected()) {
1074 *reject_reason = result.reject_reason();
1075 } else {
1076 *resolved_result = result.resolved();
1077 }
1078 }
1079 }
1080
1081 TEST_F(PromiseTest, RejectablePromise_ThenResolve) {
1082 Promise<Rejectable<int, bool>> manually_resolved_promise(
1083 promise::Create<Rejectable<int, bool>>());
1084
1085 bool was_rejected = false;
1086 int resolved_result = 0;
1087 bool reject_reason = false;
1088 Promise<void> promise(manually_resolved_promise.Then(base::Bind(
1089 &OnRejectableIntBool, &was_rejected, &resolved_result, &reject_reason)));
1090
1091 executor_->StartResolve(promise);
1092
1093 manually_resolved_promise.Resolve(10);
1094 executor_->RunUntilIdle();
1095
1096 EXPECT_FALSE(was_rejected);
1097 EXPECT_EQ(10, resolved_result);
1098 }
1099
1100 TEST_F(PromiseTest, RejectablePromise_ThenReject) {
1101 Promise<Rejectable<int, bool>> manually_resolved_promise(
1102 promise::Create<Rejectable<int, bool>>());
1103
1104 bool was_rejected = false;
1105 int resolved_result = 0;
1106 bool reject_reason = false;
1107 Promise<void> promise(manually_resolved_promise.Then(base::Bind(
1108 &OnRejectableIntBool, &was_rejected, &resolved_result, &reject_reason)));
1109
1110 executor_->StartResolve(promise);
1111
1112 manually_resolved_promise.Reject(true);
1113 executor_->RunUntilIdle();
1114
1115 EXPECT_TRUE(was_rejected);
1116 EXPECT_TRUE(reject_reason);
1117 }
1118
1119 namespace {
1120 int GetRejectionReason(Rejectable<void, int> a,
1121 Rejectable<void, int> b,
1122 Rejectable<void, int> c,
1123 Rejectable<void, int> d) {
1124 if (a.is_rejected())
1125 return a.reject_reason();
1126 if (b.is_rejected())
1127 return b.reject_reason();
1128 if (c.is_rejected())
1129 return c.reject_reason();
1130 if (d.is_rejected())
1131 return d.reject_reason();
1132 return -1;
1133 }
1134 }
1135
1136 TEST_F(PromiseTest, RejectablePromise_FastFail) {
1137 Promise<Rejectable<void, int>> promise1(
1138 promise::Create<Rejectable<void, int>>());
1139 Promise<Rejectable<void, int>> promise2(
1140 promise::Create<Rejectable<void, int>>());
1141 Promise<Rejectable<void, int>> promise3(
1142 promise::Create<Rejectable<void, int>>());
1143 Promise<Rejectable<void, int>> promise4(
1144 promise::Create<Rejectable<void, int>>());
1145 Promise<int> promise = promise::All(promise1, promise2, promise3, promise4)
1146 .Then(base::Bind(&GetRejectionReason));
1147
1148 executor_->StartResolve(promise);
1149
1150 promise4.Reject(4);
1151 executor_->RunUntilIdle();
1152
1153 EXPECT_EQ(4, promise.GetResolved());
1154 }
1155
1156 namespace {
1157 void OnRejectableIntInt(bool* was_rejected,
1158 int* resolved_result,
1159 int* reject_reason,
1160 Rejectable<int, int> result) {
1161 *was_rejected = result.is_rejected();
1162 if (result.is_rejected()) {
1163 *reject_reason = result.reject_reason();
1164 } else {
1165 DCHECK(result.is_resolved());
1166 *resolved_result = result.resolved();
1167 }
1168 }
1169 }
1170
1171 TEST_F(PromiseTest, RejectablePromise_Race) {
1172 Promise<Rejectable<int, int>> promise1(
1173 promise::Create<Rejectable<int, int>>());
1174 Promise<Rejectable<int, int>> promise2(
1175 promise::Create<Rejectable<int, int>>());
1176 Promise<Rejectable<int, int>> promise3(
1177 promise::Create<Rejectable<int, int>>());
1178 Promise<Rejectable<int, int>> promise4(
1179 promise::Create<Rejectable<int, int>>());
1180
1181 bool was_rejected = false;
1182 int resolved_result = 0;
1183 int reject_reason = 0;
1184 Promise<void> promise =
1185 promise::Race(promise1, promise2, promise3, promise4)
1186 .Then(base::Bind(&OnRejectableIntInt, &was_rejected, &resolved_result,
1187 &reject_reason));
1188
1189 executor_->StartResolve(promise);
1190
1191 promise3.Reject(3);
1192 executor_->RunUntilIdle();
1193
1194 EXPECT_TRUE(was_rejected);
1195 EXPECT_EQ(3, reject_reason);
1196 }
1197
1198 } // namespace promise
OLDNEW
« no previous file with comments | « components/scheduler/promises/promise_internal.h ('k') | components/scheduler/promises/rejectable.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698