diff --git a/spec/operators/every-spec.ts b/spec/operators/every-spec.ts index 35ce7ae568..b4a559fd63 100644 --- a/spec/operators/every-spec.ts +++ b/spec/operators/every-spec.ts @@ -1,274 +1,347 @@ +/** @prettier */ import { expect } from 'chai'; import { every, mergeMap } from 'rxjs/operators'; -import { hot, cold, expectObservable, expectSubscriptions } from '../helpers/marble-testing'; +import { TestScheduler } from 'rxjs/testing'; import { of, Observable, Observer } from 'rxjs'; +import { observableMatcher } from '../helpers/observableMatcher'; /** @test {every} */ -describe('every operator', () => { +describe('every', () => { + let testScheduler: TestScheduler; + + beforeEach(() => { + testScheduler = new TestScheduler(observableMatcher); + }); + function truePredicate(x: number | string) { return true; } function predicate(x: number | string) { - return (+x) % 5 === 0; + return +x % 5 === 0; } - it('should return false if only some of element matches with predicate', () => { - const source = hot('--a--b--c--d--e--|', {a: 5, b: 10, c: 15, d: 18, e: 20}); - const sourceSubs = '^ ! '; - const expected = '-----------(F|) '; + it('should return false if only one of elements does not match with predicate', () => { + testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { + const values = { a: 5, b: 10, c: 15, d: 18, e: 20 }; + const e1 = hot(' --a--b--c--d--e--|', values); + const e1subs = ' ^----------! '; + const expected = '-----------(x|) '; - expectObservable(source.pipe(every(predicate))).toBe(expected, {F: false}); - expectSubscriptions(source.subscriptions).toBe(sourceSubs); + expectObservable(e1.pipe(every(predicate))).toBe(expected, { x: false }); + expectSubscriptions(e1.subscriptions).toBe(e1subs); + }); }); it('should accept thisArg with scalar observables', () => { const thisArg = {}; - of(1).pipe(every(function (this: any, value: number, index: number) { - expect(this).to.deep.equal(thisArg); - return true; - }, thisArg)).subscribe(); - + of(1) + .pipe( + every(function (this: any, value: number, index: number) { + expect(this).to.deep.equal(thisArg); + return true; + }, thisArg) + ) + .subscribe(); }); it('should increment index on each call to the predicate', () => { const indices: number[] = []; - of(1, 2, 3, 4).pipe( - every((_, i) => { - indices.push(i); - return true; - }) - ).subscribe(); + of(1, 2, 3, 4) + .pipe( + every((_, i) => { + indices.push(i); + return true; + }) + ) + .subscribe(); expect(indices).to.deep.equal([0, 1, 2, 3]); }); - it('should accept thisArg with array observables', () => { + it('should accept thisArg with array observable', () => { const thisArg = {}; - of(1, 2, 3, 4).pipe(every(function (this: any, value: number, index: number) { - expect(this).to.deep.equal(thisArg); - return true; - }, thisArg)).subscribe(); + of(1, 2, 3, 4) + .pipe( + every(function (this: any, value: number, index: number) { + expect(this).to.deep.equal(thisArg); + return true; + }, thisArg) + ) + .subscribe(); }); - it('should accept thisArg with ordinary observables', () => { + it('should accept thisArg with ordinary observable', () => { const thisArg = {}; - Observable.create((observer: Observer) => { + const source = new Observable((observer: Observer) => { observer.next(1); observer.complete(); - }) - .pipe(every(function (this: any, value: number, index: number) { - expect(this).to.deep.equal(thisArg); - return true; - }, thisArg)).subscribe(); + }); + source + .pipe( + every(function (this: any, value: number, index: number) { + expect(this).to.deep.equal(thisArg); + return true; + }, thisArg) + ) + .subscribe(); }); it('should emit true if source is empty', () => { - const source = hot('-----|'); - const sourceSubs = '^ !'; - const expected = '-----(x|)'; - - expectObservable(source.pipe(every(predicate))).toBe(expected, {x: true}); - expectSubscriptions(source.subscriptions).toBe(sourceSubs); + testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { + const e1 = hot(' -----| '); + const e1subs = ' ^----! '; + const expected = '-----(x|)'; + + expectObservable(e1.pipe(every(predicate))).toBe(expected, { x: true }); + expectSubscriptions(e1.subscriptions).toBe(e1subs); + }); }); - it('should emit false if single source of element does not match with predicate', () => { - const source = hot('--a--|'); - const sourceSubs = '^ !'; - const expected = '--(x|)'; + it('should emit false if single source element does not match with predicate', () => { + testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { + const e1 = hot(' --a--|'); + const e1subs = ' ^-! '; + const expected = '--(x|)'; - expectObservable(source.pipe(every(predicate))).toBe(expected, {x: false}); - expectSubscriptions(source.subscriptions).toBe(sourceSubs); + expectObservable(e1.pipe(every(predicate))).toBe(expected, { x: false }); + expectSubscriptions(e1.subscriptions).toBe(e1subs); + }); }); - it('should emit false if none of element does not match with predicate', () => { - const source = hot('--a--b--c--d--e--|'); - const sourceSubs = '^ !'; - const expected = '--(x|)'; + it('should emit false if none of elements match with predicate', () => { + testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { + const e1 = hot(' --a--b--c--d--e--|'); + const e1subs = ' ^-! '; + const expected = '--(x|) '; - expectObservable(source.pipe(every(predicate))).toBe(expected, {x: false}); - expectSubscriptions(source.subscriptions).toBe(sourceSubs); + expectObservable(e1.pipe(every(predicate))).toBe(expected, { x: false }); + expectSubscriptions(e1.subscriptions).toBe(e1subs); + }); }); - it('should return false if only some of element matches with predicate', () => { - const source = hot('--a--b--c--d--e--|', {a: 5, b: 10, c: 15}); - const sourceSubs = '^ !'; - const expected = '-----------(x|)'; + it('should return false if only some of elements matches with predicate', () => { + testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { + const values = { a: 5, b: 10, c: 15 }; + const e1 = hot(' --a--b--c--d--e--|', values); + const e1subs = ' ^----------! '; + const expected = '-----------(x|) '; - expectObservable(source.pipe(every(predicate))).toBe(expected, {x: false}); - expectSubscriptions(source.subscriptions).toBe(sourceSubs); + expectObservable(e1.pipe(every(predicate))).toBe(expected, { x: false }); + expectSubscriptions(e1.subscriptions).toBe(e1subs); + }); }); it('should allow unsubscribing early and explicitly', () => { - const source = hot('--a--b--c--d--e--|', {a: 5, b: 10, c: 15}); - const sourceSubs = '^ ! '; - const expected = '-------- '; - const unsub = ' ! '; - - const result = source.pipe(every(predicate)); - - expectObservable(result, unsub).toBe(expected); - expectSubscriptions(source.subscriptions).toBe(sourceSubs); + testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { + const values = { a: 5, b: 10, c: 15 }; + const e1 = hot(' --a--b--c--d--e--|', values); + const e1subs = ' ^------! '; + const expected = '-------- '; + const unsub = ' -------! '; + + const result = e1.pipe(every(predicate)); + + expectObservable(result, unsub).toBe(expected); + expectSubscriptions(e1.subscriptions).toBe(e1subs); + }); }); - it('should not break unsubscription chains when result Observable is unsubscribed', () => { - const source = hot('--a--b--c--d--e--|', {a: 5, b: 10, c: 15}); - const sourceSubs = '^ ! '; - const expected = '-------- '; - const unsub = ' ! '; - - const result = source.pipe( - mergeMap((x: any) => of(x)), - every(predicate), - mergeMap((x: any) => of(x)) - ); - - expectObservable(result, unsub).toBe(expected); - expectSubscriptions(source.subscriptions).toBe(sourceSubs); + it('should not break unsubscription chains when result observable is unsubscribed', () => { + testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { + const values = { a: 5, b: 10, c: 15 }; + const e1 = hot(' --a--b--c--d--e--|', values); + const e1subs = ' ^------! '; + const expected = '-------- '; + const unsub = ' -------! '; + + const result = e1.pipe( + mergeMap((x: any) => of(x)), + every(predicate), + mergeMap((x: any) => of(x)) + ); + + expectObservable(result, unsub).toBe(expected); + expectSubscriptions(e1.subscriptions).toBe(e1subs); + }); }); it('should propagate error if predicate eventually throws', () => { - const source = hot('--a--b--c--d--e--|'); - const sourceSubs = '^ !'; - const expected = '--------#'; - - function faultyPredicate(x: string) { - if (x === 'c') { - throw 'error'; - } else { - return true; + testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { + const e1 = hot(' --a--b--c--d--e--|'); + const e1subs = ' ^-------!'; + const expected = '--------#'; + + function faultyPredicate(x: string) { + if (x === 'c') { + throw 'error'; + } else { + return true; + } } - } - expectObservable(source.pipe(every(faultyPredicate))).toBe(expected); - expectSubscriptions(source.subscriptions).toBe(sourceSubs); + expectObservable(e1.pipe(every(faultyPredicate))).toBe(expected); + expectSubscriptions(e1.subscriptions).toBe(e1subs); + }); }); - it('should emit true if single source element match with predicate', () => { - const source = hot('--a--|', {a: 5}); - const sourceSubs = '^ !'; - const expected = '-----(x|)'; + it('should emit true if single source element matches with predicate', () => { + testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { + const values = { a: 5 }; + const e1 = hot(' --a--| ', values); + const e1subs = ' ^----! '; + const expected = '-----(x|)'; - expectObservable(source.pipe(every(predicate))).toBe(expected, {x: true}); - expectSubscriptions(source.subscriptions).toBe(sourceSubs); + expectObservable(e1.pipe(every(predicate))).toBe(expected, { x: true }); + expectSubscriptions(e1.subscriptions).toBe(e1subs); + }); }); - it('should emit true if Scalar source matches with predicate', () => { - const source = of(5); - const expected = '(T|)'; + it('should emit true if scalar source matches with predicate', () => { + testScheduler.run(({ expectObservable }) => { + const e1 = of(5); + const expected = '(x|)'; - expectObservable(source.pipe(every(predicate))).toBe(expected, {T: true}); + expectObservable(e1.pipe(every(predicate))).toBe(expected, { x: true }); + }); }); - it('should emit false if Scalar source does not match with predicate', () => { - const source = of(3); - const expected = '(F|)'; + it('should emit false if scalar source does not match with predicate', () => { + testScheduler.run(({ expectObservable }) => { + const e1 = of(3); + const expected = '(x|)'; - expectObservable(source.pipe(every(predicate))).toBe(expected, {F: false}); + expectObservable(e1.pipe(every(predicate))).toBe(expected, { x: false }); + }); }); - it('should propagate error if predicate throws on Scalar source', () => { - const source = of(3); - const expected = '#'; + it('should propagate error if predicate throws on scalar source', () => { + testScheduler.run(({ expectObservable }) => { + const e1 = of(3); + const expected = '#'; - function faultyPredicate(x: number) { - throw 'error'; - } + function faultyPredicate(x: number): boolean { + throw 'error'; + } - expectObservable(source.pipe(every(faultyPredicate))).toBe(expected); + expectObservable(e1.pipe(every(faultyPredicate))).toBe(expected); + }); }); - it('should emit true if Array source matches with predicate', () => { - const source = of(5, 10, 15, 20); - const expected = '(T|)'; + it('should emit true if scalar array source matches with predicate', () => { + testScheduler.run(({ expectObservable }) => { + const e1 = of(5, 10, 15, 20); + const expected = '(x|)'; - expectObservable(source.pipe(every(predicate))).toBe(expected, {T: true}); + expectObservable(e1.pipe(every(predicate))).toBe(expected, { x: true }); + }); }); - it('should emit false if Array source does not match with predicate', () => { - const source = of(5, 9, 15, 20); - const expected = '(F|)'; + it('should emit false if scalar array source does not match with predicate', () => { + testScheduler.run(({ expectObservable }) => { + const e1 = of(5, 9, 15, 20); + const expected = '(x|)'; - expectObservable(source.pipe(every(predicate))).toBe(expected, {F: false}); + expectObservable(e1.pipe(every(predicate))).toBe(expected, { x: false }); + }); }); - it('should propagate error if predicate eventually throws on Array source', () => { - const source = of(5, 10, 15, 20); - const expected = '#'; + it('should propagate error if predicate eventually throws on scalar array source', () => { + testScheduler.run(({ expectObservable }) => { + const e1 = of(5, 10, 15, 20); + const expected = '#'; - function faultyPredicate(x: number) { - if (x === 15) { - throw 'error'; + function faultyPredicate(x: number) { + if (x === 15) { + throw 'error'; + } + return true; } - return true; - } - expectObservable(source.pipe(every(faultyPredicate))).toBe(expected); + expectObservable(e1.pipe(every(faultyPredicate))).toBe(expected); + }); }); - it('should emit true if all source element matches with predicate', () => { - const source = hot('--a--b--c--d--e--|', {a: 5, b: 10, c: 15, d: 20, e: 25}); - const sourceSubs = '^ !'; - const expected = '-----------------(x|)'; + it('should emit true if all source elements match with predicate', () => { + testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { + const values = { a: 5, b: 10, c: 15, d: 20, e: 25 }; + const e1 = hot(' --a--b--c--d--e--| ', values); + const e1subs = ' ^----------------! '; + const expected = '-----------------(x|)'; - expectObservable(source.pipe(every(predicate))).toBe(expected, {x: true}); - expectSubscriptions(source.subscriptions).toBe(sourceSubs); + expectObservable(e1.pipe(every(predicate))).toBe(expected, { x: true }); + expectSubscriptions(e1.subscriptions).toBe(e1subs); + }); }); it('should raise error if source raises error', () => { - const source = hot('--#'); - const sourceSubs = '^ !'; - const expected = '--#'; - - expectObservable(source.pipe(every(truePredicate))).toBe(expected); - expectSubscriptions(source.subscriptions).toBe(sourceSubs); + testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { + const e1 = hot(' --#'); + const e1subs = ' ^-!'; + const expected = '--#'; + + expectObservable(e1.pipe(every(truePredicate))).toBe(expected); + expectSubscriptions(e1.subscriptions).toBe(e1subs); + }); }); - it('should not completes if source never emits', () => { - const source = cold('-'); - const sourceSubs = '^'; - const expected = '-'; + it('should not complete if source never emits', () => { + testScheduler.run(({ cold, expectObservable, expectSubscriptions }) => { + const e1 = cold(' -'); + const e1subs = ' ^'; + const expected = '-'; - expectObservable(source.pipe(every(truePredicate))).toBe(expected); - expectSubscriptions(source.subscriptions).toBe(sourceSubs); + expectObservable(e1.pipe(every(truePredicate))).toBe(expected); + expectSubscriptions(e1.subscriptions).toBe(e1subs); + }); }); it('should emit true if source element matches with predicate after subscription', () => { - const source = hot('--z--^--a--b--c--d--e--|', {a: 5, b: 10, c: 15, d: 20, e: 25}); - const sourceSubs = '^ !'; - const expected = '------------------(x|)'; - - expectObservable(source.pipe(every(predicate))).toBe(expected, {x: true}); - expectSubscriptions(source.subscriptions).toBe(sourceSubs); + testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { + const values = { a: 5, b: 10, c: 15, d: 20, e: 25 }; + const e1 = hot('--z--^--a--b--c--d--e--| ', values); + const e1subs = ' ^-----------------! '; + const expected = ' ------------------(x|)'; + + expectObservable(e1.pipe(every(predicate))).toBe(expected, { x: true }); + expectSubscriptions(e1.subscriptions).toBe(e1subs); + }); }); it('should emit false if source element does not match with predicate after subscription', () => { - const source = hot('--z--^--b--c--z--d--|', {a: 5, b: 10, c: 15, d: 20}); - const sourceSubs = '^ !'; - const expected = '---------(x|)'; - - expectObservable(source.pipe(every(predicate))).toBe(expected, {x: false}); - expectSubscriptions(source.subscriptions).toBe(sourceSubs); + testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { + const values = { a: 5, b: 10, c: 15, d: 20 }; + const e1 = hot('--z--^--b--c--z--d--|', values); + const e1subs = ' ^--------! '; + const expected = ' ---------(x|) '; + + expectObservable(e1.pipe(every(predicate))).toBe(expected, { x: false }); + expectSubscriptions(e1.subscriptions).toBe(e1subs); + }); }); it('should raise error if source raises error after subscription', () => { - const source = hot('--z--^--#'); - const sourceSubs = '^ !'; - const expected = '---#'; - - expectObservable(source.pipe(every(truePredicate))).toBe(expected); - expectSubscriptions(source.subscriptions).toBe(sourceSubs); + testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { + const e1 = hot('--z--^--#'); + const e1subs = ' ^--!'; + const expected = ' ---#'; + + expectObservable(e1.pipe(every(truePredicate))).toBe(expected); + expectSubscriptions(e1.subscriptions).toBe(e1subs); + }); }); it('should emit true if source does not emit after subscription', () => { - const source = hot('--z--^-----|'); - const sourceSubs = '^ !'; - const expected = '------(x|)'; - - expectObservable(source.pipe(every(predicate))).toBe(expected, {x: true}); - expectSubscriptions(source.subscriptions).toBe(sourceSubs); + testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => { + const e1 = hot('--z--^-----| '); + const e1subs = ' ^-----! '; + const expected = ' ------(x|)'; + + expectObservable(e1.pipe(every(predicate))).toBe(expected, { x: true }); + expectSubscriptions(e1.subscriptions).toBe(e1subs); + }); }); });