build: move zone.js to angular repo (#30962)

PR Close #30962
This commit is contained in:
JiaLiPassion
2019-06-01 00:56:07 +09:00
committed by Kara Erickson
parent 7b3bcc23af
commit 5eb7426216
271 changed files with 30890 additions and 19 deletions

View File

@ -0,0 +1,79 @@
/**
* @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
*/
import {Observable, interval} from 'rxjs';
import {audit, auditTime} from 'rxjs/operators';
import {asyncTest} from '../test-util';
xdescribe('Observable.audit', () => {
let log: any[];
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('audit 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 = interval(100);
return source.pipe(audit(ev => {
expect(Zone.current.name).toEqual(constructorZone1.name);
return interval(150);
}));
});
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
if (result >= 3) {
subscriber.unsubscribe();
}
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([1, 3, 'completed']);
done();
});
});
expect(log).toEqual([]);
}, Zone.root));
xit('auditTime 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 = interval(100);
return source.pipe(auditTime(360));
});
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
if (result >= 7) {
subscriber.unsubscribe();
}
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([3, 7, 'completed']);
done();
});
});
expect(log).toEqual([]);
}, Zone.root));
});

View File

@ -0,0 +1,173 @@
/**
* @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
*/
import {Observable, empty, interval, of } from 'rxjs';
import {buffer, bufferCount, bufferTime, bufferToggle, bufferWhen} from 'rxjs/operators';
import {asyncTest} from '../test-util';
xdescribe('Observable.buffer', () => {
let log: any[];
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('buffer 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 = interval(350);
const iv = interval(100);
return iv.pipe(buffer(source));
});
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
if (result[0] >= 3) {
subscriber.unsubscribe();
}
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([[0, 1, 2], [3, 4, 5], 'completed']);
done();
});
});
expect(log).toEqual([]);
}, Zone.root));
it('bufferCount 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 iv = interval(100);
return iv.pipe(bufferCount(3));
});
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
if (result[0] >= 3) {
subscriber.unsubscribe();
}
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([[0, 1, 2], [3, 4, 5], 'completed']);
done();
});
});
expect(log).toEqual([]);
}, Zone.root));
it('bufferTime 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 iv = interval(100);
return iv.pipe(bufferTime(350));
});
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
if (result[0] >= 3) {
subscriber.unsubscribe();
}
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([[0, 1, 2], [3, 4, 5], 'completed']);
done();
});
});
expect(log).toEqual([]);
}, Zone.root));
it('bufferToggle 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 = interval(10);
const opening = interval(25);
const closingSelector = (v: any) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
return v % 2 === 0 ? of (v) : empty();
};
return source.pipe(bufferToggle(opening, closingSelector));
});
let i = 0;
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
subscriber.unsubscribe();
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([[], 'completed']);
done();
});
});
expect(log).toEqual([]);
}, Zone.root));
it('bufferWhen 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 = interval(100);
return source.pipe(bufferWhen(() => {
expect(Zone.current.name).toEqual(constructorZone1.name);
return interval(220);
}));
});
let i = 0;
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
if (i++ >= 3) {
subscriber.unsubscribe();
}
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([[0, 1], [2, 3], [4, 5], [6, 7], 'completed']);
done();
});
});
expect(log).toEqual([]);
}, Zone.root));
});

View File

@ -0,0 +1,83 @@
/**
* @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
*/
import {Observable, of } from 'rxjs';
import {catchError, map, retry} from 'rxjs/operators';
describe('Observable.catch', () => {
let log: any[];
let observable1: Observable<any>;
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) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
if (n === 2) {
throw error;
}
return n;
}));
return source.pipe(catchError((err: any) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
return of ('error1', 'error2');
}));
});
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
});
});
expect(log).toEqual([1, 'error1', 'error2', 'completed']);
});
it('retry 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(
map((n: number) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
if (n === 2) {
throw error;
}
return n;
}),
retry(1));
});
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
(error: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(error);
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
});
});
expect(log).toEqual([1, 1, error]);
});
});

View File

@ -0,0 +1,643 @@
/**
* @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
*/
import {Observable, from, interval, 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';
describe('Observable.collection', () => {
let log: any[];
let observable1: Observable<any>;
let defaultTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
beforeEach(() => {
log = [];
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
});
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)); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([2, 'completed']);
});
});
});
it('every func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
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 = everyZone1.run(() => {
return observable1.pipe(every((v: any) => {
expect(Zone.current.name).toEqual(everyZone1.name);
return v % 2 === 0;
}));
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([false, 'completed']);
});
});
});
it('filter func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
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 = filterZone1.run(() => {
return observable1.pipe(filter((v: any) => {
expect(Zone.current.name).toEqual(filterZone1.name);
return v % 2 === 0;
}));
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([2, 'completed']);
});
});
});
it('find func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
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 = findZone1.run(() => {
return observable1.pipe(find((v: any) => {
expect(Zone.current.name).toEqual(findZone1.name);
return v === 2;
}));
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([2, 'completed']);
});
});
});
it('findIndex func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
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 = findZone1.run(() => {
return observable1.pipe(findIndex((v: any) => {
expect(Zone.current.name).toEqual(findZone1.name);
return v === 2;
}));
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([1, 'completed']);
});
});
});
it('first func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
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 = firstZone1.run(() => {
return observable1.pipe(first((v: any) => {
expect(Zone.current.name).toEqual(firstZone1.name);
return v === 2;
}));
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([2, 'completed']);
});
});
});
it('groupBy func callback should run in the correct zone', () => {
if (isPhantomJS()) {
return;
}
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const groupByZone1: Zone = Zone.current.fork({name: 'groupBy Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => {
const people = [
{name: 'Sue', age: 25}, {name: 'Joe', age: 30}, {name: 'Frank', age: 25},
{name: 'Sarah', age: 35}
];
return from(people);
});
observable1 = groupByZone1.run(() => {
return observable1.pipe(
groupBy((person: any) => {
expect(Zone.current.name).toEqual(groupByZone1.name);
return person.age;
}),
// return as array of each group
flatMap((group: any) => {
return group.pipe(reduce((acc: any, curr: any) => [...acc, curr], []));
}));
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error' + err); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([
[{age: 25, name: 'Sue'}, {age: 25, name: 'Frank'}], [{age: 30, name: 'Joe'}],
[{age: 35, name: 'Sarah'}], 'completed'
]);
});
});
});
it('ignoreElements func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
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()); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => { fail('should not call next'); },
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual(['completed']);
});
});
});
it('isEmpty func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
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()); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([false, 'completed']);
});
});
});
it('last func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
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()); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([3, 'completed']);
});
});
});
it('map func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
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 = mapZone1.run(() => {
return observable1.pipe(map((v: any) => {
expect(Zone.current.name).toEqual(mapZone1.name);
return v + 1;
}));
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([2, 3, 4, 'completed']);
});
});
});
it('mapTo func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
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 = mapToZone1.run(() => { return observable1.pipe(mapTo('a')); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual(['a', 'a', 'a', 'completed']);
});
});
});
it('max 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 (4, 2, 3).pipe(max()); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([4, 'completed']);
});
});
});
it('max with comparer func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
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 = maxZone1.run(() => {
return observable1.pipe(max((x: number, y: number) => {
expect(Zone.current.name).toEqual(maxZone1.name);
return x < y ? -1 : 1;
}));
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([4, 'completed']);
});
});
});
it('min 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 (4, 2, 3).pipe(min()); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([2, 'completed']);
});
});
});
it('min with comparer func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
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 = minZone1.run(() => {
return observable1.pipe(max((x: number, y: number) => {
expect(Zone.current.name).toEqual(minZone1.name);
return x < y ? 1 : -1;
}));
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([2, 'completed']);
});
});
});
it('reduce func callback should run in the correct zone', () => {
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 = reduceZone1.run(() => {
return observable1.pipe(reduce((acc: number, one: number) => {
expect(Zone.current.name).toEqual(reduceZone1.name);
return acc + one;
}));
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([9, 'completed']);
});
});
});
it('scan func callback should run in the correct zone', () => {
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 = scanZone1.run(() => {
return observable1.pipe(scan((acc: number, one: number) => {
expect(Zone.current.name).toEqual(scanZone1.name);
return acc + one;
}));
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([4, 6, 9, 'completed']);
});
});
});
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)); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([1, 1, 'completed']);
});
});
});
it('single func callback should run in the correct zone', () => {
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 = singleZone1.run(() => {
return observable1.pipe(single((val: any) => {
expect(Zone.current.name).toEqual(singleZone1.name);
return val === 4;
}));
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([4, 'completed']);
});
});
});
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)); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([4, 5, 'completed']);
});
});
});
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))); });
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
subscriber.unsubscribe();
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([2, 'completed']);
done();
});
});
}, Zone.root));
it('skipWhile func callback should run in the correct zone', asyncTest((done: any) => {
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 = skipZone1.run(() => {
return observable1.pipe(skipWhile((val: any) => {
expect(Zone.current.name).toEqual(skipZone1.name);
return val < 2;
}));
});
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
subscriber.unsubscribe();
expect(result).toEqual(2);
done();
},
(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)); });
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([3, 1, 2, 'completed']);
});
});
});
});

