diff --git a/packages/rxjs/spec/operators/takeLast-spec.ts b/packages/rxjs/spec/operators/takeLast-spec.ts index 64c661f618..6e0910a15d 100644 --- a/packages/rxjs/spec/operators/takeLast-spec.ts +++ b/packages/rxjs/spec/operators/takeLast-spec.ts @@ -1,4 +1,5 @@ import { takeLast, mergeMap } from 'rxjs/operators'; +import { expect } from 'chai'; import { of } from 'rxjs'; import { TestScheduler } from 'rxjs/testing'; import { observableMatcher } from '../helpers/observableMatcher'; @@ -205,4 +206,25 @@ describe('takeLast operator', () => { expectSubscriptions(e1.subscriptions).toBe(e1subs); }); }); + + it('should not throw when count is Infinity and should emit all values', () => { + const results: number[] = []; + expect(() => { + of(1, 2, 3) + .pipe(takeLast(Infinity)) + .subscribe((x) => results.push(x)); + }).not.to.throw(); + expect(results).to.deep.equal([1, 2, 3]); + }); + + it('should emit all values when count exceeds source length (Infinity case)', () => { + rxTest.run(({ cold, expectObservable, expectSubscriptions }) => { + const source = cold('(abc|)'); + const expected = ' (abc|)'; + const subs = ' (^!)'; + + expectObservable(source.pipe(takeLast(Infinity))).toBe(expected); + expectSubscriptions(source.subscriptions).toBe(subs); + }); + }); }); diff --git a/packages/rxjs/src/internal/operators/takeLast.ts b/packages/rxjs/src/internal/operators/takeLast.ts index 75f7cf656e..c1190b84ce 100644 --- a/packages/rxjs/src/internal/operators/takeLast.ts +++ b/packages/rxjs/src/internal/operators/takeLast.ts @@ -46,8 +46,11 @@ export function takeLast(count: number): MonoTypeOperatorFunction { ? () => EMPTY : (source) => new Observable((destination) => { - // This is a ring buffer that will hold our values - let ring = new Array(count); + // This is a ring buffer that will hold our values. + // For non-finite counts (e.g. Infinity), use a growable array because + // `new Array(Infinity)` throws a RangeError. The ring-buffer math still + // works correctly for Infinity since `n % Infinity === n` for all finite n. + let ring: T[] = isFinite(count) ? new Array(count) : []; // This counter is how we track where we are at in the ring buffer. let counter = 0; source.subscribe(