diff --git a/NON-STANDARD-APIS.md b/NON-STANDARD-APIS.md
index 9fa15172a..0257f94f2 100644
--- a/NON-STANDARD-APIS.md
+++ b/NON-STANDARD-APIS.md
@@ -13,6 +13,48 @@ But there are still a lot of non standard APIs are not patched by default, such
## Currently supported non standard node APIs
+## Currently supported non standard common APIs
+
+* bluebird promise
+
+Browser Usage:
+
+```
+
+
+
+
+```
+
+After those steps, window.Promise will become a ZoneAware Bluebird Promise.
+
+Node Usage:
+
+```
+require('zone-node.js');
+const Bluebird = require('bluebird');
+require('zone-bluebird.js');
+Zone[Zone['__symbol__']('bluebird')](Bluebird);
+```
+
+In NodeJS environment, you can choose to use Bluebird Promise as global.Promise
+or use ZoneAwarePromise as global.Promise.
+
+To run the jasmine test cases of bluebird
+
+```
+ npm install bluebird
+```
+
+then modify test/node_tests.ts
+remove the comment of the following line
+
+```
+//import './extra/bluebird.spec';
+```
+
## Usage
By default, those APIs' support will not be loaded in zone.js or zone-node.js,
diff --git a/dist/zone-bluebird.js b/dist/zone-bluebird.js
new file mode 100644
index 000000000..d9b240f7c
--- /dev/null
+++ b/dist/zone-bluebird.js
@@ -0,0 +1,35 @@
+/**
+* @license
+* Copyright Google Inc. All Rights Reserved.
+*
+* Use of this source code is governed by an MIT-style license that can be
+* found in the LICENSE file at https://angular.io/license
+*/
+(function (global, factory) {
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory() :
+ typeof define === 'function' && define.amd ? define(factory) :
+ (factory());
+}(this, (function () { 'use strict';
+
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+(function (_global) {
+ var __symbol__ = Zone['__symbol__'];
+ // TODO: @JiaLiPassion, we can automatically patch bluebird
+ // if global.Promise = Bluebird, but sometimes in nodejs,
+ // global.Promise is not Bluebird, and Bluebird is just be
+ // used by other libraries such as sequelize, so I think it is
+ // safe to just expose a method to patch Bluebird explicitly
+ Zone[__symbol__('bluebird')] = function patchBluebird(Bluebird) {
+ Bluebird.setScheduler(function (fn) {
+ Zone.current.scheduleMicroTask('bluebird', fn);
+ });
+ };
+})(typeof window === 'object' && window || typeof self === 'object' && self || global);
+
+})));
diff --git a/dist/zone-bluebird.min.js b/dist/zone-bluebird.min.js
new file mode 100644
index 000000000..faf89a974
--- /dev/null
+++ b/dist/zone-bluebird.min.js
@@ -0,0 +1 @@
+!function(e,o){"object"==typeof exports&&"undefined"!=typeof module?o():"function"==typeof define&&define.amd?define(o):o()}(this,function(){"use strict";!function(e){var o=Zone.__symbol__;Zone[o("bluebird")]=function(e){e.setScheduler(function(e){Zone.current.scheduleMicroTask("bluebird",e)})}}("object"==typeof window&&window||"object"==typeof self&&self||global)});
\ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
index b86ed0ee8..0c65fdd54 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -99,6 +99,14 @@ gulp.task('build/webapis-notification.js', ['compile-esm'], function(cb) {
return generateScript('./lib/browser/webapis-notification.ts', 'webapis-notification.js', true, cb);
});
+gulp.task('build/bluebird.js', ['compile-esm'], function(cb) {
+ return generateScript('./lib/extra/bluebird.ts', 'zone-bluebird.js', false, cb);
+});
+
+gulp.task('build/bluebird.min.js', ['compile-esm'], function(cb) {
+ return generateScript('./lib/extra/bluebird.ts', 'zone-bluebird.min.js', true, cb);
+});
+
gulp.task('build/jasmine-patch.js', ['compile-esm'], function(cb) {
return generateScript('./lib/jasmine/jasmine.ts', 'jasmine-patch.js', false, cb);
});
@@ -167,6 +175,8 @@ gulp.task('build', [
'build/webapis-media-query.js',
'build/webapis-notification.js',
'build/zone-mix.js',
+ 'build/bluebird.js',
+ 'build/bluebird.min.js',
'build/jasmine-patch.js',
'build/jasmine-patch.min.js',
'build/mocha-patch.js',
diff --git a/lib/extra/bluebird.ts b/lib/extra/bluebird.ts
new file mode 100644
index 000000000..b32c6cd91
--- /dev/null
+++ b/lib/extra/bluebird.ts
@@ -0,0 +1,20 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+((_global: any) => {
+ const __symbol__ = Zone['__symbol__'];
+ // TODO: @JiaLiPassion, we can automatically patch bluebird
+ // if global.Promise = Bluebird, but sometimes in nodejs,
+ // global.Promise is not Bluebird, and Bluebird is just be
+ // used by other libraries such as sequelize, so I think it is
+ // safe to just expose a method to patch Bluebird explicitly
+ Zone[__symbol__('bluebird')] = function patchBluebird(Bluebird) {
+ Bluebird.setScheduler((fn) => {
+ Zone.current.scheduleMicroTask('bluebird', fn);
+ });
+ };
+})(typeof window === 'object' && window || typeof self === 'object' && self || global);
diff --git a/test/extra/bluebird.spec.ts b/test/extra/bluebird.spec.ts
new file mode 100644
index 000000000..a039455fb
--- /dev/null
+++ b/test/extra/bluebird.spec.ts
@@ -0,0 +1,588 @@
+/**
+ * @license
+ * Copyright Google Inc. All Rights Reserved.
+ *
+ * Use of this source code is governed by an MIT-style license that can be
+ * found in the LICENSE file at https://angular.io/license
+ */
+// test bluebird promise patch
+// this spec will not be integrated with Travis CI, because I don't
+// want to add bluebird into devDependencies, you can run this spec
+// on your local environment
+
+describe('bluebird promise', () => {
+ let BluebirdPromise;
+ beforeAll(() => {
+ BluebirdPromise = require('bluebird');
+ // import bluebird patch
+ require('../../lib/extra/bluebird');
+ const patchBluebird = Zone[Zone['__symbol__']('bluebird')];
+ patchBluebird(BluebirdPromise);
+ });
+
+ let log;
+
+ const zone = Zone.root.fork({
+ name: 'bluebird',
+ onScheduleTask: (delegate, curr, targetZone, task) => {
+ log.push('schedule bluebird task ' + task.source);
+ return delegate.scheduleTask(targetZone, task);
+ },
+ onInvokeTask: (delegate, curr, target, task, applyThis, applyArgs) => {
+ log.push('invoke bluebird task ' + task.source);
+ return delegate.invokeTask(target, task, applyThis, applyArgs);
+ }
+ });
+
+ beforeEach(() => {
+ log = [];
+ });
+
+ it('bluebird promise then method should be in zone and treated as microTask', (done) => {
+ zone.run(() => {
+ const p = new BluebirdPromise((resolve, reject) => {
+ setTimeout(() => {
+ resolve('test');
+ }, 0);
+ });
+ p.then(() => {
+ expect(Zone.current.name).toEqual('bluebird');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise catch method should be in zone and treated as microTask', (done) => {
+ zone.run(() => {
+ const p = new BluebirdPromise((resolve, reject) => {
+ setTimeout(() => {
+ reject('test');
+ }, 0);
+ });
+ p.catch(() => {
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise spread method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise.all([BluebirdPromise.resolve('test1'), BluebirdPromise.resolve('test2')])
+ .spread((r1, r2) => {
+ expect(r1).toEqual('test1');
+ expect(r2).toEqual('test2');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise finally method should be in zone', (done) => {
+ zone.run(() => {
+ const p = new BluebirdPromise((resolve, reject) => {
+ setTimeout(() => {
+ resolve('test');
+ }, 0);
+ });
+ p.finally(() => {
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise join method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise
+ .join(
+ BluebirdPromise.resolve('test1'), BluebirdPromise.resolve('test2'),
+ (r1, r2) => {
+ expect(r1).toEqual('test1');
+ expect(r2).toEqual('test2');
+ expect(Zone.current.name).toEqual('bluebird');
+ })
+ .then(() => {
+ expect(Zone.current.name).toEqual('bluebird');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise try method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise
+ .try(() => {
+ throw new Error('promise error');
+ })
+ .catch((err) => {
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ expect(err.message).toEqual('promise error');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise method method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise
+ .method(() => {
+ return 'test';
+ })()
+ .then((result) => {
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ expect(result).toEqual('test');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise resolve method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise.resolve('test').then((result) => {
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ expect(result).toEqual('test');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise reject method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise.reject('error').catch((error) => {
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ expect(error).toEqual('error');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise all method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise.all([BluebirdPromise.resolve('test1'), BluebirdPromise.resolve('test2')])
+ .then((r) => {
+ expect(r[0]).toEqual('test1');
+ expect(r[1]).toEqual('test2');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise props method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise
+ .props({test1: BluebirdPromise.resolve('test1'), test2: BluebirdPromise.resolve('test2')})
+ .then((r) => {
+ expect(r.test1).toEqual('test1');
+ expect(r.test2).toEqual('test2');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise any method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise.any([BluebirdPromise.resolve('test1'), BluebirdPromise.resolve('test2')])
+ .then((r) => {
+ expect(r).toEqual('test1');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise some method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise.some([BluebirdPromise.resolve('test1'), BluebirdPromise.resolve('test2')], 1)
+ .then((r) => {
+ expect(r.length).toBe(1);
+ expect(r[0]).toEqual('test1');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise map method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise
+ .map(
+ ['test1', 'test2'],
+ (value) => {
+ return BluebirdPromise.resolve(value);
+ })
+ .then((r) => {
+ expect(r.length).toBe(2);
+ expect(r[0]).toEqual('test1');
+ expect(r[1]).toEqual('test2');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise reduce method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise
+ .reduce(
+ [1, 2],
+ (total, value) => {
+ return BluebirdPromise.resolve(total + value);
+ })
+ .then((r) => {
+ expect(r).toBe(3);
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length)
+ .toBeTruthy();
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length)
+ .toBeTruthy();
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise filter method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise
+ .filter(
+ [1, 2, 3],
+ (value) => {
+ return value % 2 === 0 ? BluebirdPromise.resolve(true) :
+ BluebirdPromise.resolve(false);
+ })
+ .then((r) => {
+ expect(r[0]).toBe(2);
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise each method should be in zone', (done) => {
+ zone.run(() => {
+ const arr = [1, 2, 3];
+ BluebirdPromise.each(
+ BluebirdPromise.map(arr, (item) => BluebirdPromise.resolve(item)), (r, idx) => {
+ expect(r[idx] === arr[idx]);
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length)
+ .toBeTruthy();
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length)
+ .toBeTruthy();
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise mapSeries method should be in zone', (done) => {
+ zone.run(() => {
+ const arr = [1, 2, 3];
+ BluebirdPromise.mapSeries(
+ BluebirdPromise.map(arr, (item) => BluebirdPromise.resolve(item)), (r, idx) => {
+ expect(r[idx] === arr[idx]);
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length)
+ .toBeTruthy();
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length)
+ .toBeTruthy();
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise race method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise.race([BluebirdPromise.resolve('test1'), BluebirdPromise.resolve('test2')])
+ .then((r) => {
+ expect(r).toEqual('test1');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise using/disposer method should be in zone', (done) => {
+ zone.run(() => {
+ const p = new BluebirdPromise((resolve, reject) => {
+ setTimeout(() => {
+ resolve('test');
+ }, 0);
+ });
+ p.leakObj = [];
+ const disposer = p.disposer(() => {
+ p.leakObj = null;
+ });
+ BluebirdPromise
+ .using(
+ disposer,
+ (v) => {
+ p.leakObj.push(v);
+ })
+ .then(() => {
+ expect(Zone.current.name).toEqual('bluebird');
+ expect(p.leakObj).toBe(null);
+ // using will generate several promise inside bluebird
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise promisify method should be in zone and treated as microTask', (done) => {
+ const func = (cb: Function) => {
+ setTimeout(() => {
+ cb(null, 'test');
+ }, 10);
+ };
+
+ const promiseFunc = BluebirdPromise.promisify(func);
+ zone.run(() => {
+ promiseFunc().then((r) => {
+ expect(Zone.current.name).toEqual('bluebird');
+ expect(r).toBe('test');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise promisifyAll method should be in zone', (done) => {
+ const obj = {
+ func1: (cb: Function) => {
+ setTimeout(() => {
+ cb(null, 'test1');
+ }, 10);
+ },
+ func2: (cb: Function) => {
+ setTimeout(() => {
+ cb(null, 'test2');
+ }, 10);
+ },
+ };
+
+ const promiseObj = BluebirdPromise.promisifyAll(obj);
+ zone.run(() => {
+ BluebirdPromise.all([promiseObj.func1Async(), promiseObj.func2Async()]).then((r) => {
+ expect(Zone.current.name).toEqual('bluebird');
+ expect(r[0]).toBe('test1');
+ expect(r[1]).toBe('test2');
+ // using will generate several promise inside
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(2);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(2);
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise fromCallback method should be in zone', (done) => {
+ const resolver = (cb: Function) => {
+ setTimeout(() => {
+ cb(null, 'test');
+ }, 10);
+ };
+
+ zone.run(() => {
+ BluebirdPromise.fromCallback(resolver).then((r) => {
+ expect(Zone.current.name).toEqual('bluebird');
+ expect(r).toBe('test');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise asCallback method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise.resolve('test').asCallback((err, r) => {
+ expect(Zone.current.name).toEqual('bluebird');
+ expect(r).toBe('test');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise delay method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise.resolve('test').delay(10).then((r) => {
+ expect(Zone.current.name).toEqual('bluebird');
+ expect(r).toBe('test');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(2);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(2);
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise timeout method should be in zone', (done) => {
+ zone.run(() => {
+ new BluebirdPromise((resolve, reject) => {
+ setTimeout(() => {
+ resolve('test');
+ }, 10);
+ })
+ .timeout(100)
+ .then((r) => {
+ expect(Zone.current.name).toEqual('bluebird');
+ expect(r).toBe('test');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise tap method should be in zone', (done) => {
+ zone.run(() => {
+ const p = new BluebirdPromise((resolve, reject) => {
+ setTimeout(() => {
+ resolve('test');
+ }, 0);
+ });
+ p.tap(() => {
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise call method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise
+ .map(
+ ['test1', 'test2'],
+ (value) => {
+ return BluebirdPromise.resolve(value);
+ })
+ .call(
+ 'shift',
+ (value) => {
+ return value;
+ })
+ .then((r) => {
+ expect(r).toEqual('test1');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise get method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise.resolve(['test1', 'test2']).get(-1).then((r) => {
+ expect(r).toEqual('test2');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise return method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise.resolve().return ('test1').then((r) => {
+ expect(r).toEqual('test1');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise throw method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise.resolve().throw('test1').catch((r) => {
+ expect(r).toEqual('test1');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise catchReturn method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise.reject().catchReturn('test1').then((r) => {
+ expect(r).toEqual('test1');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise catchThrow method should be in zone', (done) => {
+ zone.run(() => {
+ BluebirdPromise.reject().catchThrow('test1').catch((r) => {
+ expect(r).toEqual('test1');
+ expect(log.filter(item => item === 'schedule bluebird task bluebird').length).toBe(1);
+ expect(log.filter(item => item === 'invoke bluebird task bluebird').length).toBe(1);
+ expect(Zone.current.name).toEqual('bluebird');
+ done();
+ });
+ });
+ });
+
+ it('bluebird promise reflect method should be in zone', (done) => {
+ zone.run(() => {
+ const promises = [BluebirdPromise.resolve('test1'), BluebirdPromise.reject('test2')];
+ BluebirdPromise
+ .all(promises.map(promise => {
+ return promise.reflect();
+ }))
+ .each((r) => {
+ if (r.isFulfilled()) {
+ expect(r.value()).toEqual('test1');
+ } else {
+ expect(r.reason()).toEqual('test2');
+ done();
+ }
+ expect(Zone.current.name).toEqual('bluebird');
+ });
+ });
+ });
+});
diff --git a/test/node/Error.spec.ts b/test/node/Error.spec.ts
index c1049dbd1..52c621bd7 100644
--- a/test/node/Error.spec.ts
+++ b/test/node/Error.spec.ts
@@ -18,15 +18,18 @@ describe('ZoneAwareError', () => {
});
it('should support prepareStackTrace', () => {
+ const originalPrepareStackTrace = (Error).prepareStackTrace;
(Error).prepareStackTrace = function(error, stack) {
return stack;
};
let obj: any = new Object();
Error.captureStackTrace(obj);
expect(obj.stack[0].getFileName()).not.toBeUndefined();
+ (Error).prepareStackTrace = originalPrepareStackTrace;
});
it('should not add additional stacktrace from Zone when use prepareStackTrace', () => {
+ const originalPrepareStackTrace = (Error).prepareStackTrace;
(Error).prepareStackTrace = function(error, stack) {
return stack;
};
@@ -36,5 +39,6 @@ describe('ZoneAwareError', () => {
obj.stack.forEach(function(st) {
expect(st.getFunctionName()).not.toEqual('zoneCaptureStackTrace');
});
+ (Error).prepareStackTrace = originalPrepareStackTrace;
});
});
diff --git a/test/node_tests.ts b/test/node_tests.ts
index 6e6d5424c..258f62eee 100644
--- a/test/node_tests.ts
+++ b/test/node_tests.ts
@@ -12,3 +12,7 @@ import './node/process.spec';
import './node/Error.spec';
import './node/crypto.spec';
import './node/http.spec';
+
+// before test bluebird, must run npm install bluebird first.
+// then remove the comment below
+// import './extra/bluebird.spec';