Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing code.
1 function ok(a, msg) {
2 dump("OK: " + !!a + " => " + a + " " + msg + "\n");
3 postMessage({type: 'status', status: !!a, msg: a + ": " + msg });
4 }
6 function is(a, b, msg) {
7 dump("IS: " + (a===b) + " => " + a + " | " + b + " " + msg + "\n");
8 postMessage({type: 'status', status: a === b, msg: a + " === " + b + ": " + msg });
9 }
11 function isnot(a, b, msg) {
12 dump("ISNOT: " + (a!==b) + " => " + a + " | " + b + " " + msg + "\n");
13 postMessage({type: 'status', status: a !== b, msg: a + " !== " + b + ": " + msg });
14 }
16 function promiseResolve() {
17 ok(Promise, "Promise object should exist");
19 var promise = new Promise(function(resolve, reject) {
20 ok(resolve, "Promise.resolve exists");
21 ok(reject, "Promise.reject exists");
23 resolve(42);
24 }).then(function(what) {
25 ok(true, "Then - resolveCb has been called");
26 is(what, 42, "ResolveCb received 42");
27 runTest();
28 }, function() {
29 ok(false, "Then - rejectCb has been called");
30 runTest();
31 });
32 }
34 function promiseResolveNoArg() {
35 var promise = new Promise(function(resolve, reject) {
36 ok(resolve, "Promise.resolve exists");
37 ok(reject, "Promise.reject exists");
39 resolve();
40 }).then(function(what) {
41 ok(true, "Then - resolveCb has been called");
42 is(what, undefined, "ResolveCb received undefined");
43 runTest();
44 }, function() {
45 ok(false, "Then - rejectCb has been called");
46 runTest();
47 });
48 }
50 function promiseRejectNoHandler() {
51 // This test only checks that the code that reports unhandled errors in the
52 // Promises implementation does not crash or leak.
53 var promise = new Promise(function(res, rej) {
54 noSuchMethod();
55 });
56 runTest();
57 }
59 function promiseReject() {
60 var promise = new Promise(function(resolve, reject) {
61 reject(42);
62 }).then(function(what) {
63 ok(false, "Then - resolveCb has been called");
64 runTest();
65 }, function(what) {
66 ok(true, "Then - rejectCb has been called");
67 is(what, 42, "RejectCb received 42");
68 runTest();
69 });
70 }
72 function promiseRejectNoArg() {
73 var promise = new Promise(function(resolve, reject) {
74 reject();
75 }).then(function(what) {
76 ok(false, "Then - resolveCb has been called");
77 runTest();
78 }, function(what) {
79 ok(true, "Then - rejectCb has been called");
80 is(what, undefined, "RejectCb received undefined");
81 runTest();
82 });
83 }
85 function promiseException() {
86 var promise = new Promise(function(resolve, reject) {
87 throw 42;
88 }).then(function(what) {
89 ok(false, "Then - resolveCb has been called");
90 runTest();
91 }, function(what) {
92 ok(true, "Then - rejectCb has been called");
93 is(what, 42, "RejectCb received 42");
94 runTest();
95 });
96 }
98 function promiseAsync() {
99 var global = "foo";
100 var f = new Promise(function(r1, r2) {
101 is(global, "foo", "Global should be foo");
102 r1(42);
103 is(global, "foo", "Global should still be foo");
104 setTimeout(function() {
105 is(global, "bar", "Global should still be bar!");
106 runTest();
107 }, 0);
108 }).then(function() {
109 global = "bar";
110 });
111 is(global, "foo", "Global should still be foo (2)");
112 }
114 function promiseDoubleThen() {
115 var steps = 0;
116 var promise = new Promise(function(r1, r2) {
117 r1(42);
118 });
120 promise.then(function(what) {
121 ok(true, "Then.resolve has been called");
122 is(what, 42, "Value == 42");
123 steps++;
124 }, function(what) {
125 ok(false, "Then.reject has been called");
126 });
128 promise.then(function(what) {
129 ok(true, "Then.resolve has been called");
130 is(steps, 1, "Then.resolve - step == 1");
131 is(what, 42, "Value == 42");
132 runTest();
133 }, function(what) {
134 ok(false, "Then.reject has been called");
135 });
136 }
138 function promiseThenException() {
139 var promise = new Promise(function(resolve, reject) {
140 resolve(42);
141 });
143 promise.then(function(what) {
144 ok(true, "Then.resolve has been called");
145 throw "booh";
146 }).catch(function(e) {
147 ok(true, "Catch has been called!");
148 runTest();
149 });
150 }
152 function promiseThenCatchThen() {
153 var promise = new Promise(function(resolve, reject) {
154 resolve(42);
155 });
157 var promise2 = promise.then(function(what) {
158 ok(true, "Then.resolve has been called");
159 is(what, 42, "Value == 42");
160 return what + 1;
161 }, function(what) {
162 ok(false, "Then.reject has been called");
163 });
165 isnot(promise, promise2, "These 2 promise objs are different");
167 promise2.then(function(what) {
168 ok(true, "Then.resolve has been called");
169 is(what, 43, "Value == 43");
170 return what + 1;
171 }, function(what) {
172 ok(false, "Then.reject has been called");
173 }).catch(function() {
174 ok(false, "Catch has been called");
175 }).then(function(what) {
176 ok(true, "Then.resolve has been called");
177 is(what, 44, "Value == 44");
178 runTest();
179 }, function(what) {
180 ok(false, "Then.reject has been called");
181 });
182 }
184 function promiseRejectThenCatchThen() {
185 var promise = new Promise(function(resolve, reject) {
186 reject(42);
187 });
189 var promise2 = promise.then(function(what) {
190 ok(false, "Then.resolve has been called");
191 }, function(what) {
192 ok(true, "Then.reject has been called");
193 is(what, 42, "Value == 42");
194 return what + 1;
195 });
197 isnot(promise, promise2, "These 2 promise objs are different");
199 promise2.then(function(what) {
200 ok(true, "Then.resolve has been called");
201 is(what, 43, "Value == 43");
202 return what+1;
203 }).catch(function(what) {
204 ok(false, "Catch has been called");
205 }).then(function(what) {
206 ok(true, "Then.resolve has been called");
207 is(what, 44, "Value == 44");
208 runTest();
209 });
210 }
212 function promiseRejectThenCatchThen2() {
213 var promise = new Promise(function(resolve, reject) {
214 reject(42);
215 });
217 promise.then(function(what) {
218 ok(true, "Then.resolve has been called");
219 is(what, 42, "Value == 42");
220 return what+1;
221 }).catch(function(what) {
222 is(what, 42, "Value == 42");
223 ok(true, "Catch has been called");
224 return what+1;
225 }).then(function(what) {
226 ok(true, "Then.resolve has been called");
227 is(what, 43, "Value == 43");
228 runTest();
229 });
230 }
232 function promiseRejectThenCatchExceptionThen() {
233 var promise = new Promise(function(resolve, reject) {
234 reject(42);
235 });
237 promise.then(function(what) {
238 ok(false, "Then.resolve has been called");
239 }, function(what) {
240 ok(true, "Then.reject has been called");
241 is(what, 42, "Value == 42");
242 throw(what + 1);
243 }).catch(function(what) {
244 ok(true, "Catch has been called");
245 is(what, 43, "Value == 43");
246 return what + 1;
247 }).then(function(what) {
248 ok(true, "Then.resolve has been called");
249 is(what, 44, "Value == 44");
250 runTest();
251 });
252 }
254 function promiseThenCatchOrderingResolve() {
255 var global = 0;
256 var f = new Promise(function(r1, r2) {
257 r1(42);
258 });
260 f.then(function() {
261 f.then(function() {
262 global++;
263 });
264 f.catch(function() {
265 global++;
266 });
267 f.then(function() {
268 global++;
269 });
270 setTimeout(function() {
271 is(global, 2, "Many steps... should return 2");
272 runTest();
273 }, 0);
274 });
275 }
277 function promiseThenCatchOrderingReject() {
278 var global = 0;
279 var f = new Promise(function(r1, r2) {
280 r2(42);
281 })
283 f.then(function() {}, function() {
284 f.then(function() {
285 global++;
286 });
287 f.catch(function() {
288 global++;
289 });
290 f.then(function() {}, function() {
291 global++;
292 });
293 setTimeout(function() {
294 is(global, 2, "Many steps... should return 2");
295 runTest();
296 }, 0);
297 });
298 }
300 function promiseThenNoArg() {
301 var promise = new Promise(function(resolve, reject) {
302 resolve(42);
303 });
305 var clone = promise.then();
306 isnot(promise, clone, "These 2 promise objs are different");
307 promise.then(function(v) {
308 clone.then(function(cv) {
309 is(v, cv, "Both resolve to the same value");
310 runTest();
311 });
312 });
313 }
315 function promiseThenUndefinedResolveFunction() {
316 var promise = new Promise(function(resolve, reject) {
317 reject(42);
318 });
320 try {
321 promise.then(undefined, function(v) {
322 is(v, 42, "Promise rejected with 42");
323 runTest();
324 });
325 } catch (e) {
326 ok(false, "then should not throw on undefined resolve function");
327 }
328 }
330 function promiseThenNullResolveFunction() {
331 var promise = new Promise(function(resolve, reject) {
332 reject(42);
333 });
335 try {
336 promise.then(null, function(v) {
337 is(v, 42, "Promise rejected with 42");
338 runTest();
339 });
340 } catch (e) {
341 ok(false, "then should not throw on null resolve function");
342 }
343 }
345 function promiseCatchNoArg() {
346 var promise = new Promise(function(resolve, reject) {
347 reject(42);
348 });
350 var clone = promise.catch();
351 isnot(promise, clone, "These 2 promise objs are different");
352 promise.catch(function(v) {
353 clone.catch(function(cv) {
354 is(v, cv, "Both reject to the same value");
355 runTest();
356 });
357 });
358 }
360 function promiseNestedPromise() {
361 new Promise(function(resolve, reject) {
362 resolve(new Promise(function(resolve, reject) {
363 ok(true, "Nested promise is executed");
364 resolve(42);
365 }));
366 }).then(function(value) {
367 is(value, 42, "Nested promise is executed and then == 42");
368 runTest();
369 });
370 }
372 function promiseNestedNestedPromise() {
373 new Promise(function(resolve, reject) {
374 resolve(new Promise(function(resolve, reject) {
375 ok(true, "Nested promise is executed");
376 resolve(42);
377 }).then(function(what) { return what+1; }));
378 }).then(function(value) {
379 is(value, 43, "Nested promise is executed and then == 43");
380 runTest();
381 });
382 }
384 function promiseWrongNestedPromise() {
385 new Promise(function(resolve, reject) {
386 resolve(new Promise(function(r, r2) {
387 ok(true, "Nested promise is executed");
388 r(42);
389 }));
390 reject(42);
391 }).then(function(value) {
392 is(value, 42, "Nested promise is executed and then == 42");
393 runTest();
394 }, function(value) {
395 ok(false, "This is wrong");
396 });
397 }
399 function promiseLoop() {
400 new Promise(function(resolve, reject) {
401 resolve(new Promise(function(r1, r2) {
402 ok(true, "Nested promise is executed");
403 r1(new Promise(function(r1, r2) {
404 ok(true, "Nested nested promise is executed");
405 r1(42);
406 }));
407 }));
408 }).then(function(value) {
409 is(value, 42, "Nested nested promise is executed and then == 42");
410 runTest();
411 }, function(value) {
412 ok(false, "This is wrong");
413 });
414 }
416 function promiseStaticReject() {
417 var promise = Promise.reject(42).then(function(what) {
418 ok(false, "This should not be called");
419 }, function(what) {
420 is(what, 42, "Value == 42");
421 runTest();
422 });
423 }
425 function promiseStaticResolve() {
426 var promise = Promise.resolve(42).then(function(what) {
427 is(what, 42, "Value == 42");
428 runTest();
429 }, function() {
430 ok(false, "This should not be called");
431 });
432 }
434 function promiseResolveNestedPromise() {
435 var promise = Promise.resolve(new Promise(function(r, r2) {
436 ok(true, "Nested promise is executed");
437 r(42);
438 }, function() {
439 ok(false, "This should not be called");
440 })).then(function(what) {
441 is(what, 42, "Value == 42");
442 runTest();
443 }, function() {
444 ok(false, "This should not be called");
445 });
446 }
448 function promiseRejectNoHandler() {
449 // This test only checks that the code that reports unhandled errors in the
450 // Promises implementation does not crash or leak.
451 var promise = new Promise(function(res, rej) {
452 noSuchMethod();
453 });
454 runTest();
455 }
457 function promiseUtilitiesDefined() {
458 ok(Promise.all, "Promise.all must be defined when Promise is enabled.");
459 ok(Promise.race, "Promise.race must be defined when Promise is enabled.");
460 runTest();
461 }
463 function promiseAllArray() {
464 var p = Promise.all([1, new Date(), Promise.resolve("firefox")]);
465 ok(p instanceof Promise, "Return value of Promise.all should be a Promise.");
466 p.then(function(values) {
467 ok(Array.isArray(values), "Resolved value should be an array.");
468 is(values.length, 3, "Resolved array length should match iterable's length.");
469 is(values[0], 1, "Array values should match.");
470 ok(values[1] instanceof Date, "Array values should match.");
471 is(values[2], "firefox", "Array values should match.");
472 runTest();
473 }, function() {
474 ok(false, "Promise.all shouldn't fail when iterable has no rejected Promises.");
475 runTest();
476 });
477 }
479 function promiseAllWaitsForAllPromises() {
480 var arr = [
481 new Promise(function(resolve) {
482 setTimeout(resolve.bind(undefined, 1), 50);
483 }),
484 new Promise(function(resolve) {
485 setTimeout(resolve.bind(undefined, 2), 10);
486 }),
487 new Promise(function(resolve) {
488 setTimeout(resolve.bind(undefined, new Promise(function(resolve2) {
489 resolve2(3);
490 })), 10);
491 }),
492 new Promise(function(resolve) {
493 setTimeout(resolve.bind(undefined, 4), 20);
494 })
495 ];
497 var p = Promise.all(arr);
498 p.then(function(values) {
499 ok(Array.isArray(values), "Resolved value should be an array.");
500 is(values.length, 4, "Resolved array length should match iterable's length.");
501 is(values[0], 1, "Array values should match.");
502 is(values[1], 2, "Array values should match.");
503 is(values[2], 3, "Array values should match.");
504 is(values[3], 4, "Array values should match.");
505 runTest();
506 }, function() {
507 ok(false, "Promise.all shouldn't fail when iterable has no rejected Promises.");
508 runTest();
509 });
510 }
512 function promiseAllRejectFails() {
513 var arr = [
514 new Promise(function(resolve) {
515 setTimeout(resolve.bind(undefined, 1), 50);
516 }),
517 new Promise(function(resolve, reject) {
518 setTimeout(reject.bind(undefined, 2), 10);
519 }),
520 new Promise(function(resolve) {
521 setTimeout(resolve.bind(undefined, 3), 10);
522 }),
523 new Promise(function(resolve) {
524 setTimeout(resolve.bind(undefined, 4), 20);
525 })
526 ];
528 var p = Promise.all(arr);
529 p.then(function(values) {
530 ok(false, "Promise.all shouldn't resolve when iterable has rejected Promises.");
531 runTest();
532 }, function(e) {
533 ok(true, "Promise.all should reject when iterable has rejected Promises.");
534 is(e, 2, "Rejection value should match.");
535 runTest();
536 });
537 }
539 function promiseRaceEmpty() {
540 var p = Promise.race([]);
541 ok(p instanceof Promise, "Should return a Promise.");
542 // An empty race never resolves!
543 runTest();
544 }
546 function promiseRaceValuesArray() {
547 var p = Promise.race([true, new Date(), 3]);
548 ok(p instanceof Promise, "Should return a Promise.");
549 p.then(function(winner) {
550 is(winner, true, "First value should win.");
551 runTest();
552 }, function(err) {
553 ok(false, "Should not fail " + err + ".");
554 runTest();
555 });
556 }
558 function promiseRacePromiseArray() {
559 var arr = [
560 new Promise(function(resolve) {
561 resolve("first");
562 }),
563 Promise.resolve("second"),
564 new Promise(function() {}),
565 new Promise(function(resolve) {
566 setTimeout(function() {
567 setTimeout(function() {
568 resolve("fourth");
569 }, 0);
570 }, 0);
571 }),
572 ];
574 var p = Promise.race(arr);
575 p.then(function(winner) {
576 is(winner, "first", "First queued resolution should win the race.");
577 runTest();
578 });
579 }
581 function promiseRaceReject() {
582 var p = Promise.race([
583 Promise.reject(new Error("Fail bad!")),
584 new Promise(function(resolve) {
585 setTimeout(resolve, 0);
586 })
587 ]);
589 p.then(function() {
590 ok(false, "Should not resolve when winning Promise rejected.");
591 runTest();
592 }, function(e) {
593 ok(true, "Should be rejected");
594 ok(e instanceof Error, "Should reject with Error.");
595 ok(e.message == "Fail bad!", "Message should match.");
596 runTest();
597 });
598 }
600 function promiseRaceThrow() {
601 var p = Promise.race([
602 new Promise(function(resolve) {
603 nonExistent();
604 }),
605 new Promise(function(resolve) {
606 setTimeout(resolve, 0);
607 })
608 ]);
610 p.then(function() {
611 ok(false, "Should not resolve when winning Promise had an error.");
612 runTest();
613 }, function(e) {
614 ok(true, "Should be rejected");
615 ok(e instanceof ReferenceError, "Should reject with ReferenceError for function nonExistent().");
616 runTest();
617 });
618 }
620 function promiseResolveArray() {
621 var p = Promise.resolve([1,2,3]);
622 ok(p instanceof Promise, "Should return a Promise.");
623 p.then(function(v) {
624 ok(Array.isArray(v), "Resolved value should be an Array");
625 is(v.length, 3, "Length should match");
626 is(v[0], 1, "Resolved value should match original");
627 is(v[1], 2, "Resolved value should match original");
628 is(v[2], 3, "Resolved value should match original");
629 runTest();
630 });
631 }
633 function promiseResolveThenable() {
634 var p = Promise.resolve({ then: function(onFulfill, onReject) { onFulfill(2); } });
635 ok(p instanceof Promise, "Should cast to a Promise.");
636 p.then(function(v) {
637 is(v, 2, "Should resolve to 2.");
638 runTest();
639 }, function(e) {
640 ok(false, "promiseResolveThenable should've resolved");
641 runTest();
642 });
643 }
645 function promiseResolvePromise() {
646 var original = Promise.resolve(true);
647 var cast = Promise.resolve(original);
649 ok(cast instanceof Promise, "Should cast to a Promise.");
650 is(cast, original, "Should return original Promise.");
651 cast.then(function(v) {
652 is(v, true, "Should resolve to true.");
653 runTest();
654 });
655 }
657 var tests = [
658 promiseResolve,
659 promiseReject,
660 promiseException,
661 promiseAsync,
662 promiseDoubleThen,
663 promiseThenException,
664 promiseThenCatchThen,
665 promiseRejectThenCatchThen,
666 promiseRejectThenCatchThen2,
667 promiseRejectThenCatchExceptionThen,
668 promiseThenCatchOrderingResolve,
669 promiseThenCatchOrderingReject,
670 promiseNestedPromise,
671 promiseNestedNestedPromise,
672 promiseWrongNestedPromise,
673 promiseLoop,
674 promiseStaticReject,
675 promiseStaticResolve,
676 promiseResolveNestedPromise,
677 promiseResolveNoArg,
678 promiseRejectNoArg,
680 promiseThenNoArg,
681 promiseThenUndefinedResolveFunction,
682 promiseThenNullResolveFunction,
683 promiseCatchNoArg,
684 promiseRejectNoHandler,
686 promiseUtilitiesDefined,
688 promiseAllArray,
689 promiseAllWaitsForAllPromises,
690 promiseAllRejectFails,
692 promiseRaceEmpty,
693 promiseRaceValuesArray,
694 promiseRacePromiseArray,
695 promiseRaceReject,
696 promiseRaceThrow,
698 promiseResolveArray,
699 promiseResolveThenable,
700 promiseResolvePromise,
701 ];
703 function runTest() {
704 if (!tests.length) {
705 postMessage({ type: 'finish' });
706 return;
707 }
709 var test = tests.shift();
710 test();
711 }
713 onmessage = function() {
714 runTest();
715 }