View File

@ -0,0 +1,128 @@
/**
* @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
*/
import {Observable, combineLatest, of } from 'rxjs';
import {combineAll, map} from 'rxjs/operators';
import {asyncTest} from '../test-util';
describe('Observable.combine', () => {
let log: any[];
let observable1: Observable<any>;
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 highOrder = source.pipe(map((src: any) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
return of (src);
}));
return highOrder.pipe(combineAll());
});
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([[1, 2], 'completed']);
done();
});
});
}, Zone.root));
it('combineAll func callback should run in the correct zone with project function',
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, 3);
const highOrder = source.pipe(map((src: any) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
return of (src);
}));
return highOrder.pipe(combineAll((x: any, y: any) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
return {x: x, y: y};
}));
});
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([{x: 1, y: 2}, 'completed']);
done();
});
});
}, Zone.root));
it('combineLatest 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 source = of (1, 2, 3);
const input = of (4, 5, 6);
return combineLatest(source, input);
});
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
});
});
expect(log).toEqual([[3, 4], [3, 5], [3, 6], 'completed']);
});
it('combineLatest func callback should run in the correct zone with project function', () => {
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; });
});
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
});
});
expect(log).toEqual([7, 8, 9, 'completed']);
});
});

View File

@ -0,0 +1,178 @@
/**
* @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
*/
import {Observable, asapScheduler, concat, of , range} from 'rxjs';
import {concatAll, concatMap, concatMapTo, map} from 'rxjs/operators';
import {asyncTest} from '../test-util';
describe('Observable instance method concat', () => {
let log: any[];
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
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'});
let observable1: Observable<any>;
let observable2: any;
let concatObservable: any;
beforeEach(() => { log = []; });
it('concat func callback should run in the correct zone', () => {
observable1 = constructorZone1.run(() => {
return new Observable(subscriber => {
expect(Zone.current.name).toEqual(constructorZone1.name);
subscriber.next(1);
subscriber.next(2);
subscriber.complete();
});
});
observable2 = constructorZone2.run(() => { return range(3, 4); });
constructorZone3.run(() => { concatObservable = concat(observable1, observable2); });
subscriptionZone.run(() => {
concatObservable.subscribe((concat: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(concat);
});
});
expect(log).toEqual([1, 2, 3, 4, 5, 6]);
});
xit('concat func callback should run in the correct zone with scheduler',
asyncTest((done: any) => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
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); });
observable2 = constructorZone2.run(() => { return range(3, 4); });
constructorZone3.run(
() => { concatObservable = concat(observable1, observable2, asapScheduler); });
subscriptionZone.run(() => {
concatObservable.subscribe(
(concat: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(concat);
},
(error: any) => { fail('subscribe failed' + error); },
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([1, 2, 3, 4, 5, 6]);
done();
});
});
expect(log).toEqual([]);
}, Zone.root));
it('concatAll func callback should run in the correct zone', asyncTest((done: any) => {
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); });
constructorZone2.run(() => {
const highOrder = observable1.pipe(map((v: any) => {
expect(Zone.current.name).toEqual(constructorZone2.name);
return of (v + 1);
}));
concatObservable = highOrder.pipe(concatAll());
});
subscriptionZone.run(() => {
concatObservable.subscribe(
(concat: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(concat);
},
(error: any) => { fail('subscribe failed' + error); },
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([1, 2, 3]);
done();
});
});
}, Zone.root));
it('concatMap func callback should run in the correct zone', asyncTest((done: any) => {
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 new Observable(subscriber => {
expect(Zone.current.name).toEqual(constructorZone1.name);
subscriber.next(1);
subscriber.next(2);
subscriber.next(3);
subscriber.next(4);
subscriber.complete();
});
});
constructorZone2.run(() => {
concatObservable = observable1.pipe(concatMap((v: any) => {
expect(Zone.current.name).toEqual(constructorZone2.name);
return of (0, 1);
}));
});
subscriptionZone.run(() => {
concatObservable.subscribe(
(concat: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(concat);
},
(error: any) => { fail('subscribe failed' + error); },
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([0, 1, 0, 1, 0, 1, 0, 1]);
done();
});
});
}, Zone.root));
it('concatMapTo func callback should run in the correct zone', asyncTest((done: any) => {
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 new Observable(subscriber => {
expect(Zone.current.name).toEqual(constructorZone1.name);
subscriber.next(1);
subscriber.next(2);
subscriber.next(3);
subscriber.next(4);
subscriber.complete();
});
});
constructorZone2.run(() => { concatObservable = observable1.pipe(concatMapTo(of (0, 1))); });
subscriptionZone.run(() => {
concatObservable.subscribe(
(concat: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(concat);
},
(error: any) => { fail('subscribe failed' + error); },
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([0, 1, 0, 1, 0, 1, 0, 1]);
done();
});
});
}, Zone.root));
});

View File

@ -0,0 +1,41 @@
/**
* @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
*/
import {Observable, range} from 'rxjs';
import {count} from 'rxjs/operators';
describe('Observable.count', () => {
let log: any[];
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('count func callback should run in the correct zone', () => {
observable1 = constructorZone1.run(() => {
return range(1, 3).pipe(count((i: number) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
return i % 2 === 0;
}));
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
});
});
expect(log).toEqual([1, 'completed']);
});
});

