Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 102 additions & 71 deletions spec/operators/take-spec.ts
Original file line number Diff line number Diff line change
@@ -1,110 +1,139 @@
import { expect } from 'chai';
import { hot, cold, expectObservable, expectSubscriptions } from '../helpers/marble-testing';
import { take, mergeMap } from 'rxjs/operators';
import { range, ArgumentOutOfRangeError, of, Observable, Subject } from 'rxjs';
import { TestScheduler } from 'rxjs/testing';
import { observableMatcher } from '../helpers/observableMatcher';

declare function asDiagram(arg: string): Function;

/** @test {take} */
describe('take operator', () => {
let testScheduler: TestScheduler;

beforeEach(() => {
testScheduler = new TestScheduler(observableMatcher);
});

asDiagram('take(2)')('should take two values of an observable with many values', () => {
const e1 = cold('--a-----b----c---d--|');
const e1subs = '^ ! ';
const expected = '--a-----(b|) ';
testScheduler.run(({ cold, expectObservable, expectSubscriptions }) => {
const e1 = cold(' --a-----b----c---d--|');
const e1subs = ' ^-------!------------';
const expected = '--a-----(b|) ';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We'd like to be able to use Prettier with the codebase and that means the alignment will need to happen within the marble strings, like this:

const e1 = cold('  --a-----b----c---d--|');
const e1subs = '   ^-------!------------';
const expected = ' --a-----(b|)         ';

As Prettier will collapse multiple adjacent spaces outside of the string literals.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok! I'll do that right now


expectObservable(e1.pipe(take(2))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
expectObservable(e1.pipe(take(2))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
});
});

it('should work with empty', () => {
const e1 = cold('|');
const e1subs = '(^!)';
const expected = '|';
testScheduler.run(({ cold, expectObservable, expectSubscriptions }) => {
const e1 = cold(' |');
const e1subs = ' (^!)';
const expected = '|';

expectObservable(e1.pipe(take(42))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
expectObservable(e1.pipe(take(42))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
});
});

it('should go on forever on never', () => {
const e1 = cold('-');
const e1subs = '^';
const expected = '-';
testScheduler.run(({ cold, expectObservable, expectSubscriptions }) => {
const e1 = cold('-');
const e1subs = ' ^';
const expected = '-';

expectObservable(e1.pipe(take(42))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
expectObservable(e1.pipe(take(42))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
});
});

it('should be empty on take(0)', () => {
const e1 = hot('--a--^--b----c---d--|');
const e1subs: string[] = []; // Don't subscribe at all
const expected = '|';
testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
const e1 = hot('--a--^--b----c---d--|');
const e1subs: string[] = []; // Don't subscribe at all
const expected = ' |';

expectObservable(e1.pipe(take(0))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
expectObservable(e1.pipe(take(0))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
});
});

it('should take one value of an observable with one value', () => {
const e1 = hot('---(a|)');
const e1subs = '^ ! ';
const expected = '---(a|)';
testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
const e1 = hot(' ---(a|)');
const e1subs = ' ^--!---';
const expected = '---(a|)';

expectObservable(e1.pipe(take(1))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
expectObservable(e1.pipe(take(1))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
});
});

it('should take one values of an observable with many values', () => {
const e1 = hot('--a--^--b----c---d--|');
const e1subs = '^ ! ';
const expected = '---(b|) ';
testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
const e1 = hot('--a--^--b----c---d--|');
const e1subs = ' ^--!------------';
const expected = ' ---(b|) ';

expectObservable(e1.pipe(take(1))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
expectObservable(e1.pipe(take(1))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
});
});

it('should error on empty', () => {
const e1 = hot('--a--^----|');
const e1subs = '^ !';
const expected = '-----|';
testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
const e1 = hot('--a--^----|');
const e1subs = ' ^----!';
const expected = ' -----|';

expectObservable(e1.pipe(take(42))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
expectObservable(e1.pipe(take(42))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
});
});

it('should propagate error from the source observable', () => {
const e1 = hot('---^---#', null, 'too bad');
const e1subs = '^ !';
const expected = '----#';
testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
const e1 = hot('---^---#', null, 'too bad');
const e1subs = ' ^---!';
const expected = ' ----#';

expectObservable(e1.pipe(take(42))).toBe(expected, null, 'too bad');
expectSubscriptions(e1.subscriptions).toBe(e1subs);
expectObservable(e1.pipe(take(42))).toBe(expected, null, 'too bad');
expectSubscriptions(e1.subscriptions).toBe(e1subs);
});
});

it('should propagate error from an observable with values', () => {
const e1 = hot('---^--a--b--#');
const e1subs = '^ !';
const expected = '---a--b--#';
testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
const e1 = hot('---^--a--b--#');
const e1subs = ' ^--------!';
const expected = ' ---a--b--#';

expectObservable(e1.pipe(take(42))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
expectObservable(e1.pipe(take(42))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
});
});

it('should allow unsubscribing explicitly and early', () => {
const e1 = hot('---^--a--b-----c--d--e--|');
const unsub = ' ! ';
const e1subs = '^ ! ';
const expected = '---a--b--- ';

expectObservable(e1.pipe(take(42)), unsub).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
const e1 = hot('---^--a--b-----c--d--e--|');
const unsub = ' ---------!------------';
const e1subs = ' ^--------!------------';
const expected = ' ---a--b--- ';

expectObservable(e1.pipe(take(42)), unsub).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
});
});

it('should work with throw', () => {
const e1 = cold('#');
const e1subs = '(^!)';
const expected = '#';
testScheduler.run(({ cold, expectObservable, expectSubscriptions }) => {
const e1 = cold(' #');
const e1subs = ' (^!)';
const expected = '#';

expectObservable(e1.pipe(take(42))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
expectObservable(e1.pipe(take(42))).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
});
});

it('should throw if total is less than zero', () => {
Expand All @@ -113,19 +142,21 @@ describe('take operator', () => {
});

it('should not break unsubscription chain when unsubscribed explicitly', () => {
const e1 = hot('---^--a--b-----c--d--e--|');
const unsub = ' ! ';
const e1subs = '^ ! ';
const expected = '---a--b--- ';

const result = e1.pipe(
mergeMap((x: string) => of(x)),
take(42),
mergeMap((x: string) => of(x))
);

expectObservable(result, unsub).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
testScheduler.run(({ hot, expectObservable, expectSubscriptions }) => {
const e1 = hot('---^--a--b-----c--d--e--|');
const unsub = ' ---------! ';
const e1subs = ' ^--------! ';
const expected = ' ---a--b--- ';

const result = e1.pipe(
mergeMap((x: string) => of(x)),
take(42),
mergeMap((x: string) => of(x))
);

expectObservable(result, unsub).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(e1subs);
});
});

it('should unsubscribe from the source when it reaches the limit', () => {
Expand Down