hunk.code_window:       toEqual: (other: Observable<T>) => {
           flushTest.ready = true;
           flushTest.expected = [];
           this.schedule(() => {
             subscription = other.subscribe(
               (x) => {
                 // Support Observable-of-Observables
                 const value = x instanceof Observable ? this.materializeInnerObservable(x, this.frame) : x;
                 flushTest.expected!.push({ frame: this.frame, notification: nextNotification(value) });
               },
  
hunk.labels: keep keep keep keep replace replace keep keep keep keep
hunk.after_edit:           subscription = other.subscribe({
               next: (x) => {
  
hunk.file_path: src/internal/testing/TestScheduler.ts
hunk.type: replace
file: import { of } from 'rxjs';
  import { combineLatest, mergeMap, distinct, count } from 'rxjs/operators';
  import { TestScheduler } from 'rxjs/testing';
  import { observableMatcher } from '../helpers/observableMatcher';
  
  /** @test {combineLatest} */
  describe('combineLatest', () => {
    let testScheduler: TestScheduler;
  
    beforeEach(() => {
      testScheduler = new TestScheduler(observableMatcher);
    });
  
    it('should combine events from two cold observables', () => {
      testScheduler.run(({ cold, expectObservable }) => {
        const e1 = cold(' -a--b-----c-d-e-|');
        const e2 = cold(' --1--2-3-4---|   ');
        const expected = '--A-BC-D-EF-G-H-|';
  
        const result = e1.pipe(combineLatest(e2, (a, b) => String(a) + String(b)));
  
        expectObservable(result).toBe(expected, {
          A: 'a1', B: 'b1', C: 'b2', D: 'b3', E: 'b4', F: 'c4', G: 'd4', H: 'e4'
        });
      });
    });
  
    it('should work with two nevers', () => {
      testScheduler.run(({ cold, expectObservable, expectSubscriptions }) => {
        const e1 = cold(' -');
        const e1subs = '  ^';
        const e2 = cold(' -');
        const e2subs = '  ^';
        const expected = '-';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should work with never and empty', () => {
      testScheduler.run(({ cold, expectObservable, expectSubscriptions }) => {
        const e1 = cold(' -');
        const e1subs = '  ^';
        const e2 = cold(' |');
        const e2subs = '  (^!)';
        const expected = '-';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should work with empty and never', () => {
      testScheduler.run(({ cold, expectObservable, expectSubscriptions }) => {
        const e1 = cold(' |');
        const e1subs = '  (^!)';
        const e2 = cold(' -');
        const e2subs = '  ^';
        const expected = '-';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should work with empty and empty', () => {
      testScheduler.run(({ cold, expectObservable, expectSubscriptions }) => {
        const e1 = cold(' |');
        const e1subs = '  (^!)';
        const e2 = cold(' |');
        const e2subs = '  (^!)';
        const expected = '|';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should work with hot-empty and hot-single', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const values = {
          a: 1,
          b: 2,
          c: 3,
          r: 1 + 3 //a + c
        };
        const e1 = hot('-a-^-|', values);
        const e1subs = '   ^-!';
        const e2 = hot('-b-^-c-|', values);
        const e2subs = '   ^---!';
        const expected = ' ----|';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, values);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should work with hot-single and hot-empty', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const values = {
          a: 1, b: 2, c: 3
        };
        const e1 = hot('-a-^-|', values);
        const e1subs = '   ^-!';
        const e2 = hot('-b-^-c-|', values);
        const e2subs = '   ^---!';
        const expected = ' ----|';
  
        const result = e2.pipe(combineLatest(e1, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, values);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should work with hot-single and never', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const values = {
          a: 1
        };
        const e1 = hot('-a-^-|', values);
        const e1subs = '   ^-!';
        const e2 = hot('------', values); //never
        const e2subs = '   ^--';
        const expected = ' ---'; //never
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, values);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should work with never and hot-single', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const values = {
          a: 1, b: 2
        };
        const e1 = hot('--------', values); //never
        const e1subs = '   ^    ';
        const e2 = hot('-a-^-b-|', values);
        const e2subs = '   ^---!';
        const expected = ' -----'; //never
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, values);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should work with hot and hot', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const e1 = hot('--a--^--b--c--|', { a: 'a', b: 'b', c: 'c' });
        const e1subs = '     ^--------!';
        const e2 = hot('---e-^---f--g--|', { e: 'e', f: 'f', g: 'g' });
        const e2subs = '     ^---------!';
        const expected = '   ----x-yz--|';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, { x: 'bf', y: 'cf', z: 'cg' });
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should accept array of observables', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const e1 = hot('--a--^--b--c--|');
        const e1subs = '     ^--------!';
        const e2 = hot('---e-^---f--g--|');
        const e2subs = '     ^---------!';
        const e3 = hot('---h-^----i--j-|');
        const e3subs = '     ^---------!';
        const expected = '   -----wxyz-|';
  
        const result = e1.pipe(combineLatest([e2, e3], (x: string, y: string, z: string) => x + y + z));
  
        expectObservable(result).toBe(expected, { w: 'bfi', x: 'cfi', y: 'cgi', z: 'cgj' });
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
        expectSubscriptions(e3.subscriptions).toBe(e3subs);
      });
    });
  
    it('should work with empty and error', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const e1 = hot('  ----------|'); //empty
        const e1subs = '  ^-----!';
        const e2 = hot('  ------#', undefined, 'shazbot!'); //error
        const e2subs = '  ^-----!';
        const expected = '------#';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, null, 'shazbot!');
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should work with error and empty', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const e1 = hot('--^---#', undefined, 'too bad, honk'); //error
        const e1subs = '  ^---!';
        const e2 = hot('--^--------|'); //empty
        const e2subs = '  ^---!';
        const expected = '----#';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, null, 'too bad, honk');
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should work with hot and throw', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const e1 = hot('-a-^--b--c--|', { a: 1, b: 2, c: 3});
        const e1subs = '   ^-!';
        const e2 = hot('---^-#', undefined, 'bazinga');
        const e2subs = '   ^-!';
        const expected = ' --#';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, null, 'bazinga');
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should work with throw and hot', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const e1 = hot('---^-#', undefined, 'bazinga');
        const e1subs = '   ^-!';
        const e2 = hot('-a-^--b--c--|', { a: 1, b: 2, c: 3});
        const e2subs = '   ^-!';
        const expected = ' --#';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, null, 'bazinga');
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should work with throw and throw', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const e1 = hot('---^----#', undefined, 'jenga');
        const e1subs = '   ^-!';
        const e2 = hot('---^-#', undefined, 'bazinga');
        const e2subs = '   ^-!';
        const expected = ' --#';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, null, 'bazinga');
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should work with error and throw', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const e1 = hot('-a-^--b--#', { a: 1, b: 2 }, 'wokka wokka');
        const e1subs = '   ^-!';
        const e2 = hot('---^-#', undefined, 'flurp');
        const e2subs = '   ^-!';
        const expected = ' --#';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, null, 'flurp');
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should work with throw and error', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const e1 = hot('---^-#', undefined, 'flurp');
        const e1subs = '   ^-!';
        const e2 = hot('-a-^--b--#', { a: 1, b: 2 }, 'wokka wokka');
        const e2subs = '   ^-!';
        const expected = ' --#';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, null, 'flurp');
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should work with never and throw', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const e1 = hot('---^-----------');
        const e1subs = '   ^-----!';
        const e2 = hot('---^-----#', undefined, 'wokka wokka');
        const e2subs = '   ^-----!';
        const expected = ' ------#';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, null, 'wokka wokka');
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should work with throw and never', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const e1 = hot('---^----#', undefined, 'wokka wokka');
        const e1subs = '   ^----!';
        const e2 = hot('---^-----------');
        const e2subs = '   ^----!';
        const expected = ' -----#';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, null, 'wokka wokka');
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should work with some and throw', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const e1 = hot('   ---^----a---b--|', { a: 1, b: 2 });
        const e1subs = '      ^--!';
        const e2 = hot('   ---^--#', undefined, 'wokka wokka');
        const e2subs = '      ^--!';
        const expected = '    ---#';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, { a: 1, b: 2}, 'wokka wokka');
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should work with throw and some', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const e1 = hot('---^--#', undefined, 'wokka wokka');
        const e1subs = '   ^--!';
        const e2 = hot('---^----a---b--|', { a: 1, b: 2 });
        const e2subs = '   ^--!';
        const expected = ' ---#';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, { a: 1, b: 2}, 'wokka wokka');
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should handle throw after complete left', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const left = hot(' --a--^--b---|', { a: 1, b: 2 });
        const leftSubs = '      ^------!';
        const right = hot('-----^--------#', undefined, 'bad things');
        const rightSubs = '     ^--------!';
        const expected = '      ---------#';
  
        const result = left.pipe(combineLatest(right, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, null, 'bad things');
        expectSubscriptions(left.subscriptions).toBe(leftSubs);
        expectSubscriptions(right.subscriptions).toBe(rightSubs);
      });
    });
  
    it('should handle throw after complete right', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const left = hot('  -----^--------#', undefined, 'bad things');
        const leftSubs = '       ^--------!';
        const right = hot(' --a--^--b---|', { a: 1, b: 2 });
        const rightSubs = '      ^------!';
        const expected = '       ---------#';
  
        const result = left.pipe(combineLatest(right, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, null, 'bad things');
        expectSubscriptions(left.subscriptions).toBe(leftSubs);
        expectSubscriptions(right.subscriptions).toBe(rightSubs);
      });
    });
  
    it('should handle interleaved with tail', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const e1 = hot('-a--^--b---c---|', { a: 'a', b: 'b', c: 'c' });
        const e1subs = '    ^----------!';
        const e2 = hot('--d-^----e---f--|', { d: 'd', e: 'e', f: 'f'});
        const e2subs = '    ^-----------!';
        const expected = '  -----x-y-z--|';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, { x: 'be', y: 'ce', z: 'cf' });
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should handle two consecutive hot observables', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const e1 = hot('--a--^--b--c--|', { a: 'a', b: 'b', c: 'c' });
        const e1subs = '     ^--------!';
        const e2 = hot('-----^----------d--e--f--|', { d: 'd', e: 'e', f: 'f' });
        const e2subs = '     ^-------------------!';
        const expected = '   -----------x--y--z--|';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, { x: 'cd', y: 'ce', z: 'cf' });
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should handle two consecutive hot observables with error left', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const left = hot(' --a--^--b--c--#', { a: 'a', b: 'b', c: 'c' }, 'jenga');
        const leftSubs = '      ^--------!';
        const right = hot('-----^----------d--e--f--|', { d: 'd', e: 'e', f: 'f' });
        const rightSubs = '     ^--------!';
        const expected = '      ---------#';
  
        const result = left.pipe(combineLatest(right, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, null, 'jenga');
        expectSubscriptions(left.subscriptions).toBe(leftSubs);
        expectSubscriptions(right.subscriptions).toBe(rightSubs);
      });
    });
  
    it('should handle two consecutive hot observables with error right', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const left = hot(' --a--^--b--c--|', { a: 'a', b: 'b', c: 'c' });
        const leftSubs = '      ^--------!';
        const right = hot('-----^----------d--e--f--#', { d: 'd', e: 'e', f: 'f' }, 'dun dun dun');
        const rightSubs = '     ^-------------------!';
        const expected = '      -----------x--y--z--#';
  
        const result = left.pipe(combineLatest(right, (x, y) => x + y));
  
        expectObservable(result).toBe(expected, { x: 'cd', y: 'ce', z: 'cf' }, 'dun dun dun');
        expectSubscriptions(left.subscriptions).toBe(leftSubs);
        expectSubscriptions(right.subscriptions).toBe(rightSubs);
      });
    });
  
    it('should handle selector throwing', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const e1 = hot('--a--^--b--|', { a: 1, b: 2});
        const e1subs = '     ^--!';
        const e2 = hot('--c--^--d--|', { c: 3, d: 4});
        const e2subs = '     ^--!';
        const expected = '   ---#';
  
        const result = e1.pipe(combineLatest(e2, (x, y) => { throw 'ha ha ' + x + ', ' + y; }));
  
        expectObservable(result).toBe(expected, null, 'ha ha 2, 4');
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should allow unsubscribing early and explicitly', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const e1 = hot('--a--^--b--c---d-| ');
        const e1subs = '     ^--------!    ';
        const e2 = hot('---e-^---f--g---h-|');
        const e2subs = '     ^--------!    ';
        const expected = '   ----x-yz--    ';
        const unsub = '      ---------!    ';
        const values = { x: 'bf', y: 'cf', z: 'cg' };
  
        const result = e1.pipe(combineLatest(e2, (x, y) => x + y));
  
        expectObservable(result, unsub).toBe(expected, values);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should not break unsubscription chains when unsubscribed explicitly', () => {
      testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
        const e1 = hot('--a--^--b--c---d-| ');
        const e1subs = '     ^--------!    ';
        const e2 = hot('---e-^---f--g---h-|');
        const e2subs = '     ^--------!    ';
        const expected = '   ----x-yz--    ';
        const unsub = '      ---------!    ';
        const values = { x: 'bf', y: 'cf', z: 'cg' };
  
        const result = e1.pipe(
          mergeMap((x) => of(x)),
          combineLatest(e2, (x, y) => x + y),
          mergeMap((x) => of(x))
        );
  
        expectObservable(result, unsub).toBe(expected, values);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
      });
    });
  
    it('should emit unique array instances with the default projection', () => {
      testScheduler.run(({ hot, expectObservable }) => {
        const e1 = hot('  -a--b--|');
        const e2 = hot('  --1--2-|');
        const expected = '-------(c|)';
  
        const result = e1.pipe(
          combineLatest(e2),
          distinct(),
          count()
        );
  
        expectObservable(result).toBe(expected, { c: 3 });
      });
    });
  });
  