View File

@ -0,0 +1,65 @@
/**
* @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
*/
import {Observable, of , timer} from 'rxjs';
import {debounce, debounceTime} from 'rxjs/operators';
import {asyncTest} from '../test-util';
describe('Observable.debounce', () => {
let log: any[];
let observable1: Observable<any>;
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(() => {
expect(Zone.current.name).toEqual(constructorZone1.name);
return timer(100);
}));
});
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
done();
});
});
expect(log).toEqual([3, 'completed']);
}, Zone.root));
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)); });
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
done();
});
});
expect(log).toEqual([3, 'completed']);
}, Zone.root));
});

View File

@ -0,0 +1,40 @@
/**
* @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
*/
import {Observable, of } from 'rxjs';
import {defaultIfEmpty} from 'rxjs/operators';
import {asyncTest} from '../test-util';
describe('Observable.defaultIfEmpty', () => {
let log: any[];
let observable1: Observable<any>;
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)); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual(['empty', 'completed']);
done();
});
});
}, Zone.root));
});

View File

@ -0,0 +1,62 @@
/**
* @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
*/
import {Observable, of , timer} from 'rxjs';
import {delay, delayWhen} from 'rxjs/operators';
import {asyncTest} from '../test-util';
describe('Observable.delay', () => {
let log: any[];
let observable1: Observable<any>;
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)); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([1, 2, 3, 'completed']);
done();
});
});
}, Zone.root));
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); })); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([1, 2, 3, 'completed']);
done();
});
});
}, Zone.root));
});

View File

@ -0,0 +1,87 @@
/**
* @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
*/
import {Observable, of } from 'rxjs';
import {distinct, distinctUntilChanged, distinctUntilKeyChanged} from 'rxjs/operators';
describe('Observable.distinct', () => {
let log: any[];
let observable1: Observable<any>;
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()); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
});
});
expect(log).toEqual([1, 2, 3, 4, 'completed']);
});
it('distinctUntilChanged 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, 1, 2, 3, 3, 4).pipe(distinctUntilChanged()); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
});
});
expect(log).toEqual([1, 2, 1, 2, 3, 4, 'completed']);
});
it('distinctUntilKeyChanged 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 ({age: 4, name: 'Foo'}, {age: 7, name: 'Bar'}, {age: 5, name: 'Foo'},
{age: 6, name: 'Foo'})
.pipe(distinctUntilKeyChanged('name'));
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
});
});
expect(log).toEqual(
[{age: 4, name: 'Foo'}, {age: 7, name: 'Bar'}, {age: 5, name: 'Foo'}, 'completed']);
});
});

View File

@ -0,0 +1,45 @@
/**
* @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
*/
import {Observable, of } from 'rxjs';
import {tap} from 'rxjs/operators';
describe('Observable.tap', () => {
let log: any[];
let observable1: Observable<any>;
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 = doZone1.run(() => {
return observable1.pipe(tap((v: any) => {
log.push(v);
expect(Zone.current.name).toEqual(doZone1.name);
}));
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push('result' + result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([1, 'result1', 'completed']);
});
});
});
});

View File

@ -0,0 +1,99 @@
/**
* @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
*/
import {Observable, observable, of } from 'rxjs';
import {pairwise, partition, pluck} from 'rxjs/operators';
import {ifEnvSupports} from '../test-util';
import {supportFeature} from './rxjs.util';
describe('Observable.map', () => {
let log: any[];
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('pairwise func callback should run in the correct zone', () => {
observable1 = constructorZone1.run(() => { return of (1, 2, 3).pipe(pairwise()); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('completed');
});
});
expect(log).toEqual([[1, 2], [2, 3], 'completed']);
});
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 part: any = partitionZone.run(() => {
return observable1.pipe(partition((val: any) => {
expect(Zone.current.name).toEqual(partitionZone.name);
return val % 2 === 0;
}));
});
subscriptionZone.run(() => {
part[0].subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('first' + result);
},
() => { fail('should not call error'); },
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('completed');
});
part[1].subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('second' + result);
},
() => { fail('should not call error'); },
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('completed');
});
});
expect(log).toEqual(['first2', 'completed', 'second1', 'second3', 'completed']);
});
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')); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('completed');
});
});
expect(log).toEqual([1, 3, 'completed']);
});
});

View File

@ -0,0 +1,209 @@
/**
* @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
*/
import {Observable, interval, merge, of , range} from 'rxjs';
import {expand, map, mergeAll, mergeMap, mergeMapTo, switchAll, switchMap, switchMapTo, take} from 'rxjs/operators';
import {asyncTest, ifEnvSupports} from '../test-util';
import {supportFeature} from './rxjs.util';
describe('Observable.merge', () => {
let log: any[];
let observable1: Observable<any>;
let defaultTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
beforeEach(() => {
log = [];
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
});
afterEach(() => { jasmine.DEFAULT_TIMEOUT_INTERVAL = defaultTimeout; });
it('expand func callback should run in the correct zone', () => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const expandZone1: Zone = Zone.current.fork({name: 'Expand Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return of (2); });
observable1 = expandZone1.run(() => {
return observable1.pipe(
expand((val: any) => {
expect(Zone.current.name).toEqual(expandZone1.name);
return of (1 + val);
}),
take(2));
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
});
});
expect(log).toEqual([2, 3, 'completed']);
});
it('merge 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'});
const error = new Error('test');
observable1 = constructorZone1.run(
() => { return merge(interval(10).pipe(take(2)), interval(15).pipe(take(1))); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([0, 0, 1, 'completed']);
done();
});
});
}, Zone.root));
it('mergeAll 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'});
const error = new Error('test');
observable1 = constructorZone1.run(
() => { return of (1, 2).pipe(map((v: any) => { return of (v + 1); }), mergeAll()); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([2, 3, 'completed']);
done();
});
});
}, Zone.root));
it('mergeMap 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).pipe(mergeMap((v: any) => { return of (v + 1); })); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([2, 3, 'completed']);
});
});
});
it('mergeMapTo 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).pipe(mergeMapTo(of (10))); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([10, 10, 'completed']);
});
});
});
it('switch 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 range(0, 3).pipe(map(function(x: any) { return range(x, 3); }), switchAll());
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([0, 1, 2, 1, 2, 3, 2, 3, 4, 'completed']);
});
});
});
it('switchMap 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 range(0, 3).pipe(switchMap(function(x: any) { return range(x, 3); })); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([0, 1, 2, 1, 2, 3, 2, 3, 4, 'completed']);
});
});
});
it('switchMapTo 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 range(0, 3).pipe(switchMapTo('a')); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual(['a', 'a', 'a', 'completed']);
});
});
});
});

View File

