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

feat(fetch): patch the fetch API #119

Merged
merged 1 commit into from
May 20, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion karma-browserify.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module.exports = function (config) {
files: [
'test/util.js',
'test/commonjs.spec.js',
{pattern: 'test/assets/**/*.html', watched: true, served: true, included: false},
{pattern: 'test/assets/**/*.*', watched: true, served: true, included: false},
{pattern: 'lib/**/*.js', watched: true, served: false, included: false}
],

Expand Down
2 changes: 1 addition & 1 deletion karma-microtasks.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module.exports = function (config) {
'test/setup-microtask.js',
'dist/*-zone.js',
'test/**/*.spec.js',
{pattern: 'test/assets/**/*.html', watched: true, served: true, included: false},
{pattern: 'test/assets/**/*.*', watched: true, served: true, included: false},
{pattern: 'lib/**/*.js', watched: true, served: false, included: false}
],

Expand Down
2 changes: 1 addition & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module.exports = function (config) {
'dist/*-zone.js',
//'test/lib/brick.js',
'test/**/*.spec.js',
{pattern: 'test/assets/**/*.html', watched: true, served: true, included: false},
{pattern: 'test/assets/**/*.*', watched: true, served: true, included: false},
{pattern: 'lib/**/*.js', watched: true, served: false, included: false}
],

Expand Down
34 changes: 34 additions & 0 deletions lib/patch/promise.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,27 @@ if (global.Promise) {
};
}


function _patchPromiseFnsOnObject(objectPath, fnNames) {
var obj = global;

var exists = objectPath.every(function (segment) {
obj = obj[segment];
return obj;
});

if (!exists) {
return;
}

fnNames.forEach(function (name) {
var fn = obj[name];
if (fn) {
obj[name] = bindPromiseFn(fn);
}
});
}

function _patchThenable(thenable) {
var then = thenable.then;
thenable.then = function () {
Expand All @@ -67,11 +88,24 @@ function _patchThenable(thenable) {


function apply() {
// Patch .then() and .catch() on native Promises to execute callbacks in the zone where
// those functions are called.
if (global.Promise) {
utils.patchPrototype(Promise.prototype, [
'then',
'catch'
]);

// Patch browser APIs that return a Promise
var patchFns = [
// fetch
[[], ['fetch']],
[['Response', 'prototype'], ['arrayBuffer', 'blob', 'json', 'text']]
];

patchFns.forEach(function(objPathAndFns) {
_patchPromiseFnsOnObject(objPathAndFns[0], objPathAndFns[1]);
});
}
}

Expand Down
1 change: 1 addition & 0 deletions test/assets/sample.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"hello": "world"}
104 changes: 84 additions & 20 deletions test/patch/Promise.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,98 @@
describe('Promise', ifEnvSupports('Promise', function () {
var testZone = window.zone.fork();

it('should work with .then', function (done) {
var resolve;

testZone.run(function() {
new Promise(function (resolveFn) {
resolve = resolveFn;
}).then(function () {
expect(window.zone).toBeDirectChildOf(testZone);
done();
describe('Promise API', function () {
it('should work with .then', function (done) {
var resolve;

testZone.run(function() {
new Promise(function (resolveFn) {
resolve = resolveFn;
}).then(function () {
expect(window.zone).toBeDirectChildOf(testZone);
done();
});
});

resolve();
});

resolve();
it('should work with .catch', function (done) {
var reject;

testZone.run(function() {
new Promise(function (resolveFn, rejectFn) {
reject = rejectFn;
}).catch(function () {
expect(window.zone).toBeDirectChildOf(testZone);
done();
});
});

reject();
});
});

it('should work with .catch', function (done) {
var reject;
describe('fetch', ifEnvSupports('fetch', function () {
it('should work for text response', function(done) {
testZone.run(function() {
fetch('/base/test/assets/sample.json').then(function(response) {
var fetchZone = zone;
expect(fetchZone).toBeDirectChildOf(testZone);

testZone.run(function() {
new Promise(function (resolveFn, rejectFn) {
reject = rejectFn;
}).catch(function () {
expect(window.zone).toBeDirectChildOf(testZone);
done();
response.text().then(function(text) {
expect(zone).toBeDirectChildOf(fetchZone);
expect(text.trim()).toEqual('{"hello": "world"}');
done();
});
});
});
});

reject();
});
it('should work for json response', function(done) {
testZone.run(function() {
fetch('/base/test/assets/sample.json').then(function(response) {
var fetchZone = zone;
expect(fetchZone).toBeDirectChildOf(testZone);

response.json().then(function(obj) {
expect(zone).toBeDirectChildOf(fetchZone);
expect(obj.hello).toEqual('world');
done();
});
});
});
});

it('should work for blob response', function(done) {
testZone.run(function() {
fetch('/base/test/assets/sample.json').then(function(response) {
var fetchZone = zone;
expect(fetchZone).toBeDirectChildOf(testZone);

response.blob().then(function(blob) {
expect(zone).toBeDirectChildOf(fetchZone);
expect(blob instanceof Blob).toEqual(true);
done();
});
});
});
});

it('should work for arrayBuffer response', function(done) {
testZone.run(function() {
fetch('/base/test/assets/sample.json').then(function(response) {
var fetchZone = zone;
expect(fetchZone).toBeDirectChildOf(testZone);

response.arrayBuffer().then(function(blob) {
expect(zone).toBeDirectChildOf(fetchZone);
expect(blob instanceof ArrayBuffer).toEqual(true);
done();
});
});
});
});
}));

}));