build: reformat repo to new clang@1.4.0 (#36628)

PR Close #36628
This commit is contained in:
Joey Perrott
2020-04-13 17:43:52 -07:00
committed by atscott
parent 4b3f9ac739
commit 26f49151e7
1163 changed files with 31727 additions and 24036 deletions

View File

@ -14,8 +14,8 @@ module.exports = function(config) {
try {
const stats = fs.statSync(target.path);
if (stats.size > target.limit) {
console.error(
`file ${target.path} size over limit, limit is ${target.limit}, actual is ${stats.size}`);
console.error(`file ${target.path} size over limit, limit is ${target.limit}, actual is ${
stats.size}`);
chkResult = false;
}
} catch (err) {

View File

@ -14,7 +14,11 @@ const callbacks = [];
const size = 100000;
for (let i = 0; i < size; i++) {
const emitter = new EventEmitter();
const callback = (function(i) { return function() { console.log(i); }; })(i);
const callback = (function(i) {
return function() {
console.log(i);
};
})(i);
emitters[i] = emitter;
callbacks[i] = callback;
}

View File

@ -25,7 +25,9 @@ Zone['countingZoneSpec'] = {
}
},
counter: function() { return this.data.count; },
counter: function() {
return this.data.count;
},
data: {count: 0, flushed: false},

View File

@ -7,7 +7,7 @@
*/
import {globalSources, patchEventPrototype, patchEventTarget, zoneSymbolEventNames} from '../common/events';
import {ADD_EVENT_LISTENER_STR, ArraySlice, FALSE_STR, ObjectCreate, ObjectDefineProperty, ObjectGetOwnPropertyDescriptor, REMOVE_EVENT_LISTENER_STR, TRUE_STR, ZONE_SYMBOL_PREFIX, attachOriginToPatched, bindArguments, isBrowser, isIEOrEdge, isMix, isNode, patchClass, patchMacroTask, patchMethod, patchOnProperties, wrapWithCurrentZone} from '../common/utils';
import {ADD_EVENT_LISTENER_STR, ArraySlice, attachOriginToPatched, bindArguments, FALSE_STR, isBrowser, isIEOrEdge, isMix, isNode, ObjectCreate, ObjectDefineProperty, ObjectGetOwnPropertyDescriptor, patchClass, patchMacroTask, patchMethod, patchOnProperties, REMOVE_EVENT_LISTENER_STR, TRUE_STR, wrapWithCurrentZone, ZONE_SYMBOL_PREFIX} from '../common/utils';
import {patchCallbacks} from './browser-util';
import {eventNames, filterProperties} from './property-descriptor';
@ -45,7 +45,17 @@ Zone.__load_patch('util', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
api.attachOriginToPatched = attachOriginToPatched;
api._redefineProperty = Object.defineProperty;
api.patchCallbacks = patchCallbacks;
api.getGlobalObjects = () =>
({globalSources, zoneSymbolEventNames, eventNames, isBrowser, isMix, isNode, TRUE_STR,
FALSE_STR, ZONE_SYMBOL_PREFIX, ADD_EVENT_LISTENER_STR, REMOVE_EVENT_LISTENER_STR});
api.getGlobalObjects = () => ({
globalSources,
zoneSymbolEventNames,
eventNames,
isBrowser,
isMix,
isNode,
TRUE_STR,
FALSE_STR,
ZONE_SYMBOL_PREFIX,
ADD_EVENT_LISTENER_STR,
REMOVE_EVENT_LISTENER_STR
});
});

View File

@ -16,23 +16,25 @@ import {propertyDescriptorLegacyPatch} from './property-descriptor-legacy';
import {registerElementPatch} from './register-element';
(function(_global: any) {
const symbolPrefix = _global['__Zone_symbol_prefix'] || '__zone_symbol__';
function __symbol__(name: string) { return symbolPrefix + name; }
_global[__symbol__('legacyPatch')] = function() {
const Zone = _global['Zone'];
Zone.__load_patch('defineProperty', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
api._redefineProperty = _redefineProperty;
propertyPatch();
});
Zone.__load_patch('registerElement', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
registerElementPatch(global, api);
});
const symbolPrefix = _global['__Zone_symbol_prefix'] || '__zone_symbol__';
function __symbol__(name: string) {
return symbolPrefix + name;
}
_global[__symbol__('legacyPatch')] = function() {
const Zone = _global['Zone'];
Zone.__load_patch('defineProperty', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
api._redefineProperty = _redefineProperty;
propertyPatch();
});
Zone.__load_patch('registerElement', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
registerElementPatch(global, api);
});
Zone.__load_patch('EventTargetLegacy', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
eventTargetLegacyPatch(global, api);
propertyDescriptorLegacyPatch(api, global);
});
};
Zone.__load_patch('EventTargetLegacy', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
eventTargetLegacyPatch(global, api);
propertyDescriptorLegacyPatch(api, global);
});
};
})(typeof window !== 'undefined' ?
window :
typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {});

View File