@ -0,0 +1,68 @@
/**
* @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
*/
import {Observable, Subject, of } from 'rxjs';
import {mapTo, multicast, tap} from 'rxjs/operators';
// TODO: @JiaLiPassion, Observable.prototype.multicast return a readonly _subscribe
// should find another way to patch subscribe
describe('Observable.multicast', () => {
let log: any[];
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const doZone1: Zone = Zone.current.fork({name: 'Do Zone1'});
const mapZone1: Zone = Zone.current.fork({name: 'Map Zone1'});
const multicastZone1: Zone = Zone.current.fork({name: 'Multicast Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('multicast func callback should run in the correct zone', () => {
observable1 = constructorZone1.run(() => { return of (1, 2, 3); });
observable1 = doZone1.run(() => {
return observable1.pipe(tap((v: any) => {
expect(Zone.current.name).toEqual(doZone1.name);
log.push('do' + v);
}));
});
observable1 = mapZone1.run(() => { return observable1.pipe(mapTo('test')); });
const multi: any = multicastZone1.run(() => {
return observable1.pipe(multicast(() => {
expect(Zone.current.name).toEqual(multicastZone1.name);
return new Subject();
}));
});
multi.subscribe((val: any) => { log.push('one' + val); });
multi.subscribe((val: any) => { log.push('two' + val); });
multi.connect();
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
});
});
expect(log).toEqual([
'do1', 'onetest', 'twotest', 'do2', 'onetest', 'twotest', 'do3', 'onetest', 'twotest', 'do1',
'test', 'do2', 'test', 'do3', 'test', 'completed'
]);
});
});

View File

@ -0,0 +1,54 @@
/**
* @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
*/
import {Notification, Observable, of } from 'rxjs';
import {dematerialize} from 'rxjs/operators';
import {asyncTest, ifEnvSupports} from '../test-util';
const supportNotification = function() {
return typeof Notification !== 'undefined';
};
(supportNotification as any).message = 'RxNotification';
describe('Observable.notification', ifEnvSupports(supportNotification, () => {
let log: any[];
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('notification 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(() => {
const notifA = new Notification('N' as any, 'A');
const notifB = new Notification('N' as any, 'B');
const notifE = new Notification('E' as any, void 0, error);
const materialized = of (notifA, notifB, notifE as any);
return materialized.pipe(dematerialize());
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => {
log.push(err);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual(['A', 'B', error]);
});
});
});
}));

View File

@ -0,0 +1,41 @@
/**
* @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
*/
import {Observable, interval, race} from 'rxjs';
import {mapTo} from 'rxjs/operators';
import {asyncTest} from '../test-util';
describe('Observable.race', () => {
let log: any[];
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('race 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 race(interval(10).pipe(mapTo('a')), interval(15).pipe(mapTo('b'))); });
subscriptionZone.run(() => {
const subscriber: any = observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
subscriber.complete();
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual(['a', 'completed']);
done();
});
});
}, Zone.root));
});

View File

@ -0,0 +1,67 @@
/**
* @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
*/
import {Observable, interval} from 'rxjs';
import {sample, take, throttle} from 'rxjs/operators';
import {asyncTest} from '../test-util';
describe('Observable.sample', () => {
let log: any[];
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('sample 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(sample(interval(15))); });
subscriptionZone.run(() => {
const subscriber: any = observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
subscriber.complete();
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([0, 'completed']);
done();
});
});
}, Zone.root));
xit('throttle 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(take(5), throttle((val: any) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
return interval(20);
}));
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([0, 2, 4, 'completed']);
done();
});
});
}, Zone.root));
});

View File

@ -0,0 +1,115 @@
/**
* @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
*/
import {Observable, interval, of } from 'rxjs';
import {take, takeLast, takeUntil, takeWhile} from 'rxjs/operators';
import {asyncTest} from '../test-util';
describe('Observable.take', () => {
let log: any[];
let observable1: Observable<any>;
let defaultTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
beforeEach(() => {
log = [];
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
});
afterEach(() => { jasmine.DEFAULT_TIMEOUT_INTERVAL = defaultTimeout; });
it('take 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).pipe(take(1)); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([1, 'completed']);
});
});
});
it('takeLast 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).pipe(takeLast(1)); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([3, 'completed']);
});
});
});
xit('takeUntil 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(takeUntil(interval(25))); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([0, 1, 'completed']);
done();
});
});
}, Zone.root));
it('takeWhile func callback should run in the correct zone', asyncTest((done: any) => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const takeZone1: Zone = Zone.current.fork({name: 'Take Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
observable1 = constructorZone1.run(() => { return interval(10); });
observable1 = takeZone1.run(() => {
return observable1.pipe(takeWhile((val: any) => {
expect(Zone.current.name).toEqual(takeZone1.name);
return val < 2;
}));
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([0, 1, 'completed']);
done();
});
});
}, Zone.root));
});

View File

@ -0,0 +1,59 @@
/**
* @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
*/
import {Observable, of } from 'rxjs';
import {timeout} from 'rxjs/operators';
import {asyncTest, isPhantomJS} from '../test-util';
describe('Observable.timeout', () => {
let log: any[];
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('timeout func callback should run in the correct zone', asyncTest((done: any) => {
if (isPhantomJS()) {
done();
return;
}
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(timeout(10)); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([1, 'completed']);
done();
});
});
}, Zone.root));
it('promise 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'});
const promise: any = constructorZone1.run(() => { return of (1).toPromise(); });
subscriptionZone.run(() => {
promise.then(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(result).toEqual(1);
done();
},
(err: any) => { fail('should not call error'); });
});
}, Zone.root));
});

View File

@ -0,0 +1,135 @@
/**
* @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
*/
import {Observable, interval, timer} from 'rxjs';
import {mergeAll, take, window, windowCount, windowToggle, windowWhen} from 'rxjs/operators';
import {asyncTest} from '../test-util';
// @JiaLiPassion, in Safari 9(iOS 9), the case is not
// stable because of the timer, try to fix it later
xdescribe('Observable.window', () => {
let log: any[];
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('window 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'});
const error = new Error('test');
observable1 = constructorZone1.run(() => {
const source = timer(0, 10).pipe(take(6));
const w = source.pipe(window(interval(30)));
return w.pipe(mergeAll());
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([0, 1, 2, 3, 4, 5, 'completed']);
done();
});
});
}, Zone.root));
it('windowCount 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'});
const error = new Error('test');
observable1 = constructorZone1.run(() => {
const source = timer(0, 10).pipe(take(10));
const window = source.pipe(windowCount(4));
return window.pipe(mergeAll());
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'completed']);
done();
});
});
}, Zone.root));
it('windowToggle func callback should run in the correct zone', asyncTest((done: any) => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const windowZone1: Zone = Zone.current.fork({name: 'Window Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return timer(0, 10).pipe(take(10)); });
windowZone1.run(() => {
return observable1.pipe(windowToggle(interval(30), (val: any) => {
expect(Zone.current.name).toEqual(windowZone1.name);
return interval(15);
}), mergeAll());
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'completed']);
done();
});
});
}, Zone.root));
it('windowWhen func callback should run in the correct zone', asyncTest((done: any) => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const windowZone1: Zone = Zone.current.fork({name: 'Window Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const error = new Error('test');
observable1 = constructorZone1.run(() => { return timer(0, 10).pipe(take(10)); });
windowZone1.run(() => {
return observable1.pipe(
windowWhen(() => {
expect(Zone.current.name).toEqual(windowZone1.name);
return interval(15);
}),
mergeAll());
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
(err: any) => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'completed']);
done();
});
});
}, Zone.root));
});

