Skip to content

Commit

Permalink
fix(takeLast): fix takeLast behavior to emit correct order
Browse files Browse the repository at this point in the history
closes #1407
  • Loading branch information
kwonoj committed Mar 2, 2016
1 parent 72d96bb commit 052b21b
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 27 deletions.
16 changes: 15 additions & 1 deletion spec/operators/takeLast-spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as Rx from '../../dist/cjs/Rx';
import {hot, cold, expectObservable, expectSubscriptions} from '../helpers/marble-testing';
import {it, asDiagram} from '../helpers/test-helper';
import {it, DoneSignature, asDiagram} from '../helpers/test-helper';

const Observable = Rx.Observable;

Expand All @@ -14,6 +14,20 @@ describe('Observable.prototype.takeLast()', () => {
expectSubscriptions(e1.subscriptions).toBe(e1subs);
});

it('should take last three values', (done: DoneSignature) => {
const expected = [2, 3, 4];
Observable.of(0, 1, 2, 3, 4).takeLast(3).subscribe((x) => {
expect(x).toBe(expected.shift());
}, done.fail, done);
});

it('should not take any values', () => {
const e1 = cold('--a-----b----c---d--|');
const expected = '|';

expectObservable(e1.takeLast(0)).toBe(expected);
});

it('should work with empty', () => {
const e1 = cold('|');
const e1subs = '(^!)';
Expand Down
36 changes: 10 additions & 26 deletions src/operator/takeLast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,50 +31,34 @@ class TakeLastOperator<T> implements Operator<T, T> {
class TakeLastSubscriber<T> extends Subscriber<T> {
private ring: T[];
private count: number = 0;
private index: number = 0;

constructor(destination: Subscriber<T>, private total: number) {
super(destination);
this.ring = new Array(total);
}

protected _next(value: T): void {

let index = this.index;
const ring = this.ring;
const total = this.total;
const count = this.count;

if (total > 1) {
if (count < total) {
this.count = count + 1;
this.index = index + 1;
} else if (index === 0) {
this.index = ++index;
} else if (index < total) {
this.index = index + 1;
} else {
this.index = index = 0;
}
} else if (count < total) {
this.count = total;
}
const count = ++this.count;

const index = count % total;
ring[index] = value;
}

protected _complete(): void {
const destination = this.destination;
let count = this.count;

let iter = -1;
const { ring, count, total, destination } = this;
let index = (total === 1 || count < total) ? 0 : this.index - 1;
if (count > 0) {
const { ring, total } = this;

while (++iter < count) {
if (iter + index === total) {
index = total - iter;
for (let i = 0; i < total; i++) {
const idx = (++count) % total;
destination.next(ring[idx]);
}
destination.next(ring[iter + index]);
}

destination.complete();
}
}

0 comments on commit 052b21b

Please sign in to comment.