Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
feat(bindPromiseFn): add bindPromiseFn method
Browse files Browse the repository at this point in the history
Closes #49
  • Loading branch information
btford committed Feb 20, 2015
1 parent fb338b6 commit 643f2ac
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 1 deletion.
2 changes: 1 addition & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ module.exports = function (config) {
config.set({
basePath: '',
files: [
'test/util.js',
'zone.js',
'*-zone.js',
//'test/lib/brick.js',
'test/util.js',
'test/**/*.spec.js',
{pattern: 'test/assets/**/*.html', watched: true, served: true, included: false}
],
Expand Down
3 changes: 3 additions & 0 deletions test/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ function ifEnvSupports(test, block) {
}
};
};

// useful for testing mocks
window.__setTimeout = window.setTimeout;
26 changes: 26 additions & 0 deletions test/zone.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,32 @@ describe('Zone', function () {
});
});

describe('bindPromiseFn', function () {
var mockPromise = function() {
return {
then: function (a, b) {
window.__setTimeout(a, 0);
return mockPromise();
}
};
};

it('should return a method that returns promises that run in the correct zone', function (done) {
zone.fork({ mark: 'a' }).run(function () {
var patched = Zone.bindPromiseFn(function() {
return mockPromise();
});

patched().then(function () {
expect(zone.mark).toBe('a');
}).then(function () {
expect(zone.mark).toBe('a');
done();
});
});
});
});

});

function throwError () {
Expand Down
46 changes: 46 additions & 0 deletions zone.js
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,52 @@ Zone.bindArgumentsOnce = function (args) {
return args;
};

/*
* patch a fn that returns a promise
*/
Zone.bindPromiseFn = (function() {
// if the browser natively supports Promises, we can just return a native promise
if (window.Promise) {
return function (delegate) {
return function() {
var delegatePromise = delegate.apply(this, arguments);
if (delegatePromise instanceof Promise) {
return delegatePromise;
} else {
return new Promise(function(resolve, reject) {
delegatePromise.then(resolve, reject);
});
}
};
};
} else {
// if the browser does not have native promises, we have to patch each promise instance
return function (delegate) {
return function () {
return patchThenable(delegate.apply(this, arguments));
};
};

function patchThenable(thenable) {
var then = thenable.then;
thenable.then = function () {
var args = Zone.bindArguments(arguments);
var nextThenable = then.apply(thenable, args);
return patchThenable(nextThenable);
};

var ocatch = thenable.catch;
thenable.catch = function () {
var args = Zone.bindArguments(arguments);
var nextThenable = ocatch.apply(thenable, args);
return patchThenable(nextThenable);
};
return thenable;
}
}
}());


Zone.patchableFn = function (obj, fnNames) {
fnNames.forEach(function (name) {
var delegate = obj[name];
Expand Down

0 comments on commit 643f2ac

Please sign in to comment.