View File

@ -0,0 +1,59 @@
/**
* @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
*/
import {asapScheduler, of } from 'rxjs';
import {map, observeOn} from 'rxjs/operators';
import {asyncTest} from '../test-util';
describe('Scheduler.asap', () => {
let log: any[];
let errorCallback: Function;
const constructorZone: Zone = Zone.root.fork({name: 'Constructor Zone'});
beforeEach(() => { log = []; });
it('scheduler asap should run in correct zone', asyncTest((done: any) => {
let observable: any;
constructorZone.run(() => { observable = of (1, 2, 3).pipe(observeOn(asapScheduler)); });
const zone = Zone.current.fork({name: 'subscribeZone'});
zone.run(() => {
observable.pipe(map((value: number) => { return value; }))
.subscribe(
(value: number) => {
expect(Zone.current.name).toEqual(zone.name);
if (value === 3) {
setTimeout(done);
}
},
(err: any) => { fail('should not be here'); });
});
}, Zone.root));
it('scheduler asap error should run in correct zone', asyncTest((done: any) => {
let observable: any;
constructorZone.run(() => { observable = of (1, 2, 3).pipe(observeOn(asapScheduler)); });
Zone.root.run(() => {
observable
.pipe(map((value: number) => {
if (value === 3) {
throw new Error('oops');
}
return value;
}))
.subscribe((value: number) => {}, (err: any) => {
expect(err.message).toEqual('oops');
expect(Zone.current.name).toEqual('<root>');
done();
});
});
}, Zone.root));
});

View File

@ -0,0 +1,86 @@
/**
* @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
*/
import {asapScheduler, bindCallback} from 'rxjs';
import {asyncTest} from '../test-util';
describe('Observable.bindCallback', () => {
let log: any[];
const constructorZone: Zone = Zone.root.fork({name: 'Constructor Zone'});
const subscriptionZone: Zone = Zone.root.fork({name: 'Subscription Zone'});
let func: any;
let boundFunc: any;
let observable: any;
beforeEach(() => { log = []; });
it('bindCallback func callback should run in the correct zone', () => {
constructorZone.run(() => {
func = function(arg0: any, callback: Function) {
expect(Zone.current.name).toEqual(constructorZone.name);
callback(arg0);
};
boundFunc = bindCallback(func);
observable = boundFunc('test');
});
subscriptionZone.run(() => {
observable.subscribe((arg: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('next' + arg);
});
});
expect(log).toEqual(['nexttest']);
});
it('bindCallback with selector should run in correct zone', () => {
constructorZone.run(() => {
func = function(arg0: any, callback: Function) {
expect(Zone.current.name).toEqual(constructorZone.name);
callback(arg0);
};
boundFunc = bindCallback(func, (arg: any) => {
expect(Zone.current.name).toEqual(constructorZone.name);
return 'selector' + arg;
});
observable = boundFunc('test');
});
subscriptionZone.run(() => {
observable.subscribe((arg: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('next' + arg);
});
});
expect(log).toEqual(['nextselectortest']);
});
it('bindCallback with async scheduler should run in correct zone', asyncTest((done: any) => {
constructorZone.run(() => {
func = function(arg0: any, callback: Function) {
expect(Zone.current.name).toEqual(constructorZone.name);
callback(arg0);
};
boundFunc = bindCallback(func, () => true, asapScheduler);
observable = boundFunc('test');
});
subscriptionZone.run(() => {
observable.subscribe((arg: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('next' + arg);
done();
});
});
expect(log).toEqual([]);
}, Zone.root));
});

View File

@ -0,0 +1,108 @@
/**
* @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
*/
import {Observable, asapScheduler, bindCallback, bindNodeCallback} from 'rxjs';
import {asyncTest} from '../test-util';
describe('Observable.bindNodeCallback', () => {
let log: any[];
const constructorZone: Zone = Zone.root.fork({name: 'Constructor Zone'});
const subscriptionZone: Zone = Zone.root.fork({name: 'Subscription Zone'});
let func: any;
let boundFunc: any;
let observable: any;
beforeEach(() => { log = []; });
it('bindNodeCallback func callback should run in the correct zone', () => {
constructorZone.run(() => {
func = function(arg: any, callback: (error: any, result: any) => any) {
expect(Zone.current.name).toEqual(constructorZone.name);
callback(null, arg);
};
boundFunc = bindNodeCallback(func);
observable = boundFunc('test');
});
subscriptionZone.run(() => {
observable.subscribe((arg: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('next' + arg);
});
});
expect(log).toEqual(['nexttest']);
});
it('bindNodeCallback with selector should run in correct zone', () => {
constructorZone.run(() => {
func = function(arg: any, callback: (error: any, result: any) => any) {
expect(Zone.current.name).toEqual(constructorZone.name);
callback(null, arg);
};
boundFunc = bindNodeCallback(func, (arg: any) => {
expect(Zone.current.name).toEqual(constructorZone.name);
return 'selector' + arg;
});
observable = boundFunc('test');
});
subscriptionZone.run(() => {
observable.subscribe((arg: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('next' + arg);
});
});
expect(log).toEqual(['nextselectortest']);
});
it('bindNodeCallback with async scheduler should run in correct zone', asyncTest((done: any) => {
constructorZone.run(() => {
func = function(arg: any, callback: (error: any, result: any) => any) {
expect(Zone.current.name).toEqual(constructorZone.name);
callback(null, arg);
};
boundFunc = bindCallback(func, () => true, asapScheduler);
observable = boundFunc('test');
});
subscriptionZone.run(() => {
observable.subscribe((arg: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('next' + arg);
done();
});
});
expect(log).toEqual([]);
}));
it('bindNodeCallback call with error should run in correct zone', () => {
constructorZone.run(() => {
func = function(arg: any, callback: (error: any, result: any) => any) {
expect(Zone.current.name).toEqual(constructorZone.name);
callback(arg, null);
};
boundFunc = bindCallback(func);
observable = boundFunc('test');
});
subscriptionZone.run(() => {
observable.subscribe(
(arg: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('next' + arg);
},
(error: any) => { log.push('error' + error); });
});
expect(log).toEqual(['nexttest,']);
});
});

View File

