From 7820c7f0f486d6ce5de28c2b5969007c6d80fc04 Mon Sep 17 00:00:00 2001 From: "JiaLi.Passion" Date: Thu, 18 May 2017 01:08:57 +0900 Subject: [PATCH] feat(patch): fix #758, patch cordova success/error with zone.wrap --- karma-build.conf.js | 2 +- lib/browser/browser.ts | 1 + lib/common/utils.ts | 2 +- lib/extra/cordova.ts | 21 +++++++++++ lib/zone.ts | 7 +++- test/browser-zone-setup.ts | 3 +- test/browser_entry_point.ts | 3 +- test/extra/cordova.spec.ts | 37 +++++++++++++++++++ ...{custom_error.ts => test_fake_polyfill.ts} | 15 ++++++++ 9 files changed, 86 insertions(+), 5 deletions(-) create mode 100644 lib/extra/cordova.ts create mode 100644 test/extra/cordova.spec.ts rename test/{custom_error.ts => test_fake_polyfill.ts} (55%) diff --git a/karma-build.conf.js b/karma-build.conf.js index 33ab1fea2..87c87a5ea 100644 --- a/karma-build.conf.js +++ b/karma-build.conf.js @@ -9,7 +9,7 @@ module.exports = function (config) { require('./karma-base.conf.js')(config); config.files.push('build/test/wtf_mock.js'); - config.files.push('build/test/custom_error.js'); + config.files.push('build/test/test_fake_polyfill.js'); config.files.push('build/lib/zone.js'); config.files.push('build/lib/common/promise.js'); config.files.push('build/lib/common/error-rewrite.js'); diff --git a/lib/browser/browser.ts b/lib/browser/browser.ts index 745910db4..42ae9937a 100644 --- a/lib/browser/browser.ts +++ b/lib/browser/browser.ts @@ -193,4 +193,5 @@ Zone.__load_patch('PromiseRejectionEvent', (global: any, Zone: ZoneType, api: _Z Zone.__load_patch('util', (global: any, Zone: ZoneType, api: _ZonePrivate) => { api.patchEventTargetMethods = patchEventTargetMethods; api.patchOnProperties = patchOnProperties; + api.patchMethod = patchMethod; }); \ No newline at end of file diff --git a/lib/common/utils.ts b/lib/common/utils.ts index 909ecad53..aa7c001c9 100644 --- a/lib/common/utils.ts +++ b/lib/common/utils.ts @@ -674,4 +674,4 @@ export function findEventTask(target: any, evtName: string): Task[] { export function attachOriginToPatched(patched: Function, original: any) { (patched as any)[zoneSymbol('OriginalDelegate')] = original; -} +} \ No newline at end of file diff --git a/lib/extra/cordova.ts b/lib/extra/cordova.ts new file mode 100644 index 000000000..d6ac49b12 --- /dev/null +++ b/lib/extra/cordova.ts @@ -0,0 +1,21 @@ +/** + * @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 + */ +Zone.__load_patch('cordova', (global: any, Zone: ZoneType, api: _ZonePrivate) => { + if (global.cordova) { + const nativeExec: Function = api.patchMethod( + global.cordova, 'exec', (delegate: Function) => function(self: any, args: any[]) { + if (args.length > 0 && typeof args[0] === 'function') { + args[0] = Zone.current.wrap(args[0], 'cordova.exec.success'); + } + if (args.length > 1 && typeof args[1] === 'function') { + args[1] = Zone.current.wrap(args[1], 'cordova.exec.error'); + } + return nativeExec.apply(self, args); + }); + } +}); \ No newline at end of file diff --git a/lib/zone.ts b/lib/zone.ts index d3f2bf597..38cb179ad 100644 --- a/lib/zone.ts +++ b/lib/zone.ts @@ -323,6 +323,10 @@ interface _ZonePrivate { patchEventTargetMethods: (obj: any, addFnName?: string, removeFnName?: string, metaCreator?: any) => boolean; patchOnProperties: (obj: any, properties: string[]) => void; + patchMethod: + (target: any, name: string, + patchFn: (delegate: Function, delegateName: string, name: string) => + (self: any, args: any[]) => any) => Function; } /** @internal */ @@ -1294,7 +1298,8 @@ const Zone: ZoneType = (function(global: any) { scheduleMicroTask: scheduleMicroTask, showUncaughtError: () => !(Zone as any)[__symbol__('ignoreConsoleErrorUncaughtError')], patchEventTargetMethods: () => false, - patchOnProperties: noop + patchOnProperties: noop, + patchMethod: () => noop }; let _currentZoneFrame: _ZoneFrame = {parent: null, zone: new Zone(null, null)}; let _currentTask: Task = null; diff --git a/test/browser-zone-setup.ts b/test/browser-zone-setup.ts index 70ec87fd5..1b3d6d6ed 100644 --- a/test/browser-zone-setup.ts +++ b/test/browser-zone-setup.ts @@ -14,4 +14,5 @@ import '../lib/zone-spec/long-stack-trace'; import '../lib/zone-spec/proxy'; import '../lib/zone-spec/sync-test'; import '../lib/zone-spec/task-tracking'; -import '../lib/zone-spec/wtf'; \ No newline at end of file +import '../lib/zone-spec/wtf'; +import '../lib/extra/cordova'; \ No newline at end of file diff --git a/test/browser_entry_point.ts b/test/browser_entry_point.ts index 99183dbec..25efb0b0f 100644 --- a/test/browser_entry_point.ts +++ b/test/browser_entry_point.ts @@ -22,4 +22,5 @@ import './browser/XMLHttpRequest.spec'; import './browser/MediaQuery.spec'; import './browser/Notification.spec'; import './mocha-patch.spec'; -import './jasmine-patch.spec'; \ No newline at end of file +import './jasmine-patch.spec'; +import './extra/cordova.spec'; \ No newline at end of file diff --git a/test/extra/cordova.spec.ts b/test/extra/cordova.spec.ts new file mode 100644 index 000000000..9a412d74b --- /dev/null +++ b/test/extra/cordova.spec.ts @@ -0,0 +1,37 @@ +/** + * @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 + */ +describe('cordova test', () => { + it('cordova.exec() should be patched as macroTask', (done) => { + const scheduleSpy = jasmine.createSpy('scheduleTask'); + const cordova = (window as any).cordova; + + const zone = Zone.current.fork({name: 'cordova'}); + + zone.run(() => { + cordova.exec( + () => { + expect(Zone.current.name).toEqual('cordova'); + done(); + }, + () => { + fail('should not fail'); + }, + 'service', 'successAction', ['arg0', 'arg1']); + + cordova.exec( + () => { + fail('should not success'); + }, + () => { + expect(Zone.current.name).toEqual('cordova'); + done(); + }, + 'service', 'failAction', ['arg0', 'arg1']); + }); + }); +}); \ No newline at end of file diff --git a/test/custom_error.ts b/test/test_fake_polyfill.ts similarity index 55% rename from test/custom_error.ts rename to test/test_fake_polyfill.ts index d5dc968e7..87ed43f3e 100644 --- a/test/custom_error.ts +++ b/test/test_fake_polyfill.ts @@ -8,7 +8,22 @@ 'use strict'; (function(global: any) { + // add custom properties to Native Error const NativeError = global['Error']; NativeError.customProperty = 'customProperty'; NativeError.customFunction = function() {}; + + // add fake cordova polyfill for test + const fakeCordova = function() {}; + + (fakeCordova as any).exec = function( + success: Function, error: Function, service: string, action: string, args: any[]) { + if (action === 'successAction') { + success(); + } else { + error(); + } + }; + + global.cordova = fakeCordova; })(typeof window === 'object' && window || typeof self === 'object' && self || global);