|
1 <!-- |
|
2 Any copyright is dedicated to the Public Domain. |
|
3 http://creativecommons.org/publicdomain/zero/1.0/ |
|
4 --> |
|
5 <html> |
|
6 <head> |
|
7 <title>Test for Promise.all, Promise.race</title> |
|
8 <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> |
|
9 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> |
|
10 </head> |
|
11 <body> |
|
12 <p id="display"></p> |
|
13 <div id="content" style="display: none"> |
|
14 |
|
15 </div> |
|
16 <pre id="test"> |
|
17 <script type="application/javascript"><!-- |
|
18 |
|
19 function promiseUtilitiesDefined() { |
|
20 ok(Promise.all, "Promise.all must be defined when Promise is enabled."); |
|
21 ok(Promise.race, "Promise.race must be defined when Promise is enabled."); |
|
22 runTest(); |
|
23 } |
|
24 |
|
25 function promiseAllEmptyArray() { |
|
26 var p = Promise.all([]); |
|
27 ok(p instanceof Promise, "Return value of Promise.all should be a Promise."); |
|
28 p.then(function(values) { |
|
29 ok(Array.isArray(values), "Resolved value should be an array."); |
|
30 is(values.length, 0, "Resolved array length should match iterable's length."); |
|
31 runTest(); |
|
32 }, function() { |
|
33 ok(false, "Promise.all shouldn't fail when iterable has no rejected Promises."); |
|
34 runTest(); |
|
35 }); |
|
36 } |
|
37 |
|
38 function promiseAllArray() { |
|
39 var p = Promise.all([1, new Date(), Promise.resolve("firefox")]); |
|
40 ok(p instanceof Promise, "Return value of Promise.all should be a Promise."); |
|
41 p.then(function(values) { |
|
42 ok(Array.isArray(values), "Resolved value should be an array."); |
|
43 is(values.length, 3, "Resolved array length should match iterable's length."); |
|
44 is(values[0], 1, "Array values should match."); |
|
45 ok(values[1] instanceof Date, "Array values should match."); |
|
46 is(values[2], "firefox", "Array values should match."); |
|
47 runTest(); |
|
48 }, function() { |
|
49 ok(false, "Promise.all shouldn't fail when iterable has no rejected Promises."); |
|
50 runTest(); |
|
51 }); |
|
52 } |
|
53 |
|
54 function promiseAllIterable() { |
|
55 function* promiseGen() { |
|
56 var i = 3; |
|
57 while (--i) { |
|
58 yield Promise.resolve(i); |
|
59 } |
|
60 |
|
61 yield new Promise(function(resolve) { |
|
62 setTimeout(resolve, 10); |
|
63 }); |
|
64 } |
|
65 |
|
66 Promise.all(promiseGen()).then(function(values) { |
|
67 is(values.length, 3, "Resolved array length should match iterable's length."); |
|
68 is(values[0], 2, "Array values should match."); |
|
69 is(values[1], 1, "Array values should match."); |
|
70 is(values[2], undefined, "Array values should match."); |
|
71 runTest(); |
|
72 }, function(e) { |
|
73 ok(false, "Promise.all shouldn't fail when an iterable is passed."); |
|
74 runTest(); |
|
75 }); |
|
76 } |
|
77 |
|
78 function promiseAllWaitsForAllPromises() { |
|
79 var arr = [ |
|
80 new Promise(function(resolve) { |
|
81 setTimeout(resolve.bind(undefined, 1), 50); |
|
82 }), |
|
83 new Promise(function(resolve) { |
|
84 setTimeout(resolve.bind(undefined, 2), 10); |
|
85 }), |
|
86 new Promise(function(resolve) { |
|
87 setTimeout(resolve.bind(undefined, new Promise(function(resolve2) { |
|
88 resolve2(3); |
|
89 })), 10); |
|
90 }), |
|
91 new Promise(function(resolve) { |
|
92 setTimeout(resolve.bind(undefined, 4), 20); |
|
93 }) |
|
94 ]; |
|
95 |
|
96 var p = Promise.all(arr); |
|
97 p.then(function(values) { |
|
98 ok(Array.isArray(values), "Resolved value should be an array."); |
|
99 is(values.length, 4, "Resolved array length should match iterable's length."); |
|
100 is(values[0], 1, "Array values should match."); |
|
101 is(values[1], 2, "Array values should match."); |
|
102 is(values[2], 3, "Array values should match."); |
|
103 is(values[3], 4, "Array values should match."); |
|
104 runTest(); |
|
105 }, function() { |
|
106 ok(false, "Promise.all shouldn't fail when iterable has no rejected Promises."); |
|
107 runTest(); |
|
108 }); |
|
109 } |
|
110 |
|
111 function promiseAllRejectFails() { |
|
112 var arr = [ |
|
113 new Promise(function(resolve) { |
|
114 setTimeout(resolve.bind(undefined, 1), 50); |
|
115 }), |
|
116 new Promise(function(resolve, reject) { |
|
117 setTimeout(reject.bind(undefined, 2), 10); |
|
118 }), |
|
119 new Promise(function(resolve) { |
|
120 setTimeout(resolve.bind(undefined, 3), 10); |
|
121 }), |
|
122 new Promise(function(resolve) { |
|
123 setTimeout(resolve.bind(undefined, 4), 20); |
|
124 }) |
|
125 ]; |
|
126 |
|
127 var p = Promise.all(arr); |
|
128 p.then(function(values) { |
|
129 ok(false, "Promise.all shouldn't resolve when iterable has rejected Promises."); |
|
130 runTest(); |
|
131 }, function(e) { |
|
132 ok(true, "Promise.all should reject when iterable has rejected Promises."); |
|
133 is(e, 2, "Rejection value should match."); |
|
134 runTest(); |
|
135 }); |
|
136 } |
|
137 |
|
138 function promiseAllCastError() { |
|
139 var p = Promise.all([Promise.resolve(2), { then: function() { foo(); } }]); |
|
140 ok(p instanceof Promise, "Should cast to a Promise."); |
|
141 p.then(function(v) { |
|
142 ok(false, "promiseAllCastError: should've rejected."); |
|
143 runTest(); |
|
144 }, function(e) { |
|
145 ok(e instanceof ReferenceError, "promiseCastThenableError"); |
|
146 runTest(); |
|
147 }); |
|
148 } |
|
149 |
|
150 // Check that the resolved array is enumerable. |
|
151 function promiseAllEnumerable() { |
|
152 var p = Promise.all([1, new Date(), Promise.resolve("firefox")]); |
|
153 p.then(function(v) { |
|
154 var count = 0; |
|
155 for (key in v) { |
|
156 ++count; |
|
157 ok(v[key] === 1 || v[key] instanceof Date || v[key] === "firefox", |
|
158 "Enumerated properties don't match."); |
|
159 } |
|
160 is(count, 3, "Resolved array from Promise.all should be enumerable"); |
|
161 runTest(); |
|
162 }, function(e) { |
|
163 ok(false, "promiseAllEnumerable: should've resolved."); |
|
164 runTest(); |
|
165 }); |
|
166 } |
|
167 |
|
168 function promiseRaceEmpty() { |
|
169 var p = Promise.race([]); |
|
170 ok(p instanceof Promise, "Should return a Promise."); |
|
171 p.then(function() { |
|
172 ok(false, "Should not resolve"); |
|
173 }, function() { |
|
174 ok(false, "Should not reject"); |
|
175 }); |
|
176 // Per spec, An empty race never resolves or rejects. |
|
177 setTimeout(function() { |
|
178 ok(true); |
|
179 runTest(); |
|
180 }, 50); |
|
181 } |
|
182 |
|
183 function promiseRaceValuesArray() { |
|
184 var p = Promise.race([true, new Date(), 3]); |
|
185 ok(p instanceof Promise, "Should return a Promise."); |
|
186 p.then(function(winner) { |
|
187 is(winner, true, "First value should win."); |
|
188 runTest(); |
|
189 }, function(err) { |
|
190 ok(false, "Should not fail " + err + "."); |
|
191 runTest(); |
|
192 }); |
|
193 } |
|
194 |
|
195 function promiseRacePromiseArray() { |
|
196 function timeoutPromise(n) { |
|
197 return new Promise(function(resolve) { |
|
198 setTimeout(function() { |
|
199 resolve(n); |
|
200 }, n); |
|
201 }); |
|
202 } |
|
203 |
|
204 var arr = [ |
|
205 new Promise(function(resolve) { |
|
206 resolve("first"); |
|
207 }), |
|
208 Promise.resolve("second"), |
|
209 new Promise(function() {}), |
|
210 new Promise(function(resolve) { |
|
211 setTimeout(function() { |
|
212 setTimeout(function() { |
|
213 resolve("fourth"); |
|
214 }, 0); |
|
215 }, 0); |
|
216 }), |
|
217 ]; |
|
218 |
|
219 var p = Promise.race(arr); |
|
220 p.then(function(winner) { |
|
221 is(winner, "first", "First queued resolution should win the race."); |
|
222 runTest(); |
|
223 }); |
|
224 } |
|
225 |
|
226 function promiseRaceIterable() { |
|
227 function* participants() { |
|
228 yield new Promise(function(resolve) { |
|
229 setTimeout(resolve, 10, 10); |
|
230 }); |
|
231 yield new Promise(function(resolve) { |
|
232 setTimeout(resolve, 20, 20); |
|
233 }); |
|
234 } |
|
235 |
|
236 Promise.race(participants()).then(function(winner) { |
|
237 is(winner, 10, "Winner should be the one that finished earlier."); |
|
238 runTest(); |
|
239 }, function(e) { |
|
240 ok(false, "Promise.race shouldn't throw when an iterable is passed!"); |
|
241 runTest(); |
|
242 }); |
|
243 } |
|
244 |
|
245 function promiseRaceReject() { |
|
246 var p = Promise.race([ |
|
247 Promise.reject(new Error("Fail bad!")), |
|
248 new Promise(function(resolve) { |
|
249 setTimeout(resolve, 0); |
|
250 }) |
|
251 ]); |
|
252 |
|
253 p.then(function() { |
|
254 ok(false, "Should not resolve when winning Promise rejected."); |
|
255 runTest(); |
|
256 }, function(e) { |
|
257 ok(true, "Should be rejected"); |
|
258 ok(e instanceof Error, "Should reject with Error."); |
|
259 ok(e.message == "Fail bad!", "Message should match."); |
|
260 runTest(); |
|
261 }); |
|
262 } |
|
263 |
|
264 function promiseRaceThrow() { |
|
265 var p = Promise.race([ |
|
266 new Promise(function(resolve) { |
|
267 nonExistent(); |
|
268 }), |
|
269 new Promise(function(resolve) { |
|
270 setTimeout(resolve, 0); |
|
271 }) |
|
272 ]); |
|
273 |
|
274 p.then(function() { |
|
275 ok(false, "Should not resolve when winning Promise had an error."); |
|
276 runTest(); |
|
277 }, function(e) { |
|
278 ok(true, "Should be rejected"); |
|
279 ok(e instanceof ReferenceError, "Should reject with ReferenceError for function nonExistent()."); |
|
280 runTest(); |
|
281 }); |
|
282 } |
|
283 |
|
284 var tests = [ |
|
285 promiseUtilitiesDefined, |
|
286 promiseAllEmptyArray, |
|
287 promiseAllArray, |
|
288 promiseAllIterable, |
|
289 promiseAllWaitsForAllPromises, |
|
290 promiseAllRejectFails, |
|
291 promiseAllCastError, |
|
292 promiseAllEnumerable, |
|
293 |
|
294 promiseRaceEmpty, |
|
295 promiseRaceValuesArray, |
|
296 promiseRacePromiseArray, |
|
297 promiseRaceIterable, |
|
298 promiseRaceReject, |
|
299 promiseRaceThrow, |
|
300 ]; |
|
301 |
|
302 function runTest() { |
|
303 if (!tests.length) { |
|
304 SimpleTest.finish(); |
|
305 return; |
|
306 } |
|
307 |
|
308 var test = tests.shift(); |
|
309 test(); |
|
310 } |
|
311 |
|
312 SimpleTest.waitForExplicitFinish(); |
|
313 runTest(); |
|
314 // --> |
|
315 </script> |
|
316 </pre> |
|
317 </body> |
|
318 </html> |
|
319 |