diff --git a/test/zone.spec.js b/test/zone.spec.js index 9253cd4d9..385f0d610 100644 --- a/test/zone.spec.js +++ b/test/zone.spec.js @@ -85,27 +85,81 @@ describe('Zone.patch', function () { it('should work', function (done) { - runs(function() { - flag = false; - hasParent = false; + runs(function() { + flag = false; + hasParent = false; + + window.requestAnimationFrame(function () { + hasParent = !!window.zone.parent; + flag = true; + }); + }); + + waitsFor(function() { + return flag; + }, "requestAnimationFrame to run", 1); - window.requestAnimationFrame(function () { - hasParent = !!window.zone.parent; - flag = true; + runs(function() { + expect(hasParent).toBe(true); }); + }); + }); - waitsFor(function() { - return flag; - }, "requestAnimationFrame to run", 1); + describe('Promise', function () { + var flag, hasParent; - runs(function() { - expect(hasParent).toBe(true); + beforeEach(function () { + flag = false; + hasParent = false; }); + it('should work with .then', function () { + if (!window.Promise) { + return; + } + + runs(function() { + new Promise(function (resolve) { + requestAnimationFrame(resolve); + }).then(function () { + hasParent = !!window.zone.parent; + flag = true; + }); + }); + + waitsFor(function() { + return flag; + }, "requestAnimationFrame to run", 1); + + runs(function() { + expect(hasParent).toBe(true); + }); }); - }); + it('should work with .catch', function () { + if (!window.Promise) { + return; + } + + runs(function() { + new Promise(function (resolve, reject) { + requestAnimationFrame(reject); + }).catch(function () { + hasParent = !!window.zone.parent; + flag = true; + }); + }); + + waitsFor(function() { + return flag; + }, "requestAnimationFrame to run", 1); + + runs(function() { + expect(hasParent).toBe(true); + }); + }); + }) describe('element', function () { diff --git a/zone.js b/zone.js index 4e94d58da..9497a0e45 100644 --- a/zone.js +++ b/zone.js @@ -96,8 +96,7 @@ Zone.patchFn = function (obj, fnNames) { var delegate = obj[name]; if (delegate) { zone[name] = function () { - arguments[0] = zone.bind(arguments[0]); - return delegate.apply(obj, arguments); + return delegate.apply(obj, Zone.bindArguments(arguments)); }; obj[name] = function marker () { @@ -107,6 +106,26 @@ Zone.patchFn = function (obj, fnNames) { }); }; +Zone.patchPrototype = function (obj, fnNames) { + fnNames.forEach(function (name) { + var delegate = obj[name]; + if (delegate) { + obj[name] = function () { + return delegate.apply(this, Zone.bindArguments(arguments)); + }; + } + }); +}; + +Zone.bindArguments = function (args) { + for (var i = args.length - 1; i >= 0; i--) { + if (typeof args[i] === 'function') { + args[i] = zone.bind(args[i]); + } + } + return args; +} + Zone.patchableFn = function (obj, fnNames) { fnNames.forEach(function (name) { var delegate = obj[name]; @@ -223,6 +242,14 @@ Zone.patch = function patch () { Zone.patchProperties(HTMLElement.prototype); Zone.patchProperties(XMLHttpRequest.prototype); + + // patch promises + if (window.Promise) { + Zone.patchPrototype(Promise.prototype, [ + 'then', + 'catch' + ]); + } }; Zone.init = function init () {