@ -0,0 +1,86 @@
/**
* @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
*/
import {Observable, combineLatest} from 'rxjs';
describe('Observable.combineLatest', () => {
let log: any[];
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
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'});
let observable1: Observable<any>;
let observable2: any;
let subscriber1: any;
let subscriber2: any;
let combinedObservable: any;
beforeEach(() => { log = []; });
it('combineLatest func should run in the correct zone', () => {
observable1 = constructorZone1.run(() => new Observable((_subscriber) => {
subscriber1 = _subscriber;
expect(Zone.current.name).toEqual(constructorZone1.name);
log.push('setup1');
}));
observable2 = constructorZone2.run(() => new Observable((_subscriber) => {
subscriber2 = _subscriber;
expect(Zone.current.name).toEqual(constructorZone2.name);
log.push('setup2');
}));
constructorZone3.run(() => { combinedObservable = combineLatest(observable1, observable2); });
subscriptionZone.run(() => {
combinedObservable.subscribe((combined: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(combined);
});
});
subscriber1.next(1);
subscriber2.next(2);
subscriber2.next(3);
expect(log).toEqual(['setup1', 'setup2', [1, 2], [1, 3]]);
});
it('combineLatest func with project function should run in the correct zone', () => {
observable1 = constructorZone1.run(() => new Observable((_subscriber) => {
subscriber1 = _subscriber;
expect(Zone.current.name).toEqual(constructorZone1.name);
log.push('setup1');
}));
observable2 = constructorZone2.run(() => new Observable((_subscriber) => {
subscriber2 = _subscriber;
expect(Zone.current.name).toEqual(constructorZone2.name);
log.push('setup2');
}));
constructorZone3.run(() => {
combinedObservable = combineLatest(observable1, observable2, (x: number, y: number) => {
expect(Zone.current.name).toEqual(constructorZone3.name);
return x + y;
});
});
subscriptionZone.run(() => {
combinedObservable.subscribe((combined: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(combined);
});
});
subscriber1.next(1);
subscriber2.next(2);
subscriber2.next(3);
expect(log).toEqual(['setup1', 'setup2', 3, 4]);
});
});

View File

@ -0,0 +1,209 @@
/**
* @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
*/
import {Observable, Subject} from 'rxjs';
import {map} from 'rxjs/operators';
/**
* The point of these tests, is to ensure that all callbacks execute in the Zone which was active
* when the callback was passed into the Rx.
*
* The implications are:
* - Observable callback passed into `Observable` executes in the same Zone as when the
* `new Observable` was invoked.
* - The subscription callbacks passed into `subscribe` execute in the same Zone as when the
* `subscribe` method was invoked.
* - The operator callbacks passe into `map`, etc..., execute in the same Zone as when the
* `operator` (`lift`) method was invoked.
*/
describe('Zone interaction', () => {
it('should run methods in the zone of declaration', () => {
const log: any[] = [];
const constructorZone: Zone = Zone.current.fork({name: 'Constructor Zone'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
let subscriber: any = null;
const observable: any =
constructorZone.run(() => new Observable((_subscriber: any) => {
subscriber = _subscriber;
log.push('setup');
expect(Zone.current.name).toEqual(constructorZone.name);
return () => {
expect(Zone.current.name).toEqual(constructorZone.name);
log.push('cleanup');
};
}));
subscriptionZone.run(
() => observable.subscribe(
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('next');
},
(): any => null,
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('complete');
}));
subscriber.next('MyValue');
subscriber.complete();
expect(log).toEqual(['setup', 'next', 'complete', 'cleanup']);
log.length = 0;
subscriptionZone.run(() => observable.subscribe((): any => null, () => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('error');
}, (): any => null));
subscriber.next('MyValue');
subscriber.error('MyError');
expect(log).toEqual(['setup', 'error', 'cleanup']);
});
it('should run methods in the zone of declaration when nexting synchronously', () => {
const log: any[] = [];
const rootZone: Zone = Zone.current;
const constructorZone: Zone = Zone.current.fork({name: 'Constructor Zone'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const observable: any =
constructorZone.run(() => new Observable((subscriber: any) => {
// Execute the `next`/`complete` in different zone, and assert that
// correct zone
// is restored.
rootZone.run(() => {
subscriber.next('MyValue');
subscriber.complete();
});
return () => {
expect(Zone.current.name).toEqual(constructorZone.name);
log.push('cleanup');
};
}));
subscriptionZone.run(
() => observable.subscribe(
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('next');
},
(): any => null,
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('complete');
}));
expect(log).toEqual(['next', 'complete', 'cleanup']);
});
it('should run operators in the zone of declaration', () => {
const log: any[] = [];
const rootZone: Zone = Zone.current;
const constructorZone: Zone = Zone.current.fork({name: 'Constructor Zone'});
const operatorZone: Zone = Zone.current.fork({name: 'Operator Zone'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
let observable: any =
constructorZone.run(() => new Observable((subscriber: any) => {
// Execute the `next`/`complete` in different zone, and assert that
// correct zone
// is restored.
rootZone.run(() => {
subscriber.next('MyValue');
subscriber.complete();
});
return () => {
expect(Zone.current.name).toEqual(constructorZone.name);
log.push('cleanup');
};
}));
observable = operatorZone.run(() => observable.pipe(map((value: any) => {
expect(Zone.current.name).toEqual(operatorZone.name);
log.push('map: ' + value);
return value;
})));
subscriptionZone.run(
() => observable.subscribe(
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('next');
},
(e: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('error: ' + e);
},
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('complete');
}));
expect(log).toEqual(['map: MyValue', 'next', 'complete', 'cleanup']);
});
it('should run subscribe in zone of declaration with Observable.create', () => {
const log: any[] = [];
const constructorZone: Zone = Zone.current.fork({name: 'Constructor Zone'});
let observable: any = constructorZone.run(() => Observable.create((subscriber: any) => {
expect(Zone.current.name).toEqual(constructorZone.name);
subscriber.next(1);
subscriber.complete();
return () => {
expect(Zone.current.name).toEqual(constructorZone.name);
log.push('cleanup');
};
}));
observable.subscribe(() => { log.push('next'); });
expect(log).toEqual(['next', 'cleanup']);
});
it('should run in the zone when subscribe is called to the same Subject', () => {
const log: any[] = [];
const constructorZone: Zone = Zone.current.fork({name: 'Constructor Zone'});
const subscriptionZone1: Zone = Zone.current.fork({name: 'Subscription Zone 1'});
const subscriptionZone2: Zone = Zone.current.fork({name: 'Subscription Zone 2'});
let subject: any;
constructorZone.run(() => { subject = new Subject(); });
let subscription1: any;
let subscription2: any;
subscriptionZone1.run(() => {
subscription1 = subject.subscribe(
() => {
expect(Zone.current.name).toEqual(subscriptionZone1.name);
log.push('next1');
},
() => {},
() => {
expect(Zone.current.name).toEqual(subscriptionZone1.name);
log.push('complete1');
});
});
subscriptionZone2.run(() => {
subscription2 = subject.subscribe(
() => {
expect(Zone.current.name).toEqual(subscriptionZone2.name);
log.push('next2');
},
() => {},
() => {
expect(Zone.current.name).toEqual(subscriptionZone2.name);
log.push('complete2');
});
});
subject.next(1);
subject.complete();
expect(log).toEqual(['next1', 'next2', 'complete1', 'complete2']);
});
});

View File