@ -12,7 +12,7 @@
import {findEventTasks} from '../common/events';
import {patchTimer} from '../common/timers';
import {ZONE_SYMBOL_ADD_EVENT_LISTENER, ZONE_SYMBOL_REMOVE_EVENT_LISTENER, patchClass, patchMethod, patchPrototype, scheduleMacroTaskWithCurrentZone, zoneSymbol} from '../common/utils';
import {patchClass, patchMethod, patchPrototype, scheduleMacroTaskWithCurrentZone, ZONE_SYMBOL_ADD_EVENT_LISTENER, ZONE_SYMBOL_REMOVE_EVENT_LISTENER, zoneSymbol} from '../common/utils';
import {patchCustomElements} from './custom-elements';
import {eventTargetPatch, patchEvent} from './event-target';
@ -99,7 +99,9 @@ Zone.__load_patch('XHR', (global: any, Zone: ZoneType) => {
}
const XMLHttpRequestPrototype: any = XMLHttpRequest.prototype;
function findPendingTask(target: any) { return target[XHR_TASK]; }
function findPendingTask(target: any) {
return target[XHR_TASK];
}
let oriAddListener = XMLHttpRequestPrototype[ZONE_SYMBOL_ADD_EVENT_LISTENER];
let oriRemoveListener = XMLHttpRequestPrototype[ZONE_SYMBOL_REMOVE_EVENT_LISTENER];
@ -170,7 +172,7 @@ Zone.__load_patch('XHR', (global: any, Zone: ZoneType) => {
if (!storedTask) {
target[XHR_TASK] = task;
}
sendNative !.apply(target, data.args);
sendNative!.apply(target, data.args);
target[XHR_SCHEDULED] = true;
return task;
}
@ -182,14 +184,14 @@ Zone.__load_patch('XHR', (global: any, Zone: ZoneType) => {
// Note - ideally, we would call data.target.removeEventListener here, but it's too late
// to prevent it from firing. So instead, we store info for the event listener.
data.aborted = true;
return abortNative !.apply(data.target, data.args);
return abortNative!.apply(data.target, data.args);
}
const openNative =
patchMethod(XMLHttpRequestPrototype, 'open', () => function(self: any, args: any[]) {
self[XHR_SYNC] = args[2] == false;
self[XHR_URL] = args[1];
return openNative !.apply(self, args);
return openNative!.apply(self, args);
});
const XMLHTTPREQUEST_SOURCE = 'XMLHttpRequest.send';
@ -201,11 +203,11 @@ Zone.__load_patch('XHR', (global: any, Zone: ZoneType) => {
// a fetch is scheduling, so we are using xhr to polyfill fetch
// and because we already schedule macroTask for fetch, we should
// not schedule a macroTask for xhr again
return sendNative !.apply(self, args);
return sendNative!.apply(self, args);
}
if (self[XHR_SYNC]) {
// if the XHR is sync there is no task to schedule, just execute the code.
return sendNative !.apply(self, args);
return sendNative!.apply(self, args);
} else {
const options: XHROptions =
{target: self, url: self[XHR_URL], isPeriodic: false, args: args, aborted: false};
@ -235,7 +237,7 @@ Zone.__load_patch('XHR', (global: any, Zone: ZoneType) => {
task.zone.cancelTask(task);
} else if ((Zone.current as any)[fetchTaskAborting] === true) {
// the abort is called from fetch polyfill, we need to call native abort of XHR.
return abortNative !.apply(self, args);
return abortNative!.apply(self, args);
}
// Otherwise, we are trying to abort an XHR which has not yet been sent, so there is no
// task

View File

@ -7,7 +7,7 @@
*/
export function patchCustomElements(_global: any, api: _ZonePrivate) {
const {isBrowser, isMix} = api.getGlobalObjects() !;
const {isBrowser, isMix} = api.getGlobalObjects()!;
if ((!isBrowser && !isMix) || !_global['customElements'] || !('customElements' in _global)) {
return;
}

View File

@ -36,7 +36,9 @@ export function propertyPatch() {
};
Object.defineProperties = function(obj, props) {
Object.keys(props).forEach(function(prop) { Object.defineProperty(obj, prop, props[prop]); });
Object.keys(props).forEach(function(prop) {
Object.defineProperty(obj, prop, props[prop]);
});
return obj;
};

View File

@ -8,7 +8,7 @@
export function eventTargetLegacyPatch(_global: any, api: _ZonePrivate) {
const {eventNames, globalSources, zoneSymbolEventNames, TRUE_STR, FALSE_STR, ZONE_SYMBOL_PREFIX} =
api.getGlobalObjects() !;
api.getGlobalObjects()!;
const WTF_ISSUE_555 =
'Anchor,Area,Audio,BR,Base,BaseFont,Body,Button,Canvas,Content,DList,Directory,Div,Embed,FieldSet,Font,Form,Frame,FrameSet,HR,Head,Heading,Html,IFrame,Image,Input,Keygen,LI,Label,Legend,Link,Map,Marquee,Media,Menu,Meta,Meter,Mod,OList,Object,OptGroup,Option,Output,Paragraph,Pre,Progress,Quote,Script,Select,Source,Span,Style,TableCaption,TableCell,TableCol,Table,TableRow,TableSection,TextArea,Title,Track,UList,Unknown,Video';
const NO_EVENT_TARGET =

View File

@ -12,7 +12,7 @@ export function eventTargetPatch(_global: any, api: _ZonePrivate) {
return;
}
const {eventNames, zoneSymbolEventNames, TRUE_STR, FALSE_STR, ZONE_SYMBOL_PREFIX} =
api.getGlobalObjects() !;
api.getGlobalObjects()!;
// predefine all __zone_symbol__ + eventName + true/false string
for (let i = 0; i < eventNames.length; i++) {
const eventName = eventNames[i];

View File

@ -13,7 +13,7 @@
import * as webSocketPatch from './websocket';
export function propertyDescriptorLegacyPatch(api: _ZonePrivate, _global: any) {
const {isNode, isMix} = api.getGlobalObjects() !;
const {isNode, isMix} = api.getGlobalObjects()!;
if (isNode && !isMix) {
return;
}
@ -31,7 +31,7 @@ export function propertyDescriptorLegacyPatch(api: _ZonePrivate, _global: any) {
}
function canPatchViaPropertyDescriptor(api: _ZonePrivate, _global: any) {
const {isBrowser, isMix} = api.getGlobalObjects() !;
const {isBrowser, isMix} = api.getGlobalObjects()!;
if ((isBrowser || isMix) &&
!api.ObjectGetOwnPropertyDescriptor(HTMLElement.prototype, 'onclick') &&
typeof Element !== 'undefined') {
@ -42,9 +42,13 @@ function canPatchViaPropertyDescriptor(api: _ZonePrivate, _global: any) {
// try to use onclick to detect whether we can patch via propertyDescriptor
// because XMLHttpRequest is not available in service worker
if (desc) {
api.ObjectDefineProperty(
Element.prototype, 'onclick',
{enumerable: true, configurable: true, get: function() { return true; }});
api.ObjectDefineProperty(Element.prototype, 'onclick', {
enumerable: true,
configurable: true,
get: function() {
return true;
}
});
const div = document.createElement('div');
const result = !!div.onclick;
api.ObjectDefineProperty(Element.prototype, 'onclick', desc);
@ -70,9 +74,13 @@ function canPatchViaPropertyDescriptor(api: _ZonePrivate, _global: any) {
// and if XMLHttpRequest.prototype.onreadystatechange is undefined,
// we should set a real desc instead a fake one
if (xhrDesc) {
api.ObjectDefineProperty(
XMLHttpRequestPrototype, ON_READY_STATE_CHANGE,
{enumerable: true, configurable: true, get: function() { return true; }});
api.ObjectDefineProperty(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE, {
enumerable: true,
configurable: true,
get: function() {
return true;
}
});
const req = new XMLHttpRequest();
const result = !!req.onreadystatechange;
// restore original desc
@ -83,8 +91,12 @@ function canPatchViaPropertyDescriptor(api: _ZonePrivate, _global: any) {
api.ObjectDefineProperty(XMLHttpRequestPrototype, ON_READY_STATE_CHANGE, {
enumerable: true,
configurable: true,
get: function() { return this[SYMBOL_FAKE_ONREADYSTATECHANGE]; },
set: function(value) { this[SYMBOL_FAKE_ONREADYSTATECHANGE] = value; }
get: function() {
return this[SYMBOL_FAKE_ONREADYSTATECHANGE];
},
set: function(value) {
this[SYMBOL_FAKE_ONREADYSTATECHANGE] = value;
}
});
const req = new XMLHttpRequest();
const detectFunc = () => {};
@ -99,7 +111,7 @@ function canPatchViaPropertyDescriptor(api: _ZonePrivate, _global: any) {
// for `onwhatever` properties and replace them with zone-bound functions
// - Chrome (for now)
function patchViaCapturingAllTheEvents(api: _ZonePrivate) {
const {eventNames} = api.getGlobalObjects() !;
const {eventNames} = api.getGlobalObjects()!;
const unboundKey = api.symbol('unbound');
for (let i = 0; i < eventNames.length; i++) {
const property = eventNames[i];

View File

@ -10,7 +10,7 @@
* @suppress {globalThis}
*/
import {ObjectGetPrototypeOf, isBrowser, isIE, isMix, isNode, patchOnProperties} from '../common/utils';
import {isBrowser, isIE, isMix, isNode, ObjectGetPrototypeOf, patchOnProperties} from '../common/utils';
const globalEventHandlersEventNames = [
'abort',

View File

@ -7,7 +7,7 @@
*/
export function registerElementPatch(_global: any, api: _ZonePrivate) {
const {isBrowser, isMix} = api.getGlobalObjects() !;
const {isBrowser, isMix} = api.getGlobalObjects()!;
if ((!isBrowser && !isMix) || !('registerElement' in (<any>_global).document)) {
return;
}

View File

@ -83,7 +83,9 @@ Zone.__load_patch('ResizeObserver', (global: any, Zone: any, api: _ZonePrivate)
ResizeObserver.prototype, 'disconnect', (delegate: Function) => (self: any, args: any[]) => {
const targets = self[resizeObserverSymbol];
if (targets) {
targets.forEach((target: any) => { target[resizeObserverSymbol] = undefined; });
targets.forEach((target: any) => {
target[resizeObserverSymbol] = undefined;
});
self[resizeObserverSymbol] = undefined;
}
return delegate.apply(self, args);

View File

@ -8,7 +8,7 @@
// we have to patch the instance since the proto is non-configurable
export function apply(api: _ZonePrivate, _global: any) {
const {ADD_EVENT_LISTENER_STR, REMOVE_EVENT_LISTENER_STR} = api.getGlobalObjects() !;
const {ADD_EVENT_LISTENER_STR, REMOVE_EVENT_LISTENER_STR} = api.getGlobalObjects()!;
const WS = (<any>_global).WebSocket;
// On Safari window.EventTarget doesn't exist so need to patch WS add/removeEventListener
// On older Chrome, no need since EventTarget was already patched

View File

@ -1,10 +1,10 @@
/**
* @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
*/
* @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
*/
/**
* @fileoverview Externs for zone.js
@ -148,8 +148,8 @@ Zone.prototype.scheduleMicroTask = function(source, callback, data, customSchedu
* @param {?function(!Task)=} customCancel
* @return {!MacroTask} macroTask
*/
Zone.prototype.scheduleMacroTask = function(source, callback, data, customSchedule, customCancel) {
};
Zone.prototype.scheduleMacroTask = function(
source, callback, data, customSchedule, customCancel) {};
/**
* @param {string} source
@ -159,8 +159,8 @@ Zone.prototype.scheduleMacroTask = function(source, callback, data, customSchedu
* @param {?function(!Task)=} customCancel
* @return {!EventTask} eventTask
*/
Zone.prototype.scheduleEventTask = function(source, callback, data, customSchedule, customCancel) {
};
Zone.prototype.scheduleEventTask = function(
source, callback, data, customSchedule, customCancel) {};
/**
* @param {!Task} task

View File

@ -53,7 +53,7 @@ Zone.__load_patch('Error', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
global['Error'] = ZoneAwareError;
const stackRewrite = 'stackRewrite';
type BlackListedStackFramesPolicy = 'default' | 'disable' | 'lazy';
type BlackListedStackFramesPolicy = 'default'|'disable'|'lazy';
const blackListedStackFramesPolicy: BlackListedStackFramesPolicy =
global['__Zone_Error_BlacklistedStackFrames_policy'] || 'default';
@ -75,7 +75,7 @@ Zone.__load_patch('Error', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
}
function buildZoneAwareStackFrames(
originalStack: string, zoneFrame: _ZoneFrame | ZoneFrameName | null, isZoneFrame = true) {
originalStack: string, zoneFrame: _ZoneFrame|ZoneFrameName|null, isZoneFrame = true) {
let frames: string[] = originalStack.split('\n');
let i = 0;
// Find the first frame
@ -115,7 +115,7 @@ Zone.__load_patch('Error', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
* This is ZoneAwareError which processes the stack frame and cleans up extra frames as well as
* adds zone information to it.
*/
function ZoneAwareError(this: unknown | typeof NativeError): Error {
function ZoneAwareError(this: unknown|typeof NativeError): Error {
// We always have to return native error otherwise the browser console will not work.
let error: Error = NativeError.apply(this, arguments);
// Save original stack trace
@ -190,8 +190,12 @@ Zone.__load_patch('Error', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
nativeErrorProperties.forEach(prop => {
if (specialPropertyNames.filter(sp => sp === prop).length === 0) {
Object.defineProperty(ZoneAwareError, prop, {
get: function() { return NativeError[prop]; },
set: function(value) { NativeError[prop] = value; }
get: function() {
return NativeError[prop];
},
set: function(value) {
NativeError[prop] = value;
}
});
}
});
@ -203,8 +207,12 @@ Zone.__load_patch('Error', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
// make sure that ZoneAwareError has the same property which forwards to NativeError.
Object.defineProperty(ZoneAwareError, 'stackTraceLimit', {
get: function() { return NativeError.stackTraceLimit; },
set: function(value) { return NativeError.stackTraceLimit = value; }
get: function() {
return NativeError.stackTraceLimit;
},
set: function(value) {
return NativeError.stackTraceLimit = value;
}
});
}
@ -220,7 +228,9 @@ Zone.__load_patch('Error', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
const ZONE_CAPTURESTACKTRACE = 'zoneCaptureStackTrace';
Object.defineProperty(ZoneAwareError, 'prepareStackTrace', {
get: function() { return NativeError.prepareStackTrace; },
get: function() {
return NativeError.prepareStackTrace;
},
set: function(value) {
if (!value || typeof value !== 'function') {
return NativeError.prepareStackTrace = value;
@ -347,13 +357,21 @@ Zone.__load_patch('Error', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
blacklistedStackFramesSymbol,
() => {
childDetectZone.scheduleMicroTask(
blacklistedStackFramesSymbol, () => { throw new Error(); }, undefined,
blacklistedStackFramesSymbol,
() => {
throw new Error();
},
undefined,
(t: Task) => {
(t as any)._transitionTo = fakeTransitionTo;
t.invoke();
});
childDetectZone.scheduleMicroTask(
blacklistedStackFramesSymbol, () => { throw Error(); }, undefined,
blacklistedStackFramesSymbol,
() => {
throw Error();
},
undefined,
(t: Task) => {
(t as any)._transitionTo = fakeTransitionTo;
t.invoke();

View File

@ -10,7 +10,7 @@
* @suppress {missingRequire}
*/
import {ADD_EVENT_LISTENER_STR, FALSE_STR, ObjectGetPrototypeOf, REMOVE_EVENT_LISTENER_STR, TRUE_STR, ZONE_SYMBOL_PREFIX, attachOriginToPatched, isNode, zoneSymbol} from './utils';
import {ADD_EVENT_LISTENER_STR, attachOriginToPatched, FALSE_STR, isNode, ObjectGetPrototypeOf, REMOVE_EVENT_LISTENER_STR, TRUE_STR, ZONE_SYMBOL_PREFIX, zoneSymbol} from './utils';
/** @internal **/
@ -23,8 +23,11 @@ let passiveSupported = false;
if (typeof window !== 'undefined') {
try {
const options =
Object.defineProperty({}, 'passive', {get: function() { passiveSupported = true; }});
const options = Object.defineProperty({}, 'passive', {
get: function() {
passiveSupported = true;
}
});
window.addEventListener('test', options, options);
window.removeEventListener('test', options, options);
} catch (err) {

View File

@ -53,7 +53,7 @@ Zone.__load_patch('fetch', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
const signal = options && options.signal;
return new Promise((res, rej) => {
const task = Zone.current.scheduleMacroTask(
'fetch', placeholder, { fetchArgs: args } as FetchTaskData,
'fetch', placeholder, {fetchArgs: args} as FetchTaskData,
() => {
let fetchPromise;
let zone = Zone.current;

View File

@ -50,11 +50,13 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam
}
}
data.args[0] = timer;
data.handleId = setNative !.apply(window, data.args);
data.handleId = setNative!.apply(window, data.args);
return task;
}
function clearTask(task: Task) { return clearNative !((<TimerOptions>task.data).handleId); }
function clearTask(task: Task) {
return clearNative!((<TimerOptions>task.data).handleId);
}
setNative =
patchMethod(window, setName, (delegate: Function) => function(self: any, args: any[]) {
@ -116,7 +118,7 @@ export function patchTimer(window: any, setName: string, cancelName: string, nam
}
if (task && typeof task.type === 'string') {
if (task.state !== 'notScheduled' &&
(task.cancelFn && task.data !.isPeriodic || task.runCount === 0)) {
(task.cancelFn && task.data!.isPeriodic || task.runCount === 0)) {
if (typeof id === 'number') {
delete tasksByHandleId[id];
} else if (id) {

View File

@ -250,8 +250,8 @@ export function patchProperty(obj: any, prop: string, prototype?: any) {
// so we should use original native get to retrieve the handler
let value = originalDescGet && originalDescGet.call(this);
if (value) {
desc !.set !.call(this, value);
if (typeof(target as any)[REMOVE_ATTRIBUTE] === 'function') {
desc!.set!.call(this, value);
if (typeof (target as any)[REMOVE_ATTRIBUTE] === 'function') {
(target as any).removeAttribute(prop);
}
return value;
@ -265,7 +265,7 @@ export function patchProperty(obj: any, prop: string, prototype?: any) {
obj[onPropPatchedSymbol] = true;
}
export function patchOnProperties(obj: any, properties: string[] | null, prototype?: any) {
export function patchOnProperties(obj: any, properties: string[]|null, prototype?: any) {
if (properties) {
for (let i = 0; i < properties.length; i++) {
patchProperty(obj, 'on' + properties[i], prototype);
@ -342,7 +342,9 @@ export function patchClass(className: string) {
this[originalInstanceKey][prop] = fn;
}
},
get: function() { return this[originalInstanceKey][prop]; }
get: function() {
return this[originalInstanceKey][prop];
}
});
}
}(prop));
@ -356,14 +358,16 @@ export function patchClass(className: string) {
}
export function copySymbolProperties(src: any, dest: any) {
if (typeof(Object as any).getOwnPropertySymbols !== 'function') {
if (typeof (Object as any).getOwnPropertySymbols !== 'function') {
return;
}
const symbols: any = (Object as any).getOwnPropertySymbols(src);
symbols.forEach((symbol: any) => {
const desc = Object.getOwnPropertyDescriptor(src, symbol);
Object.defineProperty(dest, symbol, {
get: function() { return src[symbol]; },
get: function() {
return src[symbol];
},
set: function(value: any) {
if (desc && (!desc.writable || typeof desc.set !== 'function')) {
// if src[symbol] is not writable or not have a setter, just return
@ -384,8 +388,9 @@ export function setShouldCopySymbolProperties(flag: boolean) {
}
export function patchMethod(
target: any, name: string, patchFn: (delegate: Function, delegateName: string, name: string) =>
(self: any, args: any[]) => any): Function|null {
target: any, name: string,
patchFn: (delegate: Function, delegateName: string, name: string) => (self: any, args: any[]) =>
any): Function|null {
let proto = target;
while (proto && !proto.hasOwnProperty(name)) {
proto = ObjectGetPrototypeOf(proto);
@ -403,8 +408,10 @@ export function patchMethod(
// some property is readonly in safari, such as HtmlCanvasElement.prototype.toBlob
const desc = proto && ObjectGetOwnPropertyDescriptor(proto, name);
if (isPropertyWritable(desc)) {
const patchDelegate = patchFn(delegate !, delegateName, name);
proto[name] = function() { return patchDelegate(this, arguments as any); };
const patchDelegate = patchFn(delegate!, delegateName, name);
proto[name] = function() {
return patchDelegate(this, arguments as any);
};
attachOriginToPatched(proto[name], delegate);
if (shouldCopySymbolProperties) {
copySymbolProperties(delegate, proto[name]);
@ -428,8 +435,10 @@ export function patchMacroTask(
function scheduleTask(task: Task) {
const data = <MacroTaskMeta>task.data;
data.args[data.cbIdx] = function() { task.invoke.apply(this, arguments); };
setNative !.apply(data.target, data.args);
data.args[data.cbIdx] = function() {
task.invoke.apply(this, arguments);
};
setNative!.apply(data.target, data.args);
return task;
}
@ -457,8 +466,10 @@ export function patchMicroTask(
function scheduleTask(task: Task) {
const data = <MacroTaskMeta>task.data;
data.args[data.cbIdx] = function() { task.invoke.apply(this, arguments); };
setNative !.apply(data.target, data.args);
data.args[data.cbIdx] = function() {
task.invoke.apply(this, arguments);
};
setNative!.apply(data.target, data.args);
return task;
}

View File

@ -18,7 +18,7 @@ Zone.__load_patch('cordova', (global: any, Zone: ZoneType, api: _ZonePrivate) =>
if (args.length > 1 && typeof args[1] === FUNCTION) {
args[1] = Zone.current.wrap(args[1], ERROR_SOURCE);
}
return nativeExec !.apply(self, args);
return nativeExec!.apply(self, args);
});
}
});
@ -31,7 +31,9 @@ Zone.__load_patch('cordova.FileReader', (global: any, Zone: ZoneType) => {
const eventNameSymbol = Zone.__symbol__('ON_PROPERTY' + prop);
Object.defineProperty(FileReader.prototype, eventNameSymbol, {
configurable: true,
get: function() { return this._realReader && this._realReader[eventNameSymbol]; }
get: function() {
return this._realReader && this._realReader[eventNameSymbol];
}
});
});
});

View File

@ -70,8 +70,10 @@ Zone.__load_patch('jsonp', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
api.patchMethod(
options.jsonp, options.sendFuncName, (delegate: Function) => (self: any, args: any[]) => {
global[api.symbol('jsonpTask')] = Zone.current.scheduleMacroTask(
'jsonp', noop, {}, (task: Task) => { return delegate.apply(self, args); }, noop);
global[api.symbol('jsonpTask')] =
Zone.current.scheduleMacroTask('jsonp', noop, {}, (task: Task) => {
return delegate.apply(self, args);
}, noop);
});
};
});

View File

@ -12,7 +12,9 @@ Zone.__load_patch('socketio', (global: any, Zone: ZoneType, api: _ZonePrivate) =
useG: false,
chkDup: false,
rt: true,
diff: (task: any, delegate: any) => { return task.callback === delegate; }
diff: (task: any, delegate: any) => {
return task.callback === delegate;
}
});
// also patch io.Socket.prototype.on/off/removeListener/removeAllListeners
io.Socket.prototype.on = io.Socket.prototype.addEventListener;

View File

@ -14,7 +14,9 @@ Zone.__load_patch('jasmine', (global: any, Zone: ZoneType, api: _ZonePrivate) =>
const __extends = function(d: any, b: any) {
for (const p in b)
if (b.hasOwnProperty(p)) d[p] = b[p];
function __(this: Object) { this.constructor = d; }
function __(this: Object) {
this.constructor = d;
}
d.prototype = b === null ? Object.create(b) : ((__.prototype = b.prototype), new (__ as any)());
};
// Patch jasmine's describe/it/beforeEach/afterEach functions so test code always runs
@ -126,9 +128,9 @@ Zone.__load_patch('jasmine', (global: any, Zone: ZoneType, api: _ZonePrivate) =>
if (fakeAsyncZoneSpec) {
const dateTime = arguments.length > 0 ? arguments[0] : new Date();
return fakeAsyncZoneSpec.setCurrentRealTime.apply(
fakeAsyncZoneSpec, dateTime && typeof dateTime.getTime === 'function' ?
[dateTime.getTime()] :
arguments);
fakeAsyncZoneSpec,
dateTime && typeof dateTime.getTime === 'function' ? [dateTime.getTime()] :
arguments);
}
return originalMockDate.apply(this, arguments);
};
@ -163,8 +165,8 @@ Zone.__load_patch('jasmine', (global: any, Zone: ZoneType, api: _ZonePrivate) =>
function runInTestZone(
testBody: Function, applyThis: any, queueRunner: QueueRunner, done?: Function) {
const isClockInstalled = !!(jasmine as any)[symbol('clockInstalled')];
const testProxyZoneSpec = queueRunner.testProxyZoneSpec !;
const testProxyZone = queueRunner.testProxyZone !;
const testProxyZoneSpec = queueRunner.testProxyZoneSpec!;
const testProxyZone = queueRunner.testProxyZone!;
let lastDelegate;
if (isClockInstalled && enableAutoFakeAsyncWhenClockPatched) {
// auto run a fakeAsync
@ -190,9 +192,9 @@ Zone.__load_patch('jasmine', (global: any, Zone: ZoneType, api: _ZonePrivate) =>
// Note we have to make a function with correct number of arguments, otherwise jasmine will
// think that all functions are sync or async.
return (testBody && (testBody.length ? function(this: QueueRunnerUserContext, done: Function) {
return runInTestZone(testBody, this, this.queueRunner !, done);
return runInTestZone(testBody, this, this.queueRunner!, done);
} : function(this: QueueRunnerUserContext) {
return runInTestZone(testBody, this, this.queueRunner !);
return runInTestZone(testBody, this, this.queueRunner!);
}));
}
interface QueueRunner {

View File

@ -73,7 +73,9 @@ Zone.__load_patch('jest', (context: any, Zone: ZoneType) => {
// The `done` callback is only passed through if the function expects at least one argument.
// Note we have to make a function with correct number of arguments, otherwise jest will
// think that all functions are sync or async.
return function(this: unknown, ...args: any[]) { return proxyZone.run(testBody, this, args); };
return function(this: unknown, ...args: any[]) {
return proxyZone.run(testBody, this, args);
};
}
['describe', 'xdescribe', 'fdescribe'].forEach(methodName => {

View File

@ -57,10 +57,12 @@ Zone.__load_patch('mocha', (global: any, Zone: ZoneType) => {
// Note we have to make a function with correct number of arguments,
// otherwise mocha will
// think that all functions are sync or async.
args[i] = (arg.length === 0) ? syncTest(arg) : asyncTest !(arg);
args[i] = (arg.length === 0) ? syncTest(arg) : asyncTest!(arg);
// Mocha uses toString to view the test body in the result list, make sure we return the
// correct function body
args[i].toString = function() { return arg.toString(); };
args[i].toString = function() {
return arg.toString();
};
}
}
@ -69,7 +71,9 @@ Zone.__load_patch('mocha', (global: any, Zone: ZoneType) => {
function wrapDescribeInZone(args: IArguments): any[] {
const syncTest: any = function(fn: Function) {
return function(this: unknown) { return syncZone.run(fn, this, arguments as any as any[]); };
return function(this: unknown) {
return syncZone.run(fn, this, arguments as any as any[]);
};
};
return modifyArguments(args, syncTest);
@ -77,11 +81,15 @@ Zone.__load_patch('mocha', (global: any, Zone: ZoneType) => {
function wrapTestInZone(args: IArguments): any[] {
const asyncTest = function(fn: Function) {
return function(this: unknown, done: Function) { return testZone !.run(fn, this, [done]); };
return function(this: unknown, done: Function) {
return testZone!.run(fn, this, [done]);
};
};
const syncTest: any = function(fn: Function) {
return function(this: unknown) { return testZone !.run(fn, this); };
return function(this: unknown) {
return testZone!.run(fn, this);
};
};
return modifyArguments(args, syncTest, asyncTest);
@ -89,11 +97,15 @@ Zone.__load_patch('mocha', (global: any, Zone: ZoneType) => {
function wrapSuiteInZone(args: IArguments): any[] {
const asyncTest = function(fn: Function) {
return function(this: unknown, done: Function) { return suiteZone.run(fn, this, [done]); };
return function(this: unknown, done: Function) {
return suiteZone.run(fn, this, [done]);
};
};
const syncTest: any = function(fn: Function) {
return function(this: unknown) { return suiteZone.run(fn, this); };
return function(this: unknown) {
return suiteZone.run(fn, this);
};
};
return modifyArguments(args, syncTest, asyncTest);
@ -111,8 +123,9 @@ Zone.__load_patch('mocha', (global: any, Zone: ZoneType) => {
return mochaOriginal.describe.only.apply(this, wrapDescribeInZone(arguments));
};
global.it = global.specify = global.test =
Mocha.it = function() { return mochaOriginal.it.apply(this, wrapTestInZone(arguments)); };
global.it = global.specify = global.test = Mocha.it = function() {
return mochaOriginal.it.apply(this, wrapTestInZone(arguments));
};
global.xit = global.xspecify = Mocha.it.skip = function() {
return mochaOriginal.it.skip.apply(this, wrapTestInZone(arguments));
@ -140,11 +153,15 @@ Zone.__load_patch('mocha', (global: any, Zone: ZoneType) => {
((originalRunTest, originalRun) => {
Mocha.Runner.prototype.runTest = function(fn: Function) {
Zone.current.scheduleMicroTask('mocha.forceTask', () => { originalRunTest.call(this, fn); });
Zone.current.scheduleMicroTask('mocha.forceTask', () => {
originalRunTest.call(this, fn);
});
};
Mocha.Runner.prototype.run = function(fn: Function) {
this.on('test', (e: any) => { testZone = rootZone.fork(new ProxyZoneSpec()); });
this.on('test', (e: any) => {
testZone = rootZone.fork(new ProxyZoneSpec());
});
this.on('fail', (test: any, err: any) => {
const proxyZoneSpec = testZone && testZone.get('ProxyZoneSpec');

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Scheduler, asapScheduler, asyncScheduler} from 'rxjs';
import {asapScheduler, asyncScheduler, Scheduler} from 'rxjs';
Zone.__load_patch('rxjs.Scheduler.now', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
api.patchMethod(Scheduler, 'now', (delegate: Function) => (self: any, args: any[]) => {

View File

@ -10,7 +10,7 @@ import {Observable, Subscriber, Subscription} from 'rxjs';
type ZoneSubscriberContext = {
_zone: Zone
} & Subscriber<any>;
}&Subscriber<any>;
(Zone as any).__load_patch('rxjs', (global: any, Zone: ZoneType, api: _ZonePrivate) => {
const symbol: (symbolString: string) => string = (Zone as any).__symbol__;
@ -31,7 +31,9 @@ type ZoneSubscriberContext = {
_zoneSubscribe: {value: null, writable: true, configurable: true},
source: {
configurable: true,
get: function(this: Observable<any>) { return (this as any)._zoneSource; },
get: function(this: Observable<any>) {
return (this as any)._zoneSource;
},
set: function(this: Observable<any>, source: any) {
(this as any)._zone = Zone.current;
(this as any)._zoneSource = source;
@ -75,7 +77,9 @@ type ZoneSubscriberContext = {
}
},
subjectFactory: {
get: function() { return (this as any)._zoneSubjectFactory; },
get: function() {
return (this as any)._zoneSubjectFactory;
},
set: function(factory: any) {
const zone = this._zone;
this._zoneSubjectFactory = function() {
@ -142,7 +146,9 @@ type ZoneSubscriberContext = {
Object.defineProperty(Subscriber.prototype, 'destination', {
configurable: true,
get: function(this: Subscriber<any>) { return (this as any)._zoneDestination; },
get: function(this: Subscriber<any>) {
return (this as any)._zoneDestination;
},
set: function(this: Subscriber<any>, destination: any) {
(this as any)._zone = Zone.current;
(this as any)._zoneDestination = destination;

View File

@ -22,7 +22,9 @@ Zone.__load_patch('asynctest', (global: any, Zone: ZoneType, api: _ZonePrivate)
// if we run beforeEach in @angular/core/testing/testing_internal then we get no done
// fake it here and assume sync.
done = function() {};
done.fail = function(e: any) { throw e; };
done.fail = function(e: any) {
throw e;
};
}
runInTestZone(fn, this, done, (err: any) => {
if (typeof err === 'string') {
@ -68,7 +70,7 @@ Zone.__load_patch('asynctest', (global: any, Zone: ZoneType, api: _ZonePrivate)
// If we do it in ProxyZone then we will get to infinite recursion.
const proxyZone = Zone.current.getZoneWith('ProxyZoneSpec');
const previousDelegate = proxyZoneSpec.getDelegate();
proxyZone !.parent !.run(() => {
proxyZone!.parent!.run(() => {
const testZoneSpec: ZoneSpec = new AsyncTestZoneSpec(
() => {
// Need to restore the original zone.
@ -79,7 +81,9 @@ Zone.__load_patch('asynctest', (global: any, Zone: ZoneType, api: _ZonePrivate)
proxyZoneSpec.setDelegate(previousDelegate);
}
(testZoneSpec as any).unPatchPromiseForTest();
currentZone.run(() => { finishCallback(); });
currentZone.run(() => {
finishCallback();
});
},
(error: any) => {
// Need to restore the original zone.
@ -88,7 +92,9 @@ Zone.__load_patch('asynctest', (global: any, Zone: ZoneType, api: _ZonePrivate)
proxyZoneSpec.setDelegate(previousDelegate);
}
(testZoneSpec as any).unPatchPromiseForTest();
currentZone.run(() => { failCallback(error); });
currentZone.run(() => {
failCallback(error);
});
},
'test');
proxyZoneSpec.setDelegate(testZoneSpec);

View File

@ -131,7 +131,9 @@ Zone.__load_patch('fakeasync', (global: any, Zone: ZoneType, api: _ZonePrivate)
*
* @experimental
*/
function flush(maxTurns?: number): number { return _getFakeAsyncZoneSpec().flush(maxTurns); }
function flush(maxTurns?: number): number {
return _getFakeAsyncZoneSpec().flush(maxTurns);
}
/**
* Discard all remaining periodic tasks.
@ -149,7 +151,9 @@ Zone.__load_patch('fakeasync', (global: any, Zone: ZoneType, api: _ZonePrivate)
*
* @experimental
*/
function flushMicrotasks(): void { _getFakeAsyncZoneSpec().flushMicrotasks(); }
(Zone as any)[api.symbol('fakeAsyncTest')] = {
resetFakeAsyncZone, flushMicrotasks, discardPeriodicTasks, tick, flush, fakeAsync};
function flushMicrotasks(): void {
_getFakeAsyncZoneSpec().flushMicrotasks();
}
(Zone as any)[api.symbol('fakeAsyncTest')] =
{resetFakeAsyncZone, flushMicrotasks, discardPeriodicTasks, tick, flush, fakeAsync};
});

View File

@ -6,144 +6,144 @@
* found in the LICENSE file at https://angular.io/license
*/
(function(_global: any) {
class AsyncTestZoneSpec implements ZoneSpec {
static symbolParentUnresolved = Zone.__symbol__('parentUnresolved');
class AsyncTestZoneSpec implements ZoneSpec {
static symbolParentUnresolved = Zone.__symbol__('parentUnresolved');
_pendingMicroTasks: boolean = false;
_pendingMacroTasks: boolean = false;
_alreadyErrored: boolean = false;
_isSync: boolean = false;
runZone = Zone.current;
unresolvedChainedPromiseCount = 0;
_pendingMicroTasks: boolean = false;
_pendingMacroTasks: boolean = false;
_alreadyErrored: boolean = false;
_isSync: boolean = false;
runZone = Zone.current;
unresolvedChainedPromiseCount = 0;
supportWaitUnresolvedChainedPromise = false;
supportWaitUnresolvedChainedPromise = false;
constructor(
private finishCallback: Function, private failCallback: Function, namePrefix: string) {
this.name = 'asyncTestZone for ' + namePrefix;
this.properties = {'AsyncTestZoneSpec': this};
this.supportWaitUnresolvedChainedPromise =
_global[Zone.__symbol__('supportWaitUnResolvedChainedPromise')] === true;
constructor(
private finishCallback: Function, private failCallback: Function, namePrefix: string) {
this.name = 'asyncTestZone for ' + namePrefix;
this.properties = {'AsyncTestZoneSpec': this};
this.supportWaitUnresolvedChainedPromise =
_global[Zone.__symbol__('supportWaitUnResolvedChainedPromise')] === true;
}
isUnresolvedChainedPromisePending() {
return this.unresolvedChainedPromiseCount > 0;
}
_finishCallbackIfDone() {
if (!(this._pendingMicroTasks || this._pendingMacroTasks ||
(this.supportWaitUnresolvedChainedPromise && this.isUnresolvedChainedPromisePending()))) {
// We do this because we would like to catch unhandled rejected promises.
this.runZone.run(() => {
setTimeout(() => {
if (!this._alreadyErrored && !(this._pendingMicroTasks || this._pendingMacroTasks)) {
this.finishCallback();
}
}, 0);
});
}
}
isUnresolvedChainedPromisePending() { return this.unresolvedChainedPromiseCount > 0; }
patchPromiseForTest() {
if (!this.supportWaitUnresolvedChainedPromise) {
return;
}
const patchPromiseForTest = (Promise as any)[Zone.__symbol__('patchPromiseForTest')];
if (patchPromiseForTest) {
patchPromiseForTest();
}
}
_finishCallbackIfDone() {
if (!(this._pendingMicroTasks || this._pendingMacroTasks ||
(this.supportWaitUnresolvedChainedPromise &&
this.isUnresolvedChainedPromisePending()))) {
// We do this because we would like to catch unhandled rejected promises.
this.runZone.run(() => {
setTimeout(() => {
if (!this._alreadyErrored && !(this._pendingMicroTasks || this._pendingMacroTasks)) {
this.finishCallback();
}
}, 0);
});
unPatchPromiseForTest() {
if (!this.supportWaitUnresolvedChainedPromise) {
return;
}
const unPatchPromiseForTest = (Promise as any)[Zone.__symbol__('unPatchPromiseForTest')];
if (unPatchPromiseForTest) {
unPatchPromiseForTest();
}
}
// ZoneSpec implementation below.
name: string;
properties: {[key: string]: any};
onScheduleTask(delegate: ZoneDelegate, current: Zone, target: Zone, task: Task): Task {
if (task.type !== 'eventTask') {
this._isSync = false;
}
if (task.type === 'microTask' && task.data && task.data instanceof Promise) {
// check whether the promise is a chained promise
if ((task.data as any)[AsyncTestZoneSpec.symbolParentUnresolved] === true) {
// chained promise is being scheduled
this.unresolvedChainedPromiseCount--;
}
}
return delegate.scheduleTask(target, task);
}
patchPromiseForTest() {
if (!this.supportWaitUnresolvedChainedPromise) {
return;
}
const patchPromiseForTest = (Promise as any)[Zone.__symbol__('patchPromiseForTest')];
if (patchPromiseForTest) {
patchPromiseForTest();
}
onInvokeTask(
delegate: ZoneDelegate, current: Zone, target: Zone, task: Task, applyThis: any,
applyArgs: any) {
if (task.type !== 'eventTask') {
this._isSync = false;
}
return delegate.invokeTask(target, task, applyThis, applyArgs);
}
unPatchPromiseForTest() {
if (!this.supportWaitUnresolvedChainedPromise) {
return;
}
const unPatchPromiseForTest = (Promise as any)[Zone.__symbol__('unPatchPromiseForTest')];
if (unPatchPromiseForTest) {
unPatchPromiseForTest();
}
onCancelTask(delegate: ZoneDelegate, current: Zone, target: Zone, task: Task) {
if (task.type !== 'eventTask') {
this._isSync = false;
}
return delegate.cancelTask(target, task);
}
// ZoneSpec implementation below.
name: string;
properties: {[key: string]: any};
onScheduleTask(delegate: ZoneDelegate, current: Zone, target: Zone, task: Task): Task {
if (task.type !== 'eventTask') {
this._isSync = false;
}
if (task.type === 'microTask' && task.data && task.data instanceof Promise) {
// check whether the promise is a chained promise
if ((task.data as any)[AsyncTestZoneSpec.symbolParentUnresolved] === true) {
// chained promise is being scheduled
this.unresolvedChainedPromiseCount--;
}
}
return delegate.scheduleTask(target, task);
}
onInvokeTask(
delegate: ZoneDelegate, current: Zone, target: Zone, task: Task, applyThis: any,
applyArgs: any) {
if (task.type !== 'eventTask') {
this._isSync = false;
}
return delegate.invokeTask(target, task, applyThis, applyArgs);
}
onCancelTask(delegate: ZoneDelegate, current: Zone, target: Zone, task: Task) {
if (task.type !== 'eventTask') {
this._isSync = false;
}
return delegate.cancelTask(target, task);
}
// Note - we need to use onInvoke at the moment to call finish when a test is
// fully synchronous. TODO(juliemr): remove this when the logic for
// onHasTask changes and it calls whenever the task queues are dirty.
// updated by(JiaLiPassion), only call finish callback when no task
// was scheduled/invoked/canceled.
onInvoke(
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, delegate: Function,
applyThis: any, applyArgs?: any[], source?: string): any {
let previousTaskCounts: any = null;
try {
this._isSync = true;
return parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source);
} finally {
const afterTaskCounts: any = (parentZoneDelegate as any)._taskCounts;
if (this._isSync) {
this._finishCallbackIfDone();
}
}
}
onHandleError(
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone,
error: any): boolean {
// Let the parent try to handle the error.
const result = parentZoneDelegate.handleError(targetZone, error);
if (result) {
this.failCallback(error);
this._alreadyErrored = true;
}
return false;
}
onHasTask(delegate: ZoneDelegate, current: Zone, target: Zone, hasTaskState: HasTaskState) {
delegate.hasTask(target, hasTaskState);
if (hasTaskState.change == 'microTask') {
this._pendingMicroTasks = hasTaskState.microTask;
this._finishCallbackIfDone();
} else if (hasTaskState.change == 'macroTask') {
this._pendingMacroTasks = hasTaskState.macroTask;
// Note - we need to use onInvoke at the moment to call finish when a test is
// fully synchronous. TODO(juliemr): remove this when the logic for
// onHasTask changes and it calls whenever the task queues are dirty.
// updated by(JiaLiPassion), only call finish callback when no task
// was scheduled/invoked/canceled.
onInvoke(
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, delegate: Function,
applyThis: any, applyArgs?: any[], source?: string): any {
let previousTaskCounts: any = null;
try {
this._isSync = true;
return parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source);
} finally {
const afterTaskCounts: any = (parentZoneDelegate as any)._taskCounts;
if (this._isSync) {
this._finishCallbackIfDone();
}
}
}
// Export the class so that new instances can be created with proper
// constructor params.
(Zone as any)['AsyncTestZoneSpec'] = AsyncTestZoneSpec;
onHandleError(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, error: any):
boolean {
// Let the parent try to handle the error.
const result = parentZoneDelegate.handleError(targetZone, error);
if (result) {
this.failCallback(error);
this._alreadyErrored = true;
}
return false;
}
onHasTask(delegate: ZoneDelegate, current: Zone, target: Zone, hasTaskState: HasTaskState) {
delegate.hasTask(target, hasTaskState);
if (hasTaskState.change == 'microTask') {
this._pendingMicroTasks = hasTaskState.microTask;
this._finishCallbackIfDone();
} else if (hasTaskState.change == 'macroTask') {
this._pendingMacroTasks = hasTaskState.macroTask;
this._finishCallbackIfDone();
}
}
}
// Export the class so that new instances can be created with proper
// constructor params.
(Zone as any)['AsyncTestZoneSpec'] = AsyncTestZoneSpec;
})(typeof window !== 'undefined' && window || typeof self !== 'undefined' && self || global);

File diff suppressed because it is too large Load Diff

View File

@ -88,7 +88,7 @@ function stackTracesEnabled(): boolean {
return (Error as any).stackTraceLimit > 0;
}
type LongStackTraceZoneSpec = ZoneSpec & {longStackTraceLimit: number};
type LongStackTraceZoneSpec = ZoneSpec&{longStackTraceLimit: number};
(Zone as any)['longStackTraceZoneSpec'] = <LongStackTraceZoneSpec>{
name: 'long-stack-trace',

View File

@ -18,9 +18,13 @@ class ProxyZoneSpec implements ZoneSpec {
private tasks: Task[] = [];
static get(): ProxyZoneSpec { return Zone.current.get('ProxyZoneSpec'); }
static get(): ProxyZoneSpec {
return Zone.current.get('ProxyZoneSpec');
}
static isLoaded(): boolean { return ProxyZoneSpec.get() instanceof ProxyZoneSpec; }
static isLoaded(): boolean {
return ProxyZoneSpec.get() instanceof ProxyZoneSpec;
}
static assertPresent(): ProxyZoneSpec {
if (!ProxyZoneSpec.isLoaded()) {
@ -40,7 +44,7 @@ class ProxyZoneSpec implements ZoneSpec {
this.propertyKeys = null;
if (delegateSpec && delegateSpec.properties) {
this.propertyKeys = Object.keys(delegateSpec.properties);
this.propertyKeys.forEach((k) => this.properties[k] = delegateSpec.properties ![k]);
this.propertyKeys.forEach((k) => this.properties[k] = delegateSpec.properties![k]);
}
// if a new delegateSpec was set, check if we need to trigger hasTask
if (isNewDelegate && this.lastTaskState &&
@ -49,7 +53,9 @@ class ProxyZoneSpec implements ZoneSpec {
}
}
getDelegate() { return this._delegateSpec; }
getDelegate() {
return this._delegateSpec;
}
resetDelegate() {
@ -85,7 +91,9 @@ class ProxyZoneSpec implements ZoneSpec {
const taskInfo = this.tasks.map((task: Task) => {
const dataInfo = task.data &&
Object.keys(task.data)
.map((key: string) => { return key + ':' + (task.data as any)[key]; })
.map((key: string) => {
return key + ':' + (task.data as any)[key];
})
.join(',');
return `type: ${task.type}, source: ${task.source}, args: {${dataInfo}}`;
});

View File

@ -9,7 +9,9 @@
class SyncTestZoneSpec implements ZoneSpec {
runZone = Zone.current;
constructor(namePrefix: string) { this.name = 'syncTestZone for ' + namePrefix; }
constructor(namePrefix: string) {
this.name = 'syncTestZone for ' + namePrefix;
}
// ZoneSpec implementation below.

View File

@ -19,7 +19,9 @@ class TaskTrackingZoneSpec implements ZoneSpec {
eventTasks: Task[] = [];
properties: {[key: string]: any} = {'TaskTrackingZone': this};
static get() { return Zone.current.get('TaskTrackingZone'); }
static get() {
return Zone.current.get('TaskTrackingZone');
}
private getTasksFor(type: string): Task[] {
switch (type) {

View File

@ -11,152 +11,150 @@
*/
(function(global: any) {
interface Wtf {
trace: WtfTrace;
}
interface WtfScope {}
interface WtfRange {}
interface WtfTrace {
events: WtfEvents;
leaveScope(scope: WtfScope, returnValue?: any): void;
beginTimeRange(rangeType: string, action: string): WtfRange;
endTimeRange(range: WtfRange): void;
}
interface WtfEvents {
createScope(signature: string, flags?: any): WtfScopeFn;
createInstance(signature: string, flags?: any): WtfEventFn;
}
interface Wtf {
trace: WtfTrace;
}
interface WtfScope {}
interface WtfRange {}
interface WtfTrace {
events: WtfEvents;
leaveScope(scope: WtfScope, returnValue?: any): void;
beginTimeRange(rangeType: string, action: string): WtfRange;
endTimeRange(range: WtfRange): void;
}
interface WtfEvents {
createScope(signature: string, flags?: any): WtfScopeFn;
createInstance(signature: string, flags?: any): WtfEventFn;
}
type WtfScopeFn = (...args: any[]) => WtfScope;
type WtfEventFn = (...args: any[]) => any;
type WtfScopeFn = (...args: any[]) => WtfScope;
type WtfEventFn = (...args: any[]) => any;
// Detect and setup WTF.
let wtfTrace: WtfTrace|null = null;
let wtfEvents: WtfEvents|null = null;
const wtfEnabled: boolean = (function(): boolean {
const wtf: Wtf = global['wtf'];
if (wtf) {
wtfTrace = wtf.trace;
if (wtfTrace) {
wtfEvents = wtfTrace.events;
return true;
}
}
return false;
})();
class WtfZoneSpec implements ZoneSpec {
name: string = 'WTF';
static forkInstance =
wtfEnabled? wtfEvents !.createInstance('Zone:fork(ascii zone, ascii newZone)'): null;
static scheduleInstance: {[key: string]: WtfEventFn} = {};
static cancelInstance: {[key: string]: WtfEventFn} = {};
static invokeScope: {[key: string]: WtfEventFn} = {};
static invokeTaskScope: {[key: string]: WtfEventFn} = {};
onFork(
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone,
zoneSpec: ZoneSpec): Zone {
const retValue = parentZoneDelegate.fork(targetZone, zoneSpec);
WtfZoneSpec.forkInstance !(zonePathName(targetZone), retValue.name);
return retValue;
}
onInvoke(
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, delegate: Function,
applyThis: any, applyArgs?: any[], source?: string): any {
const src = source || 'unknown';
let scope = WtfZoneSpec.invokeScope[src];
if (!scope) {
scope = WtfZoneSpec.invokeScope[src] =
wtfEvents !.createScope(`Zone:invoke:${source}(ascii zone)`);
}
return wtfTrace !.leaveScope(
scope(zonePathName(targetZone)),
parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source));
}
onHandleError(
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone,
error: any): boolean {
return parentZoneDelegate.handleError(targetZone, error);
}
onScheduleTask(
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task): any {
const key = task.type + ':' + task.source;
let instance = WtfZoneSpec.scheduleInstance[key];
if (!instance) {
instance = WtfZoneSpec.scheduleInstance[key] =
wtfEvents !.createInstance(`Zone:schedule:${key}(ascii zone, any data)`);
}
const retValue = parentZoneDelegate.scheduleTask(targetZone, task);
instance(zonePathName(targetZone), shallowObj(task.data, 2));
return retValue;
}
onInvokeTask(
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task,
applyThis?: any, applyArgs?: any[]): any {
const source = task.source;
let scope = WtfZoneSpec.invokeTaskScope[source];
if (!scope) {
scope = WtfZoneSpec.invokeTaskScope[source] =
wtfEvents !.createScope(`Zone:invokeTask:${source}(ascii zone)`);
}
return wtfTrace !.leaveScope(
scope(zonePathName(targetZone)),
parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs));
}
onCancelTask(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task):
any {
const key = task.source;
let instance = WtfZoneSpec.cancelInstance[key];
if (!instance) {
instance = WtfZoneSpec.cancelInstance[key] =
wtfEvents !.createInstance(`Zone:cancel:${key}(ascii zone, any options)`);
}
const retValue = parentZoneDelegate.cancelTask(targetZone, task);
instance(zonePathName(targetZone), shallowObj(task.data, 2));
return retValue;
// Detect and setup WTF.
let wtfTrace: WtfTrace|null = null;
let wtfEvents: WtfEvents|null = null;
const wtfEnabled: boolean = (function(): boolean {
const wtf: Wtf = global['wtf'];
if (wtf) {
wtfTrace = wtf.trace;
if (wtfTrace) {
wtfEvents = wtfTrace.events;
return true;
}
}
return false;
})();
function shallowObj(obj: {[k: string]: any} | undefined, depth: number): any {
if (!obj || !depth) return null;
const out: {[k: string]: any} = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
// explicit : any due to https://github.com/microsoft/TypeScript/issues/33191
let value: any = obj[key];
switch (typeof value) {
case 'object':
const name = value && value.constructor && (<any>value.constructor).name;
value = name == (<any>Object).name ? shallowObj(value, depth - 1) : name;
break;
case 'function':
value = value.name || undefined;
break;
}
out[key] = value;
class WtfZoneSpec implements ZoneSpec {
name: string = 'WTF';
static forkInstance =
wtfEnabled ? wtfEvents!.createInstance('Zone:fork(ascii zone, ascii newZone)') : null;
static scheduleInstance: {[key: string]: WtfEventFn} = {};
static cancelInstance: {[key: string]: WtfEventFn} = {};
static invokeScope: {[key: string]: WtfEventFn} = {};
static invokeTaskScope: {[key: string]: WtfEventFn} = {};
onFork(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, zoneSpec: ZoneSpec):
Zone {
const retValue = parentZoneDelegate.fork(targetZone, zoneSpec);
WtfZoneSpec.forkInstance!(zonePathName(targetZone), retValue.name);
return retValue;
}
onInvoke(
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, delegate: Function,
applyThis: any, applyArgs?: any[], source?: string): any {
const src = source || 'unknown';
let scope = WtfZoneSpec.invokeScope[src];
if (!scope) {
scope = WtfZoneSpec.invokeScope[src] =
wtfEvents!.createScope(`Zone:invoke:${source}(ascii zone)`);
}
return wtfTrace!.leaveScope(
scope(zonePathName(targetZone)),
parentZoneDelegate.invoke(targetZone, delegate, applyThis, applyArgs, source));
}
onHandleError(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, error: any):
boolean {
return parentZoneDelegate.handleError(targetZone, error);
}
onScheduleTask(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task):
any {
const key = task.type + ':' + task.source;
let instance = WtfZoneSpec.scheduleInstance[key];
if (!instance) {
instance = WtfZoneSpec.scheduleInstance[key] =
wtfEvents!.createInstance(`Zone:schedule:${key}(ascii zone, any data)`);
}
const retValue = parentZoneDelegate.scheduleTask(targetZone, task);
instance(zonePathName(targetZone), shallowObj(task.data, 2));
return retValue;
}
onInvokeTask(
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task,
applyThis?: any, applyArgs?: any[]): any {
const source = task.source;
let scope = WtfZoneSpec.invokeTaskScope[source];
if (!scope) {
scope = WtfZoneSpec.invokeTaskScope[source] =
wtfEvents!.createScope(`Zone:invokeTask:${source}(ascii zone)`);
}
return wtfTrace!.leaveScope(
scope(zonePathName(targetZone)),
parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs));
}
onCancelTask(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task):
any {
const key = task.source;
let instance = WtfZoneSpec.cancelInstance[key];
if (!instance) {
instance = WtfZoneSpec.cancelInstance[key] =
wtfEvents!.createInstance(`Zone:cancel:${key}(ascii zone, any options)`);
}
const retValue = parentZoneDelegate.cancelTask(targetZone, task);
instance(zonePathName(targetZone), shallowObj(task.data, 2));
return retValue;
}
}
function shallowObj(obj: {[k: string]: any}|undefined, depth: number): any {
if (!obj || !depth) return null;
const out: {[k: string]: any} = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
// explicit : any due to https://github.com/microsoft/TypeScript/issues/33191
let value: any = obj[key];
switch (typeof value) {
case 'object':
const name = value && value.constructor && (<any>value.constructor).name;
value = name == (<any>Object).name ? shallowObj(value, depth - 1) : name;
break;
case 'function':
value = value.name || undefined;
break;
}
out[key] = value;
}
return out;
}
return out;
}
function zonePathName(zone: Zone) {
let name: string = zone.name;
let localZone = zone.parent;
while (localZone != null) {
name = localZone.name + '::' + name;
localZone = localZone.parent;
}
return name;
function zonePathName(zone: Zone) {
let name: string = zone.name;
let localZone = zone.parent;
while (localZone != null) {
name = localZone.name + '::' + name;
localZone = localZone.parent;
}
return name;
}
(Zone as any)['wtfZoneSpec'] = !wtfEnabled ? null : new WtfZoneSpec();
(Zone as any)['wtfZoneSpec'] = !wtfEnabled ? null : new WtfZoneSpec();
})(typeof window === 'object' && window || typeof self === 'object' && self || global);

View File

@ -310,9 +310,9 @@ interface ZoneType {
root: Zone;
/**
* load patch for specified native module, allow user to
* define their own patch, user can use this API after loading zone.js
*/
* load patch for specified native module, allow user to
* define their own patch, user can use this API after loading zone.js
*/
__load_patch(name: string, fn: _PatchFn): void;
/**
@ -547,12 +547,12 @@ type HasTaskState = {
/**
* Task type: `microTask`, `macroTask`, `eventTask`.
*/
type TaskType = 'microTask' | 'macroTask' | 'eventTask';
type TaskType = 'microTask'|'macroTask'|'eventTask';
/**
* Task type: `notScheduled`, `scheduling`, `scheduled`, `running`, `canceling`, 'unknown'.
*/
type TaskState = 'notScheduled' | 'scheduling' | 'scheduled' | 'running' | 'canceling' | 'unknown';
type TaskState = 'notScheduled'|'scheduling'|'scheduled'|'running'|'canceling'|'unknown';
/**
@ -684,7 +684,9 @@ declare var global: NodeJS.Global;
const Zone: ZoneType = (function(global: any) {
const performance: {mark(name: string): void; measure(name: string, label: string): void;} =
global['performance'];
function mark(name: string) { performance && performance['mark'] && performance['mark'](name); }
function mark(name: string) {
performance && performance['mark'] && performance['mark'](name);
}
function performanceMeasure(name: string, label: string) {
performance && performance['measure'] && performance['measure'](name, label);
}
@ -695,7 +697,9 @@ const Zone: ZoneType = (function(global: any) {
// symbol prefix with a custom one if needed.
const symbolPrefix = global['__Zone_symbol_prefix'] || '__zone_symbol__';
function __symbol__(name: string) { return symbolPrefix + name; }
function __symbol__(name: string) {
return symbolPrefix + name;
}
const checkDuplicate = global[__symbol__('forceDuplicateZoneCheck')] === true;
if (global['Zone']) {
@ -738,9 +742,13 @@ const Zone: ZoneType = (function(global: any) {
return zone;
}
static get current(): AmbientZone { return _currentZoneFrame.zone; }
static get current(): AmbientZone {
return _currentZoneFrame.zone;
}
static get currentTask(): Task|null { return _currentTask; }
static get currentTask(): Task|null {
return _currentTask;
}
// tslint:disable-next-line:require-internal-with-underscore
static __load_patch(name: string, fn: _PatchFn): void {
@ -756,9 +764,13 @@ const Zone: ZoneType = (function(global: any) {
}
}
public get parent(): AmbientZone|null { return this._parent; }
public get parent(): AmbientZone|null {
return this._parent;
}
public get name(): string { return this._name; }
public get name(): string {
return this._name;
}
private _parent: Zone|null;
@ -813,7 +825,7 @@ const Zone: ZoneType = (function(global: any) {
try {
return this._zoneDelegate.invoke(this, callback, applyThis, applyArgs, source);
} finally {
_currentZoneFrame = _currentZoneFrame.parent !;
_currentZoneFrame = _currentZoneFrame.parent!;
}
}
@ -831,7 +843,7 @@ const Zone: ZoneType = (function(global: any) {
}
}
} finally {
_currentZoneFrame = _currentZoneFrame.parent !;
_currentZoneFrame = _currentZoneFrame.parent!;
}
}
@ -880,7 +892,7 @@ const Zone: ZoneType = (function(global: any) {
(task as ZoneTask<any>)._transitionTo(notScheduled, running, notScheduled);
}
}
_currentZoneFrame = _currentZoneFrame.parent !;
_currentZoneFrame = _currentZoneFrame.parent!;
_currentTask = previousTask;
}
}
@ -964,7 +976,7 @@ const Zone: ZoneType = (function(global: any) {
}
private _updateTaskCount(task: ZoneTask<any>, count: number) {
const zoneDelegates = task._zoneDelegates !;
const zoneDelegates = task._zoneDelegates!;
if (count == -1) {
task._zoneDelegates = null;
}
@ -976,23 +988,27 @@ const Zone: ZoneType = (function(global: any) {
const DELEGATE_ZS: ZoneSpec = {
name: '',
onHasTask: (delegate: AmbientZoneDelegate, _: AmbientZone, target: AmbientZone,
hasTaskState: HasTaskState): void => delegate.hasTask(target, hasTaskState),
onScheduleTask: (delegate: AmbientZoneDelegate, _: AmbientZone, target: AmbientZone,
task: Task): Task => delegate.scheduleTask(target, task),
onInvokeTask: (delegate: AmbientZoneDelegate, _: AmbientZone, target: AmbientZone, task: Task,
applyThis: any, applyArgs: any): any =>
delegate.invokeTask(target, task, applyThis, applyArgs),
onHasTask:
(delegate: AmbientZoneDelegate, _: AmbientZone, target: AmbientZone,
hasTaskState: HasTaskState): void => delegate.hasTask(target, hasTaskState),
onScheduleTask:
(delegate: AmbientZoneDelegate, _: AmbientZone, target: AmbientZone, task: Task): Task =>
delegate.scheduleTask(target, task),
onInvokeTask:
(delegate: AmbientZoneDelegate, _: AmbientZone, target: AmbientZone, task: Task,
applyThis: any, applyArgs: any): any =>
delegate.invokeTask(target, task, applyThis, applyArgs),
onCancelTask: (delegate: AmbientZoneDelegate, _: AmbientZone, target: AmbientZone, task: Task):
any => delegate.cancelTask(target, task)
any => delegate.cancelTask(target, task)
};
class ZoneDelegate implements AmbientZoneDelegate {
public zone: Zone;
private _taskCounts: {microTask: number,
macroTask: number,
eventTask: number} = {'microTask': 0, 'macroTask': 0, 'eventTask': 0};
private _taskCounts:
{microTask: number,
macroTask: number,
eventTask: number} = {'microTask': 0, 'macroTask': 0, 'eventTask': 0};
private _parentDelegate: ZoneDelegate|null;
@ -1033,52 +1049,51 @@ const Zone: ZoneType = (function(global: any) {
this.zone = zone;
this._parentDelegate = parentDelegate;
this._forkZS =
zoneSpec && (zoneSpec && zoneSpec.onFork ? zoneSpec : parentDelegate !._forkZS);
this._forkDlgt = zoneSpec && (zoneSpec.onFork ? parentDelegate : parentDelegate !._forkDlgt);
this._forkZS = zoneSpec && (zoneSpec && zoneSpec.onFork ? zoneSpec : parentDelegate!._forkZS);
this._forkDlgt = zoneSpec && (zoneSpec.onFork ? parentDelegate : parentDelegate!._forkDlgt);
this._forkCurrZone =
zoneSpec && (zoneSpec.onFork ? this.zone : parentDelegate !._forkCurrZone);
zoneSpec && (zoneSpec.onFork ? this.zone : parentDelegate!._forkCurrZone);
this._interceptZS =
zoneSpec && (zoneSpec.onIntercept ? zoneSpec : parentDelegate !._interceptZS);
zoneSpec && (zoneSpec.onIntercept ? zoneSpec : parentDelegate!._interceptZS);
this._interceptDlgt =
zoneSpec && (zoneSpec.onIntercept ? parentDelegate : parentDelegate !._interceptDlgt);
zoneSpec && (zoneSpec.onIntercept ? parentDelegate : parentDelegate!._interceptDlgt);
this._interceptCurrZone =
zoneSpec && (zoneSpec.onIntercept ? this.zone : parentDelegate !._interceptCurrZone);
zoneSpec && (zoneSpec.onIntercept ? this.zone : parentDelegate!._interceptCurrZone);
this._invokeZS = zoneSpec && (zoneSpec.onInvoke ? zoneSpec : parentDelegate !._invokeZS);
this._invokeZS = zoneSpec && (zoneSpec.onInvoke ? zoneSpec : parentDelegate!._invokeZS);
this._invokeDlgt =
zoneSpec && (zoneSpec.onInvoke ? parentDelegate ! : parentDelegate !._invokeDlgt);
zoneSpec && (zoneSpec.onInvoke ? parentDelegate! : parentDelegate!._invokeDlgt);
this._invokeCurrZone =
zoneSpec && (zoneSpec.onInvoke ? this.zone : parentDelegate !._invokeCurrZone);
zoneSpec && (zoneSpec.onInvoke ? this.zone : parentDelegate!._invokeCurrZone);
this._handleErrorZS =
zoneSpec && (zoneSpec.onHandleError ? zoneSpec : parentDelegate !._handleErrorZS);
this._handleErrorDlgt = zoneSpec &&
(zoneSpec.onHandleError ? parentDelegate ! : parentDelegate !._handleErrorDlgt);
zoneSpec && (zoneSpec.onHandleError ? zoneSpec : parentDelegate!._handleErrorZS);
this._handleErrorDlgt =
zoneSpec && (zoneSpec.onHandleError ? parentDelegate! : parentDelegate!._handleErrorDlgt);
this._handleErrorCurrZone =
zoneSpec && (zoneSpec.onHandleError ? this.zone : parentDelegate !._handleErrorCurrZone);
zoneSpec && (zoneSpec.onHandleError ? this.zone : parentDelegate!._handleErrorCurrZone);
this._scheduleTaskZS =
zoneSpec && (zoneSpec.onScheduleTask ? zoneSpec : parentDelegate !._scheduleTaskZS);
zoneSpec && (zoneSpec.onScheduleTask ? zoneSpec : parentDelegate!._scheduleTaskZS);
this._scheduleTaskDlgt = zoneSpec &&
(zoneSpec.onScheduleTask ? parentDelegate ! : parentDelegate !._scheduleTaskDlgt);
this._scheduleTaskCurrZone = zoneSpec &&
(zoneSpec.onScheduleTask ? this.zone : parentDelegate !._scheduleTaskCurrZone);
(zoneSpec.onScheduleTask ? parentDelegate! : parentDelegate!._scheduleTaskDlgt);
this._scheduleTaskCurrZone =
zoneSpec && (zoneSpec.onScheduleTask ? this.zone : parentDelegate!._scheduleTaskCurrZone);
this._invokeTaskZS =
zoneSpec && (zoneSpec.onInvokeTask ? zoneSpec : parentDelegate !._invokeTaskZS);
zoneSpec && (zoneSpec.onInvokeTask ? zoneSpec : parentDelegate!._invokeTaskZS);
this._invokeTaskDlgt =
zoneSpec && (zoneSpec.onInvokeTask ? parentDelegate ! : parentDelegate !._invokeTaskDlgt);
zoneSpec && (zoneSpec.onInvokeTask ? parentDelegate! : parentDelegate!._invokeTaskDlgt);
this._invokeTaskCurrZone =
zoneSpec && (zoneSpec.onInvokeTask ? this.zone : parentDelegate !._invokeTaskCurrZone);
zoneSpec && (zoneSpec.onInvokeTask ? this.zone : parentDelegate!._invokeTaskCurrZone);
this._cancelTaskZS =
zoneSpec && (zoneSpec.onCancelTask ? zoneSpec : parentDelegate !._cancelTaskZS);
zoneSpec && (zoneSpec.onCancelTask ? zoneSpec : parentDelegate!._cancelTaskZS);
this._cancelTaskDlgt =
zoneSpec && (zoneSpec.onCancelTask ? parentDelegate ! : parentDelegate !._cancelTaskDlgt);
zoneSpec && (zoneSpec.onCancelTask ? parentDelegate! : parentDelegate!._cancelTaskDlgt);
this._cancelTaskCurrZone =
zoneSpec && (zoneSpec.onCancelTask ? this.zone : parentDelegate !._cancelTaskCurrZone);
zoneSpec && (zoneSpec.onCancelTask ? this.zone : parentDelegate!._cancelTaskCurrZone);
this._hasTaskZS = null;
this._hasTaskDlgt = null;
@ -1094,51 +1109,49 @@ const Zone: ZoneType = (function(global: any) {
this._hasTaskDlgt = parentDelegate;
this._hasTaskDlgtOwner = this;
this._hasTaskCurrZone = zone;
if (!zoneSpec !.onScheduleTask) {
if (!zoneSpec!.onScheduleTask) {
this._scheduleTaskZS = DELEGATE_ZS;
this._scheduleTaskDlgt = parentDelegate !;
this._scheduleTaskDlgt = parentDelegate!;
this._scheduleTaskCurrZone = this.zone;
}
if (!zoneSpec !.onInvokeTask) {
if (!zoneSpec!.onInvokeTask) {
this._invokeTaskZS = DELEGATE_ZS;
this._invokeTaskDlgt = parentDelegate !;
this._invokeTaskDlgt = parentDelegate!;
this._invokeTaskCurrZone = this.zone;
}
if (!zoneSpec !.onCancelTask) {
if (!zoneSpec!.onCancelTask) {
this._cancelTaskZS = DELEGATE_ZS;
this._cancelTaskDlgt = parentDelegate !;
this._cancelTaskDlgt = parentDelegate!;
this._cancelTaskCurrZone = this.zone;
}
}
}
fork(targetZone: Zone, zoneSpec: ZoneSpec): AmbientZone {
return this._forkZS ?
this._forkZS.onFork !(this._forkDlgt !, this.zone, targetZone, zoneSpec) :
new Zone(targetZone, zoneSpec);
return this._forkZS ? this._forkZS.onFork!(this._forkDlgt!, this.zone, targetZone, zoneSpec) :
new Zone(targetZone, zoneSpec);
}
intercept(targetZone: Zone, callback: Function, source: string): Function {
return this._interceptZS ?
this._interceptZS.onIntercept !(
this._interceptDlgt !, this._interceptCurrZone !, targetZone, callback, source) :
this._interceptZS.onIntercept!
(this._interceptDlgt!, this._interceptCurrZone!, targetZone, callback, source) :
callback;
}
invoke(
targetZone: Zone, callback: Function, applyThis: any, applyArgs?: any[],
source?: string): any {
return this._invokeZS ?
this._invokeZS.onInvoke !(
this._invokeDlgt !, this._invokeCurrZone !, targetZone, callback, applyThis,
applyArgs, source) :
callback.apply(applyThis, applyArgs);
return this._invokeZS ? this._invokeZS.onInvoke!
(this._invokeDlgt!, this._invokeCurrZone!, targetZone, callback,
applyThis, applyArgs, source) :
callback.apply(applyThis, applyArgs);
}
handleError(targetZone: Zone, error: any): boolean {
return this._handleErrorZS ?
this._handleErrorZS.onHandleError !(
this._handleErrorDlgt !, this._handleErrorCurrZone !, targetZone, error) :
this._handleErrorZS.onHandleError!
(this._handleErrorDlgt!, this._handleErrorCurrZone!, targetZone, error) :
true;
}
@ -1146,7 +1159,7 @@ const Zone: ZoneType = (function(global: any) {
let returnTask: ZoneTask<any> = task as ZoneTask<any>;
if (this._scheduleTaskZS) {
if (this._hasTaskZS) {
returnTask._zoneDelegates !.push(this._hasTaskDlgtOwner !);
returnTask._zoneDelegates!.push(this._hasTaskDlgtOwner!);
}
// clang-format off
returnTask = this._scheduleTaskZS.onScheduleTask !(
@ -1166,18 +1179,17 @@ const Zone: ZoneType = (function(global: any) {
}
invokeTask(targetZone: Zone, task: Task, applyThis: any, applyArgs?: any[]): any {
return this._invokeTaskZS ?
this._invokeTaskZS.onInvokeTask !(
this._invokeTaskDlgt !, this._invokeTaskCurrZone !, targetZone, task, applyThis,
applyArgs) :
task.callback.apply(applyThis, applyArgs);
return this._invokeTaskZS ? this._invokeTaskZS.onInvokeTask!
(this._invokeTaskDlgt!, this._invokeTaskCurrZone!, targetZone,
task, applyThis, applyArgs) :
task.callback.apply(applyThis, applyArgs);
}
cancelTask(targetZone: Zone, task: Task): any {
let value: any;
if (this._cancelTaskZS) {
value = this._cancelTaskZS.onCancelTask !(
this._cancelTaskDlgt !, this._cancelTaskCurrZone !, targetZone, task);
value = this._cancelTaskZS.onCancelTask!
(this._cancelTaskDlgt!, this._cancelTaskCurrZone!, targetZone, task);
} else {
if (!task.cancelFn) {
throw Error('Task is not cancelable');
@ -1192,8 +1204,8 @@ const Zone: ZoneType = (function(global: any) {
// can still trigger hasTask callback
try {
this._hasTaskZS &&
this._hasTaskZS.onHasTask !(
this._hasTaskDlgt !, this._hasTaskCurrZone !, targetZone, isEmpty);
this._hasTaskZS.onHasTask!
(this._hasTaskDlgt!, this._hasTaskCurrZone!, targetZone, isEmpty);
} catch (err) {
this.handleError(targetZone, err);
}
@ -1274,11 +1286,17 @@ const Zone: ZoneType = (function(global: any) {
}
}
get zone(): Zone { return this._zone !; }
get zone(): Zone {
return this._zone!;
}
get state(): TaskState { return this._state; }
get state(): TaskState {
return this._state;
}
public cancelScheduleRequest() { this._transitionTo(notScheduled, scheduling); }
public cancelScheduleRequest() {
this._transitionTo(notScheduled, scheduling);
}
// tslint:disable-next-line:require-internal-with-underscore
_transitionTo(toState: TaskState, fromState1: TaskState, fromState2?: TaskState) {

View File

@ -22,7 +22,11 @@ module.exports = function(config, ignoredLaunchers) {
customLaunchers = basicLaunchers;
} else {
Object.keys(basicLaunchers).forEach(function(key) {
if (ignoredLaunchers.filter(function(ignore) { return ignore === key; }).length === 0) {
if (ignoredLaunchers
.filter(function(ignore) {
return ignore === key;
})
.length === 0) {
customLaunchers[key] = basicLaunchers[key];
}
});

View File

@ -107,7 +107,11 @@ module.exports = function(config, ignoredLaunchers) {
customLaunchers = basicLaunchers;
} else {
Object.keys(basicLaunchers).forEach(function(key) {
if (ignoredLaunchers.filter(function(ignore) { return ignore === key; }).length === 0) {
if (ignoredLaunchers
.filter(function(ignore) {
return ignore === key;
})
.length === 0) {
customLaunchers[key] = basicLaunchers[key];
}
});

View File

@ -13,7 +13,11 @@ module.exports = function(config, ignoredLaunchers) {
customLaunchers = basicLaunchers;
} else {
Object.keys(basicLaunchers).forEach(function(key) {
if (ignoredLaunchers.filter(function(ignore) { return ignore === key; }).length === 0) {
if (ignoredLaunchers
.filter(function(ignore) {
return ignore === key;
})
.length === 0) {
customLaunchers[key] = basicLaunchers[key];
}
});

View File

@ -21,7 +21,9 @@ function writeNotFound(res) {
function requestHandler(req, res) {
if (req.url === '/close') {
res.end('server closing');
setTimeout(() => { process.exit(0); }, 1000);
setTimeout(() => {
process.exit(0);
}, 1000);
} else {
const file = path.resolve(localFolder, req.url);
if (!file.startsWith(localFolder + '/')) {

View File

@ -30,7 +30,7 @@ describe('HTML Imports', ifEnvSupports(supportsImports, function() {
});
});
document.head.appendChild(link !);
document.head.appendChild(link!);
});
function supportsOnEvents() {
@ -56,7 +56,7 @@ describe('HTML Imports', ifEnvSupports(supportsImports, function() {
};
});
document.head.appendChild(link !);
document.head.appendChild(link!);
});
it('should work with onload', function(done) {
@ -73,7 +73,7 @@ describe('HTML Imports', ifEnvSupports(supportsImports, function() {
};
});
document.head.appendChild(link !);
document.head.appendChild(link!);
});
});
}));

View File

@ -14,7 +14,9 @@ describe('MutationObserver', ifEnvSupports('MutationObserver', function() {
let elt: HTMLDivElement;
const testZone = Zone.current.fork({name: 'test'});
beforeEach(function() { elt = document.createElement('div'); });
beforeEach(function() {
elt = document.createElement('div');
});
it('should run observers within the zone', function(done) {
let ob;
@ -35,12 +37,18 @@ describe('MutationObserver', ifEnvSupports('MutationObserver', function() {
let ob: MutationObserver;
let flag = false;
const elt = document.createElement('div');
const childZone =
Zone.current.fork({name: 'test', onInvokeTask: function() { flag = true; }});
const childZone = Zone.current.fork({
name: 'test',
onInvokeTask: function() {
flag = true;
}
});
childZone.run(function() { ob = new MutationObserver(function() {}); });
childZone.run(function() {
ob = new MutationObserver(function() {});
});
ob !.disconnect();
ob!.disconnect();
expect(flag).toBe(false);
});
}));
@ -62,6 +70,6 @@ describe('WebKitMutationObserver', ifEnvSupports('WebKitMutationObserver', funct
ob.observe(elt, {childList: true});
});
elt !.innerHTML = '<p>hey</p>';
elt!.innerHTML = '<p>hey</p>';
});
}));

View File

@ -22,7 +22,9 @@ if (!window['saucelabs']) {
beforeEach(function(done) {
socket = new WebSocket(TEST_SERVER_URL);
socket.addEventListener('open', function() { done(); });
socket.addEventListener('open', function() {
done();
});
socket.addEventListener('error', function() {
fail(
'Can\'t establish socket to ' + TEST_SERVER_URL +
@ -32,7 +34,9 @@ if (!window['saucelabs']) {
}, TIMEOUT);
afterEach(function(done) {
socket.addEventListener('close', function() { done(); });
socket.addEventListener('close', function() {
done();
});
socket.close();
}, TIMEOUT);
@ -116,7 +120,9 @@ if (!window['saucelabs']) {
it('should handler removing onmessage', function(done) {
let log = '';
socket.onmessage = function() { log += 'a'; };
socket.onmessage = function() {
log += 'a';
};
socket.onmessage = null as any;

View File

@ -13,7 +13,9 @@ const wtfMock = global.wtfMock;
describe('XMLHttpRequest', function() {
let testZone: Zone;
beforeEach(() => { testZone = Zone.current.fork({name: 'test'}); });
beforeEach(() => {
testZone = Zone.current.fork({name: 'test'});
});
it('should intercept XHRs and treat them as MacroTasks', function(done) {
let req: XMLHttpRequest;
@ -30,7 +32,9 @@ describe('XMLHttpRequest', function() {
testZoneWithWtf.run(() => {
req = new XMLHttpRequest();
const logs: string[] = [];
req.onload = () => { logs.push('onload'); };
req.onload = () => {
logs.push('onload');
};
onStable = function() {
expect(wtfMock.log[wtfMock.log.length - 2])
.toEqual('> Zone:invokeTask:XMLHttpRequest.send("<root>::ProxyZone::WTF::TestZone")');
@ -96,7 +100,7 @@ describe('XMLHttpRequest', function() {
req.open('get', '/', true);
});
req !.send();
req!.send();
});
it('should return null when access ontimeout first time without error', function() {
@ -104,7 +108,9 @@ describe('XMLHttpRequest', function() {
expect(req.ontimeout).toBe(null);
});
const supportsOnProgress = function() { return 'onprogress' in (new XMLHttpRequest()); };
const supportsOnProgress = function() {
return 'onprogress' in (new XMLHttpRequest());
};
(<any>supportsOnProgress).message = 'XMLHttpRequest.onprogress';
@ -122,7 +128,7 @@ describe('XMLHttpRequest', function() {
req.open('get', '/', true);
});
req !.send();
req!.send();
});
it('should allow canceling of an XMLHttpRequest', function(done) {
@ -132,13 +138,14 @@ describe('XMLHttpRequest', function() {
const trackingTestZone = Zone.current.fork({
name: 'tracking test zone',
onHasTask: (delegate: ZoneDelegate, current: Zone, target: Zone,
hasTaskState: HasTaskState) => {
if (hasTaskState.change == 'macroTask') {
pending = hasTaskState.macroTask;
}
delegate.hasTask(target, hasTaskState);
}
onHasTask:
(delegate: ZoneDelegate, current: Zone, target: Zone,
hasTaskState: HasTaskState) => {
if (hasTaskState.change == 'macroTask') {
pending = hasTaskState.macroTask;
}
delegate.hasTask(target, hasTaskState);
}
});
trackingTestZone.run(function() {
@ -234,8 +241,12 @@ describe('XMLHttpRequest', function() {
req.onload = function() {
req.onload = null as any;
req.open('get', '/', true);
req.onload = function() { done(); };
expect(() => { req.send(); }).not.toThrow();
req.onload = function() {
done();
};
expect(() => {
req.send();
}).not.toThrow();
};
});
});
@ -248,7 +259,9 @@ describe('XMLHttpRequest', function() {
req.send();
req.addEventListener('readystatechange', function(ev) {
if (req.readyState >= 2) {
expect(() => { req.abort(); }).not.toThrow();
expect(() => {
req.abort();
}).not.toThrow();
done();
}
});
@ -374,7 +387,9 @@ describe('XMLHttpRequest', function() {
}
};
expect(req.onreadystatechange).toBe(listener);
req.onreadystatechange = function() { return listener.call(this); };
req.onreadystatechange = function() {
return listener.call(this);
};
req.send();
});
}));

File diff suppressed because it is too large Load Diff

View File

@ -26,22 +26,34 @@ describe('customElements', function() {
};
class TestCustomElement extends HTMLElement {
constructor() { super(); }
constructor() {
super();
}
static get observedAttributes() { return ['attr1', 'attr2']; }
static get observedAttributes() {
return ['attr1', 'attr2'];
}
connectedCallback() { return bridge.connectedCallback(); }
connectedCallback() {
return bridge.connectedCallback();
}
disconnectedCallback() { return bridge.disconnectedCallback(); }
disconnectedCallback() {
return bridge.disconnectedCallback();
}
attributeChangedCallback(attrName, oldVal, newVal) {
return bridge.attributeChangedCallback(attrName, oldVal, newVal);
}
adoptedCallback() { return bridge.adoptedCallback(); }
adoptedCallback() {
return bridge.adoptedCallback();
}
}
testZone.run(() => { customElements.define('x-test', TestCustomElement); });
testZone.run(() => {
customElements.define('x-test', TestCustomElement);
});
let elt;

View File

@ -16,7 +16,9 @@ describe('element', function() {
document.body.appendChild(button);
});
afterEach(function() { document.body.removeChild(button); });
afterEach(function() {
document.body.removeChild(button);
});
// https://github.com/angular/zone.js/issues/190
it('should work when addEventListener / removeEventListener are called in the global context',
@ -49,7 +51,9 @@ describe('element', function() {
const clickEvent = document.createEvent('Event');
clickEvent.initEvent('click', true, true);
button.addEventListener('click', function(event) { expect(event).toBe(clickEvent as any); });
button.addEventListener('click', function(event) {
expect(event).toBe(clickEvent as any);
});
button.dispatchEvent(clickEvent);
});
@ -122,7 +126,9 @@ describe('element', function() {
it('should respect removeEventListener when called with a function listener', function() {
let log = '';
const logFunction = function logFunction() { log += 'a'; };
const logFunction = function logFunction() {
log += 'a';
};
button.addEventListener('click', logFunction);
button.addEventListener('focus', logFunction);
@ -180,7 +186,9 @@ describe('element', function() {
const log: string[] = [];
const clickEvent = document.createEvent('Event');
function listener() { log.push('listener'); }
function listener() {
log.push('listener');
}
clickEvent.initEvent('click', true, true);
@ -201,9 +209,13 @@ describe('element', function() {
const log: string[] = [];
const clickEvent = document.createEvent('Event');
function capturingListener() { log.push('capturingListener'); }
function capturingListener() {
log.push('capturingListener');
}
function bubblingListener() { log.push('bubblingListener'); }
function bubblingListener() {
log.push('bubblingListener');
}
clickEvent.initEvent('click', true, true);
@ -219,7 +231,9 @@ describe('element', function() {
const log: string[] = [];
const clickEvent = document.createEvent('Event');
function listener() { log.push('listener'); }
function listener() {
log.push('listener');
}
clickEvent.initEvent('click', true, true);
@ -250,7 +264,9 @@ describe('element', function() {
ifEnvSupports(supportsOnClick, function() {
it('should spawn new child zones', function() {
let run = false;
button.onclick = function() { run = true; };
button.onclick = function() {
run = true;
};
button.click();
expect(run).toBeTruthy();
@ -260,8 +276,12 @@ describe('element', function() {
it('should only allow one onclick handler', function() {
let log = '';
button.onclick = function() { log += 'a'; };
button.onclick = function() { log += 'b'; };
button.onclick = function() {
log += 'a';
};
button.onclick = function() {
log += 'b';
};
button.click();
expect(log).toEqual('b');
@ -270,7 +290,9 @@ describe('element', function() {
it('should handler removing onclick', function() {
let log = '';
button.onclick = function() { log += 'a'; };
button.onclick = function() {
log += 'a';
};
button.onclick = null as any;
button.click();
@ -293,10 +315,14 @@ describe('element', function() {
document.body.appendChild(checkbox);
});
afterEach(function() { document.body.removeChild(checkbox); });
afterEach(function() {
document.body.removeChild(checkbox);
});
it('should be possible to prevent default behavior by returning false', function() {
checkbox.onclick = function() { return false; };
checkbox.onclick = function() {
return false;
};
checkbox.click();
expect(checkbox.checked).toBe(false);

View File

@ -30,7 +30,9 @@ describe(
callbackNames.forEach(function(callbackName) {
const fullCallbackName = callbackName + 'Callback';
const proto = Object.create(HTMLElement.prototype);
(proto as any)[fullCallbackName] = function(arg: any) { callbacks[callbackName](arg); };
(proto as any)[fullCallbackName] = function(arg: any) {
callbacks[callbackName](arg);
};
(<any>document).registerElement('x-' + callbackName.toLowerCase(), {prototype: proto});
});
});
@ -106,9 +108,11 @@ describe(
testZone.run(function() {
const proto = Object.create(HTMLElement.prototype);
Object.defineProperties(
proto,
{createdCallback: <any>{writable: false, configurable: false, value: checkZone}});
Object.defineProperties(proto, {
createdCallback: <any> {
writable: false, configurable: false, value: checkZone
}
});
(<any>document).registerElement('x-props-desc', {prototype: proto});
@ -124,8 +128,9 @@ describe(
it('should not throw with frozen prototypes ', function() {
testZone.run(function() {
const proto = Object.create(HTMLElement.prototype, Object.freeze(<PropertyDescriptorMap>{
createdCallback:
<PropertyDescriptor>{value: () => {}, writable: true, configurable: true}
createdCallback: <PropertyDescriptor> {
value: () => {}, writable: true, configurable: true
}
}));
Object.defineProperty(
@ -159,6 +164,8 @@ describe(
it('should not throw if no options passed to registerElement', function() {
expect(function() { (<any>document).registerElement('x-no-opts'); }).not.toThrow();
expect(function() {
(<any>document).registerElement('x-no-opts');
}).not.toThrow();
});
}));

View File

@ -16,14 +16,20 @@ describe('requestAnimationFrame', function() {
functions.forEach(function(fnName) {
describe(fnName, ifEnvSupports(fnName, function() {
const originalTimeout: number = (<any>jasmine).DEFAULT_TIMEOUT_INTERVAL;
beforeEach(() => { (<any>jasmine).DEFAULT_TIMEOUT_INTERVAL = 10000; });
beforeEach(() => {
(<any>jasmine).DEFAULT_TIMEOUT_INTERVAL = 10000;
});
afterEach(() => { (<any>jasmine).DEFAULT_TIMEOUT_INTERVAL = originalTimeout; });
afterEach(() => {
(<any>jasmine).DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
});
const rAF = window[fnName];
it('should be tolerant of invalid arguments', function() {
// rAF throws an error on invalid arguments, so expect that.
expect(function() { rAF(null); }).toThrow();
expect(function() {
rAF(null);
}).toThrow();
});
it('should bind to same zone when called recursively', function(done) {

View File

@ -25,8 +25,11 @@ describe('shadydom', () => {
const target = t.target;
const zone = Zone.current.fork({name: 'zone'});
const logs: string[] = [];
zone.run(
() => { target.addEventListener('click', () => { logs.push(Zone.current.name); }); });
zone.run(() => {
target.addEventListener('click', () => {
logs.push(Zone.current.name);
});
});
const event = document.createEvent('MouseEvent');
event.initEvent('click', true, true);
target.dispatchEvent(event);

View File

@ -12,12 +12,17 @@ const testClosureFunction = () => {
const testZoneSpec: ZoneSpec = {
name: 'closure',
properties: {},
onFork: (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone,
zoneSpec: ZoneSpec) => { return parentZoneDelegate.fork(targetZone, zoneSpec); },
onFork:
(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone,
zoneSpec: ZoneSpec) => {
return parentZoneDelegate.fork(targetZone, zoneSpec);
},
onIntercept:
(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, delegate: Function,
source: string) => { return parentZoneDelegate.intercept(targetZone, delegate, source); },
source: string) => {
return parentZoneDelegate.intercept(targetZone, delegate, source);
},
onInvoke: function(
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, delegate: Function,
@ -59,19 +64,25 @@ const testClosureFunction = () => {
testZone.runGuarded(() => {
testZone.run(() => {
const properties = testZoneSpec.properties;
properties !['key'] = 'value';
properties!['key'] = 'value';
const keyZone = Zone.current.getZoneWith('key');
logs.push('current' + Zone.current.name);
logs.push('parent' + Zone.current.parent !.name);
logs.push('getZoneWith' + keyZone !.name);
logs.push('get' + keyZone !.get('key'));
logs.push('parent' + Zone.current.parent!.name);
logs.push('getZoneWith' + keyZone!.name);
logs.push('get' + keyZone!.get('key'));
logs.push('root' + Zone.root.name);
Object.keys((Zone as any).prototype).forEach(key => { logs.push(key); });
Object.keys(testZoneSpec).forEach(key => { logs.push(key); });
Object.keys((Zone as any).prototype).forEach(key => {
logs.push(key);
});
Object.keys(testZoneSpec).forEach(key => {
logs.push(key);
});
const task = Zone.current.scheduleMicroTask('testTask', () => {}, undefined, () => {});
Object.keys(task).forEach(key => { logs.push(key); });
Object.keys(task).forEach(key => {
logs.push(key);
});
});
});
@ -128,6 +139,8 @@ const testClosureFunction = () => {
}
process['exit'](result ? 0 : 1);
};
process['on']('uncaughtException', (err: any) => { process['exit'](1); });
process['on']('uncaughtException', (err: any) => {
process['exit'](1);
});
testClosureFunction();

View File

@ -19,12 +19,24 @@ class BaseError extends Error {
this._nativeError = nativeError;
}
get message() { return this._nativeError.message; }
set message(message) { this._nativeError.message = message; }
get name() { return this._nativeError.name; }
get stack() { return (this._nativeError as any).stack; }
set stack(value) { (this._nativeError as any).stack = value; }
toString() { return this._nativeError.toString(); }
get message() {
return this._nativeError.message;
}
set message(message) {
this._nativeError.message = message;
}
get name() {
return this._nativeError.name;
}
get stack() {
return (this._nativeError as any).stack;
}
set stack(value) {
(this._nativeError as any).stack = value;
}
toString() {
return this._nativeError.toString();
}
}
class WrappedError extends BaseError {
@ -46,7 +58,9 @@ class TestError extends WrappedError {
super(`${message} caused by: ${error instanceof Error ? error.message : error}`, error);
}
get message() { return 'test ' + this.originalError.message; }
get message() {
return 'test ' + this.originalError.message;
}
}
class TestMessageError extends WrappedError {
@ -54,9 +68,13 @@ class TestMessageError extends WrappedError {
super(`${message} caused by: ${error instanceof Error ? error.message : error}`, error);
}
get message() { return 'test ' + this.originalError.message; }
get message() {
return 'test ' + this.originalError.message;
}
set message(value) { this.originalError.message = value; }
set message(value) {
this.originalError.message = value;
}
}
describe('ZoneAwareError', () => {
@ -153,9 +171,11 @@ describe('ZoneAwareError', () => {
it('should copy customized NativeError properties to ZoneAwareError', () => {
const spy = jasmine.createSpy('errorCustomFunction');
const NativeError = (global as any)[(Zone as any).__symbol__('Error')];
NativeError.customFunction = function(args: any) { spy(args); };
NativeError.customFunction = function(args: any) {
spy(args);
};
expect((Error as any)['customProperty']).toBe('customProperty');
expect(typeof(Error as any)['customFunction']).toBe('function');
expect(typeof (Error as any)['customFunction']).toBe('function');
(Error as any)['customFunction']('test');
expect(spy).toHaveBeenCalledWith('test');
});
@ -166,8 +186,8 @@ describe('ZoneAwareError', () => {
// there event without throw
const error = new Error('test');
const errorWithoutNew = Error('test');
expect(error.stack !.split('\n').length > 0).toBeTruthy();
expect(errorWithoutNew.stack !.split('\n').length > 0).toBeTruthy();
expect(error.stack!.split('\n').length > 0).toBeTruthy();
expect(errorWithoutNew.stack!.split('\n').length > 0).toBeTruthy();
});
it('should show zone names in stack frames and remove extra frames', () => {
@ -218,14 +238,14 @@ describe('ZoneAwareError', () => {
expect(outside.stack).toEqual(outside.zoneAwareStack);
expect(outsideWithoutNew.stack).toEqual(outsideWithoutNew.zoneAwareStack);
expect(inside !.stack).toEqual(inside !.zoneAwareStack);
expect(insideWithoutNew !.stack).toEqual(insideWithoutNew !.zoneAwareStack);
expect(typeof inside !.originalStack).toEqual('string');
expect(typeof insideWithoutNew !.originalStack).toEqual('string');
const outsideFrames = outside.stack !.split(/\n/);
const insideFrames = inside !.stack !.split(/\n/);
const outsideWithoutNewFrames = outsideWithoutNew !.stack !.split(/\n/);
const insideWithoutNewFrames = insideWithoutNew !.stack !.split(/\n/);
expect(inside!.stack).toEqual(inside!.zoneAwareStack);
expect(insideWithoutNew!.stack).toEqual(insideWithoutNew!.zoneAwareStack);
expect(typeof inside!.originalStack).toEqual('string');
expect(typeof insideWithoutNew!.originalStack).toEqual('string');
const outsideFrames = outside.stack!.split(/\n/);
const insideFrames = inside!.stack!.split(/\n/);
const outsideWithoutNewFrames = outsideWithoutNew!.stack!.split(/\n/);
const insideWithoutNewFrames = insideWithoutNew!.stack!.split(/\n/);
// throw away first line if it contains the error
if (/Outside/.test(outsideFrames[0])) {
@ -304,7 +324,9 @@ describe('ZoneAwareError', () => {
onHandleError:
(parentDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, error: Error) => {
assertStackDoesNotContainZoneFrames(error);
setTimeout(() => { errorZoneSpec.done && errorZoneSpec.done(); }, 0);
setTimeout(() => {
errorZoneSpec.done && errorZoneSpec.done();
}, 0);
return false;
}
};
@ -320,17 +342,26 @@ describe('ZoneAwareError', () => {
describe('Error stack', () => {
it('Error with new which occurs in setTimeout callback should not have zone frames visible',
assertStackDoesNotContainZoneFramesTest(
() => { setTimeout(() => { throw new Error('timeout test error'); }, 10); }));
assertStackDoesNotContainZoneFramesTest(() => {
setTimeout(() => {
throw new Error('timeout test error');
}, 10);
}));
it('Error without new which occurs in setTimeout callback should not have zone frames visible',
assertStackDoesNotContainZoneFramesTest(
() => { setTimeout(() => { throw Error('test error'); }, 10); }));
assertStackDoesNotContainZoneFramesTest(() => {
setTimeout(() => {
throw Error('test error');
}, 10);
}));
it('Error with new which cause by promise rejection should not have zone frames visible',
(done) => {
const p = new Promise(
(resolve, reject) => { setTimeout(() => { reject(new Error('test error')); }); });
const p = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('test error'));
});
});
p.catch(err => {
assertStackDoesNotContainZoneFrames(err);
done();
@ -339,8 +370,11 @@ describe('ZoneAwareError', () => {
it('Error without new which cause by promise rejection should not have zone frames visible',
(done) => {
const p = new Promise(
(resolve, reject) => { setTimeout(() => { reject(Error('test error')); }); });
const p = new Promise((resolve, reject) => {
setTimeout(() => {
reject(Error('test error'));
});
});
p.catch(err => {
assertStackDoesNotContainZoneFrames(err);
done();
@ -357,8 +391,9 @@ describe('ZoneAwareError', () => {
it('Error without new which occurs in eventTask callback should not have zone frames visible',
assertStackDoesNotContainZoneFramesTest(() => {
const task = Zone.current.scheduleEventTask(
'errorEvent', () => { throw Error('test error'); }, undefined, () => null, undefined);
const task = Zone.current.scheduleEventTask('errorEvent', () => {
throw Error('test error');
}, undefined, () => null, undefined);
task.invoke();
}));

View File

@ -19,7 +19,7 @@ class MicroTaskQueueZoneSpec implements ZoneSpec {
flush() {
while (this.queue.length) {
const task = this.queue.shift();
task !.invoke();
task!.invoke();
}
}
@ -50,11 +50,12 @@ describe(
pZone = Zone.current.fork({
name: 'promise-zone',
onScheduleTask: (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone,
task: Task): any => {
log.push('scheduleTask');
parentZoneDelegate.scheduleTask(targetZone, task);
}
onScheduleTask:
(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task):
any => {
log.push('scheduleTask');
parentZoneDelegate.scheduleTask(targetZone, task);
}
});
queueZone = Zone.current.fork(new MicroTaskQueueZoneSpec());
@ -77,7 +78,9 @@ describe(
expect(value).toBe(0);
done();
})
.catch(error => { fail(error); });
.catch(error => {
fail(error);
});
} finally {
global['Promise'] = NativePromise;
Zone.assertZonePatched();
@ -85,8 +88,9 @@ describe(
}
});
it('should pretend to be a native code',
() => { expect(String(Promise).indexOf('[native code]') >= 0).toBe(true); });
it('should pretend to be a native code', () => {
expect(String(Promise).indexOf('[native code]') >= 0).toBe(true);
});
it('should use native toString for promise instance', () => {
expect(Object.prototype.toString.call(Promise.resolve())).toEqual('[object Promise]');
@ -105,16 +109,22 @@ describe(
it('should allow subclassing without Symbol.species', () => {
class MyPromise extends Promise<any> {
constructor(fn: any) { super(fn); }
constructor(fn: any) {
super(fn);
}
}
expect(new MyPromise(() => {}).then(() => null) instanceof MyPromise).toBe(true);
});
it('should allow subclassing with Symbol.species', () => {
class MyPromise extends Promise<any> {
constructor(fn: any) { super(fn); }
constructor(fn: any) {
super(fn);
}
static get[Symbol.species]() { return MyPromise; }
static get[Symbol.species]() {
return MyPromise;
}
}
expect(new MyPromise(() => {}).then(() => null) instanceof MyPromise).toBe(true);
});
@ -122,15 +132,18 @@ describe(
it('Symbol.species should return ZoneAwarePromise', () => {
const empty = function() {};
const promise = Promise.resolve(1);
const FakePromise = ((promise.constructor = {} as any) as any)[Symbol.species] = function(
exec: any) { exec(empty, empty); };
const FakePromise =
((promise.constructor = {} as any) as any)[Symbol.species] = function(exec: any) {
exec(empty, empty);
};
expect(promise.then(empty) instanceof FakePromise).toBe(true);
});
it('should intercept scheduling of resolution and then', (done) => {
pZone.run(() => {
let p: Promise<any> =
new Promise(function(resolve, reject) { expect(resolve('RValue')).toBe(undefined); });
let p: Promise<any> = new Promise(function(resolve, reject) {
expect(resolve('RValue')).toBe(undefined);
});
expect(log).toEqual([]);
expect(p instanceof Promise).toBe(true);
p = p.then((v) => {
@ -155,12 +168,16 @@ describe(
queueZone.run(() => {
const flush = Zone.current.get('flush');
const queue = Zone.current.get('queue');
const p = new Promise<string>(function(resolve, reject) { resolve('RValue'); })
const p = new Promise<string>(function(resolve, reject) {
resolve('RValue');
})
.then((v: string) => {
log.push(v);
return 'second value';
})
.then((v: string) => { log.push(v); });
.then((v: string) => {
log.push(v);
});
expect(queue.length).toEqual(1);
expect(log).toEqual([]);
flush();
@ -172,13 +189,16 @@ describe(
queueZone.run(() => {
const flush = Zone.current.get('flush');
const queue = Zone.current.get('queue');
const p =
new Promise<string>(function(resolve, reject) { resolve(Promise.resolve('RValue')); })
.then((v: string) => {
log.push(v);
return Promise.resolve('second value');
})
.then((v: string) => { log.push(v); });
const p = new Promise<string>(function(resolve, reject) {
resolve(Promise.resolve('RValue'));
})
.then((v: string) => {
log.push(v);
return Promise.resolve('second value');
})
.then((v: string) => {
log.push(v);
});
expect(queue.length).toEqual(1);
expect(log).toEqual([]);
flush();
@ -191,55 +211,65 @@ describe(
let resolve: Function|null = null;
testZone.run(function() {
new Promise(function(resolveFn) { resolve = resolveFn; }).then(function() {
new Promise(function(resolveFn) {
resolve = resolveFn;
}).then(function() {
expect(Zone.current).toBe(testZone);
done();
});
});
resolve !();
resolve!();
});
it('should work with .catch', function(done) {
let reject: (() => void)|null = null;
testZone.run(function() {
new Promise(function(resolveFn, rejectFn) { reject = rejectFn; })['catch'](function() {
new Promise(function(resolveFn, rejectFn) {
reject = rejectFn;
})['catch'](function() {
expect(Zone.current).toBe(testZone);
done();
});
});
expect(reject !()).toBe(undefined);
expect(reject!()).toBe(undefined);
});
it('should work with .finally with resolved promise', function(done) {
let resolve: Function|null = null;
testZone.run(function() {
(new Promise(function(resolveFn) { resolve = resolveFn; }) as any).finally(function() {
expect(arguments.length).toBe(0);
expect(Zone.current).toBe(testZone);
done();
});
(new Promise(function(resolveFn) {
resolve = resolveFn;
}) as any)
.finally(function() {
expect(arguments.length).toBe(0);
expect(Zone.current).toBe(testZone);
done();
});
});
resolve !('value');
resolve!('value');
});
it('should work with .finally with rejected promise', function(done) {
let reject: Function|null = null;
testZone.run(function() {
(new Promise(function(_, rejectFn) { reject = rejectFn; }) as any).finally(function() {
expect(arguments.length).toBe(0);
expect(Zone.current).toBe(testZone);
done();
});
(new Promise(function(_, rejectFn) {
reject = rejectFn;
}) as any)
.finally(function() {
expect(arguments.length).toBe(0);
expect(Zone.current).toBe(testZone);
done();
});
});
reject !('error');
reject!('error');
});
it('should work with Promise.resolve', () => {
@ -275,8 +305,9 @@ describe(
it('should re-reject promise', () => {
queueZone.run(() => {
let value: any = null;
Promise.reject('rejectReason')['catch']((v) => { throw v; })['catch'](
(v) => value = v);
Promise.reject('rejectReason')['catch']((v) => {
throw v;
})['catch']((v) => value = v);
flushMicrotasks();
expect(value).toEqual('rejectReason');
});
@ -308,7 +339,9 @@ describe(
(Zone as any)[Zone.__symbol__('ignoreConsoleErrorUncaughtError')] = false;
const originalConsoleError = console.error;
console.error = jasmine.createSpy('consoleErr');
const p = new Promise((resolve, reject) => { throw new Error('promise error'); });
const p = new Promise((resolve, reject) => {
throw new Error('promise error');
});
setTimeout(() => {
expect(console.error).toHaveBeenCalled();
console.error = originalConsoleError;
@ -323,7 +356,9 @@ describe(
(Zone as any)[Zone.__symbol__('ignoreConsoleErrorUncaughtError')] = true;
const originalConsoleError = console.error;
console.error = jasmine.createSpy('consoleErr');
const p = new Promise((resolve, reject) => { throw new Error('promise error'); });
const p = new Promise((resolve, reject) => {
throw new Error('promise error');
});
setTimeout(() => {
expect(console.error).not.toHaveBeenCalled();
console.error = originalConsoleError;
@ -342,11 +377,11 @@ describe(
.fork({
name: 'promise-error',
onHandleError: (delegate: ZoneDelegate, current: Zone, target: Zone, error: any):
boolean => {
promiseError = error;
delegate.handleError(target, error);
return false;
}
boolean => {
promiseError = error;
delegate.handleError(target, error);
return false;
}
})
.run(() => {
zone = Zone.current;
@ -362,10 +397,10 @@ describe(
});
setTimeout((): any => null);
setTimeout(() => {
expect(promiseError !.message)
expect(promiseError!.message)
.toBe(
'Uncaught (in promise): ' + error +
(error !.stack ? '\n' + error !.stack : ''));
(error!.stack ? '\n' + error!.stack : ''));
expect((promiseError as any)['rejection']).toBe(error);
expect((promiseError as any)['zone']).toBe(zone);
expect((promiseError as any)['task']).toBe(task);
@ -382,11 +417,11 @@ describe(
.fork({
name: 'promise-error',
onHandleError: (delegate: ZoneDelegate, current: Zone, target: Zone, error: any):
boolean => {
promiseError = error;
delegate.handleError(target, error);
return false;
}
boolean => {
promiseError = error;
delegate.handleError(target, error);
return false;
}
})
.run(() => {
zone = Zone.current;
@ -399,7 +434,7 @@ describe(
});
setTimeout((): any => null);
setTimeout(() => {
expect(promiseError !.message)
expect(promiseError!.message)
.toMatch(/Uncaught \(in promise\):.*: {"prop1":"value1","prop2":"value2"}/);
done();
});
@ -456,8 +491,16 @@ describe(
it('should resolve with the sync then operation', () => {
queueZone.run(() => {
let value: any = null;
const p1 = {then: function(thenCallback: Function) { return thenCallback('p1'); }};
const p2 = {then: function(thenCallback: Function) { return thenCallback('p2'); }};
const p1 = {
then: function(thenCallback: Function) {
return thenCallback('p1');
}
};
const p2 = {
then: function(thenCallback: Function) {
return thenCallback('p2');
}
};
Promise.all([p1, 'v1', p2]).then((v: any) => value = v);
// expect(Zone.current.get('queue').length).toEqual(2);
flushMicrotasks();
@ -467,16 +510,20 @@ describe(
it('should resolve generators',
ifEnvSupports(
() => { return isNode; },
() => {
const generators: any = function* () {
return isNode;
},
() => {
const generators: any = function*() {
yield Promise.resolve(1);
yield Promise.resolve(2);
return;
};
queueZone.run(() => {
let value: any = null;
Promise.all(generators()).then(val => { value = val; });
Promise.all(generators()).then(val => {
value = val;
});
// expect(Zone.current.get('queue').length).toEqual(2);
flushMicrotasks();
expect(value).toEqual([1, 2]);
@ -488,7 +535,9 @@ describe(
describe('Promise subclasses', function() {
class MyPromise<T> {
private _promise: Promise<any>;
constructor(init: any) { this._promise = new Promise(init); }
constructor(init: any) {
this._promise = new Promise(init);
}
catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>)|
undefined|null): Promise<T|TResult> {
@ -511,29 +560,43 @@ describe(
setPrototypeOf(MyPromise.prototype, Promise.prototype);
it('should reject if the Promise subclass rejects', function() {
const myPromise =
new MyPromise(function(resolve: any, reject: any): void { reject('foo'); });
const myPromise = new MyPromise(function(resolve: any, reject: any): void {
reject('foo');
});
return Promise.resolve()
.then(function() { return myPromise; })
.then(function() {
return myPromise;
})
.then(
function() { throw new Error('Unexpected resolution'); },
function(result) { expect(result).toBe('foo'); });
function() {
throw new Error('Unexpected resolution');
},
function(result) {
expect(result).toBe('foo');
});
});
function testPromiseSubClass(done?: Function) {
const myPromise =
new MyPromise(function(resolve: any, reject: Function) { resolve('foo'); });
return Promise.resolve().then(function() { return myPromise; }).then(function(result) {
expect(result).toBe('foo');
done && done();
const myPromise = new MyPromise(function(resolve: any, reject: Function) {
resolve('foo');
});
return Promise.resolve()
.then(function() {
return myPromise;
})
.then(function(result) {
expect(result).toBe('foo');
done && done();
});
}
it('should resolve if the Promise subclass resolves', jasmine ? function(done) {
testPromiseSubClass(done);
} : function() { testPromiseSubClass(); });
} : function() {
testPromiseSubClass();
});
});
describe('Promise.allSettled', () => {
@ -589,9 +652,13 @@ describe(
});
it('poisoned .then', (done: DoneFn) => {
const promise = new Promise(function() {});
promise.then = function() { throw new EvalError(); };
promise.then = function() {
throw new EvalError();
};
allSettled([promise]).then(
() => { fail('should not reach here'); },
() => {
fail('should not reach here');
},
(reason: any) => {
expect(reason instanceof EvalError).toBe(true);
done();

View File

@ -12,7 +12,9 @@ declare const global: any;
describe(
'fetch', ifEnvSupports('fetch', function() {
let testZone: Zone;
beforeEach(() => { testZone = Zone.current.fork({name: 'TestZone'}); });
beforeEach(() => {
testZone = Zone.current.fork({name: 'TestZone'});
});
it('should work for text response', function(done) {
testZone.run(function() {
global['fetch']('/base/angular/packages/zone.js/test/assets/sample.json')
@ -92,7 +94,9 @@ describe(
testZone.run(function() {
global['fetch']('http://user:password@example.com')
.then(
function(response: any) { fail('should not success'); },
function(response: any) {
fail('should not success');
},
(error: any) => {
expect(Zone.current.name).toEqual(testZone.name);
expect(error.constructor.name).toEqual('TypeError');
@ -118,13 +122,14 @@ describe(
}
return delegate.scheduleTask(target, task);
},
onInvokeTask: (delegate: ZoneDelegate, curr: Zone, target: Zone, task: Task,
applyThis: any, applyArgs: any) => {
if (task.type !== 'eventTask') {
logs.push(`invokeTask:${task.source}:${task.type}`);
}
return delegate.invokeTask(target, task, applyThis, applyArgs);
},
onInvokeTask:
(delegate: ZoneDelegate, curr: Zone, target: Zone, task: Task, applyThis: any,
applyArgs: any) => {
if (task.type !== 'eventTask') {
logs.push(`invokeTask:${task.source}:${task.type}`);
}
return delegate.invokeTask(target, task, applyThis, applyArgs);
},
onCancelTask: (delegate: ZoneDelegate, curr: Zone, target: Zone, task: Task) => {
if (task.type !== 'eventTask') {
logs.push(`cancelTask:${task.source}:${task.type}`);
@ -160,7 +165,9 @@ describe(
const abort = new AbortController();
const signal = abort.signal;
global['fetch']('/base/angular/packages/zone.js/test/assets/sample.json', {signal})
.then(function(response: any) { fail('should not get response'); })
.then(function(response: any) {
fail('should not get response');
})
.catch(function(error: any) {
expect(error.name).toEqual('AbortError');
expect(logs).toEqual([
@ -187,7 +194,9 @@ describe(
const abort = new AbortController();
const signal = abort.signal;
global['fetch']('/base/angular/packages/zone.js/test/assets/sample.json', {signal})
.then(function(response: any) { fail('should not get response'); })
.then(function(response: any) {
fail('should not get response');
})
.catch(function(error: any) {
expect(error.name).toEqual('AbortError');
expect(logs).toEqual([

View File

@ -9,7 +9,9 @@
describe('Microtasks', function() {
if (!global.Promise) return;
function scheduleFn(task: Task) { Promise.resolve().then(<any>task.invoke); }
function scheduleFn(task: Task) {
Promise.resolve().then(<any>task.invoke);
}
it('should execute microtasks enqueued in the root zone', function(done) {
const log: number[] = [];
@ -35,7 +37,9 @@ describe('Microtasks', function() {
log.push('-mat1');
}, 10);
setTimeout(function() { log.push('mat2'); }, 30);
setTimeout(function() {
log.push('mat2');
}, 30);
setTimeout(function() {
expect(log).toEqual(['+root', '-root', 'root.mit', '+mat1', '-mat1', 'mat1.mit', 'mat2']);
@ -62,7 +66,9 @@ describe('Microtasks', function() {
'in different zone.',
function(done) {
let resolve: Function;
const promise = new Promise(function(rs) { resolve = rs; });
const promise = new Promise(function(rs) {
resolve = rs;
});
const testZone = Zone.current.fork({name: 'test'});
@ -73,7 +79,9 @@ describe('Microtasks', function() {
});
});
Zone.current.fork({name: 'test'}).run(function() { resolve(null); });
Zone.current.fork({name: 'test'}).run(function() {
resolve(null);
});
});
describe('Promise', function() {

View File

@ -21,11 +21,11 @@ describe('disable wrap uncaught promise rejection', () => {
.fork({
name: 'promise-error',
onHandleError: (delegate: ZoneDelegate, current: Zone, target: Zone, error: any):
boolean => {
promiseError = error;
delegate.handleError(target, error);
return false;
}
boolean => {
promiseError = error;
delegate.handleError(target, error);
return false;
}
})
.run(() => {
zone = Zone.current;
@ -56,11 +56,11 @@ describe('disable wrap uncaught promise rejection', () => {
.fork({
name: 'promise-error',
onHandleError: (delegate: ZoneDelegate, current: Zone, target: Zone, error: any):
boolean => {
promiseError = error;
delegate.handleError(target, error);
return false;
}
boolean => {
promiseError = error;
delegate.handleError(target, error);
return false;
}
})
.run(() => {
rejectObj = new TestRejection();

View File

@ -7,7 +7,7 @@
*/
const noop = function() {};
let log: {zone: string, taskZone: undefined | string, toState: TaskState, fromState: TaskState}[] =
let log: {zone: string, taskZone: undefined|string, toState: TaskState, fromState: TaskState}[] =
[];
const detectTask = Zone.current.scheduleMacroTask('detectTask', noop, undefined, noop, noop);
const originalTransitionTo = detectTask.constructor.prototype._transitionTo;
@ -34,14 +34,18 @@ function testFnWithLoggedTransitionTo(testFn: Function) {
describe('task lifecycle', () => {
describe('event task lifecycle', () => {
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('task should transit from notScheduled to scheduling then to scheduled state when scheduleTask',
testFnWithLoggedTransitionTo(() => {
Zone.current.fork({name: 'testEventTaskZone'}).run(() => {
Zone.current.scheduleEventTask('testEventTask', noop, undefined, noop, noop);
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'}
@ -63,7 +67,9 @@ describe('task lifecycle', () => {
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'unknown', fromState: 'scheduling'}
@ -77,7 +83,9 @@ describe('task lifecycle', () => {
Zone.current.scheduleEventTask('testEventTask', noop, undefined, noop, noop);
task.invoke();
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -93,7 +101,9 @@ describe('task lifecycle', () => {
Zone.current.scheduleEventTask('testEventTask', noop, undefined, noop, noop);
Zone.current.cancelTask(task);
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -105,11 +115,14 @@ describe('task lifecycle', () => {
it('task should transit from running to canceling then from canceling to notScheduled when task is canceled in running state',
testFnWithLoggedTransitionTo(() => {
Zone.current.fork({name: 'testEventTaskZone'}).run(() => {
const task = Zone.current.scheduleEventTask(
'testEventTask', () => { Zone.current.cancelTask(task); }, undefined, noop, noop);
const task = Zone.current.scheduleEventTask('testEventTask', () => {
Zone.current.cancelTask(task);
}, undefined, noop, noop);
task.invoke();
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -122,14 +135,17 @@ describe('task lifecycle', () => {
it('task should transit from running to scheduled when task.callback throw error',
testFnWithLoggedTransitionTo(() => {
Zone.current.fork({name: 'testEventTaskZone'}).run(() => {
const task = Zone.current.scheduleEventTask(
'testEventTask', () => { throw Error('invoke error'); }, undefined, noop, noop);
const task = Zone.current.scheduleEventTask('testEventTask', () => {
throw Error('invoke error');
}, undefined, noop, noop);
try {
task.invoke();
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -141,14 +157,18 @@ describe('task lifecycle', () => {
it('task should transit from canceling to unknown when zoneSpec.onCancelTask throw error before task running',
testFnWithLoggedTransitionTo(() => {
Zone.current.fork({name: 'testEventTaskZone'}).run(() => {
const task = Zone.current.scheduleEventTask(
'testEventTask', noop, undefined, noop, () => { throw Error('cancel task'); });
const task =
Zone.current.scheduleEventTask('testEventTask', noop, undefined, noop, () => {
throw Error('cancel task');
});
try {
Zone.current.cancelTask(task);
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -160,14 +180,18 @@ describe('task lifecycle', () => {
it('task should transit from canceling to unknown when zoneSpec.onCancelTask throw error in running state',
testFnWithLoggedTransitionTo(() => {
Zone.current.fork({name: 'testEventTaskZone'}).run(() => {
const task = Zone.current.scheduleEventTask(
'testEventTask', noop, undefined, noop, () => { throw Error('cancel task'); });
const task =
Zone.current.scheduleEventTask('testEventTask', noop, undefined, noop, () => {
throw Error('cancel task');
});
try {
Zone.current.cancelTask(task);
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -191,7 +215,9 @@ describe('task lifecycle', () => {
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'}
@ -218,7 +244,9 @@ describe('task lifecycle', () => {
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -229,14 +257,18 @@ describe('task lifecycle', () => {
});
describe('non periodical macroTask lifecycle', () => {
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('task should transit from notScheduled to scheduling then to scheduled state when scheduleTask',
testFnWithLoggedTransitionTo(() => {
Zone.current.fork({name: 'testMacroTaskZone'}).run(() => {
Zone.current.scheduleMacroTask('testMacroTask', noop, undefined, noop, noop);
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'}
@ -258,7 +290,9 @@ describe('task lifecycle', () => {
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'unknown', fromState: 'scheduling'}
@ -272,7 +306,9 @@ describe('task lifecycle', () => {
Zone.current.scheduleMacroTask('testMacroTask', noop, undefined, noop, noop);
task.invoke();
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -288,7 +324,9 @@ describe('task lifecycle', () => {
Zone.current.scheduleMacroTask('testMacrotask', noop, undefined, noop, noop);
Zone.current.cancelTask(task);
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -300,11 +338,14 @@ describe('task lifecycle', () => {
it('task should transit from running to canceling then from canceling to notScheduled when task is canceled in running state',
testFnWithLoggedTransitionTo(() => {
Zone.current.fork({name: 'testMacroTaskZone'}).run(() => {
const task = Zone.current.scheduleMacroTask(
'testMacroTask', () => { Zone.current.cancelTask(task); }, undefined, noop, noop);
const task = Zone.current.scheduleMacroTask('testMacroTask', () => {
Zone.current.cancelTask(task);
}, undefined, noop, noop);
task.invoke();
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -317,14 +358,17 @@ describe('task lifecycle', () => {
it('task should transit from running to noScheduled when task.callback throw error',
testFnWithLoggedTransitionTo(() => {
Zone.current.fork({name: 'testMacroTaskZone'}).run(() => {
const task = Zone.current.scheduleMacroTask(
'testMacroTask', () => { throw Error('invoke error'); }, undefined, noop, noop);
const task = Zone.current.scheduleMacroTask('testMacroTask', () => {
throw Error('invoke error');
}, undefined, noop, noop);
try {
task.invoke();
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -336,14 +380,18 @@ describe('task lifecycle', () => {
it('task should transit from canceling to unknown when zoneSpec.onCancelTask throw error before task running',
testFnWithLoggedTransitionTo(() => {
Zone.current.fork({name: 'testMacroTaskZone'}).run(() => {
const task = Zone.current.scheduleMacroTask(
'testMacroTask', noop, undefined, noop, () => { throw Error('cancel task'); });
const task =
Zone.current.scheduleMacroTask('testMacroTask', noop, undefined, noop, () => {
throw Error('cancel task');
});
try {
Zone.current.cancelTask(task);
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -355,14 +403,18 @@ describe('task lifecycle', () => {
it('task should transit from canceling to unknown when zoneSpec.onCancelTask throw error in running state',
testFnWithLoggedTransitionTo(() => {
Zone.current.fork({name: 'testMacroTaskZone'}).run(() => {
const task = Zone.current.scheduleMacroTask(
'testMacroTask', noop, undefined, noop, () => { throw Error('cancel task'); });
const task =
Zone.current.scheduleMacroTask('testMacroTask', noop, undefined, noop, () => {
throw Error('cancel task');
});
try {
Zone.current.cancelTask(task);
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -386,7 +438,9 @@ describe('task lifecycle', () => {
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'}
@ -413,7 +467,9 @@ describe('task lifecycle', () => {
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -442,7 +498,9 @@ describe('task lifecycle', () => {
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -469,7 +527,9 @@ describe('task lifecycle', () => {
task = Zone.current.scheduleMacroTask(
'testPeriodicalTask', noop, {isPeriodic: true}, noop, noop);
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'}
@ -492,7 +552,9 @@ describe('task lifecycle', () => {
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'unknown', fromState: 'scheduling'}
@ -506,7 +568,9 @@ describe('task lifecycle', () => {
'testPeriodicalTask', noop, {isPeriodic: true}, noop, noop);
task.invoke();
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -522,7 +586,9 @@ describe('task lifecycle', () => {
'testPeriodicalTask', noop, {isPeriodic: true}, noop, noop);
Zone.current.cancelTask(task);
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -535,11 +601,13 @@ describe('task lifecycle', () => {
testFnWithLoggedTransitionTo(() => {
Zone.current.fork({name: 'testPeriodicalTaskZone'}).run(() => {
task = Zone.current.scheduleMacroTask('testPeriodicalTask', () => {
Zone.current.cancelTask(task !);
Zone.current.cancelTask(task!);
}, {isPeriodic: true}, noop, noop);
task.invoke();
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -560,7 +628,9 @@ describe('task lifecycle', () => {
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -573,14 +643,17 @@ describe('task lifecycle', () => {
testFnWithLoggedTransitionTo(() => {
Zone.current.fork({name: 'testPeriodicalTaskZone'}).run(() => {
task = Zone.current.scheduleMacroTask(
'testPeriodicalTask', noop, {isPeriodic: true}, noop,
() => { throw Error('cancel task'); });
'testPeriodicalTask', noop, {isPeriodic: true}, noop, () => {
throw Error('cancel task');
});
try {
Zone.current.cancelTask(task);
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -593,14 +666,17 @@ describe('task lifecycle', () => {
testFnWithLoggedTransitionTo(() => {
Zone.current.fork({name: 'testPeriodicalTaskZone'}).run(() => {
task = Zone.current.scheduleMacroTask(
'testPeriodicalTask', noop, {isPeriodic: true}, noop,
() => { throw Error('cancel task'); });
'testPeriodicalTask', noop, {isPeriodic: true}, noop, () => {
throw Error('cancel task');
});
try {
Zone.current.cancelTask(task);
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -625,7 +701,9 @@ describe('task lifecycle', () => {
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'}
@ -651,7 +729,9 @@ describe('task lifecycle', () => {
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -662,14 +742,18 @@ describe('task lifecycle', () => {
});
describe('microTask lifecycle', () => {
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('task should transit from notScheduled to scheduling then to scheduled state when scheduleTask',
testFnWithLoggedTransitionTo(() => {
Zone.current.fork({name: 'testMicroTaskZone'}).run(() => {
Zone.current.scheduleMicroTask('testMicroTask', noop, undefined, noop);
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'}
@ -691,7 +775,9 @@ describe('task lifecycle', () => {
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'unknown', fromState: 'scheduling'}
@ -704,7 +790,9 @@ describe('task lifecycle', () => {
const task = Zone.current.scheduleMicroTask('testMicroTask', noop, undefined, noop);
task.invoke();
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -716,21 +804,26 @@ describe('task lifecycle', () => {
it('should throw error when try to cancel a microTask', testFnWithLoggedTransitionTo(() => {
Zone.current.fork({name: 'testMicroTaskZone'}).run(() => {
const task = Zone.current.scheduleMicroTask('testMicroTask', () => {}, undefined, noop);
expect(() => { Zone.current.cancelTask(task); }).toThrowError('Task is not cancelable');
expect(() => {
Zone.current.cancelTask(task);
}).toThrowError('Task is not cancelable');
});
}));
it('task should transit from running to notScheduled when task.callback throw error',
testFnWithLoggedTransitionTo(() => {
Zone.current.fork({name: 'testMicroTaskZone'}).run(() => {
const task = Zone.current.scheduleMicroTask(
'testMicroTask', () => { throw Error('invoke error'); }, undefined, noop);
const task = Zone.current.scheduleMicroTask('testMicroTask', () => {
throw Error('invoke error');
}, undefined, noop);
try {
task.invoke();
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -754,7 +847,9 @@ describe('task lifecycle', () => {
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'}
@ -780,7 +875,9 @@ describe('task lifecycle', () => {
} catch (err) {
}
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -798,7 +895,9 @@ describe('task lifecycle', () => {
Zone.current.cancelTask(task);
task.invoke();
});
expect(log.map(item => { return {toState: item.toState, fromState: item.fromState}; }))
expect(log.map(item => {
return {toState: item.toState, fromState: item.fromState};
}))
.toEqual([
{toState: 'scheduling', fromState: 'notScheduled'},
{toState: 'scheduled', fromState: 'scheduling'},
@ -809,7 +908,7 @@ describe('task lifecycle', () => {
});
describe('reschedule zone', () => {
let callbackLogs: ({pos: string, method: string, zone: string, task: string} | HasTaskState)[];
let callbackLogs: ({pos: string, method: string, zone: string, task: string}|HasTaskState)[];
const newZone = Zone.root.fork({
name: 'new',
onScheduleTask: (delegate, currZone, targetZone, task) => {
@ -861,7 +960,9 @@ describe('task lifecycle', () => {
}
});
beforeEach(() => { callbackLogs = []; });
beforeEach(() => {
callbackLogs = [];
});
it('should be able to reschedule zone when in scheduling state, after that, task will completely go to new zone, has nothing to do with original one',
testFnWithLoggedTransitionTo(() => {
@ -876,13 +977,8 @@ describe('task lifecycle', () => {
{pos: 'before', method: 'onScheduleTask', zone: 'new', task: 'new'},
{microTask: false, macroTask: true, eventTask: false, change: 'macroTask', zone: 'new'},
{pos: 'after', method: 'onScheduleTask', zone: 'original', task: 'new'},
{pos: 'before', method: 'onInvokeTask', zone: 'new', task: 'new'}, {
microTask: false,
macroTask: false,
eventTask: false,
change: 'macroTask',
zone: 'new'
}
{pos: 'before', method: 'onInvokeTask', zone: 'new', task: 'new'},
{microTask: false, macroTask: false, eventTask: false, change: 'macroTask', zone: 'new'}
]);
}));
@ -892,7 +988,9 @@ describe('task lifecycle', () => {
const t = Zone.current.scheduleMacroTask(
'testRescheduleZoneTask', noop, undefined, noop, noop);
Zone.current.cancelTask(t);
expect(() => { t.cancelScheduleRequest(); })
expect(() => {
t.cancelScheduleRequest();
})
.toThrow(Error(
`macroTask 'testRescheduleZoneTask': can not transition to ` +
`'notScheduled', expecting state 'scheduling', was 'notScheduled'.`));
@ -902,7 +1000,9 @@ describe('task lifecycle', () => {
.fork({
name: 'rescheduleRunning',
onInvokeTask: (delegate, currZone, targetZone, task, applyThis, applyArgs) => {
expect(() => { task.cancelScheduleRequest(); })
expect(() => {
task.cancelScheduleRequest();
})
.toThrow(Error(
`macroTask 'testRescheduleZoneTask': can not transition to ` +
`'notScheduled', expecting state 'scheduling', was 'running'.`));
@ -918,7 +1018,9 @@ describe('task lifecycle', () => {
.fork({
name: 'rescheduleCanceling',
onCancelTask: (delegate, currZone, targetZone, task) => {
expect(() => { task.cancelScheduleRequest(); })
expect(() => {
task.cancelScheduleRequest();
})
.toThrow(Error(
`macroTask 'testRescheduleZoneTask': can not transition to ` +
`'notScheduled', expecting state 'scheduling', was 'canceling'.`));

View File

@ -32,8 +32,9 @@ describe('global function patch', () => {
});
describe('isNative', () => {
it('ZoneAwareError toString should look like native',
() => { expect(Function.prototype.toString.call(Error)).toContain('[native code]'); });
it('ZoneAwareError toString should look like native', () => {
expect(Function.prototype.toString.call(Error)).toContain('[native code]');
});
it('Function toString should look like native', () => {
expect(Function.prototype.toString.call(Function.prototype.toString))

View File

@ -29,27 +29,33 @@ describe('utils', function() {
expect(name).toEqual('method');
delegateMethod = delegate;
delegateSymbol = symbol;
return function(self, args) { return delegate.apply(self, ['patch', args[0]]); };
})).toBe(delegateMethod !);
return function(self, args) {
return delegate.apply(self, ['patch', args[0]]);
};
})).toBe(delegateMethod!);
expect(instance.method('a0')).toEqual('OK');
expect(args).toEqual(['patch', 'a0']);
expect(self).toBe(instance);
expect(delegateMethod !).toBe(method);
expect(delegateSymbol !).toEqual(zoneSymbol('method'));
expect((Type.prototype as any)[delegateSymbol !]).toBe(method);
expect(delegateMethod!).toBe(method);
expect(delegateSymbol!).toEqual(zoneSymbol('method'));
expect((Type.prototype as any)[delegateSymbol!]).toBe(method);
});
it('should not double patch', () => {
const Type = function() {};
const method = Type.prototype.method = function() {};
patchMethod(Type.prototype, 'method', (delegate) => {
return function(self, args: any[]) { return delegate.apply(self, ['patch', ...args]); };
return function(self, args: any[]) {
return delegate.apply(self, ['patch', ...args]);
};
});
const pMethod = Type.prototype.method;
expect(pMethod).not.toBe(method);
patchMethod(Type.prototype, 'method', (delegate) => {
return function(self, args) { return delegate.apply(self, ['patch', ...args]); };
return function(self, args) {
return delegate.apply(self, ['patch', ...args]);
};
});
expect(pMethod).toBe(Type.prototype.method);
});
@ -68,8 +74,8 @@ describe('utils', function() {
}
patchProperty(TestType.prototype, 'nonConfigurableProperty');
const desc = Object.getOwnPropertyDescriptor(TestType.prototype, 'nonConfigurableProperty');
expect(desc !.writable).toBeTruthy();
expect(!desc !.get).toBeTruthy();
expect(desc!.writable).toBeTruthy();
expect(!desc!.get).toBeTruthy();
});
});
@ -80,13 +86,17 @@ describe('utils', function() {
const log: string[] = [];
Object.defineProperties(TestFunction.prototype, {
'property1': {
value: function Property1(callback: Function) { Zone.root.run(callback); },
value: function Property1(callback: Function) {
Zone.root.run(callback);
},
writable: true,
configurable: true,
enumerable: true
},
'property2': {
value: function Property2(callback: Function) { Zone.root.run(callback); },
value: function Property2(callback: Function) {
Zone.root.run(callback);
},
writable: true,
configurable: false,
enumerable: true
@ -97,8 +107,12 @@ describe('utils', function() {
zone.run(() => {
const instance = new TestFunction();
instance.property1(() => { log.push('property1' + Zone.current.name); });
instance.property2(() => { log.push('property2' + Zone.current.name); });
instance.property1(() => {
log.push('property1' + Zone.current.name);
});
instance.property2(() => {
log.push('property2' + Zone.current.name);
});
});
expect(log).toEqual(['property1<root>', 'property2<root>']);
log.length = 0;
@ -107,8 +121,12 @@ describe('utils', function() {
zone.run(() => {
const instance = new TestFunction();
instance.property1(() => { log.push('property1' + Zone.current.name); });
instance.property2(() => { log.push('property2' + Zone.current.name); });
instance.property1(() => {
log.push('property1' + Zone.current.name);
});
instance.property2(() => {
log.push('property2' + Zone.current.name);
});
});
expect(log).toEqual(['property1patch', 'property2patch']);
});
@ -119,13 +137,17 @@ describe('utils', function() {
const log: string[] = [];
Object.defineProperties(TestFunction.prototype, {
'property1': {
value: function Property1(callback: Function) { Zone.root.run(callback); },
value: function Property1(callback: Function) {
Zone.root.run(callback);
},
writable: true,
configurable: true,
enumerable: true
},
'property2': {
value: function Property2(callback: Function) { Zone.root.run(callback); },
value: function Property2(callback: Function) {
Zone.root.run(callback);
},
writable: false,
configurable: true,
enumerable: true
@ -136,8 +158,12 @@ describe('utils', function() {
zone.run(() => {
const instance = new TestFunction();
instance.property1(() => { log.push('property1' + Zone.current.name); });
instance.property2(() => { log.push('property2' + Zone.current.name); });
instance.property1(() => {
log.push('property1' + Zone.current.name);
});
instance.property2(() => {
log.push('property2' + Zone.current.name);
});
});
expect(log).toEqual(['property1<root>', 'property2<root>']);
log.length = 0;
@ -146,8 +172,12 @@ describe('utils', function() {
zone.run(() => {
const instance = new TestFunction();
instance.property1(() => { log.push('property1' + Zone.current.name); });
instance.property2(() => { log.push('property2' + Zone.current.name); });
instance.property1(() => {
log.push('property1' + Zone.current.name);
});
instance.property2(() => {
log.push('property2' + Zone.current.name);
});
});
expect(log).toEqual(['property1patch', 'property2<root>']);
});
@ -160,17 +190,23 @@ describe('utils', function() {
'property1': {
get: function() {
if (!this._property1) {
this._property1 = function Property2(callback: Function) { Zone.root.run(callback); };
this._property1 = function Property2(callback: Function) {
Zone.root.run(callback);
};
}
return this._property1;
},
set: function(func: Function) { this._property1 = func; },
set: function(func: Function) {
this._property1 = func;
},
configurable: true,
enumerable: true
},
'property2': {
get: function() {
return function Property2(callback: Function) { Zone.root.run(callback); };
return function Property2(callback: Function) {
Zone.root.run(callback);
};
},
configurable: true,
enumerable: true
@ -181,8 +217,12 @@ describe('utils', function() {
zone.run(() => {
const instance = new TestFunction();
instance.property1(() => { log.push('property1' + Zone.current.name); });
instance.property2(() => { log.push('property2' + Zone.current.name); });
instance.property1(() => {
log.push('property1' + Zone.current.name);
});
instance.property2(() => {
log.push('property2' + Zone.current.name);
});
});
expect(log).toEqual(['property1<root>', 'property2<root>']);
log.length = 0;
@ -191,8 +231,12 @@ describe('utils', function() {
zone.run(() => {
const instance = new TestFunction();
instance.property1(() => { log.push('property1' + Zone.current.name); });
instance.property2(() => { log.push('property2' + Zone.current.name); });
instance.property1(() => {
log.push('property1' + Zone.current.name);
});
instance.property2(() => {
log.push('property2' + Zone.current.name);
});
});
expect(log).toEqual(['property1patch', 'property2<root>']);
});
@ -203,7 +247,9 @@ describe('utils', function() {
const log: string[] = [];
Object.defineProperties(TestFunction.prototype, {
'property2': {
value: function Property2(callback: Function) { Zone.root.run(callback); },
value: function Property2(callback: Function) {
Zone.root.run(callback);
},
writable: false,
configurable: true,
enumerable: true
@ -214,7 +260,9 @@ describe('utils', function() {
zone.run(() => {
const instance = new TestFunction();
instance.property2(() => { log.push('property2' + Zone.current.name); });
instance.property2(() => {
log.push('property2' + Zone.current.name);
});
});
expect(log).toEqual(['property2<root>']);
log.length = 0;
@ -222,12 +270,16 @@ describe('utils', function() {
patchMethod(
TestFunction.prototype, 'property2',
function(delegate: Function, delegateName: string, name: string) {
return function(self: any, args: any) { log.push('patched property2'); };
return function(self: any, args: any) {
log.push('patched property2');
};
});
zone.run(() => {
const instance = new TestFunction();
instance.property2(() => { log.push('property2' + Zone.current.name); });
instance.property2(() => {
log.push('property2' + Zone.current.name);
});
});
expect(log).toEqual(['property2<root>']);
});
@ -239,7 +291,9 @@ describe('utils', function() {
Object.defineProperties(TestFunction.prototype, {
'property2': {
get: function() {
return function Property2(callback: Function) { Zone.root.run(callback); };
return function Property2(callback: Function) {
Zone.root.run(callback);
};
},
configurable: true,
enumerable: true
@ -250,7 +304,9 @@ describe('utils', function() {
zone.run(() => {
const instance = new TestFunction();
instance.property2(() => { log.push('property2' + Zone.current.name); });
instance.property2(() => {
log.push('property2' + Zone.current.name);
});
});
expect(log).toEqual(['property2<root>']);
log.length = 0;
@ -258,12 +314,16 @@ describe('utils', function() {
patchMethod(
TestFunction.prototype, 'property2',
function(delegate: Function, delegateName: string, name: string) {
return function(self: any, args: any) { log.push('patched property2'); };
return function(self: any, args: any) {
log.push('patched property2');
};
});
zone.run(() => {
const instance = new TestFunction();
instance.property2(() => { log.push('property2' + Zone.current.name); });
instance.property2(() => {
log.push('property2' + Zone.current.name);
});
});
expect(log).toEqual(['property2<root>']);
});

View File

@ -10,11 +10,16 @@ import {zoneSymbol} from '../../lib/common/utils';
describe('Zone', function() {
const rootZone = Zone.current;
it('should have a name', function() { expect(Zone.current.name).toBeDefined(); });
it('should have a name', function() {
expect(Zone.current.name).toBeDefined();
});
describe('hooks', function() {
it('should throw if onError is not defined',
function() { expect(function() { Zone.current.run(throwError); }).toThrow(); });
it('should throw if onError is not defined', function() {
expect(function() {
Zone.current.run(throwError);
}).toThrow();
});
it('should fire onError if a function run by a zone throws', function() {
@ -23,7 +28,9 @@ describe('Zone', function() {
expect(errorSpy).not.toHaveBeenCalled();
expect(function() { myZone.runGuarded(throwError); }).not.toThrow();
expect(function() {
myZone.runGuarded(throwError);
}).not.toThrow();
expect(errorSpy).toHaveBeenCalled();
});
@ -73,7 +80,9 @@ describe('Zone', function() {
const zoneB = zone.fork({name: 'B'});
zoneA.run(function() {
zoneB.run(function() { expect(Zone.current).toBe(zoneB); });
zoneB.run(function() {
expect(Zone.current).toBe(zoneB);
});
expect(Zone.current).toBe(zoneA);
});
expect(Zone.current).toBe(zone);
@ -97,7 +106,9 @@ describe('Zone', function() {
it('should be able to get run under rootZone', function() {
Zone.current.fork({name: 'testZone'}).run(function() {
Zone.root.run(() => { expect(Zone.current.name).toEqual('<root>'); });
Zone.root.run(() => {
expect(Zone.current.name).toEqual('<root>');
});
});
});
@ -105,7 +116,7 @@ describe('Zone', function() {
Zone.current.fork({name: 'testZone'}).run(function() {
Zone.root.fork({name: 'newTestZone'}).run(() => {
expect(Zone.current.name).toEqual('newTestZone');
expect(Zone.current.parent !.name).toEqual('<root>');
expect(Zone.current.parent!.name).toEqual('<root>');
});
});
});
@ -130,10 +141,10 @@ describe('Zone', function() {
const zone: Zone = Zone.current.fork({
name: 'parent',
onHasTask: (delegate: ZoneDelegate, current: Zone, target: Zone, hasTaskState: HasTaskState):
void => {
(hasTaskState as any)['zone'] = target.name;
log.push(hasTaskState);
},
void => {
(hasTaskState as any)['zone'] = target.name;
log.push(hasTaskState);
},
onScheduleTask: (delegate: ZoneDelegate, current: Zone, target: Zone, task: Task) => {
// Do nothing to prevent tasks from being run on VM turn;
// Tests run task explicitly.
@ -141,12 +152,16 @@ describe('Zone', function() {
}
});
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('task can only run in the zone of creation', () => {
const task =
zone.fork({name: 'createZone'}).scheduleMacroTask('test', noop, undefined, noop, noop);
expect(() => { Zone.current.fork({name: 'anotherZone'}).runTask(task); })
expect(() => {
Zone.current.fork({name: 'anotherZone'}).runTask(task);
})
.toThrowError(
'A task can only be run in the zone of creation! (Creation: createZone; Execution: anotherZone)');
task.zone.cancelTask(task);
@ -155,7 +170,9 @@ describe('Zone', function() {
it('task can only cancel in the zone of creation', () => {
const task =
zone.fork({name: 'createZone'}).scheduleMacroTask('test', noop, undefined, noop, noop);
expect(() => { Zone.current.fork({name: 'anotherZone'}).cancelTask(task); })
expect(() => {
Zone.current.fork({name: 'anotherZone'}).cancelTask(task);
})
.toThrowError(
'A task can only be cancelled in the zone of creation! (Creation: createZone; Execution: anotherZone)');
task.zone.cancelTask(task);
@ -183,13 +200,8 @@ describe('Zone', function() {
});
expect(log).toEqual([
{microTask: false, macroTask: true, eventTask: false, change: 'macroTask', zone: 'parent'},
'macroTask', 'macroTask', {
microTask: false,
macroTask: false,
eventTask: false,
change: 'macroTask',
zone: 'parent'
}
'macroTask', 'macroTask',
{microTask: false, macroTask: false, eventTask: false, change: 'macroTask', zone: 'parent'}
]);
});
@ -209,13 +221,7 @@ describe('Zone', function() {
{microTask: false, macroTask: true, eventTask: false, change: 'macroTask', zone: 'parent'},
{microTask: false, macroTask: false, eventTask: false, change: 'macroTask', zone: 'parent'},
{microTask: false, macroTask: false, eventTask: true, change: 'eventTask', zone: 'parent'},
{
microTask: false,
macroTask: false,
eventTask: false,
change: 'eventTask',
zone: 'parent'
}
{microTask: false, macroTask: false, eventTask: false, change: 'eventTask', zone: 'parent'}
]);
});
@ -315,15 +321,18 @@ describe('Zone', function() {
() => {
const zone = Zone.current.fork({name: 'testZone'});
const task = zone.scheduleEventTask(
'testEventTask', () => { zone.cancelTask(task); }, undefined, () => {}, () => {});
const task = zone.scheduleEventTask('testEventTask', () => {
zone.cancelTask(task);
}, undefined, () => {}, () => {});
task.invoke();
expect(task.state).toBe('notScheduled');
});
describe('assert ZoneAwarePromise', () => {
it('should not throw when all is OK', () => { Zone.assertZonePatched(); });
it('should not throw when all is OK', () => {
Zone.assertZonePatched();
});
it('should keep ZoneAwarePromise has been patched', () => {
class WrongPromise {
@ -353,7 +362,9 @@ describe('Zone', function() {
function noop() {}
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('should not drain the microtask queue too early', () => {
const z = Zone.current;
@ -375,17 +386,26 @@ describe('Zone', function() {
const event = z.scheduleEventTask('test', () => {}, undefined, noop, noop);
const micro = z.scheduleMicroTask('test', () => {});
const macro = z.scheduleMacroTask('test', () => {}, undefined, noop, noop);
expect(function() { JSON.stringify(event); }).not.toThrow();
expect(function() { JSON.stringify(micro); }).not.toThrow();
expect(function() { JSON.stringify(macro); }).not.toThrow();
expect(function() {
JSON.stringify(event);
}).not.toThrow();
expect(function() {
JSON.stringify(micro);
}).not.toThrow();
expect(function() {
JSON.stringify(macro);
}).not.toThrow();
});
it('should call onHandleError callback when zoneSpec onHasTask throw error', () => {
const spy = jasmine.createSpy('error');
const hasTaskZone = Zone.current.fork({
name: 'hasTask',
onHasTask: (delegate: ZoneDelegate, currentZone: Zone, targetZone: Zone,
hasTasState: HasTaskState) => { throw new Error('onHasTask Error'); },
onHasTask:
(delegate: ZoneDelegate, currentZone: Zone, targetZone: Zone,
hasTasState: HasTaskState) => {
throw new Error('onHasTask Error');
},
onHandleError:
(delegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, error: Error) => {
spy(error.message);

View File

@ -38,12 +38,17 @@ describe('bluebird promise', () => {
}
});
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('bluebird promise then method should be in zone and treated as microTask', (done) => {
zone.run(() => {
const p = new BluebirdPromise(
(resolve: any, reject: any) => { setTimeout(() => { resolve('test'); }, 0); });
const p = new BluebirdPromise((resolve: any, reject: any) => {
setTimeout(() => {
resolve('test');
}, 0);
});
p.then(() => {
expect(Zone.current.name).toEqual('bluebird');
expect(log.filter(item => item === 'schedule bluebird task Promise.then').length).toBe(1);
@ -55,8 +60,11 @@ describe('bluebird promise', () => {
it('bluebird promise catch method should be in zone and treated as microTask', (done) => {
zone.run(() => {
const p = new BluebirdPromise(
(resolve: any, reject: any) => { setTimeout(() => { reject('test'); }, 0); });
const p = new BluebirdPromise((resolve: any, reject: any) => {
setTimeout(() => {
reject('test');
}, 0);
});
p.catch(() => {
expect(log.filter(item => item === 'schedule bluebird task Promise.then').length).toBe(1);
expect(log.filter(item => item === 'invoke bluebird task Promise.then').length).toBe(1);
@ -83,8 +91,11 @@ describe('bluebird promise', () => {
it('bluebird promise finally method should be in zone', (done) => {
zone.run(() => {
const p = new BluebirdPromise(
(resolve: any, reject: any) => { setTimeout(() => { resolve('test'); }, 0); });
const p = new BluebirdPromise((resolve: any, reject: any) => {
setTimeout(() => {
resolve('test');
}, 0);
});
p.finally(() => {
expect(log.filter(item => item === 'schedule bluebird task Promise.then').length).toBe(1);
expect(log.filter(item => item === 'invoke bluebird task Promise.then').length).toBe(1);
@ -116,25 +127,35 @@ describe('bluebird promise', () => {
it('bluebird promise try method should be in zone', (done) => {
zone.run(() => {
BluebirdPromise.try(() => { throw new Error('promise error'); }).catch((err: Error) => {
expect(log.filter(item => item === 'schedule bluebird task Promise.then').length).toBe(1);
expect(log.filter(item => item === 'invoke bluebird task Promise.then').length).toBe(1);
expect(Zone.current.name).toEqual('bluebird');
expect(err.message).toEqual('promise error');
done();
});
BluebirdPromise
.try(() => {
throw new Error('promise error');
})
.catch((err: Error) => {
expect(log.filter(item => item === 'schedule bluebird task Promise.then').length)
.toBe(1);
expect(log.filter(item => item === 'invoke bluebird task Promise.then').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: string) => {
expect(log.filter(item => item === 'schedule bluebird task Promise.then').length).toBe(1);
expect(log.filter(item => item === 'invoke bluebird task Promise.then').length).toBe(1);
expect(Zone.current.name).toEqual('bluebird');
expect(result).toEqual('test');
done();
});
BluebirdPromise
.method(() => {
return 'test';
})()
.then((result: string) => {
expect(log.filter(item => item === 'schedule bluebird task Promise.then').length)
.toBe(1);
expect(log.filter(item => item === 'invoke bluebird task Promise.then').length).toBe(1);
expect(Zone.current.name).toEqual('bluebird');
expect(result).toEqual('test');
done();
});
});
});
@ -225,7 +246,11 @@ describe('bluebird promise', () => {
it('bluebird promise map method should be in zone', (done) => {
zone.run(() => {
BluebirdPromise
.map(['test1', 'test2'], (value: any) => { return BluebirdPromise.resolve(value); })
.map(
['test1', 'test2'],
(value: any) => {
return BluebirdPromise.resolve(value);
})
.then((r: string[]) => {
expect(r.length).toBe(2);
expect(r[0]).toEqual('test1');
@ -244,7 +269,9 @@ describe('bluebird promise', () => {
BluebirdPromise
.reduce(
[1, 2],
(total: string, value: string) => { return BluebirdPromise.resolve(total + value); })
(total: string, value: string) => {
return BluebirdPromise.resolve(total + value);
})
.then((r: number) => {
expect(r).toBe(3);
expect(log.filter(item => item === 'schedule bluebird task Promise.then').length)
@ -336,25 +363,40 @@ describe('bluebird promise', () => {
it('bluebird promise using/disposer method should be in zone', (done) => {
zone.run(() => {
const p = new BluebirdPromise(
(resolve: Function, reject: any) => { setTimeout(() => { resolve('test'); }, 0); });
p.leakObj = [];
const disposer = p.disposer(() => { p.leakObj = null; });
BluebirdPromise.using(disposer, (v: string) => { 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 Promise.then').length)
.toBeTruthy();
expect(log.filter(item => item === 'invoke bluebird task Promise.then').length)
.toBeTruthy();
done();
const p = new BluebirdPromise((resolve: Function, reject: any) => {
setTimeout(() => {
resolve('test');
}, 0);
});
p.leakObj = [];
const disposer = p.disposer(() => {
p.leakObj = null;
});
BluebirdPromise
.using(
disposer,
(v: string) => {
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 Promise.then').length)
.toBeTruthy();
expect(log.filter(item => item === 'invoke bluebird task Promise.then').length)
.toBeTruthy();
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 func = (cb: Function) => {
setTimeout(() => {
cb(null, 'test');
}, 10);
};
const promiseFunc = BluebirdPromise.promisify(func);
zone.run(() => {
@ -370,8 +412,16 @@ describe('bluebird promise', () => {
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); },
func1: (cb: Function) => {
setTimeout(() => {
cb(null, 'test1');
}, 10);
},
func2: (cb: Function) => {
setTimeout(() => {
cb(null, 'test2');
}, 10);
},
};
const promiseObj = BluebirdPromise.promisifyAll(obj);
@ -391,7 +441,11 @@ describe('bluebird promise', () => {
});
it('bluebird promise fromCallback method should be in zone', (done) => {
const resolver = (cb: Function) => { setTimeout(() => { cb(null, 'test'); }, 10); };
const resolver = (cb: Function) => {
setTimeout(() => {
cb(null, 'test');
}, 10);
};
zone.run(() => {
BluebirdPromise.fromCallback(resolver).then((r: string) => {
@ -428,8 +482,11 @@ describe('bluebird promise', () => {
it('bluebird promise timeout method should be in zone', (done) => {
zone.run(() => {
new BluebirdPromise(
(resolve: any, reject: any) => { setTimeout(() => { resolve('test'); }, 10); })
new BluebirdPromise((resolve: any, reject: any) => {
setTimeout(() => {
resolve('test');
}, 10);
})
.timeout(100)
.then((r: string) => {
expect(Zone.current.name).toEqual('bluebird');
@ -444,9 +501,14 @@ describe('bluebird promise', () => {
it('bluebird promise tap method should be in zone', (done) => {
zone.run(() => {
const p = new BluebirdPromise(
(resolve: any, reject: any) => { setTimeout(() => { resolve('test'); }, 0); });
p.tap(() => { expect(Zone.current.name).toEqual('bluebird'); }).then(() => {
const p = new BluebirdPromise((resolve: any, reject: any) => {
setTimeout(() => {
resolve('test');
}, 0);
});
p.tap(() => {
expect(Zone.current.name).toEqual('bluebird');
}).then(() => {
expect(log.filter(item => item === 'schedule bluebird task Promise.then').length).toBe(1);
expect(log.filter(item => item === 'invoke bluebird task Promise.then').length).toBe(1);
expect(Zone.current.name).toEqual('bluebird');
@ -458,8 +520,16 @@ describe('bluebird promise', () => {
it('bluebird promise call method should be in zone', (done) => {
zone.run(() => {
BluebirdPromise
.map(['test1', 'test2'], (value: any) => { return BluebirdPromise.resolve(value); })
.call('shift', (value: any) => { return value; })
.map(
['test1', 'test2'],
(value: any) => {
return BluebirdPromise.resolve(value);
})
.call(
'shift',
(value: any) => {
return value;
})
.then((r: string) => {
expect(r).toEqual('test1');
expect(log.filter(item => item === 'schedule bluebird task Promise.then').length)
@ -485,7 +555,7 @@ describe('bluebird promise', () => {
it('bluebird promise return method should be in zone', (done) => {
zone.run(() => {
BluebirdPromise.resolve().return ('test1').then((r: string) => {
BluebirdPromise.resolve().return('test1').then((r: string) => {
expect(r).toEqual('test1');
expect(log.filter(item => item === 'schedule bluebird task Promise.then').length).toBe(1);
expect(log.filter(item => item === 'invoke bluebird task Promise.then').length).toBe(1);
@ -534,15 +604,19 @@ describe('bluebird promise', () => {
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: any) => {
if (r.isFulfilled()) {
expect(r.value()).toEqual('test1');
} else {
expect(r.reason()).toEqual('test2');
done();
}
expect(Zone.current.name).toEqual('bluebird');
});
BluebirdPromise
.all(promises.map(promise => {
return promise.reflect();
}))
.each((r: any) => {
if (r.isFulfilled()) {
expect(r.value()).toEqual('test1');
} else {
expect(r.reason()).toEqual('test2');
done();
}
expect(Zone.current.name).toEqual('bluebird');
});
});
});
@ -551,7 +625,9 @@ describe('bluebird promise', () => {
new BluebirdPromise((resolve: any, reject: any) => {
expect(Zone.current.name).toEqual('zone_A');
resolve(1);
}).then((r: any) => { expect(Zone.current.name).toEqual('zone_A'); });
}).then((r: any) => {
expect(Zone.current.name).toEqual('zone_A');
});
});
Zone.current.fork({name: 'zone_B'}).run(() => {
@ -587,7 +663,9 @@ describe('bluebird promise', () => {
reject(1);
})
.then(
() => { fail('should not be here.'); },
() => {
fail('should not be here.');
},
(r: any) => {
expect(r).toBe(1);
expect(Zone.current.name).toEqual('zone_B');
@ -613,10 +691,14 @@ describe('bluebird promise', () => {
});
zone.runGuarded(() => {
return BluebirdPromise.resolve().then(() => { throw new Error('test error'); }).catch(() => {
expect(logs).toEqual([]);
done();
});
return BluebirdPromise.resolve()
.then(() => {
throw new Error('test error');
})
.catch(() => {
expect(logs).toEqual([]);
done();
});
});
});
@ -632,10 +714,14 @@ describe('bluebird promise', () => {
});
zone.runGuarded(() => {
return Promise.resolve().then(() => { throw new Error('test error'); }).catch(() => {
expect(logs).toEqual([]);
done();
});
return Promise.resolve()
.then(() => {
throw new Error('test error');
})
.catch(() => {
expect(logs).toEqual([]);
done();
});
});
});
@ -686,7 +772,9 @@ describe('bluebird promise', () => {
}
});
zone.runGuarded(() => { return Promise.reject(new Error('reject')); });
zone.runGuarded(() => {
return Promise.reject(new Error('reject'));
});
});
it('should trigger onHandleError when unhandledRejection in chained Promise', (done: DoneFn) => {
@ -698,11 +786,17 @@ describe('bluebird promise', () => {
}
});
zone.runGuarded(() => { return Promise.resolve().then(() => { throw new Error('test'); }); });
zone.runGuarded(() => {
return Promise.resolve().then(() => {
throw new Error('test');
});
});
});
it('should not trigger unhandledrejection if zone.onHandleError return false', (done: DoneFn) => {
const listener = function() { fail('should not be here'); };
const listener = function() {
fail('should not be here');
};
if (typeof window !== 'undefined') {
window.addEventListener('unhandledrejection', listener);
@ -725,7 +819,11 @@ describe('bluebird promise', () => {
}
});
zone.runGuarded(() => { return Promise.resolve().then(() => { throw new Error('test'); }); });
zone.runGuarded(() => {
return Promise.resolve().then(() => {
throw new Error('test');
});
});
});
it('should trigger unhandledrejection if zone.onHandleError return true', (done: DoneFn) => {
@ -748,9 +846,17 @@ describe('bluebird promise', () => {
process.on('unhandledRejection', listener);
}
const zone =
Zone.current.fork({name: 'testErrorHandling', onHandleError: function() { return true; }});
const zone = Zone.current.fork({
name: 'testErrorHandling',
onHandleError: function() {
return true;
}
});
zone.runGuarded(() => { return Promise.resolve().then(() => { throw new Error('test'); }); });
zone.runGuarded(() => {
return Promise.resolve().then(() => {
throw new Error('test');
});
});
});
});

View File

@ -21,10 +21,15 @@ describe('cordova test', () => {
expect(Zone.current.name).toEqual('cordova');
done();
},
() => { fail('should not fail'); }, 'service', 'successAction', ['arg0', 'arg1']);
() => {
fail('should not fail');
},
'service', 'successAction', ['arg0', 'arg1']);
cordova.exec(
() => { fail('should not success'); },
() => {
fail('should not success');
},
() => {
expect(Zone.current.name).toEqual('cordova');
done();

View File

@ -10,9 +10,21 @@ var mockRequire = require('mock-require');
var nativeTimeout = setTimeout;
require('./zone-mix');
mockRequire('electron', {
desktopCapturer: {getSources: function(callback) { nativeTimeout(callback); }},
shell: {openExternal: function(callback) { nativeTimeout(callback); }},
ipcRenderer: {on: function(callback) { nativeTimeout(callback); }},
desktopCapturer: {
getSources: function(callback) {
nativeTimeout(callback);
}
},
shell: {
openExternal: function(callback) {
nativeTimeout(callback);
}
},
ipcRenderer: {
on: function(callback) {
nativeTimeout(callback);
}
},
});
require('./zone-patch-electron');
var electron = require('electron');

View File

@ -47,20 +47,22 @@ ifEnvSupports(supportJasmineSpec, () => {
afterEach(() => {
let zone = Zone.current;
expect(zone.name).toEqual('ProxyZone');
expect(beforeEachZone !.name).toEqual(zone.name);
expect(beforeEachZone!.name).toEqual(zone.name);
expect(itZone).toBe(zone);
});
afterAll(() => {
let zone = Zone.current;
expect(zone.name).toEqual('ProxyZone');
expect(beforeAllZone !.name).toEqual(zone.name);
expect(beforeAllZone!.name).toEqual(zone.name);
});
});
describe('return promise', () => {
let log: string[];
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('should wait for promise to resolve', () => {
return new Promise((res, _) => {
@ -71,6 +73,8 @@ ifEnvSupports(supportJasmineSpec, () => {
});
});
afterEach(() => { expect(log).toEqual(['resolved']); });
afterEach(() => {
expect(log).toEqual(['resolved']);
});
});
})();

View File

@ -6,10 +6,18 @@ function assertInsideSyncDescribeZone() {
}
describe('describe', () => {
assertInsideSyncDescribeZone();
beforeEach(() => { assertInsideProxyZone(); });
beforeAll(() => { assertInsideProxyZone(); });
afterEach(() => { assertInsideProxyZone(); });
afterAll(() => { assertInsideProxyZone(); });
beforeEach(() => {
assertInsideProxyZone();
});
beforeAll(() => {
assertInsideProxyZone();
});
afterEach(() => {
assertInsideProxyZone();
});
afterAll(() => {
assertInsideProxyZone();
});
});
describe.each([[1, 2]])('describe.each', (arg1, arg2) => {
assertInsideSyncDescribeZone();
@ -17,23 +25,35 @@ describe.each([[1, 2]])('describe.each', (arg1, arg2) => {
expect(arg2).toBe(2);
});
describe('test', () => {
it('it', () => { assertInsideProxyZone(); });
it('it', () => {
assertInsideProxyZone();
});
it.each([[1, 2]])('it.each', (arg1, arg2) => {
assertInsideProxyZone();
expect(arg1).toBe(1);
expect(arg2).toBe(2);
});
test('test', () => { assertInsideProxyZone(); });
test.each([[]])('test.each', () => { assertInsideProxyZone(); });
test('test', () => {
assertInsideProxyZone();
});
test.each([[]])('test.each', () => {
assertInsideProxyZone();
});
});
it('it', () => { assertInsideProxyZone(); });
it('it', () => {
assertInsideProxyZone();
});
it.each([[1, 2]])('it.each', (arg1, arg2) => {
assertInsideProxyZone();
expect(arg1).toBe(1);
expect(arg2).toBe(2);
});
test('test', () => { assertInsideProxyZone(); });
test.each([[]])('test.each', () => { assertInsideProxyZone(); });
test('test', () => {
assertInsideProxyZone();
});
test.each([[]])('test.each', () => {
assertInsideProxyZone();
});
test.todo('todo');

View File

@ -51,7 +51,7 @@ if ((window as any)[(Zone as any).__symbol__('setTimeout')]) {
// build mode and need to load the browser patch.
browserPatchedPromise =
System.import('/base/angular/packages/zone.js/test/browser-zone-setup').then(() => {
let testFrameworkPatch = typeof(window as any).Mocha !== 'undefined' ?
let testFrameworkPatch = typeof (window as any).Mocha !== 'undefined' ?
'/base/angular/packages/zone.js/lib/mocha/mocha' :
'/base/angular/packages/zone.js/lib/jasmine/jasmine';
return System.import(testFrameworkPatch);
@ -59,7 +59,7 @@ if ((window as any)[(Zone as any).__symbol__('setTimeout')]) {
}
browserPatchedPromise.then(() => {
let testFrameworkPatch = typeof(window as any).Mocha !== 'undefined' ?
let testFrameworkPatch = typeof (window as any).Mocha !== 'undefined' ?
'/base/angular/packages/zone.js/test/test-env-setup-mocha' :
'/base/angular/packages/zone.js/test/test-env-setup-jasmine';
// Setup test environment
@ -67,8 +67,12 @@ browserPatchedPromise.then(() => {
System.import('/base/angular/packages/zone.js/lib/common/error-rewrite').then(() => {
System.import(`/base/angular/packages/zone.js/test/${entryPoint}`)
.then(
() => { __karma__.start(); },
(error: any) => { console.error(error.stack || error); });
() => {
__karma__.start();
},
(error: any) => {
console.error(error.stack || error);
});
});
});
});

View File

@ -9,17 +9,17 @@
// Extra Mocha-specific typings to make sure typescript compiler is happy
// Didn't want to add @types/mocha because of duplication in typings-file with @types/jasmine
declare function suite(description: string, suiteFn: () => void): void;
declare function test(description: string, testFn: () => void): void;
declare function specify(description: string, testFn: () => void): void;
declare function setup(fn: () => void): void; declare function teardown(fn: () => void): void;
declare function suiteSetup(fn: () => void): void;
declare function suiteTeardown(fn: () => void): void;
declare function before(fn: () => void): void; declare function after(fn: () => void): void;
//
declare function test(description: string, testFn: () => void): void;
declare function specify(description: string, testFn: () => void): void;
declare function setup(fn: () => void): void;
declare function teardown(fn: () => void): void;
declare function suiteSetup(fn: () => void): void;
declare function suiteTeardown(fn: () => void): void;
declare function before(fn: () => void): void;
declare function after(fn: () => void): void;
//
import {
ifEnvSupports
} from './test-util';
import {ifEnvSupports} from './test-util';
ifEnvSupports('Mocha', function() {
describe('Mocha BDD-style', () => {
@ -29,7 +29,9 @@ ifEnvSupports('Mocha', function() {
const syncZone = Zone.current;
let beforeZone: Zone|null = null;
before(() => { beforeZone = Zone.current; });
before(() => {
beforeZone = Zone.current;
});
try {
Zone.current.scheduleMicroTask('dontallow', (): any => null);
@ -53,7 +55,9 @@ ifEnvSupports('Mocha', function() {
expect(itZone).toBe(zone);
});
after(() => { expect(beforeZone).toBe(Zone.current); });
after(() => {
expect(beforeZone).toBe(Zone.current);
});
});
suite('Mocha TDD-style', () => {
@ -61,9 +65,13 @@ ifEnvSupports('Mocha', function() {
let beforeEachZone: Zone|null = null;
let suiteSetupZone: Zone|null = null;
suiteSetup(() => { suiteSetupZone = Zone.current; });
suiteSetup(() => {
suiteSetupZone = Zone.current;
});
setup(() => { beforeEachZone = Zone.current; });
setup(() => {
beforeEachZone = Zone.current;
});
test('should run in Zone with "test"-syntax in TDD-mode', () => {
testZone = Zone.current;
@ -83,12 +91,16 @@ ifEnvSupports('Mocha', function() {
expect(testZone).toBe(Zone.current);
});
suiteTeardown(() => { expect(suiteSetupZone).toBe(Zone.current); });
suiteTeardown(() => {
expect(suiteSetupZone).toBe(Zone.current);
});
});
describe('return promise', () => {
let log: string[];
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('should wait for promise to resolve', () => {
return new Promise((res, _) => {
@ -99,6 +111,8 @@ ifEnvSupports('Mocha', function() {
});
});
afterEach(() => { expect(log).toEqual(['resolved']); });
afterEach(() => {
expect(log).toEqual(['resolved']);
});
});
})();

View File

@ -19,7 +19,9 @@ describe('ZoneAwareError', () => {
it('should support prepareStackTrace', () => {
const originalPrepareStackTrace = (<any>Error).prepareStackTrace;
(<any>Error).prepareStackTrace = function(error: Error, stack: string) { return stack; };
(<any>Error).prepareStackTrace = function(error: Error, stack: string) {
return stack;
};
let obj: any = new Object();
Error.captureStackTrace(obj);
expect(obj.stack[0].getFileName()).not.toBeUndefined();
@ -28,7 +30,9 @@ describe('ZoneAwareError', () => {
it('should not add additional stacktrace from Zone when use prepareStackTrace', () => {
const originalPrepareStackTrace = (<any>Error).prepareStackTrace;
(<any>Error).prepareStackTrace = function(error: Error, stack: string) { return stack; };
(<any>Error).prepareStackTrace = function(error: Error, stack: string) {
return stack;
};
let obj: any = new Object();
Error.captureStackTrace(obj);
expect(obj.stack.length).not.toBe(0);

View File

@ -16,7 +16,9 @@ describe('node console', () => {
}
});
beforeEach(() => { log.length = 0; });
beforeEach(() => {
log.length = 0;
});
it('console methods should run in root zone', () => {
zone.run(() => {

View File

@ -28,11 +28,17 @@ describe('nodejs EventEmitter', () => {
expect(value).toBe('test value');
}
function listenerA() { zoneResults.push('A'); }
function listenerA() {
zoneResults.push('A');
}
function listenerB() { zoneResults.push('B'); }
function listenerB() {
zoneResults.push('B');
}
function shouldNotRun() { fail('this listener should not run'); }
function shouldNotRun() {
fail('this listener should not run');
}
it('should register listeners in the current zone', () => {
zoneA.run(() => {
@ -68,12 +74,19 @@ describe('nodejs EventEmitter', () => {
});
});
it('should return all listeners for an event', () => {
zoneA.run(() => { emitter.on('test', expectZoneA); });
zoneB.run(() => { emitter.on('test', shouldNotRun); });
zoneA.run(() => {
emitter.on('test', expectZoneA);
});
zoneB.run(() => {
emitter.on('test', shouldNotRun);
});
expect(emitter.listeners('test')).toEqual([expectZoneA, shouldNotRun]);
});
it('should return empty array when an event has no listeners',
() => { zoneA.run(() => { expect(emitter.listeners('test')).toEqual([]); }); });
it('should return empty array when an event has no listeners', () => {
zoneA.run(() => {
expect(emitter.listeners('test')).toEqual([]);
});
});
it('should prepend listener by order', () => {
zoneA.run(() => {
emitter.on('test', listenerA);
@ -136,8 +149,9 @@ describe('nodejs EventEmitter', () => {
emitter.on('removeListener', function(type: string, handler: any) {
zoneResults.push('remove' + type);
});
emitter.on(
'newListener', function(type: string, handler: any) { zoneResults.push('new' + type); });
emitter.on('newListener', function(type: string, handler: any) {
zoneResults.push('new' + type);
});
emitter.on('test', shouldNotRun);
emitter.removeListener('test', shouldNotRun);
expect(zoneResults).toEqual(['newtest', 'removetest']);
@ -171,7 +185,9 @@ describe('nodejs EventEmitter', () => {
});
it('should not enter endless loop when register uncaughtException to process', () => {
require('domain');
zoneA.run(() => { process.on('uncaughtException', function() {}); });
zoneA.run(() => {
process.on('uncaughtException', function() {});
});
});
it('should be able to addEventListener with symbol eventName', () => {
zoneA.run(() => {

View File

@ -25,7 +25,9 @@ describe('nodejs file system', () => {
const zoneASpec = {
name: 'A',
onScheduleTask: (delegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task):
Task => { return delegate.scheduleTask(targetZone, task); }
Task => {
return delegate.scheduleTask(targetZone, task);
}
};
const zoneA = Zone.current.fork(zoneASpec);
spyOn(zoneASpec, 'onScheduleTask').and.callThrough();
@ -42,7 +44,9 @@ describe('nodejs file system', () => {
const zoneASpec = {
name: 'A',
onScheduleTask: (delegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task):
Task => { return delegate.scheduleTask(targetZone, task); }
Task => {
return delegate.scheduleTask(targetZone, task);
}
};
it('fs.watch has been patched as eventTask', (done) => {
@ -56,7 +60,9 @@ describe('nodejs file system', () => {
expect(zoneASpec.onScheduleTask).toHaveBeenCalled();
expect(Zone.current.name).toBe('A');
watcher.close();
unlink('testfile', () => { done(); });
unlink('testfile', () => {
done();
});
});
writeFile('testfile', 'test new content', () => {});
});
@ -74,7 +80,9 @@ describe('nodejs file system', () => {
expect(zoneASpec.onScheduleTask).toHaveBeenCalled();
expect(Zone.current.name).toBe('A');
unwatchFile('testfile');
unlink('testfile', () => { done(); });
unlink('testfile', () => {
done();
});
});
writeFile('testfile', 'test new content', () => {});
});
@ -92,7 +100,9 @@ describe('util.promisify', () => {
expect(r).toBe(true);
done();
},
err => { fail(`should not be here with error: ${err}`); });
err => {
fail(`should not be here with error: ${err}`);
});
});
it('fs.read should work with util.promisify', (done: DoneFn) => {

View File

@ -8,12 +8,16 @@
const http = require('http');
describe('http test', () => {
it('http.request should be patched as eventTask', (done) => {
const server = http.createServer((req: any, res: any) => { res.end(); });
const server = http.createServer((req: any, res: any) => {
res.end();
});
server.listen(9999, () => {
const zoneASpec = {
name: 'A',
onScheduleTask: (delegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task):
Task => { return delegate.scheduleTask(targetZone, task); }
Task => {
return delegate.scheduleTask(targetZone, task);
}
};
const zoneA = Zone.current.fork(zoneASpec);
spyOn(zoneASpec, 'onScheduleTask').and.callThrough();
@ -22,7 +26,9 @@ describe('http test', () => {
http.request({hostname: 'localhost', port: '9999', method: 'GET'}, (res: any) => {
expect(Zone.current.name).toEqual('A');
expect(zoneASpec.onScheduleTask).toHaveBeenCalled();
server.close(() => { done(); });
server.close(() => {
done();
});
});
req.end();
});

View File

@ -24,8 +24,12 @@ describe('process related test', () => {
});
it('process.nextTick should be executed before macroTask and promise', (done) => {
zoneA.run(function() {
setTimeout(() => { result.push('timeout'); }, 0);
process.nextTick(() => { result.push('tick'); });
setTimeout(() => {
result.push('timeout');
}, 0);
process.nextTick(() => {
result.push('tick');
});
setTimeout(() => {
expect(result).toEqual(['tick', 'timeout']);
done();
@ -35,18 +39,24 @@ describe('process related test', () => {
it('process.nextTick should be treated as microTask', (done) => {
let zoneTick = Zone.current.fork({
name: 'zoneTick',
onScheduleTask: (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone,
task: Task): Task => {
result.push({callback: 'scheduleTask', targetZone: targetZone.name, task: task.source});
return parentZoneDelegate.scheduleTask(targetZone, task);
},
onInvokeTask: (parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone,
task: Task, applyThis?: any, applyArgs?: any): any => {
result.push({callback: 'invokeTask', targetZone: targetZone.name, task: task.source});
return parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs);
}
onScheduleTask: (
parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task):
Task => {
result.push({callback: 'scheduleTask', targetZone: targetZone.name, task: task.source});
return parentZoneDelegate.scheduleTask(targetZone, task);
},
onInvokeTask:
(parentZoneDelegate: ZoneDelegate, currentZone: Zone, targetZone: Zone, task: Task,
applyThis?: any, applyArgs?: any): any => {
result.push({callback: 'invokeTask', targetZone: targetZone.name, task: task.source});
return parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs);
}
});
zoneTick.run(() => {
process.nextTick(() => {
result.push('tick');
});
});
zoneTick.run(() => { process.nextTick(() => { result.push('tick'); }); });
setTimeout(() => {
expect(result.length).toBe(3);
expect(result[0]).toEqual(
@ -66,7 +76,9 @@ describe('process related test', () => {
process.removeListener('unhandledRejection', listener);
};
process.on('unhandledRejection', listener);
const p = new Promise((resolve, reject) => { throw new Error('promise error'); });
const p = new Promise((resolve, reject) => {
throw new Error('promise error');
});
setTimeout(function() {
expect(hookSpy).toHaveBeenCalledWith(p, 'promise error');
@ -84,9 +96,13 @@ describe('process related test', () => {
done();
};
process.on('rejectionHandled', listener);
const p = new Promise((resolve, reject) => { throw new Error('promise error'); });
const p = new Promise((resolve, reject) => {
throw new Error('promise error');
});
setTimeout(function() { p.catch(reason => {}); }, 10);
setTimeout(function() {
p.catch(reason => {});
}, 10);
});
});
@ -104,7 +120,9 @@ describe('process related test', () => {
};
process.on('unhandledRejection', listener1);
process.on('unhandledRejection', listener2);
const p = new Promise((resolve, reject) => { throw new Error('promise error'); });
const p = new Promise((resolve, reject) => {
throw new Error('promise error');
});
setTimeout(function() {
expect(hookSpy.calls.count()).toBe(2);

View File

@ -16,7 +16,9 @@ describe('node timer', () => {
expect(value).toEqual('value');
done();
},
error => { fail(`should not be here with error: ${error}.`); });
error => {
fail(`should not be here with error: ${error}.`);
});
});
it('util.promisify should work with setImmediate', (done: DoneFn) => {
@ -26,6 +28,8 @@ describe('node timer', () => {
expect(value).toEqual('value');
done();
},
error => { fail(`should not be here with error: ${error}.`); });
error => {
fail(`should not be here with error: ${error}.`);
});
});
});

View File

@ -14,34 +14,43 @@ describe('Zone.js npm_package', () => {
path.dirname(require.resolve('angular/packages/zone.js/npm_package/package.json')))});
describe('misc root files', () => {
describe('README.md', () => {
it('should have a README.md file with basic info',
() => { expect(shx.cat('README.md')).toContain(`Zone`); });
it('should have a README.md file with basic info', () => {
expect(shx.cat('README.md')).toContain(`Zone`);
});
});
});
describe('primary entry-point', () => {
const packageJson = 'package.json';
it('should have a package.json file',
() => { expect(shx.grep('"name":', packageJson)).toContain(`zone.js`); });
it('should have a package.json file', () => {
expect(shx.grep('"name":', packageJson)).toContain(`zone.js`);
});
it('should contain correct version number with the PLACEHOLDER string replaced', () => {
expect(shx.grep('"version":', packageJson)).toMatch(/\d+\.\d+\.\d+(?!-PLACEHOLDER)/);
});
it('should contain module resolution mappings',
() => { expect(shx.grep('"main":', packageJson)).toContain(`dist/zone-node.js`); });
it('should contain module resolution mappings', () => {
expect(shx.grep('"main":', packageJson)).toContain(`dist/zone-node.js`);
});
});
describe('check dist folder', () => {
beforeEach(() => { shx.cd('./dist'); });
afterEach(() => { shx.cd('../'); });
beforeEach(() => {
shx.cd('./dist');
});
afterEach(() => {
shx.cd('../');
});
describe('typescript support', () => {
it('should have an zone.js.d.ts file',
() => { expect(shx.cat('zone.js.d.ts')).toContain('declare const'); });
it('should have an zone.js.d.ts file', () => {
expect(shx.cat('zone.js.d.ts')).toContain('declare const');
});
it('should have an zone.api.extensions.ts file',
() => { expect(shx.cat('zone.api.extensions.ts')).toContain('EventTarget'); });
it('should have an zone.api.extensions.ts file', () => {
expect(shx.cat('zone.api.extensions.ts')).toContain('EventTarget');
});
it('should have an zone.configurations.api.ts file', () => {
expect(shx.cat('zone.configurations.api.ts')).toContain('ZoneGlobalConfigurations');
@ -49,8 +58,9 @@ describe('Zone.js npm_package', () => {
});
describe('closure', () => {
it('should contain externs',
() => { expect(shx.cat('zone_externs.js')).toContain('Externs for zone.js'); });
it('should contain externs', () => {
expect(shx.cat('zone_externs.js')).toContain('Externs for zone.js');
});
});
describe('rxjs patch', () => {
@ -61,18 +71,22 @@ describe('Zone.js npm_package', () => {
});
describe('es5', () => {
it('zone.js(es5) should not contain es6 spread code',
() => { expect(shx.cat('zone.js')).not.toContain('let value of values'); });
it('zone.js(es5) should not contain es6 spread code', () => {
expect(shx.cat('zone.js')).not.toContain('let value of values');
});
it('zone.js(es5) should not contain source map comment',
() => { expect(shx.cat('zone.js')).not.toContain('sourceMappingURL'); });
it('zone.js(es5) should not contain source map comment', () => {
expect(shx.cat('zone.js')).not.toContain('sourceMappingURL');
});
});
describe('es2015', () => {
it('zone-evergreen.js(es2015) should contain es6 code',
() => { expect(shx.cat('zone-evergreen.js')).toContain('let value of values'); });
it('zone.js(es5) should not contain source map comment',
() => { expect(shx.cat('zone-evergreen.js')).not.toContain('sourceMappingURL'); });
it('zone-evergreen.js(es2015) should contain es6 code', () => {
expect(shx.cat('zone-evergreen.js')).toContain('let value of values');
});
it('zone.js(es5) should not contain source map comment', () => {
expect(shx.cat('zone-evergreen.js')).not.toContain('sourceMappingURL');
});
});
describe('dist file list', () => {

View File

@ -25,7 +25,9 @@ describe(
var testStore =
db.transaction('test-object-store', 'readwrite').objectStore('test-object-store');
testStore.add({key: 1, data: 'Test data'});
testStore.transaction.oncomplete = function() { done(); }
testStore.transaction.oncomplete = function() {
done();
}
};
};
});
@ -34,7 +36,9 @@ describe(
db.close();
var openRequest = indexedDB.deleteDatabase('_zone_testdb');
openRequest.onsuccess = function(event) { done(); };
openRequest.onsuccess = function(event) {
done();
};
});
describe('IDBRequest', function() {

View File

@ -6,75 +6,79 @@
* found in the LICENSE file at https://angular.io/license
*/
(function(_global) {
var testRunner = _global['__zone_symbol__testRunner'];
var mark = _global['__zone_symbol__mark'];
var measure = _global['__zone_symbol__measure'];
var zone = _global['__zone_symbol__callbackZone'];
var button;
var testTarget = {
title: 'addEventListener',
times: 10,
before: function() {
button = document.createElement('button');
document.body.appendChild(button);
_global['__zone_symbol__callbackContext'].measureName = 'addEventListener_callback';
_global['__zone_symbol__callbackContext'].type = 'eventTask';
_global['__zone_symbol__callbackContext'].source = 'addEventListener';
},
after: function() {
document.body.removeChild(button);
button = null;
},
apis: [
{
supportClear: true,
method: 'addEventListener',
nativeMethod: '__zone_symbol__addEventListener',
clearMethod: 'removeEventListener',
nativeClearMethod: '__zone_symbol__removeEventListener',
run: function() {
var listener = function() {};
button.addEventListener('click', listener);
return listener;
},
runClear: function(timerId) { return button.removeEventListener('click', timerId); },
nativeRun: function() {
var listener = function() {};
button['__zone_symbol__addEventListener']('click', listener);
return listener;
},
nativeRunClear: function(timerId) {
return button['__zone_symbol__removeEventListener']('click', timerId);
}
var testRunner = _global['__zone_symbol__testRunner'];
var mark = _global['__zone_symbol__mark'];
var measure = _global['__zone_symbol__measure'];
var zone = _global['__zone_symbol__callbackZone'];
var button;
var testTarget = {
title: 'addEventListener',
times: 10,
before: function() {
button = document.createElement('button');
document.body.appendChild(button);
_global['__zone_symbol__callbackContext'].measureName = 'addEventListener_callback';
_global['__zone_symbol__callbackContext'].type = 'eventTask';
_global['__zone_symbol__callbackContext'].source = 'addEventListener';
},
after: function() {
document.body.removeChild(button);
button = null;
},
apis: [
{
supportClear: true,
method: 'addEventListener',
nativeMethod: '__zone_symbol__addEventListener',
clearMethod: 'removeEventListener',
nativeClearMethod: '__zone_symbol__removeEventListener',
run: function() {
var listener = function() {};
button.addEventListener('click', listener);
return listener;
},
{
isCallback: true,
supportClear: false,
method: 'addEventListener_callback',
nativeMethod: 'native_addEventListener_callback',
run: function() {
var listener = function() {};
zone.run(function() { button.addEventListener('click', listener); });
var event = document.createEvent('Event');
event.initEvent('click', true, true);
button.dispatchEvent(event);
button.removeEventListener('click', listener);
},
nativeRun: function() {
var func = function() {};
var listener = function() {
mark('native_addEventListener_callback');
func.apply(this, arguments);
measure('native_addEventListener_callback', 'native_addEventListener_callback');
};
button['__zone_symbol__addEventListener']('click', listener);
var event = document.createEvent('Event');
event.initEvent('click', true, true);
button.dispatchEvent(event);
button['__zone_symbol__removeEventListener']('click', listener);
}
runClear: function(timerId) {
return button.removeEventListener('click', timerId);
},
nativeRun: function() {
var listener = function() {};
button['__zone_symbol__addEventListener']('click', listener);
return listener;
},
nativeRunClear: function(timerId) {
return button['__zone_symbol__removeEventListener']('click', timerId);
}
],
};
return testRunner(testTarget);
},
{
isCallback: true,
supportClear: false,
method: 'addEventListener_callback',
nativeMethod: 'native_addEventListener_callback',
run: function() {
var listener = function() {};
zone.run(function() {
button.addEventListener('click', listener);
});
var event = document.createEvent('Event');
event.initEvent('click', true, true);
button.dispatchEvent(event);
button.removeEventListener('click', listener);
},
nativeRun: function() {
var func = function() {};
var listener = function() {
mark('native_addEventListener_callback');
func.apply(this, arguments);
measure('native_addEventListener_callback', 'native_addEventListener_callback');
};
button['__zone_symbol__addEventListener']('click', listener);
var event = document.createEvent('Event');
event.initEvent('click', true, true);
button.dispatchEvent(event);
button['__zone_symbol__removeEventListener']('click', listener);
}
}
],
};
return testRunner(testTarget);
}(typeof window === 'undefined' ? global : window));

View File

@ -6,279 +6,290 @@
* found in the LICENSE file at https://angular.io/license
*/
(function(_global) {
var allTasks = _global['__zone_symbol__performance_tasks'];
if (!allTasks) {
allTasks = _global['__zone_symbol__performance_tasks'] = [];
}
var allTasks = _global['__zone_symbol__performance_tasks'];
if (!allTasks) {
allTasks = _global['__zone_symbol__performance_tasks'] = [];
}
var mark = _global['__zone_symbol__mark'] = function(name) {
performance && performance['mark'] && performance['mark'](name);
};
var mark = _global['__zone_symbol__mark'] = function(name) {
performance && performance['mark'] && performance['mark'](name);
};
var measure = _global['__zone_symbol__measure'] = function(name, label) {
performance && performance['measure'] && performance['measure'](name, label);
};
var measure = _global['__zone_symbol__measure'] = function(name, label) {
performance && performance['measure'] && performance['measure'](name, label);
};
var getEntries = _global['__zone_symbol__getEntries'] = function() {
performance && performance['getEntries'] && performance['getEntries']();
};
var getEntries = _global['__zone_symbol__getEntries'] = function() {
performance && performance['getEntries'] && performance['getEntries']();
};
var getEntriesByName = _global['__zone_symbol__getEntriesByName'] = function(name) {
return performance && performance['getEntriesByName'] && performance['getEntriesByName'](name);
};
var getEntriesByName = _global['__zone_symbol__getEntriesByName'] = function(name) {
return performance && performance['getEntriesByName'] && performance['getEntriesByName'](name);
};
var clearMarks = _global['__zone_symbol__clearMarks'] = function(name) {
return performance && performance['clearMarks'] && performance['clearMarks'](name);
};
var clearMarks = _global['__zone_symbol__clearMarks'] = function(name) {
return performance && performance['clearMarks'] && performance['clearMarks'](name);
};
var clearMeasures = _global['__zone_symbol__clearMeasures'] = function(name) {
return performance && performance['clearMeasures'] && performance['clearMeasures'](name);
};
var clearMeasures = _global['__zone_symbol__clearMeasures'] = function(name) {
return performance && performance['clearMeasures'] && performance['clearMeasures'](name);
};
var averageMeasures = _global['__zone_symbol__averageMeasures'] = function(name, times) {
var sum = _global['__zone_symbol__getEntriesByName'](name)
.filter(function(m) { return m.entryType === 'measure'; })
.map(function(m) { return m.duration })
.reduce(function(sum, d) { return sum + d; });
return sum / times;
};
var averageMeasures = _global['__zone_symbol__averageMeasures'] = function(name, times) {
var sum = _global['__zone_symbol__getEntriesByName'](name)
.filter(function(m) {
return m.entryType === 'measure';
})
.map(function(m) {
return m.duration
})
.reduce(function(sum, d) {
return sum + d;
});
return sum / times;
};
var serialPromise = _global['__zone_symbol__serialPromise'] =
function(promiseFactories) {
let lastPromise;
for (var i = 0; i < promiseFactories.length; i++) {
var promiseFactory = promiseFactories[i];
if (!lastPromise) {
lastPromise = promiseFactory.factory(promiseFactory.context).then(function(value) {
return {value, idx: 0};
});
} else {
lastPromise = lastPromise.then(function(ctx) {
var idx = ctx.idx + 1;
var promiseFactory = promiseFactories[idx];
return promiseFactory.factory(promiseFactory.context).then(function(value) {
return {value, idx};
});
});
}
}
return lastPromise;
}
var callbackContext = _global['__zone_symbol__callbackContext'] = {};
var zone = _global['__zone_symbol__callbackZone'] = Zone.current.fork({
name: 'callback',
onScheduleTask: function(delegate, curr, target, task) {
delegate.scheduleTask(target, task);
if (task.type === callbackContext.type &&
task.source.indexOf(callbackContext.source) !== -1) {
if (task.type === 'macroTask' || task.type === 'eventTask') {
var invoke = task.invoke;
task.invoke = function() {
mark(callbackContext.measureName);
var result = invoke.apply(this, arguments);
measure(callbackContext.measureName, callbackContext.measureName);
return result;
};
} else if (task.type === 'microTask') {
var callback = task.callback;
task.callback = function() {
mark(callbackContext.measureName);
var result = callback.apply(this, arguments);
measure(callbackContext.measureName, callbackContext.measureName);
return result;
};
}
}
return task;
}
});
var runAsync = _global['__zone_symbol__runAsync'] = function(testFn, times, _delay) {
var delay = _delay | 100;
const fnPromise = function() {
return new Promise(function(res, rej) {
// run test with a setTimeout
// several times to decrease measurement error
setTimeout(function() { testFn().then(function() { res(); }); }, delay);
var serialPromise = _global['__zone_symbol__serialPromise'] =
function(promiseFactories) {
let lastPromise;
for (var i = 0; i < promiseFactories.length; i++) {
var promiseFactory = promiseFactories[i];
if (!lastPromise) {
lastPromise = promiseFactory.factory(promiseFactory.context).then(function(value) {
return {value, idx: 0};
});
};
var promiseFactories = [];
for (var i = 0; i < times; i++) {
promiseFactories.push({factory: fnPromise, context: {}});
}
return serialPromise(promiseFactories);
};
var getNativeMethodName = function(nativeWithSymbol) {
return nativeWithSymbol.replace('__zone_symbol__', 'native_');
};
function testAddRemove(api, count) {
var timerId = [];
var name = api.method;
mark(name);
for (var i = 0; i < count; i++) {
timerId.push(api.run());
}
measure(name, name);
if (api.supportClear) {
var clearName = api.clearMethod;
mark(clearName);
for (var i = 0; i < count; i++) {
api.runClear(timerId[i]);
}
measure(clearName, clearName);
}
timerId = [];
var nativeName = getNativeMethodName(api.nativeMethod);
mark(nativeName);
for (var i = 0; i < count; i++) {
timerId.push(api.nativeRun());
}
measure(nativeName, nativeName);
if (api.supportClear) {
var nativeClearName = getNativeMethodName(api.nativeClearMethod);
mark(nativeClearName);
for (var i = 0; i < count; i++) {
api.nativeRunClear(timerId[i]);
}
measure(nativeClearName, nativeClearName);
}
return Promise.resolve(1);
}
function testCallback(api, count) {
var promises = [Promise.resolve(1)];
for (var i = 0; i < count; i++) {
var r = api.run();
if (api.isAsync) {
promises.push(r);
}
}
for (var i = 0; i < count; i++) {
var r = api.nativeRun();
if (api.isAsync) {
promises.push(r);
}
}
return Promise.all(promises);
}
function measureCallback(api, ops) {
var times = ops.times;
var displayText = ops.displayText;
var rawData = ops.rawData;
var summary = ops.summary;
var name = api.method;
var nativeName = getNativeMethodName(api.nativeMethod);
var measure = averageMeasures(name, times);
var nativeMeasure = averageMeasures(nativeName, times);
displayText += `- ${name} costs ${measure} ms\n`;
displayText += `- ${nativeName} costs ${nativeMeasure} ms\n`;
var absolute = Math.floor(1000 * (measure - nativeMeasure)) / 1000;
displayText += `# ${name} is ${absolute}ms slower than ${nativeName}\n`;
rawData[name + '_measure'] = measure;
rawData[nativeName + '_measure'] = nativeMeasure;
summary[name] = absolute + 'ms';
}
function measureAddRemove(api, ops) {
var times = ops.times;
var displayText = ops.displayText;
var rawData = ops.rawData;
var summary = ops.summary;
var name = api.method;
var nativeName = getNativeMethodName(api.nativeMethod);
var measure = averageMeasures(name, times);
var nativeMeasure = averageMeasures(nativeName, times);
displayText += `- ${name} costs ${measure} ms\n`;
displayText += `- ${nativeName} costs ${nativeMeasure} ms\n`;
var percent = Math.floor(100 * (measure - nativeMeasure) / nativeMeasure);
displayText += `# ${name} is ${percent}% slower than ${nativeName}\n`;
rawData[name + '_measure'] = measure;
rawData[nativeName + '_measure'] = nativeMeasure;
summary[name] = percent + '%';
if (api.supportClear) {
var clearName = api.clearMethod;
var nativeClearName = getNativeMethodName(api.nativeClearMethod);
var clearMeasure = averageMeasures(clearName, times);
var nativeClearMeasure = averageMeasures(nativeClearName, times);
var clearPercent = Math.floor(100 * (clearMeasure - nativeClearMeasure) / nativeClearMeasure);
displayText += `- ${clearName} costs ${clearMeasure} ms\n`;
displayText += `- ${nativeClearName} costs ${nativeClearMeasure} ms\n`;
displayText += `# ${clearName} is ${clearPercent}% slower than ${nativeClearName}\n`;
rawData[clearName + '_measure'] = clearMeasure;
rawData[nativeClearName + '_measure'] = nativeClearMeasure;
summary[clearName] = clearPercent + '%';
}
}
var testRunner = _global['__zone_symbol__testRunner'] = function(testTarget) {
var title = testTarget.title;
var apis = testTarget.apis;
var methods = apis.reduce(function(acc, api) {
return acc.concat([
api.method, api.nativeMethod
].concat(api.supportClear ? [api.clearMethod, api.nativeClearMethod] : [])
.concat[api.method + '_callback', api.nativeMethod + '_callback']);
}, []);
var times = testTarget.times;
allTasks.push({
title: title,
cleanFn: function() {
methods.forEach(function(m) {
clearMarks(m);
clearMeasures(m);
} else {
lastPromise = lastPromise.then(function(ctx) {
var idx = ctx.idx + 1;
var promiseFactory = promiseFactories[idx];
return promiseFactory.factory(promiseFactory.context).then(function(value) {
return {value, idx};
});
},
before: function() { testTarget.before && testTarget.before(); },
after: function() { testTarget.after && testTarget.after(); },
testFn: function() {
var count = typeof testTarget.count === 'number' ? testTarget.count : 10000;
var times = typeof testTarget.times === 'number' ? testTarget.times : 5;
});
}
}
return lastPromise;
}
var testFunction = function() {
var promises = [];
apis.forEach(function(api) {
if (api.isCallback) {
var r = testCallback(api, count / 100);
promises.push(api.isAsync ? r : Promise.resolve(1));
} else {
var r = testAddRemove(api, count);
promises.push[api.isAsync ? r : Promise.resolve(1)];
}
});
return Promise.all(promises);
var callbackContext = _global['__zone_symbol__callbackContext'] = {};
var zone = _global['__zone_symbol__callbackZone'] = Zone.current.fork({
name: 'callback',
onScheduleTask: function(delegate, curr, target, task) {
delegate.scheduleTask(target, task);
if (task.type === callbackContext.type && task.source.indexOf(callbackContext.source) !== -1) {
if (task.type === 'macroTask' || task.type === 'eventTask') {
var invoke = task.invoke;
task.invoke = function() {
mark(callbackContext.measureName);
var result = invoke.apply(this, arguments);
measure(callbackContext.measureName, callbackContext.measureName);
return result;
};
} else if (task.type === 'microTask') {
var callback = task.callback;
task.callback = function() {
mark(callbackContext.measureName);
var result = callback.apply(this, arguments);
measure(callbackContext.measureName, callbackContext.measureName);
return result;
};
return runAsync(testFunction, times).then(function() {
var displayText = `running ${count} times\n`;
var rawData = {};
var summary = {};
apis.forEach(function(api) {
if (api.isCallback) {
measureCallback(api, {times, displayText, rawData, summary});
} else {
measureAddRemove(api, {times, displayText, rawData, summary});
}
});
return Promise.resolve({displayText: displayText, rawData: rawData, summary: summary});
});
}
}
return task;
}
});
var runAsync = _global['__zone_symbol__runAsync'] = function(testFn, times, _delay) {
var delay = _delay | 100;
const fnPromise = function() {
return new Promise(function(res, rej) {
// run test with a setTimeout
// several times to decrease measurement error
setTimeout(function() {
testFn().then(function() {
res();
});
}, delay);
});
};
var promiseFactories = [];
for (var i = 0; i < times; i++) {
promiseFactories.push({factory: fnPromise, context: {}});
}
return serialPromise(promiseFactories);
};
var getNativeMethodName = function(nativeWithSymbol) {
return nativeWithSymbol.replace('__zone_symbol__', 'native_');
};
function testAddRemove(api, count) {
var timerId = [];
var name = api.method;
mark(name);
for (var i = 0; i < count; i++) {
timerId.push(api.run());
}
measure(name, name);
if (api.supportClear) {
var clearName = api.clearMethod;
mark(clearName);
for (var i = 0; i < count; i++) {
api.runClear(timerId[i]);
}
measure(clearName, clearName);
}
timerId = [];
var nativeName = getNativeMethodName(api.nativeMethod);
mark(nativeName);
for (var i = 0; i < count; i++) {
timerId.push(api.nativeRun());
}
measure(nativeName, nativeName);
if (api.supportClear) {
var nativeClearName = getNativeMethodName(api.nativeClearMethod);
mark(nativeClearName);
for (var i = 0; i < count; i++) {
api.nativeRunClear(timerId[i]);
}
measure(nativeClearName, nativeClearName);
}
return Promise.resolve(1);
}
function testCallback(api, count) {
var promises = [Promise.resolve(1)];
for (var i = 0; i < count; i++) {
var r = api.run();
if (api.isAsync) {
promises.push(r);
}
}
for (var i = 0; i < count; i++) {
var r = api.nativeRun();
if (api.isAsync) {
promises.push(r);
}
}
return Promise.all(promises);
}
function measureCallback(api, ops) {
var times = ops.times;
var displayText = ops.displayText;
var rawData = ops.rawData;
var summary = ops.summary;
var name = api.method;
var nativeName = getNativeMethodName(api.nativeMethod);
var measure = averageMeasures(name, times);
var nativeMeasure = averageMeasures(nativeName, times);
displayText += `- ${name} costs ${measure} ms\n`;
displayText += `- ${nativeName} costs ${nativeMeasure} ms\n`;
var absolute = Math.floor(1000 * (measure - nativeMeasure)) / 1000;
displayText += `# ${name} is ${absolute}ms slower than ${nativeName}\n`;
rawData[name + '_measure'] = measure;
rawData[nativeName + '_measure'] = nativeMeasure;
summary[name] = absolute + 'ms';
}
function measureAddRemove(api, ops) {
var times = ops.times;
var displayText = ops.displayText;
var rawData = ops.rawData;
var summary = ops.summary;
var name = api.method;
var nativeName = getNativeMethodName(api.nativeMethod);
var measure = averageMeasures(name, times);
var nativeMeasure = averageMeasures(nativeName, times);
displayText += `- ${name} costs ${measure} ms\n`;
displayText += `- ${nativeName} costs ${nativeMeasure} ms\n`;
var percent = Math.floor(100 * (measure - nativeMeasure) / nativeMeasure);
displayText += `# ${name} is ${percent}% slower than ${nativeName}\n`;
rawData[name + '_measure'] = measure;
rawData[nativeName + '_measure'] = nativeMeasure;
summary[name] = percent + '%';
if (api.supportClear) {
var clearName = api.clearMethod;
var nativeClearName = getNativeMethodName(api.nativeClearMethod);
var clearMeasure = averageMeasures(clearName, times);
var nativeClearMeasure = averageMeasures(nativeClearName, times);
var clearPercent = Math.floor(100 * (clearMeasure - nativeClearMeasure) / nativeClearMeasure);
displayText += `- ${clearName} costs ${clearMeasure} ms\n`;
displayText += `- ${nativeClearName} costs ${nativeClearMeasure} ms\n`;
displayText += `# ${clearName} is ${clearPercent}% slower than ${nativeClearName}\n`;
rawData[clearName + '_measure'] = clearMeasure;
rawData[nativeClearName + '_measure'] = nativeClearMeasure;
summary[clearName] = clearPercent + '%';
}
}
var testRunner = _global['__zone_symbol__testRunner'] = function(testTarget) {
var title = testTarget.title;
var apis = testTarget.apis;
var methods = apis.reduce(function(acc, api) {
return acc.concat([api.method, api.nativeMethod]
.concat(api.supportClear ? [api.clearMethod, api.nativeClearMethod] : [])
.concat[api.method + '_callback', api.nativeMethod + '_callback']);
}, []);
var times = testTarget.times;
allTasks.push({
title: title,
cleanFn: function() {
methods.forEach(function(m) {
clearMarks(m);
clearMeasures(m);
});
},
before: function() {
testTarget.before && testTarget.before();
},
after: function() {
testTarget.after && testTarget.after();
},
testFn: function() {
var count = typeof testTarget.count === 'number' ? testTarget.count : 10000;
var times = typeof testTarget.times === 'number' ? testTarget.times : 5;
var testFunction = function() {
var promises = [];
apis.forEach(function(api) {
if (api.isCallback) {
var r = testCallback(api, count / 100);
promises.push(api.isAsync ? r : Promise.resolve(1));
} else {
var r = testAddRemove(api, count);
promises.push[api.isAsync ? r : Promise.resolve(1)];
}
});
return Promise.all(promises);
};
return runAsync(testFunction, times).then(function() {
var displayText = `running ${count} times\n`;
var rawData = {};
var summary = {};
apis.forEach(function(api) {
if (api.isCallback) {
measureCallback(api, {times, displayText, rawData, summary});
} else {
measureAddRemove(api, {times, displayText, rawData, summary});
}
});
return Promise.resolve({displayText: displayText, rawData: rawData, summary: summary});
});
}
});
};
}(typeof window === 'undefined' ? global : window));

View File

@ -6,151 +6,157 @@
* found in the LICENSE file at https://angular.io/license
*/
(function(_global) {
var options;
var options;
function setAttributes(elem, attrs) {
if (!attrs) {
return;
}
Object.keys(attrs).forEach(function(key) { elem.setAttribute(key, attrs[key]); });
function setAttributes(elem, attrs) {
if (!attrs) {
return;
}
Object.keys(attrs).forEach(function(key) {
elem.setAttribute(key, attrs[key]);
});
}
function createLi(attrs) {
var li = document.createElement('li');
setAttributes(li, attrs);
return li;
}
function createLi(attrs) {
var li = document.createElement('li');
setAttributes(li, attrs);
return li;
}
function createLabel(attrs) {
var label = document.createElement('label');
setAttributes(label, attrs);
return label;
}
function createLabel(attrs) {
var label = document.createElement('label');
setAttributes(label, attrs);
return label;
}
function createButton(attrs, innerHtml) {
var button = document.createElement('button');
button.innerHTML = innerHtml;
setAttributes(button, attrs);
return button;
}
function createButton(attrs, innerHtml) {
var button = document.createElement('button');
button.innerHTML = innerHtml;
setAttributes(button, attrs);
return button;
}
function createTextNode(text) { return document.createTextNode(text); }
function createTextNode(text) {
return document.createTextNode(text);
}
function createCheckbox(attrs, checked) {
var checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.checked = !!checked;
setAttributes(checkbox, attrs);
return checkbox;
}
function createCheckbox(attrs, checked) {
var checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.checked = !!checked;
setAttributes(checkbox, attrs);
return checkbox;
}
function createUl(attrs) {
var ul = document.createElement('ul');
setAttributes(ul, attrs);
return ul;
}
function createUl(attrs) {
var ul = document.createElement('ul');
setAttributes(ul, attrs);
return ul;
}
var serailPromise = _global['__zone_symbol__serialPromise'];
_global['__zone_symbol__testTargetsUIBuild'] = function(_options) {
options = _options;
var allButton = createButton({}, 'test selected');
allButton.addEventListener('click', function() {
var promiseFactories = [];
for (var i = 0; i < options.tests.length; i++) {
var checkbox = document.getElementById('testcheck' + i);
if (checkbox.checked) {
var test = options.tests[i];
promiseFactories.push({
factory: function(context) { return doTest(context.test, context.idx); },
context: {test: test, idx: i}
});
}
}
serailPromise(promiseFactories);
});
options.targetContainer.appendChild(allButton);
var ul = createUl();
options.targetContainer.appendChild(ul);
var serailPromise = _global['__zone_symbol__serialPromise'];
_global['__zone_symbol__testTargetsUIBuild'] = function(_options) {
options = _options;
var allButton = createButton({}, 'test selected');
allButton.addEventListener('click', function() {
var promiseFactories = [];
for (var i = 0; i < options.tests.length; i++) {
buildTestItemUI(ul, options.tests[i], i);
}
};
function buildTestItemUI(ul, testItem, idx) {
var li = createLi({'id': 'test' + idx});
var button = createButton({'id': 'buttontest' + idx}, 'begin test');
buildButtonClickHandler(button);
var title = createTextNode(options.tests[idx].title);
var checkbox = createCheckbox({'id': 'testcheck' + idx}, true);
var label = createLabel({'id': 'label' + idx});
li.appendChild(checkbox);
li.appendChild(title);
li.appendChild(button);
li.appendChild(label);
ul.appendChild(li);
}
function processTestResult(test, result, id) {
var split = result.displayText.split('\n');
options.jsonResult[test.title] = result.rawData;
options.jsonContainer.innerHTML =
'<div style="display:none">' + JSON.stringify(options.jsonResult) + '</div>';
var summary = result.summary;
var row = options.resultsContainer.insertRow();
var cell = row.insertCell();
cell.innerHTML = test.title;
cell.rowSpan = Object.keys(summary).length;
var idx = 0;
Object.keys(summary).forEach(function(key) {
var tableRow = row;
if (idx !== 0) {
tableRow = options.resultsContainer.insertRow();
var checkbox = document.getElementById('testcheck' + i);
if (checkbox.checked) {
var test = options.tests[i];
promiseFactories.push({
factory: function(context) {
return doTest(context.test, context.idx);
},
context: {test: test, idx: i}
});
}
var keyCell = tableRow.insertCell();
keyCell.innerHTML = key;
var valueCell = tableRow.insertCell();
valueCell.innerHTML = summary[key];
idx++;
});
var testLi = document.getElementById('test' + id);
for (var j = 0; j < split.length; j++) {
var br = document.createElement('br');
var s = document.createTextNode(split[j]);
testLi.appendChild(br);
testLi.appendChild(s);
}
}
serailPromise(promiseFactories);
});
options.targetContainer.appendChild(allButton);
function doTest(test, id) {
test.cleanFn();
test.before();
var button = document.getElementById('buttontest' + id);
button.setAttribute('enabled', 'false');
var label = document.getElementById('label' + id);
label.innerHTML = 'Testing';
return test.testFn().then(function(result) {
processTestResult(test, result, id);
test.after();
label.innerHTML = 'Finished';
button.setAttribute('enabled', 'true');
});
}
var ul = createUl();
options.targetContainer.appendChild(ul);
function buildButtonClickHandler(button) {
button.onclick = function(event) {
var target = event.target;
var id = target.getAttribute('id').substring(10);
var test = options.tests[id];
doTest(test, id);
};
for (var i = 0; i < options.tests.length; i++) {
buildTestItemUI(ul, options.tests[i], i);
}
};
function buildTestItemUI(ul, testItem, idx) {
var li = createLi({'id': 'test' + idx});
var button = createButton({'id': 'buttontest' + idx}, 'begin test');
buildButtonClickHandler(button);
var title = createTextNode(options.tests[idx].title);
var checkbox = createCheckbox({'id': 'testcheck' + idx}, true);
var label = createLabel({'id': 'label' + idx});
li.appendChild(checkbox);
li.appendChild(title);
li.appendChild(button);
li.appendChild(label);
ul.appendChild(li);
}
function processTestResult(test, result, id) {
var split = result.displayText.split('\n');
options.jsonResult[test.title] = result.rawData;
options.jsonContainer.innerHTML =
'<div style="display:none">' + JSON.stringify(options.jsonResult) + '</div>';
var summary = result.summary;
var row = options.resultsContainer.insertRow();
var cell = row.insertCell();
cell.innerHTML = test.title;
cell.rowSpan = Object.keys(summary).length;
var idx = 0;
Object.keys(summary).forEach(function(key) {
var tableRow = row;
if (idx !== 0) {
tableRow = options.resultsContainer.insertRow();
}
var keyCell = tableRow.insertCell();
keyCell.innerHTML = key;
var valueCell = tableRow.insertCell();
valueCell.innerHTML = summary[key];
idx++;
});
var testLi = document.getElementById('test' + id);
for (var j = 0; j < split.length; j++) {
var br = document.createElement('br');
var s = document.createTextNode(split[j]);
testLi.appendChild(br);
testLi.appendChild(s);
}
}
function doTest(test, id) {
test.cleanFn();
test.before();
var button = document.getElementById('buttontest' + id);
button.setAttribute('enabled', 'false');
var label = document.getElementById('label' + id);
label.innerHTML = 'Testing';
return test.testFn().then(function(result) {
processTestResult(test, result, id);
test.after();
label.innerHTML = 'Finished';
button.setAttribute('enabled', 'true');
});
}
function buildButtonClickHandler(button) {
button.onclick = function(event) {
var target = event.target;
var id = target.getAttribute('id').substring(10);
var test = options.tests[id];
doTest(test, id);
};
}
}(typeof window === 'undefined' ? global : window));

View File

@ -6,52 +6,58 @@
* found in the LICENSE file at https://angular.io/license
*/
(function(_global) {
var mark = _global['__zone_symbol__mark'];
var measure = _global['__zone_symbol__measure'];
var testRunner = _global['__zone_symbol__testRunner'];
var zone = _global['__zone_symbol__callbackZone'];
var nativePromise = _global['__zone_symbol__Promise'];
var resolved = Promise.resolve(1);
var nativeResolved = nativePromise.resolve(1);
var testTarget = {
title: 'Promise',
times: 10,
before: function() {
_global['__zone_symbol__callbackContext'].measureName = 'Promise_callback';
_global['__zone_symbol__callbackContext'].type = 'microTask';
_global['__zone_symbol__callbackContext'].source = 'Promise.then';
},
apis: [
{
supportClear: false,
isAsync: true,
method: 'Promise',
nativeMethod: 'native_Promise',
run: function() { return resolved.then(function() {}); },
nativeRun: function() { return nativeResolved['__zone_symbol__then'](function() {}); },
var mark = _global['__zone_symbol__mark'];
var measure = _global['__zone_symbol__measure'];
var testRunner = _global['__zone_symbol__testRunner'];
var zone = _global['__zone_symbol__callbackZone'];
var nativePromise = _global['__zone_symbol__Promise'];
var resolved = Promise.resolve(1);
var nativeResolved = nativePromise.resolve(1);
var testTarget = {
title: 'Promise',
times: 10,
before: function() {
_global['__zone_symbol__callbackContext'].measureName = 'Promise_callback';
_global['__zone_symbol__callbackContext'].type = 'microTask';
_global['__zone_symbol__callbackContext'].source = 'Promise.then';
},
apis: [
{
supportClear: false,
isAsync: true,
method: 'Promise',
nativeMethod: 'native_Promise',
run: function() {
return resolved.then(function() {});
},
{
isCallback: true,
isAsync: true,
supportClear: false,
method: 'Promise_callback',
nativeMethod: 'native_Promise_callback',
run: function() {
return zone.run(function() {
return Promise.resolve(1).then(function(v) { return v; });
nativeRun: function() {
return nativeResolved['__zone_symbol__then'](function() {});
},
},
{
isCallback: true,
isAsync: true,
supportClear: false,
method: 'Promise_callback',
nativeMethod: 'native_Promise_callback',
run: function() {
return zone.run(function() {
return Promise.resolve(1).then(function(v) {
return v;
});
},
nativeRun: function() {
var func = function() {};
return _global['__zone_symbol__Promise'].resolve(1)['__zone_symbol__then'](function() {
mark('native_Promise_callback');
var result = func.apply(this, arguments);
measure('native_Promise_callback', 'native_Promise_callback');
return result;
});
}
});
},
nativeRun: function() {
var func = function() {};
return _global['__zone_symbol__Promise'].resolve(1)['__zone_symbol__then'](function() {
mark('native_Promise_callback');
var result = func.apply(this, arguments);
measure('native_Promise_callback', 'native_Promise_callback');
return result;
});
}
],
};
return testRunner(testTarget);
}
],
};
return testRunner(testTarget);
}(typeof window === 'undefined' ? global : window));

View File

@ -6,51 +6,62 @@
* found in the LICENSE file at https://angular.io/license
*/
(function(_global) {
var mark = _global['__zone_symbol__mark'];
var measure = _global['__zone_symbol__measure'];
var zone = _global['__zone_symbol__callbackZone'];
var testRunner = _global['__zone_symbol__testRunner'];
var raf = _global['requestAnimationFrame'];
var cancel = _global['cancelAnimationFrame'];
var nativeRaf = _global['__zone_symbol__requestAnimationFrame'];
var nativeCancel = _global['__zone_symbol__cancelAnimationFrame'];
var testTarget = {
title: 'requestAnimationFrame',
times: 10,
before: function() {
_global['__zone_symbol__callbackContext'].measureName = 'requestAnimationFrame_callback';
_global['__zone_symbol__callbackContext'].type = 'macroTask';
_global['__zone_symbol__callbackContext'].source = 'requestAnimationFrame';
},
apis: [
{
supportClear: true,
method: 'requestAnimationFrame',
nativeMethod: '__zone_symbol__requestAnimationFrame',
clearMethod: 'cancelAnimationFrame',
nativeClearMethod: '__zone_symbol__cancelAnimationFrame',
run: function() { return raf(function() {}); },
runClear: function(timerId) { return cancel(timerId); },
nativeRun: function() { return nativeRaf(function() {}); },
nativeRunClear: function(timerId) { return nativeCancel(timerId); }
var mark = _global['__zone_symbol__mark'];
var measure = _global['__zone_symbol__measure'];
var zone = _global['__zone_symbol__callbackZone'];
var testRunner = _global['__zone_symbol__testRunner'];
var raf = _global['requestAnimationFrame'];
var cancel = _global['cancelAnimationFrame'];
var nativeRaf = _global['__zone_symbol__requestAnimationFrame'];
var nativeCancel = _global['__zone_symbol__cancelAnimationFrame'];
var testTarget = {
title: 'requestAnimationFrame',
times: 10,
before: function() {
_global['__zone_symbol__callbackContext'].measureName = 'requestAnimationFrame_callback';
_global['__zone_symbol__callbackContext'].type = 'macroTask';
_global['__zone_symbol__callbackContext'].source = 'requestAnimationFrame';
},
apis: [
{
supportClear: true,
method: 'requestAnimationFrame',
nativeMethod: '__zone_symbol__requestAnimationFrame',
clearMethod: 'cancelAnimationFrame',
nativeClearMethod: '__zone_symbol__cancelAnimationFrame',
run: function() {
return raf(function() {});
},
{
isCallback: true,
supportClear: false,
method: 'requestAnimationFrame_callback',
nativeMethod: 'native_requestAnimationFrame_callback',
run: function() { zone.run(function() { raf(function() {}); }); },
nativeRun: function() {
var func = function() {};
nativeRaf(function() {
mark('native_requestAnimationFrame_callback');
func.apply(this, arguments);
measure(
'native_requestAnimationFrame_callback', 'native_requestAnimationFrame_callback');
});
}
runClear: function(timerId) {
return cancel(timerId);
},
nativeRun: function() {
return nativeRaf(function() {});
},
nativeRunClear: function(timerId) {
return nativeCancel(timerId);
}
],
};
return testRunner(testTarget);
},
{
isCallback: true,
supportClear: false,
method: 'requestAnimationFrame_callback',
nativeMethod: 'native_requestAnimationFrame_callback',
run: function() {
zone.run(function() {
raf(function() {});
});
},
nativeRun: function() {
var func = function() {};
nativeRaf(function() {
mark('native_requestAnimationFrame_callback');
func.apply(this, arguments);
measure('native_requestAnimationFrame_callback', 'native_requestAnimationFrame_callback');
});
}
}
],
};
return testRunner(testTarget);
}(typeof window === 'undefined' ? global : window));

View File

@ -6,50 +6,62 @@
* found in the LICENSE file at https://angular.io/license
*/
(function(_global) {
var mark = _global['__zone_symbol__mark'];
var measure = _global['__zone_symbol__measure'];
var testRunner = _global['__zone_symbol__testRunner'];
var setTimeout = _global['setTimeout'];
var clearTimeout = _global['clearTimeout'];
var nativeSetTimeout = _global['__zone_symbol__setTimeout'];
var nativeClearTimeout = _global['__zone_symbol__clearTimeout'];
var zone = _global['__zone_symbol__callbackZone'];
var testTarget = {
title: 'timer',
times: 10,
before: function() {
_global['__zone_symbol__callbackContext'].measureName = 'setTimeout_callback';
_global['__zone_symbol__callbackContext'].type = 'macroTask';
_global['__zone_symbol__callbackContext'].source = 'setTimeout';
},
apis: [
{
supportClear: true,
method: 'setTimeout',
nativeMethod: '__zone_symbol__setTimeout',
clearMethod: 'clearTimeout',
nativeClearMethod: '__zone_symbol__clearTimeout',
run: function() { return setTimeout(function() {}); },
runClear: function(timerId) { return clearTimeout(timerId); },
nativeRun: function() { return nativeSetTimeout(function() {}); },
nativeRunClear: function(timerId) { return nativeClearTimeout(timerId); }
var mark = _global['__zone_symbol__mark'];
var measure = _global['__zone_symbol__measure'];
var testRunner = _global['__zone_symbol__testRunner'];
var setTimeout = _global['setTimeout'];
var clearTimeout = _global['clearTimeout'];
var nativeSetTimeout = _global['__zone_symbol__setTimeout'];
var nativeClearTimeout = _global['__zone_symbol__clearTimeout'];
var zone = _global['__zone_symbol__callbackZone'];
var testTarget = {
title: 'timer',
times: 10,
before: function() {
_global['__zone_symbol__callbackContext'].measureName = 'setTimeout_callback';
_global['__zone_symbol__callbackContext'].type = 'macroTask';
_global['__zone_symbol__callbackContext'].source = 'setTimeout';
},
apis: [
{
supportClear: true,
method: 'setTimeout',
nativeMethod: '__zone_symbol__setTimeout',
clearMethod: 'clearTimeout',
nativeClearMethod: '__zone_symbol__clearTimeout',
run: function() {
return setTimeout(function() {});
},
{
isCallback: true,
supportClear: false,
method: 'setTimeout_callback',
nativeMethod: 'native_setTimeout_callback',
run: function() { zone.run(function() { setTimeout(function() {}); }); },
nativeRun: function() {
var func = function() {};
nativeSetTimeout(function() {
mark('native_setTimeout_callback');
func.apply(this, arguments);
measure('native_setTimeout_callback', 'native_setTimeout_callback');
});
}
runClear: function(timerId) {
return clearTimeout(timerId);
},
nativeRun: function() {
return nativeSetTimeout(function() {});
},
nativeRunClear: function(timerId) {
return nativeClearTimeout(timerId);
}
],
};
return testRunner(testTarget);
},
{
isCallback: true,
supportClear: false,
method: 'setTimeout_callback',
nativeMethod: 'native_setTimeout_callback',
run: function() {
zone.run(function() {
setTimeout(function() {});
});
},
nativeRun: function() {
var func = function() {};
nativeSetTimeout(function() {
mark('native_setTimeout_callback');
func.apply(this, arguments);
measure('native_setTimeout_callback', 'native_setTimeout_callback');
});
}
}
],
};
return testRunner(testTarget);
}(typeof window === 'undefined' ? global : window));

View File

@ -6,42 +6,46 @@
* found in the LICENSE file at https://angular.io/license
*/
(function(_global) {
var mark = _global['__zone_symbol__mark'];
var measure = _global['__zone_symbol__measure'];
var testRunner = _global['__zone_symbol__testRunner'];
var zone = _global['__zone_symbol__callbackZone'];
var testTarget = {
title: 'xhr',
times: 3,
count: 1000,
before: function() {
_global['__zone_symbol__callbackContext'].measureName = 'xhr_callback';
_global['__zone_symbol__callbackContext'].type = 'macroTask';
_global['__zone_symbol__callbackContext'].source = 'send';
},
apis: [
{
supportClear: true,
method: 'XHR.send',
nativeMethod: 'native.XHR.send',
clearMethod: 'XHR.abort',
nativeClearMethod: 'native.XHR.abort',
run: function() {
var xhr = new XMLHttpRequest();
xhr.open('get', 'http://localhost:8080', true);
xhr.send();
return xhr;
},
runClear: function(xhr) { xhr.abort(); },
nativeRun: function() {
var xhr = new XMLHttpRequest();
xhr['__zone_symbol__open']('get', 'http://localhost:8080', true);
xhr['__zone_symbol__send']();
return xhr;
},
nativeRunClear: function(xhr) { xhr['__zone_symbol__abort'](); }
var mark = _global['__zone_symbol__mark'];
var measure = _global['__zone_symbol__measure'];
var testRunner = _global['__zone_symbol__testRunner'];
var zone = _global['__zone_symbol__callbackZone'];
var testTarget = {
title: 'xhr',
times: 3,
count: 1000,
before: function() {
_global['__zone_symbol__callbackContext'].measureName = 'xhr_callback';
_global['__zone_symbol__callbackContext'].type = 'macroTask';
_global['__zone_symbol__callbackContext'].source = 'send';
},
apis: [
{
supportClear: true,
method: 'XHR.send',
nativeMethod: 'native.XHR.send',
clearMethod: 'XHR.abort',
nativeClearMethod: 'native.XHR.abort',
run: function() {
var xhr = new XMLHttpRequest();
xhr.open('get', 'http://localhost:8080', true);
xhr.send();
return xhr;
},
],
};
return testRunner(testTarget);
runClear: function(xhr) {
xhr.abort();
},
nativeRun: function() {
var xhr = new XMLHttpRequest();
xhr['__zone_symbol__open']('get', 'http://localhost:8080', true);
xhr['__zone_symbol__send']();
return xhr;
},
nativeRunClear: function(xhr) {
xhr['__zone_symbol__abort']();
}
},
],
};
return testRunner(testTarget);
}(typeof window === 'undefined' ? global : window));

View File

@ -6,17 +6,23 @@ var P = global[Zone.__symbol__('Promise')];
var someRejectionReason = {message: 'some rejection reason'};
var anotherReason = {message: 'another rejection reason'};
process.on(
'unhandledRejection', function(reason, promise) { console.log('unhandledRejection', reason); });
process.on('unhandledRejection', function(reason, promise) {
console.log('unhandledRejection', reason);
});
describe('mocha promise sanity check', () => {
it('passes with a resolved promise', () => { return P.resolve(3); });
it('passes with a resolved promise', () => {
return P.resolve(3);
});
it('passes with a rejected then resolved promise',
() => { return P.reject(someRejectionReason).catch(x => 'this should be resolved'); });
it('passes with a rejected then resolved promise', () => {
return P.reject(someRejectionReason).catch(x => 'this should be resolved');
});
var ifPromiseIt = P === Promise ? it : it.skip;
ifPromiseIt('is the native Promise', () => { assert.equal(P, Promise); });
ifPromiseIt('is the native Promise', () => {
assert.equal(P, Promise);
});
});
describe('onFinally', () => {
@ -33,7 +39,9 @@ describe('onFinally', () => {
assert.strictEqual(x, 3);
done();
},
function onRejected() { done(new Error('should not be called')); });
function onRejected() {
done(new Error('should not be called'));
});
});
specify('from rejected', (done) => {
@ -44,7 +52,9 @@ describe('onFinally', () => {
})
.finally()
.then(
function onFulfilled() { done(new Error('should not be called')); },
function onFulfilled() {
done(new Error('should not be called'));
},
function onRejected(reason) {
assert.strictEqual(reason, someRejectionReason);
done();
@ -64,7 +74,9 @@ describe('onFinally', () => {
throw someRejectionReason;
})
.then(
function onFulfilled() { done(new Error('should not be called')); },
function onFulfilled() {
done(new Error('should not be called'));
},
function onRejected(reason) {
assert.strictEqual(reason, someRejectionReason);
done();
@ -78,7 +90,9 @@ describe('onFinally', () => {
throw someRejectionReason;
})
.then(
function onFulfilled() { done(new Error('should not be called')); },
function onFulfilled() {
done(new Error('should not be called'));
},
function onRejected(reason) {
assert.strictEqual(reason, someRejectionReason);
done();
@ -102,7 +116,9 @@ describe('onFinally', () => {
assert.strictEqual(x, 3);
done();
},
function onRejected() { done(new Error('should not be called')); });
function onRejected() {
done(new Error('should not be called'));
});
});
specify('from rejected', (done) => {
@ -116,7 +132,9 @@ describe('onFinally', () => {
throw someRejectionReason;
})
.then(
function onFulfilled() { done(new Error('should not be called')); },
function onFulfilled() {
done(new Error('should not be called'));
},
function onRejected(e) {
assert.strictEqual(e, someRejectionReason);
done();
@ -188,7 +206,9 @@ describe('onFinally', () => {
assert.strictEqual(x, 3);
done();
},
function onRejected() { done(new Error('should not be called')); });
function onRejected() {
done(new Error('should not be called'));
});
});
specify('from rejected', (done) => {
@ -202,7 +222,9 @@ describe('onFinally', () => {
return adapter.resolved(4);
})
.then(
function onFulfilled() { done(new Error('should not be called')); },
function onFulfilled() {
done(new Error('should not be called'));
},
function onRejected(e) {
assert.strictEqual(e, someRejectionReason);
done();
@ -222,7 +244,9 @@ describe('onFinally', () => {
return adapter.rejected(4);
})
.then(
function onFulfilled(x) { done(new Error('should not be called')); },
function onFulfilled(x) {
done(new Error('should not be called'));
},
function onRejected(e) {
assert.strictEqual(e, 4);
done();
@ -241,7 +265,9 @@ describe('onFinally', () => {
return adapter.rejected(newReason);
})
.then(
function onFulfilled(x) { done(new Error('should not be called')); },
function onFulfilled(x) {
done(new Error('should not be called'));
},
function onRejected(e) {
assert.strictEqual(e, newReason);
done();
@ -260,7 +286,9 @@ describe('onFinally', () => {
.finally(function onFinally() {
assert(arguments.length === 0);
timeout = setTimeout(done, 1.5e3);
return new P((resolve) => { setTimeout(() => resolve(4), 1e3); });
return new P((resolve) => {
setTimeout(() => resolve(4), 1e3);
});
})
.then(
function onFulfilled(x) {
@ -284,7 +312,9 @@ describe('onFinally', () => {
.finally(function onFinally() {
assert(arguments.length === 0);
timeout = setTimeout(done, 1.5e3);
return new P((resolve) => { setTimeout(() => resolve(4), 1e3); });
return new P((resolve) => {
setTimeout(() => resolve(4), 1e3);
});
})
.then(
function onFulfilled() {
@ -310,7 +340,9 @@ describe('onFinally', () => {
.finally(function onFinally() {
assert(arguments.length === 0);
timeout = setTimeout(done, 1.5e3);
return new P((resolve, reject) => { setTimeout(() => reject(4), 1e3); });
return new P((resolve, reject) => {
setTimeout(() => reject(4), 1e3);
});
})
.then(
function onFulfilled() {
@ -334,7 +366,9 @@ describe('onFinally', () => {
.finally(function onFinally() {
assert(arguments.length === 0);
timeout = setTimeout(done, 1.5e3);
return new P((resolve, reject) => { setTimeout(() => reject(anotherReason), 1e3); });
return new P((resolve, reject) => {
setTimeout(() => reject(anotherReason), 1e3);
});
})
.then(
function onFulfilled() {

View File

@ -5,7 +5,7 @@
* 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
*/
import {Observable, interval} from 'rxjs';
import {interval, Observable} from 'rxjs';
import {audit, auditTime} from 'rxjs/operators';
import {asyncTest} from '../test-util';
@ -14,7 +14,9 @@ xdescribe('Observable.audit', () => {
let log: any[];
let observable1: Observable<any>;
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('audit func callback should run in the correct zone', asyncTest((done: any) => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
@ -36,7 +38,9 @@ xdescribe('Observable.audit', () => {
subscriber.unsubscribe();
}
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -65,7 +69,9 @@ xdescribe('Observable.audit', () => {
subscriber.unsubscribe();
}
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Observable, empty, interval, of } from 'rxjs';
import {empty, interval, Observable, of} from 'rxjs';
import {buffer, bufferCount, bufferTime, bufferToggle, bufferWhen} from 'rxjs/operators';
import {asyncTest} from '../test-util';
@ -15,7 +15,9 @@ xdescribe('Observable.buffer', () => {
let log: any[];
let observable1: Observable<any>;
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('buffer func callback should run in the correct zone', asyncTest((done: any) => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
@ -35,7 +37,9 @@ xdescribe('Observable.buffer', () => {
subscriber.unsubscribe();
}
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -64,7 +68,9 @@ xdescribe('Observable.buffer', () => {
subscriber.unsubscribe();
}
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -93,7 +99,9 @@ xdescribe('Observable.buffer', () => {
subscriber.unsubscribe();
}
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -113,7 +121,7 @@ xdescribe('Observable.buffer', () => {
const opening = interval(25);
const closingSelector = (v: any) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
return v % 2 === 0 ? of (v) : empty();
return v % 2 === 0 ? of(v) : empty();
};
return source.pipe(bufferToggle(opening, closingSelector));
});
@ -126,7 +134,9 @@ xdescribe('Observable.buffer', () => {
log.push(result);
subscriber.unsubscribe();
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -159,7 +169,9 @@ xdescribe('Observable.buffer', () => {
subscriber.unsubscribe();
}
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);

View File

@ -5,21 +5,23 @@
* 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
*/
import {Observable, of } from 'rxjs';
import {Observable, of} from 'rxjs';
import {catchError, map, retry} from 'rxjs/operators';
describe('Observable.catch', () => {
let log: any[];
let observable1: Observable<any>;
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('catch func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => {
const error = new Error('test');
const source = of (1, 2, 3).pipe(map((n: number) => {
const source = of(1, 2, 3).pipe(map((n: number) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
if (n === 2) {
throw error;
@ -28,7 +30,7 @@ describe('Observable.catch', () => {
}));
return source.pipe(catchError((err: any) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
return of ('error1', 'error2');
return of('error1', 'error2');
}));
});
@ -38,7 +40,9 @@ describe('Observable.catch', () => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -52,7 +56,7 @@ describe('Observable.catch', () => {
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => {
return of (1, 2, 3).pipe(
return of(1, 2, 3).pipe(
map((n: number) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
if (n === 2) {

View File

@ -5,7 +5,7 @@
* 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
*/
import {Observable, from, interval, of } from 'rxjs';
import {from, interval, Observable, of} from 'rxjs';
import {elementAt, every, filter, find, findIndex, first, flatMap, groupBy, ignoreElements, isEmpty, last, map, mapTo, max, min, reduce, repeat, scan, single, skip, skipUntil, skipWhile, startWith} from 'rxjs/operators';
import {asyncTest, isPhantomJS} from '../test-util';
@ -20,13 +20,17 @@ describe('Observable.collection', () => {
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
});
afterEach(function() { jasmine.DEFAULT_TIMEOUT_INTERVAL = defaultTimeout; });
afterEach(function() {
jasmine.DEFAULT_TIMEOUT_INTERVAL = defaultTimeout;
});
it('elementAt func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return of (1, 2, 3).pipe(elementAt(1)); });
observable1 = constructorZone1.run(() => {
return of(1, 2, 3).pipe(elementAt(1));
});
subscriptionZone.run(() => {
observable1.subscribe(
@ -34,7 +38,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -48,7 +54,9 @@ describe('Observable.collection', () => {
const everyZone1: Zone = Zone.current.fork({name: 'Every Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return of (1, 2, 3); });
observable1 = constructorZone1.run(() => {
return of(1, 2, 3);
});
observable1 = everyZone1.run(() => {
return observable1.pipe(every((v: any) => {
@ -63,7 +71,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -77,7 +87,9 @@ describe('Observable.collection', () => {
const filterZone1: Zone = Zone.current.fork({name: 'Filter Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return of (1, 2, 3); });
observable1 = constructorZone1.run(() => {
return of(1, 2, 3);
});
observable1 = filterZone1.run(() => {
return observable1.pipe(filter((v: any) => {
@ -92,7 +104,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -106,7 +120,9 @@ describe('Observable.collection', () => {
const findZone1: Zone = Zone.current.fork({name: 'Find Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return of (1, 2, 3); });
observable1 = constructorZone1.run(() => {
return of(1, 2, 3);
});
observable1 = findZone1.run(() => {
return observable1.pipe(find((v: any) => {
@ -121,7 +137,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -135,7 +153,9 @@ describe('Observable.collection', () => {
const findZone1: Zone = Zone.current.fork({name: 'Find Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return of (1, 2, 3); });
observable1 = constructorZone1.run(() => {
return of(1, 2, 3);
});
observable1 = findZone1.run(() => {
return observable1.pipe(findIndex((v: any) => {
@ -150,7 +170,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -164,7 +186,9 @@ describe('Observable.collection', () => {
const firstZone1: Zone = Zone.current.fork({name: 'First Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return of (1, 2, 3); });
observable1 = constructorZone1.run(() => {
return of(1, 2, 3);
});
observable1 = firstZone1.run(() => {
return observable1.pipe(first((v: any) => {
@ -179,7 +203,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -221,7 +247,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error' + err); },
(err: any) => {
fail('should not call error' + err);
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -238,12 +266,18 @@ describe('Observable.collection', () => {
const ignoreZone1: Zone = Zone.current.fork({name: 'Ignore Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return of (1, 2, 3).pipe(ignoreElements()); });
observable1 = constructorZone1.run(() => {
return of(1, 2, 3).pipe(ignoreElements());
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => { fail('should not call next'); },
(err: any) => { fail('should not call error'); },
(result: any) => {
fail('should not call next');
},
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -257,7 +291,9 @@ describe('Observable.collection', () => {
const isEmptyZone1: Zone = Zone.current.fork({name: 'IsEmpty Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return of (1, 2, 3).pipe(isEmpty()); });
observable1 = constructorZone1.run(() => {
return of(1, 2, 3).pipe(isEmpty());
});
subscriptionZone.run(() => {
observable1.subscribe(
@ -265,7 +301,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -279,7 +317,9 @@ describe('Observable.collection', () => {
const lastZone1: Zone = Zone.current.fork({name: 'Last Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return of (1, 2, 3).pipe(last()); });
observable1 = constructorZone1.run(() => {
return of(1, 2, 3).pipe(last());
});
subscriptionZone.run(() => {
observable1.subscribe(
@ -287,7 +327,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -301,7 +343,9 @@ describe('Observable.collection', () => {
const mapZone1: Zone = Zone.current.fork({name: 'Map Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return of (1, 2, 3); });
observable1 = constructorZone1.run(() => {
return of(1, 2, 3);
});
observable1 = mapZone1.run(() => {
return observable1.pipe(map((v: any) => {
@ -316,7 +360,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -330,9 +376,13 @@ describe('Observable.collection', () => {
const mapToZone1: Zone = Zone.current.fork({name: 'MapTo Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return of (1, 2, 3); });
observable1 = constructorZone1.run(() => {
return of(1, 2, 3);
});
observable1 = mapToZone1.run(() => { return observable1.pipe(mapTo('a')); });
observable1 = mapToZone1.run(() => {
return observable1.pipe(mapTo('a'));
});
subscriptionZone.run(() => {
observable1.subscribe(
@ -340,7 +390,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -353,7 +405,9 @@ describe('Observable.collection', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return of (4, 2, 3).pipe(max()); });
observable1 = constructorZone1.run(() => {
return of(4, 2, 3).pipe(max());
});
subscriptionZone.run(() => {
observable1.subscribe(
@ -361,7 +415,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -375,7 +431,9 @@ describe('Observable.collection', () => {
const maxZone1: Zone = Zone.current.fork({name: 'Max Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return of (4, 2, 3); });
observable1 = constructorZone1.run(() => {
return of(4, 2, 3);
});
observable1 = maxZone1.run(() => {
return observable1.pipe(max((x: number, y: number) => {
@ -390,7 +448,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -403,7 +463,9 @@ describe('Observable.collection', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return of (4, 2, 3).pipe(min()); });
observable1 = constructorZone1.run(() => {
return of(4, 2, 3).pipe(min());
});
subscriptionZone.run(() => {
observable1.subscribe(
@ -411,7 +473,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -425,7 +489,9 @@ describe('Observable.collection', () => {
const minZone1: Zone = Zone.current.fork({name: 'Min Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return of (4, 2, 3); });
observable1 = constructorZone1.run(() => {
return of(4, 2, 3);
});
observable1 = minZone1.run(() => {
return observable1.pipe(max((x: number, y: number) => {
@ -440,7 +506,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -453,7 +521,9 @@ describe('Observable.collection', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const reduceZone1: Zone = Zone.current.fork({name: 'Min Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => { return of (4, 2, 3); });
observable1 = constructorZone1.run(() => {
return of(4, 2, 3);
});
observable1 = reduceZone1.run(() => {
return observable1.pipe(reduce((acc: number, one: number) => {
@ -468,7 +538,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -481,7 +553,9 @@ describe('Observable.collection', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const scanZone1: Zone = Zone.current.fork({name: 'Min Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => { return of (4, 2, 3); });
observable1 = constructorZone1.run(() => {
return of(4, 2, 3);
});
observable1 = scanZone1.run(() => {
return observable1.pipe(scan((acc: number, one: number) => {
@ -496,7 +570,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -508,7 +584,9 @@ describe('Observable.collection', () => {
it('repeat func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => { return of (1).pipe(repeat(2)); });
observable1 = constructorZone1.run(() => {
return of(1).pipe(repeat(2));
});
subscriptionZone.run(() => {
observable1.subscribe(
@ -516,7 +594,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -529,7 +609,9 @@ describe('Observable.collection', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const singleZone1: Zone = Zone.current.fork({name: 'Single Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => { return of (1, 2, 3, 4, 5); });
observable1 = constructorZone1.run(() => {
return of(1, 2, 3, 4, 5);
});
observable1 = singleZone1.run(() => {
return observable1.pipe(single((val: any) => {
@ -544,7 +626,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -556,7 +640,9 @@ describe('Observable.collection', () => {
it('skip func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => { return of (1, 2, 3, 4, 5).pipe(skip(3)); });
observable1 = constructorZone1.run(() => {
return of(1, 2, 3, 4, 5).pipe(skip(3));
});
subscriptionZone.run(() => {
observable1.subscribe(
@ -564,7 +650,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -576,8 +664,9 @@ describe('Observable.collection', () => {
xit('skipUntil func callback should run in the correct zone', asyncTest((done: any) => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 =
constructorZone1.run(() => { return interval(10).pipe(skipUntil(interval(25))); });
observable1 = constructorZone1.run(() => {
return interval(10).pipe(skipUntil(interval(25)));
});
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
@ -586,7 +675,9 @@ describe('Observable.collection', () => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
subscriber.unsubscribe();
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -600,7 +691,9 @@ describe('Observable.collection', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const skipZone1: Zone = Zone.current.fork({name: 'Skip Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => { return interval(10); });
observable1 = constructorZone1.run(() => {
return interval(10);
});
observable1 = skipZone1.run(() => {
return observable1.pipe(skipWhile((val: any) => {
@ -617,14 +710,18 @@ describe('Observable.collection', () => {
expect(result).toEqual(2);
done();
},
(err: any) => { fail('should not call error'); });
(err: any) => {
fail('should not call error');
});
});
}, Zone.root));
it('startWith func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => { return of (1, 2).pipe(startWith(3)); });
observable1 = constructorZone1.run(() => {
return of(1, 2).pipe(startWith(3));
});
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
@ -632,7 +729,9 @@ describe('Observable.collection', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);

View File

@ -5,7 +5,7 @@
* 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
*/
import {Observable, combineLatest, of } from 'rxjs';
import {combineLatest, Observable, of} from 'rxjs';
import {combineAll, map} from 'rxjs/operators';
import {asyncTest} from '../test-util';
@ -14,16 +14,18 @@ describe('Observable.combine', () => {
let log: any[];
let observable1: Observable<any>;
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('combineAll func callback should run in the correct zone', asyncTest((done: any) => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => {
const source = of (1, 2);
const source = of(1, 2);
const highOrder = source.pipe(map((src: any) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
return of (src);
return of(src);
}));
return highOrder.pipe(combineAll());
});
@ -34,7 +36,9 @@ describe('Observable.combine', () => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -49,10 +53,10 @@ describe('Observable.combine', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => {
const source = of (1, 2, 3);
const source = of(1, 2, 3);
const highOrder = source.pipe(map((src: any) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
return of (src);
return of(src);
}));
return highOrder.pipe(combineAll((x: any, y: any) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
@ -66,7 +70,9 @@ describe('Observable.combine', () => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -80,8 +86,8 @@ describe('Observable.combine', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => {
const source = of (1, 2, 3);
const input = of (4, 5, 6);
const source = of(1, 2, 3);
const input = of(4, 5, 6);
return combineLatest(source, input);
});
@ -91,7 +97,9 @@ describe('Observable.combine', () => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -105,9 +113,11 @@ describe('Observable.combine', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => {
const source = of (1, 2, 3);
const input = of (4, 5, 6);
return combineLatest(source, input, (x: number, y: number) => { return x + y; });
const source = of(1, 2, 3);
const input = of(4, 5, 6);
return combineLatest(source, input, (x: number, y: number) => {
return x + y;
});
});
subscriptionZone.run(() => {
@ -116,7 +126,9 @@ describe('Observable.combine', () => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Observable, asapScheduler, concat, of , range} from 'rxjs';
import {asapScheduler, concat, Observable, of, range} from 'rxjs';
import {concatAll, concatMap, concatMapTo, map} from 'rxjs/operators';
import {asyncTest} from '../test-util';
@ -22,7 +22,9 @@ describe('Observable instance method concat', () => {
let concatObservable: any;
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('concat func callback should run in the correct zone', () => {
observable1 = constructorZone1.run(() => {
@ -34,9 +36,13 @@ describe('Observable instance method concat', () => {
});
});
observable2 = constructorZone2.run(() => { return range(3, 4); });
observable2 = constructorZone2.run(() => {
return range(3, 4);
});
constructorZone3.run(() => { concatObservable = concat(observable1, observable2); });
constructorZone3.run(() => {
concatObservable = concat(observable1, observable2);
});
subscriptionZone.run(() => {
concatObservable.subscribe((concat: any) => {
@ -54,12 +60,17 @@ describe('Observable instance method concat', () => {
const constructorZone2: Zone = Zone.current.fork({name: 'Constructor Zone2'});
const constructorZone3: Zone = Zone.current.fork({name: 'Constructor Zone3'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => { return of (1, 2); });
observable1 = constructorZone1.run(() => {
return of(1, 2);
});
observable2 = constructorZone2.run(() => { return range(3, 4); });
observable2 = constructorZone2.run(() => {
return range(3, 4);
});
constructorZone3.run(
() => { concatObservable = concat(observable1, observable2, asapScheduler); });
constructorZone3.run(() => {
concatObservable = concat(observable1, observable2, asapScheduler);
});
subscriptionZone.run(() => {
concatObservable.subscribe(
@ -67,7 +78,9 @@ describe('Observable instance method concat', () => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(concat);
},
(error: any) => { fail('subscribe failed' + error); },
(error: any) => {
fail('subscribe failed' + error);
},
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([1, 2, 3, 4, 5, 6]);
@ -82,12 +95,14 @@ describe('Observable instance method concat', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const constructorZone2: Zone = Zone.current.fork({name: 'Constructor Zone2'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => { return of (0, 1, 2); });
observable1 = constructorZone1.run(() => {
return of(0, 1, 2);
});
constructorZone2.run(() => {
const highOrder = observable1.pipe(map((v: any) => {
expect(Zone.current.name).toEqual(constructorZone2.name);
return of (v + 1);
return of(v + 1);
}));
concatObservable = highOrder.pipe(concatAll());
});
@ -98,7 +113,9 @@ describe('Observable instance method concat', () => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(concat);
},
(error: any) => { fail('subscribe failed' + error); },
(error: any) => {
fail('subscribe failed' + error);
},
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([1, 2, 3]);
@ -125,7 +142,7 @@ describe('Observable instance method concat', () => {
constructorZone2.run(() => {
concatObservable = observable1.pipe(concatMap((v: any) => {
expect(Zone.current.name).toEqual(constructorZone2.name);
return of (0, 1);
return of(0, 1);
}));
});
@ -135,7 +152,9 @@ describe('Observable instance method concat', () => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(concat);
},
(error: any) => { fail('subscribe failed' + error); },
(error: any) => {
fail('subscribe failed' + error);
},
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([0, 1, 0, 1, 0, 1, 0, 1]);
@ -159,7 +178,9 @@ describe('Observable instance method concat', () => {
});
});
constructorZone2.run(() => { concatObservable = observable1.pipe(concatMapTo(of (0, 1))); });
constructorZone2.run(() => {
concatObservable = observable1.pipe(concatMapTo(of(0, 1)));
});
subscriptionZone.run(() => {
concatObservable.subscribe(
@ -167,7 +188,9 @@ describe('Observable instance method concat', () => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(concat);
},
(error: any) => { fail('subscribe failed' + error); },
(error: any) => {
fail('subscribe failed' + error);
},
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([0, 1, 0, 1, 0, 1, 0, 1]);

View File

@ -14,7 +14,9 @@ describe('Observable.count', () => {
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
let observable1: Observable<any>;
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('count func callback should run in the correct zone', () => {
observable1 = constructorZone1.run(() => {
@ -30,7 +32,9 @@ describe('Observable.count', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);

View File

@ -5,7 +5,7 @@
* 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
*/
import {Observable, of , timer} from 'rxjs';
import {Observable, of, timer} from 'rxjs';
import {debounce, debounceTime} from 'rxjs/operators';
import {asyncTest} from '../test-util';
@ -14,13 +14,15 @@ describe('Observable.debounce', () => {
let log: any[];
let observable1: Observable<any>;
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('debounce func callback should run in the correct zone', asyncTest((done: any) => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => {
return of (1, 2, 3).pipe(debounce(() => {
return of(1, 2, 3).pipe(debounce(() => {
expect(Zone.current.name).toEqual(constructorZone1.name);
return timer(100);
}));
@ -32,7 +34,9 @@ describe('Observable.debounce', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -45,7 +49,9 @@ describe('Observable.debounce', () => {
it('debounceTime func callback should run in the correct zone', asyncTest((done: any) => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => { return of (1, 2, 3).pipe(debounceTime(100)); });
observable1 = constructorZone1.run(() => {
return of(1, 2, 3).pipe(debounceTime(100));
});
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
@ -53,7 +59,9 @@ describe('Observable.debounce', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);

View File

@ -5,7 +5,7 @@
* 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
*/
import {Observable, of } from 'rxjs';
import {Observable, of} from 'rxjs';
import {defaultIfEmpty} from 'rxjs/operators';
import {asyncTest} from '../test-util';
@ -14,13 +14,16 @@ describe('Observable.defaultIfEmpty', () => {
let log: any[];
let observable1: Observable<any>;
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('defaultIfEmpty func callback should run in the correct zone', asyncTest((done: any) => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 =
constructorZone1.run(() => { return of ().pipe(defaultIfEmpty('empty' as any)); });
observable1 = constructorZone1.run(() => {
return of().pipe(defaultIfEmpty('empty' as any));
});
subscriptionZone.run(() => {
observable1.subscribe(
@ -28,7 +31,9 @@ describe('Observable.defaultIfEmpty', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Observable, of , timer} from 'rxjs';
import {Observable, of, timer} from 'rxjs';
import {delay, delayWhen} from 'rxjs/operators';
import {asyncTest} from '../test-util';
@ -15,12 +15,16 @@ describe('Observable.delay', () => {
let log: any[];
let observable1: Observable<any>;
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('delay func callback should run in the correct zone', asyncTest((done: any) => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => { return of (1, 2, 3).pipe(delay(100)); });
observable1 = constructorZone1.run(() => {
return of(1, 2, 3).pipe(delay(100));
});
subscriptionZone.run(() => {
observable1.subscribe(
@ -28,7 +32,9 @@ describe('Observable.delay', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -41,8 +47,11 @@ describe('Observable.delay', () => {
it('delayWhen func callback should run in the correct zone', asyncTest((done: any) => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(
() => { return of (1, 2, 3).pipe(delayWhen((v: any) => { return timer(v * 10); })); });
observable1 = constructorZone1.run(() => {
return of(1, 2, 3).pipe(delayWhen((v: any) => {
return timer(v * 10);
}));
});
subscriptionZone.run(() => {
observable1.subscribe(
@ -50,7 +59,9 @@ describe('Observable.delay', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);

View File

@ -6,21 +6,24 @@
* found in the LICENSE file at https://angular.io/license
*/
import {Observable, of } from 'rxjs';
import {Observable, of} from 'rxjs';
import {distinct, distinctUntilChanged, distinctUntilKeyChanged} from 'rxjs/operators';
describe('Observable.distinct', () => {
let log: any[];
let observable1: Observable<any>;
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('distinct func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(
() => { return of (1, 1, 2, 2, 2, 1, 2, 3, 4, 3, 2, 1).pipe(distinct()); });
observable1 = constructorZone1.run(() => {
return of(1, 1, 2, 2, 2, 1, 2, 3, 4, 3, 2, 1).pipe(distinct());
});
subscriptionZone.run(() => {
observable1.subscribe(
@ -28,7 +31,9 @@ describe('Observable.distinct', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -41,8 +46,9 @@ describe('Observable.distinct', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(
() => { return of (1, 1, 2, 2, 2, 1, 1, 2, 3, 3, 4).pipe(distinctUntilChanged()); });
observable1 = constructorZone1.run(() => {
return of(1, 1, 2, 2, 2, 1, 1, 2, 3, 3, 4).pipe(distinctUntilChanged());
});
subscriptionZone.run(() => {
observable1.subscribe(
@ -50,7 +56,9 @@ describe('Observable.distinct', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
@ -64,8 +72,8 @@ describe('Observable.distinct', () => {
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => {
return of ({age: 4, name: 'Foo'}, {age: 7, name: 'Bar'}, {age: 5, name: 'Foo'},
{age: 6, name: 'Foo'})
return of({age: 4, name: 'Foo'}, {age: 7, name: 'Bar'}, {age: 5, name: 'Foo'},
{age: 6, name: 'Foo'})
.pipe(distinctUntilKeyChanged('name'));
});
@ -75,7 +83,9 @@ describe('Observable.distinct', () => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);

View File

@ -5,21 +5,25 @@
* 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
*/
import {Observable, of } from 'rxjs';
import {Observable, of} from 'rxjs';
import {tap} from 'rxjs/operators';
describe('Observable.tap', () => {
let log: any[];
let observable1: Observable<any>;
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('do func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const doZone1: Zone = Zone.current.fork({name: 'Do Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return of (1); });
observable1 = constructorZone1.run(() => {
return of(1);
});
observable1 = doZone1.run(() => {
return observable1.pipe(tap((v: any) => {
@ -34,7 +38,9 @@ describe('Observable.tap', () => {
log.push('result' + result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
(err: any) => {
fail('should not call error');
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);

View File

@ -5,7 +5,7 @@
* 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
*/
import {Observable, observable, of } from 'rxjs';
import {Observable, observable, of} from 'rxjs';
import {pairwise, partition, pluck} from 'rxjs/operators';
import {ifEnvSupports} from '../test-util';
@ -18,10 +18,14 @@ describe('Observable.map', () => {
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
let observable1: Observable<any>;
beforeEach(() => { log = []; });
beforeEach(() => {
log = [];
});
it('pairwise func callback should run in the correct zone', () => {
observable1 = constructorZone1.run(() => { return of (1, 2, 3).pipe(pairwise()); });
observable1 = constructorZone1.run(() => {
return of(1, 2, 3).pipe(pairwise());
});
subscriptionZone.run(() => {
observable1.subscribe(
@ -29,7 +33,9 @@ describe('Observable.map', () => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('completed');
@ -41,7 +47,9 @@ describe('Observable.map', () => {
it('partition func callback should run in the correct zone', () => {
const partitionZone = Zone.current.fork({name: 'Partition Zone1'});
const observable1: any = constructorZone1.run(() => { return of (1, 2, 3); });
const observable1: any = constructorZone1.run(() => {
return of(1, 2, 3);
});
const part: any = partitionZone.run(() => {
return observable1.pipe(partition((val: any) => {
@ -56,7 +64,9 @@ describe('Observable.map', () => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('first' + result);
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('completed');
@ -67,7 +77,9 @@ describe('Observable.map', () => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('second' + result);
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('completed');
@ -78,8 +90,9 @@ describe('Observable.map', () => {
});
it('pluck func callback should run in the correct zone', () => {
observable1 =
constructorZone1.run(() => { return of ({a: 1, b: 2}, {a: 3, b: 4}).pipe(pluck('a')); });
observable1 = constructorZone1.run(() => {
return of({a: 1, b: 2}, {a: 3, b: 4}).pipe(pluck('a'));
});
subscriptionZone.run(() => {
observable1.subscribe(
@ -87,7 +100,9 @@ describe('Observable.map', () => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
fail('should not call error');
},
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('completed');

Some files were not shown because too many files have changed in this diff Show More