From f99b804f5b3c2c9f82eb666b093ded1dbfd9da88 Mon Sep 17 00:00:00 2001 From: spacejack Date: Sun, 18 Feb 2018 20:18:13 -0500 Subject: [PATCH 1/3] Add Promise finally method to polyfill --- promise/promise.js | 26 ++++++++++++++++++++++++-- promise/tests/test-promise.js | 19 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/promise/promise.js b/promise/promise.js index 53aefecc..51d124e8 100644 --- a/promise/promise.js +++ b/promise/promise.js @@ -61,6 +61,20 @@ PromisePolyfill.prototype.then = function(onFulfilled, onRejection) { PromisePolyfill.prototype.catch = function(onRejection) { return this.then(null, onRejection) } +PromisePolyfill.prototype.finally = function(callback) { + return this.then( + function(value) { + return PromisePolyfill.resolve(callback()).then(function() { + return value + }) + }, + function(reason) { + return PromisePolyfill.resolve(callback()).then(function() { + return PromisePolyfill.reject(reason); + }) + } + ) +} PromisePolyfill.resolve = function(value) { if (value instanceof PromisePolyfill) return value return new PromisePolyfill(function(resolve) {resolve(value)}) @@ -96,10 +110,18 @@ PromisePolyfill.race = function(list) { } if (typeof window !== "undefined") { - if (typeof window.Promise === "undefined") window.Promise = PromisePolyfill + if (typeof window.Promise === "undefined") { + window.Promise = PromisePolyfill + } else if (!window.Promise.prototype.finally) { + window.Promise.prototype.finally = PromisePolyfill.prototype.finally + } module.exports = window.Promise } else if (typeof global !== "undefined") { - if (typeof global.Promise === "undefined") global.Promise = PromisePolyfill + if (typeof global.Promise === "undefined") { + global.Promise = PromisePolyfill + } else if (!global.Promise.prototype.finally) { + global.Promise.prototype.finally = PromisePolyfill.prototype.finally + } module.exports = global.Promise } else { module.exports = PromisePolyfill diff --git a/promise/tests/test-promise.js b/promise/tests/test-promise.js index e368165c..7798293f 100644 --- a/promise/tests/test-promise.js +++ b/promise/tests/test-promise.js @@ -15,6 +15,7 @@ o.spec("promise", function() { o("constructor has correct methods", function() { o(typeof Promise.prototype.then).equals("function") o(typeof Promise.prototype.catch).equals("function") + o(typeof Promise.prototype.finally).equals("function") o(typeof Promise.resolve).equals("function") o(typeof Promise.reject).equals("function") o(typeof Promise.race).equals("function") @@ -53,6 +54,24 @@ o.spec("promise", function() { o(value).equals(1) }).then(done) }) + o("finally after then returns promise", function(done) { + var promise = Promise.resolve(1) + + promise.then(function(value) { + o(value).equals(1) + }).finally(function(value) { + o(value).equals(undefined) + }).then(done) + }) + o("finally after catch returns promise", function(done) { + var promise = Promise.reject(1) + + promise.catch(function(value) { + o(value).equals(1) + }).finally(function(value) { + o(value).equals(undefined) + }).then(done) + }) }) o.spec("resolve", function() { o("resolves once", function(done) { From 17c7855d913704f989d99c1343d5e7daa9f4fcd4 Mon Sep 17 00:00:00 2001 From: spacejack Date: Mon, 19 Feb 2018 15:03:53 -0500 Subject: [PATCH 2/3] Add another simple finally test --- promise/tests/test-promise.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/promise/tests/test-promise.js b/promise/tests/test-promise.js index 7798293f..7bddbb5d 100644 --- a/promise/tests/test-promise.js +++ b/promise/tests/test-promise.js @@ -54,6 +54,13 @@ o.spec("promise", function() { o(value).equals(1) }).then(done) }) + o("finally returns promise", function(done) { + var promise = Promise.resolve(1) + + promise.finally(function(value) { + o(value).equals(undefined) + }).finally(done) + }) o("finally after then returns promise", function(done) { var promise = Promise.resolve(1) From 8217d68e18a6dd2be70eef6d37d4628c87ba97cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pierre-Yves=20G=C3=A9rardy?= Date: Tue, 20 Feb 2018 00:27:39 +0100 Subject: [PATCH 3/3] Better tests for Promise.prototype.finally --- promise/tests/test-promise.js | 83 +++++++++++++++++++++++++++-------- 1 file changed, 65 insertions(+), 18 deletions(-) diff --git a/promise/tests/test-promise.js b/promise/tests/test-promise.js index 4e85c9a4..7dcc21f6 100644 --- a/promise/tests/test-promise.js +++ b/promise/tests/test-promise.js @@ -54,30 +54,77 @@ o.spec("promise", function() { o(value).equals(1) }).then(done) }) - o("finally returns promise", function(done) { + o("finally lets a fulfilled value pass though", function(done) { var promise = Promise.resolve(1) + var spy = o.spy(function(){return 2}) - promise.finally(function(value) { - o(value).equals(undefined) - }).finally(done) - }) - o("finally after then returns promise", function(done) { - var promise = Promise.resolve(1) - - promise.then(function(value) { + promise.finally(spy).then(function(value){ o(value).equals(1) - }).finally(function(value) { - o(value).equals(undefined) - }).then(done) + o(spy.callCount).equals(1) + o(spy.args.length).equals(0) + o(spy.this).equals(undefined) + done() + }) }) - o("finally after catch returns promise", function(done) { + o("finally lets a rejected reason pass though", function(done) { var promise = Promise.reject(1) + var spy = o.spy(function(){return 2}) - promise.catch(function(value) { - o(value).equals(1) - }).finally(function(value) { - o(value).equals(undefined) - }).then(done) + promise.finally(spy).catch(function(reason){ + o(reason).equals(1) + o(spy.callCount).equals(1) + o(spy.args.length).equals(0) + o(spy.this).equals(undefined) + done() + }) + }) + o("finally overrrides a fulfilled value when it throws", function(done) { + var promise = Promise.resolve(1) + var spy = o.spy(function(){throw 2}) + + promise.finally(spy).catch(function(reason){ + o(reason).equals(2) + o(spy.callCount).equals(1) + o(spy.args.length).equals(0) + o(spy.this).equals(undefined) + done() + }) + }) + o("finally overrrides a fulfilled value when it returns a rejected Promise", function(done) { + var promise = Promise.resolve(1) + var spy = o.spy(function(){return Promise.reject(2)}) + + promise.finally(spy).catch(function(reason){ + o(reason).equals(2) + o(spy.callCount).equals(1) + o(spy.args.length).equals(0) + o(spy.this).equals(undefined) + done() + }) + }) + o("finally overrrides a rejected reason when it throws", function(done) { + var promise = Promise.reject(1) + var spy = o.spy(function(){throw 2}) + + promise.finally(spy).catch(function(reason){ + o(reason).equals(2) + o(spy.callCount).equals(1) + o(spy.args.length).equals(0) + o(spy.this).equals(undefined) + done() + }) + }) + o("finally overrrides a rejected reason when it returns a rejected Promise", function(done) { + var promise = Promise.reject(1) + var spy = o.spy(function(){return Promise.reject(2)}) + + promise.finally(spy).catch(function(reason){ + o(reason).equals(2) + o(spy.callCount).equals(1) + o(spy.args.length).equals(0) + o(spy.this).equals(undefined) + done() + }) }) }) o.spec("resolve", function() {