From 4c56e4ffdc5eb944b1fcb84085001ebe22d9dccc Mon Sep 17 00:00:00 2001 From: Pete Richards Date: Thu, 6 Aug 2015 14:53:59 -0700 Subject: [PATCH] [Test] add a synchronous controlled promise for testing Add ControlledPromise, a synchronous promise that can be controlled, allowing for easier testing of promise resolution flow. --- .../entanglement/test/ControlledPromise.js | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 platform/entanglement/test/ControlledPromise.js diff --git a/platform/entanglement/test/ControlledPromise.js b/platform/entanglement/test/ControlledPromise.js new file mode 100644 index 0000000000..428bb18d10 --- /dev/null +++ b/platform/entanglement/test/ControlledPromise.js @@ -0,0 +1,78 @@ +/*global define,spyOn */ + +define( + function () { + + /** + * An instrumented promise implementation for better control of promises + * during tests. + * + */ + function ControlledPromise() { + this.resolveHandlers = []; + this.rejectHandlers = []; + spyOn(this, 'then').andCallThrough(); + } + + + /** + * Resolve the promise, passing the supplied value to all resolve + * handlers. + */ + ControlledPromise.prototype.resolve = function(value) { + this.resolveHandlers.forEach(function(handler) { + handler(value); + }); + }; + + /** + * Reject the promise, passing the supplied value to all rejection + * handlers. + */ + ControlledPromise.prototype.reject = function(value) { + this.rejectHandlers.forEach(function(handler) { + handler(value); + }); + }; + + /** + * Standard promise.then, returns a promise that support chaining. + * TODO: Need to support resolve/reject handlers that return promises. + */ + ControlledPromise.prototype.then = function (onResolve, onReject) { + var returnPromise = new ControlledPromise(); + + if (onResolve) { + this.resolveHandlers.push(function(resolveWith) { + var chainResult = onResolve(resolveWith); + if (chainResult && chainResult.then) { + // chainResult is a promise, resolve when it resolves. + chainResult.then(function(pipedResult) { + return returnPromise.resolve(pipedResult); + }); + } else { + returnPromise.resolve(chainResult); + } + }); + } + + if (onReject) { + this.rejectHandlers.push(function(rejectWith) { + var chainResult = onReject(rejectWith); + if (chainResult && chainResult.then) { + chainResult.then(function(pipedResult) { + returnPromise.reject(pipedResult); + }); + } else { + returnPromise.reject(chainResult); + } + }); + } + + return returnPromise; + }; + + return ControlledPromise; + + } +);