зеркало из https://github.com/mozilla/gecko-dev.git
622 строки
15 KiB
HTML
622 строки
15 KiB
HTML
<!--
|
|
Any copyright is dedicated to the Public Domain.
|
|
http://creativecommons.org/publicdomain/zero/1.0/
|
|
-->
|
|
<html>
|
|
<head>
|
|
<title>Basic Promise Test</title>
|
|
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
|
</head>
|
|
<body>
|
|
<p id="display"></p>
|
|
<div id="content" style="display: none">
|
|
|
|
</div>
|
|
<pre id="test">
|
|
<script type="application/javascript"><!--
|
|
|
|
function promiseResolve() {
|
|
ok(Promise, "Promise object should exist");
|
|
|
|
var promise = new Promise(function(resolve, reject) {
|
|
ok(resolve, "Promise.resolve exists");
|
|
ok(reject, "Promise.reject exists");
|
|
|
|
resolve(42);
|
|
}).then(function(what) {
|
|
ok(true, "Then - resolveCb has been called");
|
|
is(what, 42, "ResolveCb received 42");
|
|
runTest();
|
|
}, function() {
|
|
ok(false, "Then - rejectCb has been called");
|
|
runTest();
|
|
});
|
|
}
|
|
|
|
function promiseResolveNoArg() {
|
|
var promise = new Promise(function(resolve, reject) {
|
|
ok(resolve, "Promise.resolve exists");
|
|
ok(reject, "Promise.reject exists");
|
|
|
|
resolve();
|
|
}).then(function(what) {
|
|
ok(true, "Then - resolveCb has been called");
|
|
is(what, undefined, "ResolveCb received undefined");
|
|
runTest();
|
|
}, function() {
|
|
ok(false, "Then - rejectCb has been called");
|
|
runTest();
|
|
});
|
|
}
|
|
|
|
function promiseReject() {
|
|
var promise = new Promise(function(resolve, reject) {
|
|
reject(42);
|
|
}).then(function(what) {
|
|
ok(false, "Then - resolveCb has been called");
|
|
runTest();
|
|
}, function(what) {
|
|
ok(true, "Then - rejectCb has been called");
|
|
is(what, 42, "RejectCb received 42");
|
|
runTest();
|
|
});
|
|
}
|
|
|
|
function promiseRejectNoHandler() {
|
|
// This test only checks that the code that reports unhandled errors in the
|
|
// Promises implementation does not crash or leak.
|
|
var promise = new Promise(function(res, rej) {
|
|
noSuchMethod();
|
|
});
|
|
runTest();
|
|
}
|
|
|
|
function promiseRejectNoArg() {
|
|
var promise = new Promise(function(resolve, reject) {
|
|
reject();
|
|
}).then(function(what) {
|
|
ok(false, "Then - resolveCb has been called");
|
|
runTest();
|
|
}, function(what) {
|
|
ok(true, "Then - rejectCb has been called");
|
|
is(what, undefined, "RejectCb received undefined");
|
|
runTest();
|
|
});
|
|
}
|
|
|
|
function promiseException() {
|
|
var promise = new Promise(function(resolve, reject) {
|
|
throw 42;
|
|
}).then(function(what) {
|
|
ok(false, "Then - resolveCb has been called");
|
|
runTest();
|
|
}, function(what) {
|
|
ok(true, "Then - rejectCb has been called");
|
|
is(what, 42, "RejectCb received 42");
|
|
runTest();
|
|
});
|
|
}
|
|
|
|
function promiseGC() {
|
|
var resolve;
|
|
var promise = new Promise(function(r1, r2) {
|
|
resolve = r1;
|
|
}).then(function(what) {
|
|
ok(true, "Then - promise is still alive");
|
|
runTest();
|
|
});
|
|
|
|
promise = null;
|
|
|
|
SpecialPowers.gc();
|
|
SpecialPowers.forceGC();
|
|
SpecialPowers.forceCC();
|
|
|
|
resolve(42);
|
|
}
|
|
|
|
function promiseAsync() {
|
|
var global = "foo";
|
|
var f = new Promise(function(r1, r2) {
|
|
is(global, "foo", "Global should be foo");
|
|
r1(42);
|
|
is(global, "foo", "Global should still be foo");
|
|
setTimeout(function() {
|
|
is(global, "bar", "Global should still be bar!");
|
|
runTest();
|
|
}, 0);
|
|
}).then(function() {
|
|
global = "bar";
|
|
});
|
|
is(global, "foo", "Global should still be foo (2)");
|
|
}
|
|
|
|
function promiseDoubleThen() {
|
|
var steps = 0;
|
|
var promise = new Promise(function(r1, r2) {
|
|
r1(42);
|
|
});
|
|
|
|
promise.then(function(what) {
|
|
ok(true, "Then.resolve has been called");
|
|
is(what, 42, "Value == 42");
|
|
steps++;
|
|
}, function(what) {
|
|
ok(false, "Then.reject has been called");
|
|
});
|
|
|
|
promise.then(function(what) {
|
|
ok(true, "Then.resolve has been called");
|
|
is(steps, 1, "Then.resolve - step == 1");
|
|
is(what, 42, "Value == 42");
|
|
runTest();
|
|
}, function(what) {
|
|
ok(false, "Then.reject has been called");
|
|
});
|
|
}
|
|
|
|
function promiseThenException() {
|
|
var promise = new Promise(function(resolve, reject) {
|
|
resolve(42);
|
|
});
|
|
|
|
promise.then(function(what) {
|
|
ok(true, "Then.resolve has been called");
|
|
throw "booh";
|
|
}).catch(function(e) {
|
|
ok(true, "window.onerror has been called!");
|
|
runTest();
|
|
});
|
|
}
|
|
|
|
function promiseThenCatchThen() {
|
|
var promise = new Promise(function(resolve, reject) {
|
|
resolve(42);
|
|
});
|
|
|
|
var promise2 = promise.then(function(what) {
|
|
ok(true, "Then.resolve has been called");
|
|
is(what, 42, "Value == 42");
|
|
return what + 1;
|
|
}, function(what) {
|
|
ok(false, "Then.reject has been called");
|
|
});
|
|
|
|
isnot(promise, promise2, "These 2 promise objs are different");
|
|
|
|
promise2.then(function(what) {
|
|
ok(true, "Then.resolve has been called");
|
|
is(what, 43, "Value == 43");
|
|
return what + 1;
|
|
}, function(what) {
|
|
ok(false, "Then.reject has been called");
|
|
}).catch(function() {
|
|
ok(false, "Catch has been called");
|
|
}).then(function(what) {
|
|
ok(true, "Then.resolve has been called");
|
|
is(what, 44, "Value == 44");
|
|
runTest();
|
|
}, function(what) {
|
|
ok(false, "Then.reject has been called");
|
|
});
|
|
}
|
|
|
|
function promiseThenNoArg() {
|
|
var promise = new Promise(function(resolve, reject) {
|
|
resolve(42);
|
|
});
|
|
|
|
var clone = promise.then();
|
|
isnot(promise, clone, "These 2 promise objs are different");
|
|
promise.then(function(v) {
|
|
clone.then(function(cv) {
|
|
is(v, cv, "Both resolve to the same value");
|
|
runTest();
|
|
});
|
|
});
|
|
}
|
|
|
|
function promiseThenUndefinedResolveFunction() {
|
|
var promise = new Promise(function(resolve, reject) {
|
|
reject(42);
|
|
});
|
|
|
|
try {
|
|
promise.then(undefined, function(v) {
|
|
is(v, 42, "Promise rejected with 42");
|
|
runTest();
|
|
});
|
|
} catch (e) {
|
|
ok(false, "then should not throw on undefined resolve function");
|
|
}
|
|
}
|
|
|
|
function promiseThenNullResolveFunction() {
|
|
var promise = new Promise(function(resolve, reject) {
|
|
reject(42);
|
|
});
|
|
|
|
try {
|
|
promise.then(null, function(v) {
|
|
is(v, 42, "Promise rejected with 42");
|
|
runTest();
|
|
});
|
|
} catch (e) {
|
|
ok(false, "then should not throw on null resolve function");
|
|
}
|
|
}
|
|
|
|
function promiseRejectThenCatchThen() {
|
|
var promise = new Promise(function(resolve, reject) {
|
|
reject(42);
|
|
});
|
|
|
|
var promise2 = promise.then(function(what) {
|
|
ok(false, "Then.resolve has been called");
|
|
}, function(what) {
|
|
ok(true, "Then.reject has been called");
|
|
is(what, 42, "Value == 42");
|
|
return what + 1;
|
|
});
|
|
|
|
isnot(promise, promise2, "These 2 promise objs are different");
|
|
|
|
promise2.then(function(what) {
|
|
ok(true, "Then.resolve has been called");
|
|
is(what, 43, "Value == 43");
|
|
return what+1;
|
|
}).catch(function(what) {
|
|
ok(false, "Catch has been called");
|
|
}).then(function(what) {
|
|
ok(true, "Then.resolve has been called");
|
|
is(what, 44, "Value == 44");
|
|
runTest();
|
|
});
|
|
}
|
|
|
|
function promiseRejectThenCatchThen2() {
|
|
var promise = new Promise(function(resolve, reject) {
|
|
reject(42);
|
|
});
|
|
|
|
promise.then(function(what) {
|
|
ok(true, "Then.resolve has been called");
|
|
is(what, 42, "Value == 42");
|
|
return what+1;
|
|
}).catch(function(what) {
|
|
is(what, 42, "Value == 42");
|
|
ok(true, "Catch has been called");
|
|
return what+1;
|
|
}).then(function(what) {
|
|
ok(true, "Then.resolve has been called");
|
|
is(what, 43, "Value == 43");
|
|
runTest();
|
|
});
|
|
}
|
|
|
|
function promiseRejectThenCatchExceptionThen() {
|
|
var promise = new Promise(function(resolve, reject) {
|
|
reject(42);
|
|
});
|
|
|
|
promise.then(function(what) {
|
|
ok(false, "Then.resolve has been called");
|
|
}, function(what) {
|
|
ok(true, "Then.reject has been called");
|
|
is(what, 42, "Value == 42");
|
|
throw(what + 1);
|
|
}).catch(function(what) {
|
|
ok(true, "Catch has been called");
|
|
is(what, 43, "Value == 43");
|
|
return what + 1;
|
|
}).then(function(what) {
|
|
ok(true, "Then.resolve has been called");
|
|
is(what, 44, "Value == 44");
|
|
runTest();
|
|
});
|
|
}
|
|
|
|
function promiseThenCatchOrderingResolve() {
|
|
var global = 0;
|
|
var f = new Promise(function(r1, r2) {
|
|
r1(42);
|
|
});
|
|
|
|
f.then(function() {
|
|
f.then(function() {
|
|
global++;
|
|
});
|
|
f.catch(function() {
|
|
global++;
|
|
});
|
|
f.then(function() {
|
|
global++;
|
|
});
|
|
setTimeout(function() {
|
|
is(global, 2, "Many steps... should return 2");
|
|
runTest();
|
|
}, 0);
|
|
});
|
|
}
|
|
|
|
function promiseThenCatchOrderingReject() {
|
|
var global = 0;
|
|
var f = new Promise(function(r1, r2) {
|
|
r2(42);
|
|
})
|
|
|
|
f.then(function() {}, function() {
|
|
f.then(function() {
|
|
global++;
|
|
});
|
|
f.catch(function() {
|
|
global++;
|
|
});
|
|
f.then(function() {}, function() {
|
|
global++;
|
|
});
|
|
setTimeout(function() {
|
|
is(global, 2, "Many steps... should return 2");
|
|
runTest();
|
|
}, 0);
|
|
});
|
|
}
|
|
|
|
function promiseCatchNoArg() {
|
|
var promise = new Promise(function(resolve, reject) {
|
|
reject(42);
|
|
});
|
|
|
|
var clone = promise.catch();
|
|
isnot(promise, clone, "These 2 promise objs are different");
|
|
promise.catch(function(v) {
|
|
clone.catch(function(cv) {
|
|
is(v, cv, "Both reject to the same value");
|
|
runTest();
|
|
});
|
|
});
|
|
}
|
|
|
|
function promiseNestedPromise() {
|
|
new Promise(function(resolve, reject) {
|
|
resolve(new Promise(function(resolve, reject) {
|
|
ok(true, "Nested promise is executed");
|
|
resolve(42);
|
|
}));
|
|
}).then(function(value) {
|
|
is(value, 42, "Nested promise is executed and then == 42");
|
|
runTest();
|
|
});
|
|
}
|
|
|
|
function promiseNestedNestedPromise() {
|
|
new Promise(function(resolve, reject) {
|
|
resolve(new Promise(function(resolve, reject) {
|
|
ok(true, "Nested promise is executed");
|
|
resolve(42);
|
|
}).then(function(what) { return what+1; }));
|
|
}).then(function(value) {
|
|
is(value, 43, "Nested promise is executed and then == 43");
|
|
runTest();
|
|
});
|
|
}
|
|
|
|
function promiseWrongNestedPromise() {
|
|
new Promise(function(resolve, reject) {
|
|
resolve(new Promise(function(r, r2) {
|
|
ok(true, "Nested promise is executed");
|
|
r(42);
|
|
}));
|
|
reject(42);
|
|
}).then(function(value) {
|
|
is(value, 42, "Nested promise is executed and then == 42");
|
|
runTest();
|
|
}, function(value) {
|
|
ok(false, "This is wrong");
|
|
});
|
|
}
|
|
|
|
function promiseLoop() {
|
|
new Promise(function(resolve, reject) {
|
|
resolve(new Promise(function(r1, r2) {
|
|
ok(true, "Nested promise is executed");
|
|
r1(new Promise(function(r1, r2) {
|
|
ok(true, "Nested nested promise is executed");
|
|
r1(42);
|
|
}));
|
|
}));
|
|
}).then(function(value) {
|
|
is(value, 42, "Nested nested promise is executed and then == 42");
|
|
runTest();
|
|
}, function(value) {
|
|
ok(false, "This is wrong");
|
|
});
|
|
}
|
|
|
|
function promiseStaticReject() {
|
|
var promise = Promise.reject(42).then(function(what) {
|
|
ok(false, "This should not be called");
|
|
}, function(what) {
|
|
is(what, 42, "Value == 42");
|
|
runTest();
|
|
});
|
|
}
|
|
|
|
function promiseStaticResolve() {
|
|
var promise = Promise.resolve(42).then(function(what) {
|
|
is(what, 42, "Value == 42");
|
|
runTest();
|
|
}, function() {
|
|
ok(false, "This should not be called");
|
|
});
|
|
}
|
|
|
|
function promiseResolveNestedPromise() {
|
|
var promise = Promise.resolve(new Promise(function(r, r2) {
|
|
ok(true, "Nested promise is executed");
|
|
r(42);
|
|
}, function() {
|
|
ok(false, "This should not be called");
|
|
})).then(function(what) {
|
|
is(what, 42, "Value == 42");
|
|
runTest();
|
|
}, function() {
|
|
ok(false, "This should not be called");
|
|
});
|
|
}
|
|
|
|
function promiseSimpleThenableResolve() {
|
|
var thenable = { then: function(resolve) { resolve(5); } };
|
|
var promise = new Promise(function(resolve, reject) {
|
|
resolve(thenable);
|
|
});
|
|
|
|
promise.then(function(v) {
|
|
ok(v === 5, "promiseSimpleThenableResolve");
|
|
runTest();
|
|
}, function(e) {
|
|
ok(false, "promiseSimpleThenableResolve: Should not reject");
|
|
});
|
|
}
|
|
|
|
function promiseSimpleThenableReject() {
|
|
var thenable = { then: function(resolve, reject) { reject(5); } };
|
|
var promise = new Promise(function(resolve, reject) {
|
|
resolve(thenable);
|
|
});
|
|
|
|
promise.then(function() {
|
|
ok(false, "promiseSimpleThenableReject: Should not resolve");
|
|
runTest();
|
|
}, function(e) {
|
|
ok(e === 5, "promiseSimpleThenableReject");
|
|
runTest();
|
|
});
|
|
}
|
|
|
|
function promiseThenableThrowsBeforeCallback() {
|
|
var thenable = { then: function(resolve) {
|
|
throw new TypeError("Hi there");
|
|
resolve(5);
|
|
}};
|
|
|
|
var promise = Promise.resolve(thenable);
|
|
promise.then(function(v) {
|
|
ok(false, "promiseThenableThrowsBeforeCallback: Should've rejected");
|
|
runTest();
|
|
}, function(e) {
|
|
ok(e instanceof TypeError, "promiseThenableThrowsBeforeCallback");
|
|
runTest();
|
|
});
|
|
}
|
|
|
|
function promiseThenableThrowsAfterCallback() {
|
|
var thenable = { then: function(resolve) {
|
|
resolve(5);
|
|
throw new TypeError("Hi there");
|
|
}};
|
|
|
|
var promise = Promise.resolve(thenable);
|
|
promise.then(function(v) {
|
|
ok(v === 5, "promiseThenableThrowsAfterCallback");
|
|
runTest();
|
|
}, function(e) {
|
|
ok(false, "promiseThenableThrowsAfterCallback: Should've resolved");
|
|
runTest();
|
|
});
|
|
}
|
|
|
|
function promiseThenableRejectThenResolve() {
|
|
var thenable = { then: function(resolve, reject) {
|
|
reject(new TypeError("Hi there"));
|
|
resolve(5);
|
|
}};
|
|
|
|
var promise = Promise.resolve(thenable);
|
|
promise.then(function(v) {
|
|
ok(false, "promiseThenableRejectThenResolve should have rejected");
|
|
runTest();
|
|
}, function(e) {
|
|
ok(e instanceof TypeError, "promiseThenableRejectThenResolve");
|
|
runTest();
|
|
});
|
|
}
|
|
|
|
function promiseWithThenReplaced() {
|
|
// Ensure that we call the 'then' on the promise and not the internal then.
|
|
var promise = new Promise(function(resolve, reject) {
|
|
resolve(5);
|
|
});
|
|
|
|
// Rogue `then` always rejects.
|
|
promise.then = function(onFulfill, onReject) {
|
|
onReject(new TypeError("Foo"));
|
|
}
|
|
|
|
var promise2 = Promise.resolve(promise);
|
|
promise2.then(function(v) {
|
|
ok(false, "promiseWithThenReplaced: Should've rejected");
|
|
runTest();
|
|
}, function(e) {
|
|
ok(e instanceof TypeError, "promiseWithThenReplaced");
|
|
runTest();
|
|
});
|
|
}
|
|
|
|
function promiseStrictHandlers() {
|
|
var promise = Promise.resolve(5);
|
|
promise.then(function() {
|
|
"use strict";
|
|
ok(this === undefined, "Strict mode callback should have this === undefined.");
|
|
runTest();
|
|
});
|
|
}
|
|
|
|
var tests = [ promiseResolve, promiseReject,
|
|
promiseException, promiseGC, promiseAsync,
|
|
promiseDoubleThen, promiseThenException,
|
|
promiseThenCatchThen, promiseRejectThenCatchThen,
|
|
promiseRejectThenCatchThen2,
|
|
promiseRejectThenCatchExceptionThen,
|
|
promiseThenCatchOrderingResolve,
|
|
promiseThenCatchOrderingReject,
|
|
promiseNestedPromise, promiseNestedNestedPromise,
|
|
promiseWrongNestedPromise, promiseLoop,
|
|
promiseStaticReject, promiseStaticResolve,
|
|
promiseResolveNestedPromise,
|
|
promiseResolveNoArg,
|
|
promiseRejectNoArg,
|
|
promiseThenNoArg,
|
|
promiseThenUndefinedResolveFunction,
|
|
promiseThenNullResolveFunction,
|
|
promiseCatchNoArg,
|
|
promiseRejectNoHandler,
|
|
promiseSimpleThenableResolve,
|
|
promiseSimpleThenableReject,
|
|
promiseThenableThrowsBeforeCallback,
|
|
promiseThenableThrowsAfterCallback,
|
|
promiseThenableRejectThenResolve,
|
|
promiseWithThenReplaced,
|
|
promiseStrictHandlers,
|
|
];
|
|
|
|
function runTest() {
|
|
if (!tests.length) {
|
|
SimpleTest.finish();
|
|
return;
|
|
}
|
|
|
|
var test = tests.shift();
|
|
test();
|
|
}
|
|
|
|
SimpleTest.waitForExplicitFinish();
|
|
runTest();
|
|
// -->
|
|
</script>
|
|
</pre>
|
|
</body>
|
|
</html>
|
|
|