@ -0,0 +1,86 @@
/**
* @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
*/
import {Observable, asapScheduler, concat, range} from 'rxjs';
import {asyncTest} from '../test-util';
describe('Observable.concat', () => {
let log: any[];
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
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'});
let observable1: Observable<any>;
let observable2: any;
let concatObservable: any;
beforeEach(() => { log = []; });
it('concat func callback should run in the correct zone', () => {
observable1 = constructorZone1.run(() => {
return new Observable(subscriber => {
expect(Zone.current.name).toEqual(constructorZone1.name);
subscriber.next(1);
subscriber.next(2);
subscriber.complete();
});
});
observable2 = constructorZone2.run(() => { return range(3, 4); });
constructorZone3.run(() => { concatObservable = concat(observable1, observable2); });
subscriptionZone.run(() => {
concatObservable.subscribe((concat: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(concat);
});
});
expect(log).toEqual([1, 2, 3, 4, 5, 6]);
});
it('concat func callback should run in the correct zone with scheduler',
asyncTest((done: any) => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
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 new Observable(subscriber => {
expect(Zone.current.name).toEqual(constructorZone1.name);
subscriber.next(1);
subscriber.next(2);
subscriber.complete();
});
});
observable2 = constructorZone2.run(() => { return range(3, 4); });
constructorZone3.run(
() => { concatObservable = concat(observable1, observable2, asapScheduler); });
subscriptionZone.run(() => {
concatObservable.subscribe(
(concat: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(concat);
},
(error: any) => { fail('subscribe failed' + error); },
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([1, 2, 3, 4, 5, 6]);
done();
});
});
expect(log).toEqual([]);
}, Zone.root));
});

View File

@ -0,0 +1,44 @@
/**
* @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
*/
import {Observable, defer} from 'rxjs';
describe('Observable.defer', () => {
let log: any[];
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('defer func callback should run in the correct zone', () => {
observable1 = constructorZone1.run(() => {
return defer(() => {
return new Observable<number>(subscribe => {
log.push('setup');
expect(Zone.current.name).toEqual(constructorZone1.name);
subscribe.next(1);
subscribe.complete();
return () => {
expect(Zone.current.name).toEqual(constructorZone1.name);
log.push('cleanup');
};
});
});
});
subscriptionZone.run(() => {
observable1.subscribe((result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
});
});
expect(log).toEqual(['setup', 1, 'cleanup']);
});
});

View File

@ -0,0 +1,28 @@
/**
* @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
*/
import {Observable, empty} from 'rxjs';
describe('Observable.empty', () => {
let log: any[];
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('empty func callback should run in the correct zone', () => {
observable1 = constructorZone1.run(() => { return empty(); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => { fail('should not call next'); },
() => { fail('should not call error'); },
() => { expect(Zone.current.name).toEqual(subscriptionZone.name); });
});
});
});

View File

@ -0,0 +1,61 @@
/**
* @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
*/
import {Observable, forkJoin, from, range} from 'rxjs';
describe('Observable.forkjoin', () => {
let log: any[];
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('forkjoin func callback should run in the correct zone', () => {
observable1 = constructorZone1.run(() => { return forkJoin(range(1, 2), from([4, 5])); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('completed');
});
});
expect(log).toEqual([[2, 5], 'completed']);
});
it('forkjoin func callback with selector should run in the correct zone', () => {
observable1 = constructorZone1.run(() => {
return forkJoin(range(1, 2), from([4, 5]), (x: number, y: number) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
return x + y;
});
});
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('completed');
});
});
expect(log).toEqual([7, 'completed']);
});
});

View File

@ -0,0 +1,81 @@
/**
* @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
*/
import {Observable, from} from 'rxjs';
import {asyncTest} from '../test-util';
describe('Observable.from', () => {
let log: any[];
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('from array should run in the correct zone', () => {
observable1 = constructorZone1.run(() => { return from([1, 2]); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('completed');
});
});
expect(log).toEqual([1, 2, 'completed']);
});
it('from array like object should run in the correct zone', () => {
observable1 = constructorZone1.run(() => { return from('foo'); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('completed');
});
});
expect(log).toEqual(['f', 'o', 'o', 'completed']);
});
it('from promise object 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 from(new Promise((resolve, reject) => { resolve(1); })); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
(error: any) => { fail('should not call error' + error); },
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('completed');
expect(log).toEqual([1, 'completed']);
done();
});
});
expect(log).toEqual([]);
}, Zone.root));
});

View File

@ -0,0 +1,95 @@
/**
* @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
*/
import {Observable, fromEvent, fromEventPattern} from 'rxjs';
import {isBrowser} from '../../lib/common/utils';
import {ifEnvSupports} from '../test-util';
function isEventTarget() {
return isBrowser;
}
(isEventTarget as any).message = 'EventTargetTest';
describe('Observable.fromEvent', () => {
let log: any[];
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
const triggerZone: Zone = Zone.current.fork({name: 'Trigger Zone'});
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('fromEvent EventTarget func callback should run in the correct zone',
ifEnvSupports(isEventTarget, () => {
observable1 = constructorZone1.run(() => { return fromEvent(document, 'click'); });
const clickEvent = document.createEvent('Event');
clickEvent.initEvent('click', true, true);
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('completed');
});
});
triggerZone.run(() => { document.dispatchEvent(clickEvent); });
expect(log).toEqual([clickEvent]);
}));
it('fromEventPattern EventTarget func callback should run in the correct zone',
ifEnvSupports(isEventTarget, () => {
const button = document.createElement('button');
document.body.appendChild(button);
observable1 = constructorZone1.run(() => {
return fromEventPattern(
(handler: any) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
button.addEventListener('click', handler);
log.push('addListener');
},
(handler: any) => {
expect(Zone.current.name).toEqual(constructorZone1.name);
button.removeEventListener('click', handler);
document.body.removeChild(button);
log.push('removeListener');
});
});
const clickEvent = document.createEvent('Event');
clickEvent.initEvent('click', false, false);
const subscriper: any = subscriptionZone.run(() => {
return observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('completed');
});
});
triggerZone.run(() => {
button.dispatchEvent(clickEvent);
subscriper.complete();
});
expect(log).toEqual(['addListener', clickEvent, 'completed', 'removeListener']);
}));
});

View File

@ -0,0 +1,41 @@
/**
* @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
*/
import {from} from 'rxjs';
import {asyncTest} from '../test-util';
describe('Observable.fromPromise', () => {
let log: any[];
let observable1: any;
beforeEach(() => { log = []; });
it('fromPromise func callback should run in the correct zone', asyncTest((done: any) => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const promiseZone1: Zone = Zone.current.fork({name: 'Promise Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
let res: any;
let promise: any =
promiseZone1.run(() => { return new Promise((resolve, reject) => { res = resolve; }); });
observable1 = constructorZone1.run(() => { return from(promise); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
expect(log).toEqual([1]);
done();
},
() => { fail('should not call error'); }, () => {});
});
res(1);
expect(log).toEqual([]);
}, Zone.root));
});

View File

@ -0,0 +1,37 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {Observable, interval} from 'rxjs';
import {asyncTest} from '../test-util';
describe('Observable.interval', () => {
let log: any[];
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('interval 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); });
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
if (result >= 3) {
subscriber.unsubscribe();
expect(log).toEqual([0, 1, 2, 3]);
done();
}
},
() => { fail('should not call error'); }, () => {});
});
}, Zone.root));
});

View File

@ -0,0 +1,47 @@
/**
* @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
*/
import {Observable, interval, merge} from 'rxjs';
import {map, take} from 'rxjs/operators';
import {asyncTest} from '../test-util';
describe('Observable.merge', () => {
let log: any[];
beforeEach(() => { log = []; });
it('merge func callback should run in the correct zone', asyncTest((done: any) => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
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'});
const observable1: any = constructorZone1.run(
() => { return interval(8).pipe(map(v => 'observable1' + v), take(1)); });
const observable2: any = constructorZone2.run(
() => { return interval(10).pipe(map(v => 'observable2' + v), take(1)); });
const observable3: any =
constructorZone3.run(() => { return merge(observable1, observable2); });
subscriptionZone.run(() => {
const subscriber = observable3.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual(['observable10', 'observable20', 'completed']);
done();
});
});
}, Zone.root));
});

