2 // Alex Russell (slightlyoff@chromium.org)
3 // Use of this source code is governed by
4 // http://www.apache.org/licenses/LICENSE-2.0
14 var log = console.log.bind(console);
16 var rejected = Promise.reject;
17 var asyncRejected = function(reason) {
18 return new Promise(function(r) {
19 setTimeout(r.reject.bind(r, reason), 0);
23 var fulfilled = Promise.fulfill;
24 var asyncAccepted = function(value) {
25 return new Promise(function(r) {
26 setTimeout(r.fulfill.bind(r, value), 0);
30 var resolved = Promise.resolve;
31 var asyncResolved = function(value) {
32 return new Promise(function(r) {
33 setTimeout(r.resolve.bind(r, value), 0);
37 var pending = function() {
39 var future = new Promise(function(r) { resolver = r; });
42 fulfill: resolver.fulfill,
43 reject: resolver.reject,
44 resolve: resolver.resolve,
48 var dummy = { dummy: "dummy" };
49 var sentinel = { sentinel: "sentinel" };
50 var fulfilledSentinel = fulfilled(sentinel);
51 var rejectedSentinel = rejected(sentinel);
53 var async = function(desc, test) {
57 var d = new doh.Deferred();
58 test(d, d.callback.bind(d), d.errback.bind(d));
65 function prototypeMethods() {
66 t.is(typeof Promise.prototype.then, "function");
67 t.is(Promise.prototype.then.length, 2);
68 t.is(typeof Promise.prototype.catch, "function");
69 t.is(Promise.prototype.catch.length, 1);
72 for(var x in Promise.prototype) { c++; }
76 function no_arg_ctor() {
77 var future = new Promise();
78 t.is("pending", future._state);
81 function base_state() {
83 t.is(undefined, resolver);
84 var future = new Promise(function(r) { resolver = r; });
85 t.t(future instanceof Promise);
86 t.is(undefined, future._value);
87 t.is(undefined, future._error);
88 t.is("pending", future._state);
89 t.is("object", typeof resolver);
90 t.is(false, resolver._isResolved);
93 async("Is delivery delayed?", function(d) {
96 var future = new Promise(function(r) { resolver = r; });
97 future.then(function(value) {
103 t.is(future._state, "pending");
104 t.is(false, resolved);
105 // t.is(false, resolver._isResolved);
106 resolver.resolve(true);
107 // FIXME: what should future._value be here?
109 t.is("pending", future._state);
110 t.is(true, resolver._isResolved);
113 function then_does_not_return_self() {
114 var f = new Promise();
118 function catch_does_not_return_self() {
119 var f = new Promise();
120 t.t(f.catch() !== f);
123 async("Values forward correctly", function(d) {
124 var eb = d.errback.bind(d);
125 var f = fulfilled(dummy);
134 async("Errors forward correctly", function(d) {
135 var f = rejected("meh");
137 .then(log, function(e) {
144 doh.add("Resolver", [
146 function invariants() {
147 new Promise(function(r) {
148 t.is(r._isResolved, false)
149 var isResolvedPD = Object.getOwnPropertyDescriptor(r, "_isResolved");
150 t.is("function", typeof isResolvedPD.get);
151 t.is("undefined", typeof isResolvedPD.set);
152 t.t(isResolvedPD.enumerable);
153 t.f(isResolvedPD.configurable);
155 t.is("function", typeof r.fulfill);
156 t.is("function", typeof r.reject);
157 t.is("function", typeof r.resolve);
158 t.is("function", typeof r.cancel);
159 t.is("function", typeof r.timeout);
163 async("cancel", function(d) {
165 var future = new Promise(function(r) {
170 t.t(resolver._isResolved);
175 t.is("pending", future._state);
179 t.is("object", typeof e);
180 t.t(e instanceof Error);
181 // FIXME: e doesn't seem to have a .name property!!!
182 t.is("Error: Cancel", e.toString());
186 t.t(resolver._isResolved);
187 t.is("pending", future._state);
190 async("timeout", function(d) {
192 var future = new Promise(function(r) {
197 t.t(resolver._isResolved);
202 t.is("pending", future._state);
206 t.is("object", typeof e);
207 t.t(e instanceof Error);
208 t.is("Error: Timeout", e.toString());
212 t.t(resolver._isResolved);
213 t.is("pending", future._state);
216 async("resolve forwards errors", function(d) {
217 var e = new Error("synthetic");
219 var f1 = new Promise(function(r) {
222 var f2 = new Promise(function(r) {
228 t.is("object", typeof err);
229 t.t(err instanceof Error);
230 t.is("Error: synthetic", err.toString());
231 t.is(e.toString(), err.toString());
238 async("resolve forwards values", function(d) {
239 var v = new Error("synthetic");
241 var f1 = new Promise(function(r) {
244 var f2 = new Promise(function(r) {
249 t.is("object", typeof value);
250 t.t(value instanceof Error);
251 t.is("Error: synthetic", value.toString());
259 async("resolve does not forward non futures", function(d) {
260 var v = new Error("synthetic");
262 var f1 = new Promise(function(r) {
265 var f2 = new Promise(function(r) {
270 t.is("object", typeof value);
271 t.t(value instanceof Error);
272 t.is("Error: synthetic", value.toString());
280 async("resolve forwards values through then", function(d) {
281 var v = new Error("synthetic");
283 var f1 = new Promise(function(r) {
286 var f2 = new Promise(function(r) {
291 t.is("object", typeof value);
292 t.t(value instanceof Error);
293 t.is("Error: synthetic", value.toString());
295 return new Promise(function(r) {
296 r.resolve("some other value");
299 function(e) { return e; }
303 t.is("some other value", value);
310 async("Promises forward through then", function(d, then, error) {
311 // FIXME(slightlyoff)
316 async("isResolved is true while forwarding", function(d) {
319 var f2 = new Promise(function(r) {
327 async("Throwing in a then callback rejects next.", function(d, then, e) {
328 fulfilled(5).then(function(v) {
329 throw new Error("Blarg!");
330 }).then(e, function(e){then();});
334 // Inspired by the promises-tests repo.
336 async("non function rejected callbacks are ignored",
337 function(d, then, error) {
338 var nonFunction = 10;
339 rejected(dummy).then(10, then);
343 async("non function fulfilled callbacks are ignored",
344 function(d, then, error) {
345 var nonFunction = 10;
346 fulfilled(dummy).then(then, 10);
352 async("Promise.any fails on no values", function(d, then, error) {
353 Promise.any().then(error, then);
356 async("Promise.any succeeds on undefined", function(d, then, error) {
357 Promise.any(undefined).then(then, error);
360 async("Promise.any succeeds on raw values", function(d, then, error) {
361 Promise.any("thinger", undefined, [], new String("blarg")).then(then, error);
364 async("Promise.any fails on rejected", function(d, then, error) {
365 Promise.any(rejected()).then(error, then);
368 async("Promise.any succeeds on fulfilled", function(d, then, error) {
369 Promise.any(fulfilled()).then(then, error);
372 async("Promise.any succeeds on fulfilled sentinel", function(d, then, error) {
373 Promise.any(fulfilledSentinel).then(then, error);
376 async("Promise.any succeeds on asyncAccepted", function(d, then, error) {
377 Promise.any(asyncAccepted()).then(then, error);
380 async("Promise.any succeeds on value + fulfilled", function(d, then, error) {
381 Promise.any("thinger", fulfilled(dummy)).then(then, error);
384 async("Promise.any succeeds on fulfilled + rejected", function(d, then, error) {
385 Promise.any(fulfilledSentinel, rejectedSentinel).then(then, error);
388 async("Promise.any fails on rejected + fulfilled", function(d, then, error) {
389 Promise.any(rejected(dummy), fulfilled("thinger")).then(error, then);
392 async("Promise.any succeeds on pre-fulfilled + pre-rejected",
393 function(d, then, error) {
394 Promise.any(fulfilledSentinel, rejectedSentinel).then(then, error);
398 async("Promise.any succeeds on value + rejected", function(d, then, error) {
399 Promise.any("value", rejected("error")).then(then, error);
402 async("Promise.any succeeds on rejected + value", function(d, then, error) {
403 Promise.any(rejectedSentinel, "thinger").then(then, error);
408 async("Promise.every fails on no values", function(d, then, error) {
409 Promise.every().then(error, then);
412 async("Promise.every succeeds on undefined", function(d, then, error) {
413 Promise.every(undefined).then(then, error);
416 async("Promise.every succeeds on raw values", function(d, then, error) {
417 Promise.every("thinger", undefined, [], new String("blarg")).then(then, error);
420 async("Promise.every fails on rejected", function(d, then, error) {
421 Promise.any(rejected()).then(error, then);
424 async("Promise.every succeeds on fulfilled", function(d, then, error) {
425 Promise.every(fulfilled()).then(then, error);
428 async("Promise.every succeeds on asyncAccepted", function(d, then, error) {
429 Promise.every(asyncAccepted()).then(then, error);
432 async("Promise.every fails on rejected + value", function(d, then, error) {
433 Promise.every(rejected(), "thinger").then(error, then);
436 async("Promise.every fails on asyncRejected + value", function(d, then, error) {
437 Promise.every(asyncRejected(), "thinger").then(error, then);
440 async("Promise.every forwards values", function(d, then, error) {
442 Promise.every(asyncAccepted(5), "thinger").then(function(values) {
443 t.is([5, "thinger"], values);
445 Promise.every(asyncAccepted(5), "thinger").then(function(values) {
446 t.is([5, "thinger"], values);
451 async("Promise.every forwards values multiple levels",
452 function(d, then, error) {
453 Promise.every(asyncResolved(asyncResolved(5)), "thinger")
454 .then(function(values) {
455 t.is([5, "thinger"], values);
463 async("Promise.some fails on no values", function(d, then, error) {
464 Promise.some().then(error, then);
467 async("Promise.some succeeds on undefined", function(d, then, error) {
468 Promise.some(undefined).then(then, error);
471 async("Promise.some succeeds on raw values", function(d, then, error) {
472 Promise.some("thinger", undefined, [], new String("blarg")).then(then, error);
475 async("Promise.some fails on rejected", function(d, then, error) {
476 Promise.some(rejected()).then(error, then);
479 async("Promise.some succeeds on fulfilled", function(d, then, error) {
480 Promise.some(fulfilled()).then(then, error);
483 async("Promise.some succeeds on asyncAccepted", function(d, then, error) {
484 Promise.some(asyncAccepted()).then(then, error);
487 async("Promise.some succeeds on rejected + fulfilled", function(d, then, error) {
488 Promise.some(rejectedSentinel, fulfilledSentinel).then(then, error);
491 async("Promise.some succeeds on value + rejected", function(d, then, error) {
492 Promise.some("thinger", rejectedSentinel).then(then, error);
497 async("Promise.fulfill is sane", function(d, then, error) {
498 Promise.fulfill(sentinel).then(function(v) {
504 // FIXME(slightlyoff): MOAR TESTS
509 async("Promise.resolve is sane", function(d, then, error) {
510 Promise.resolve(sentinel).then(function(v) {
516 // FIXME(slightlyoff): MOAR TESTS
521 async("Promise.reject is sane", function(d, then, error) {
522 Promise.reject(sentinel).then(error, function(reason) {
523 t.is(sentinel, reason);
528 // FIXME(slightlyoff): MOAR TESTS