View File

@ -0,0 +1,33 @@
/**
* @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
*/
import {NEVER, Observable} from 'rxjs';
import {startWith} from 'rxjs/operators';
describe('Observable.never', () => {
let log: any[];
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('never func callback should run in the correct zone', () => {
observable1 = constructorZone1.run(() => { return NEVER.pipe(startWith(7)); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); }, () => { fail('should not call complete'); });
});
expect(log).toEqual([7]);
});
});

View File

@ -0,0 +1,36 @@
/**
* @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
*/
import {Observable, of } from 'rxjs';
describe('Observable.of', () => {
let log: any[];
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('of func callback should run in the correct zone', () => {
observable1 = constructorZone1.run(() => { return of (1, 2, 3); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push(result);
},
() => { fail('should not call error'); },
() => {
expect(Zone.current.name).toEqual(subscriptionZone.name);
log.push('completed');
});
});
expect(log).toEqual([1, 2, 3, 'completed']);
});
});

View File

@ -0,0 +1,61 @@
/**
* @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
*/
import {Observable, asapScheduler, range} from 'rxjs';
import {asyncTest} from '../test-util';
describe('Observable.range', () => {
let log: any[];
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('range func callback should run in the correct zone', () => {
observable1 = constructorZone1.run(() => { return range(1, 3); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
});
});
expect(log).toEqual([1, 2, 3, 'completed']);
});
it('range func callback should run in the correct zone with scheduler', 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 range(1, 3, asapScheduler); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([1, 2, 3, 'completed']);
done();
});
});
expect(log).toEqual([]);
}, Zone.root));
});

View File

@ -0,0 +1,54 @@
/**
* @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
*/
(Object as any).setPrototypeOf = (Object as any).setPrototypeOf || function(obj: any, proto: any) {
obj.__proto__ = proto;
return obj;
};
import '../../lib/rxjs/rxjs';
import './rxjs.common.spec';
import './rxjs.asap.spec';
import './rxjs.bindCallback.spec';
import './rxjs.bindNodeCallback.spec';
import './rxjs.combineLatest.spec';
import './rxjs.concat.spec';
import './rxjs.defer.spec';
import './rxjs.empty.spec';
import './rxjs.forkjoin.spec';
import './rxjs.from.spec';
import './rxjs.fromEvent.spec';
import './rxjs.fromPromise.spec';
import './rxjs.interval.spec';
import './rxjs.merge.spec';
import './rxjs.never.spec';
import './rxjs.of.spec';
import './rxjs.range.spec';
import './rxjs.throw.spec';
import './rxjs.timer.spec';
import './rxjs.zip.spec';
import './rxjs.Observable.audit.spec';
import './rxjs.Observable.buffer.spec';
import './rxjs.Observable.catch.spec';
import './rxjs.Observable.combine.spec';
import './rxjs.Observable.concat.spec';
import './rxjs.Observable.count.spec';
import './rxjs.Observable.debounce.spec';
import './rxjs.Observable.default.spec';
import './rxjs.Observable.delay.spec';
import './rxjs.Observable.notification.spec';
import './rxjs.Observable.distinct.spec';
import './rxjs.Observable.do.spec';
import './rxjs.Observable.collection.spec';
// // TODO: @JiaLiPassion, add exhaust test
import './rxjs.Observable.merge.spec';
import './rxjs.Observable.multicast.spec';
import './rxjs.Observable.map.spec';
import './rxjs.Observable.race.spec';
import './rxjs.Observable.sample.spec';
import './rxjs.Observable.take.spec';
import './rxjs.Observable.timeout.spec';
import './rxjs.Observable.window.spec';

View File

@ -0,0 +1,57 @@
/**
* @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
*/
import {Observable, asapScheduler, throwError} from 'rxjs';
import {asyncTest} from '../test-util';
describe('Observable.throw', () => {
let log: any[];
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('throw func callback should run in the correct zone', () => {
let error = new Error('test');
observable1 = constructorZone1.run(() => { return throwError(error); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => { fail('should not call next'); },
(error: any) => {
log.push(error);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
() => { fail('should not call complete'); });
});
expect(log).toEqual([error]);
});
it('throw func callback should run in the correct zone with scheduler', asyncTest((done: any) => {
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
let error = new Error('test');
observable1 = constructorZone1.run(() => { return throwError(error, asapScheduler); });
subscriptionZone.run(() => {
observable1.subscribe(
(result: any) => { fail('should not call next'); },
(error: any) => {
log.push(error);
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([error]);
done();
},
() => { fail('should not call complete'); });
});
expect(log).toEqual([]);
}, Zone.root));
});

View File

@ -0,0 +1,40 @@
/**
* @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
*/
import {Observable, timer} from 'rxjs';
import {asyncTest} from '../test-util';
describe('Observable.timer', () => {
let log: any[];
let observable1: Observable<any>;
beforeEach(() => { log = []; });
it('timer 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 timer(10, 20); });
subscriptionZone.run(() => {
const subscriber = observable1.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
if (result >= 3) {
// subscriber.complete();
subscriber.unsubscribe();
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
expect(log).toEqual([0, 1, 2, 3, 'completed']);
done();
}
},
() => { fail('should not call error'); });
expect(log).toEqual([]);
});
}, Zone.root));
});

View File

@ -0,0 +1,12 @@
/**
* @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
*/
export function supportFeature(Observable: any, method: string) {
const func = function() { return !!Observable.prototype[method]; };
(func as any).message = `Observable.${method} not support`;
}

View File

@ -0,0 +1,44 @@
/**
* @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
*/
import {of , range, zip} from 'rxjs';
describe('Observable.zip', () => {
let log: any[];
const constructorZone1: Zone = Zone.current.fork({name: 'Constructor Zone1'});
const subscriptionZone: Zone = Zone.current.fork({name: 'Subscription Zone'});
beforeEach(() => { log = []; });
it('zip func callback should run in the correct zone', () => {
const observable1: any = constructorZone1.run(() => { return range(1, 3); });
const observable2: any = constructorZone1.run(() => { return of ('foo', 'bar', 'beer'); });
const observable3: any = constructorZone1.run(() => {
return zip(observable1, observable2, function(n: number, str: string) {
expect(Zone.current.name).toEqual(constructorZone1.name);
return {n: n, str: str};
});
});
subscriptionZone.run(() => {
observable3.subscribe(
(result: any) => {
log.push(result);
expect(Zone.current.name).toEqual(subscriptionZone.name);
},
() => { fail('should not call error'); },
() => {
log.push('completed');
expect(Zone.current.name).toEqual(subscriptionZone.name);
});
});
expect(log).toEqual([{n: 1, str: 'foo'}, {n: 2, str: 'bar'}, {n: 3, str: 'beer'}, 'completed']);
});
});