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
  • Loading branch information
kwonoj committed Mar 2, 2016
1 parent 72d96bb commit 5c7a473
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 29 deletions.
42 changes: 41 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,46 @@ 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, () => {
expect(expected.length).toBe(0);
done();
});
});

it('should take all element when try to take larger then source', (done: DoneSignature) => {
const expected = [0, 1, 2];

Observable.of(0, 1, 2).takeLast(5).subscribe((x) => {
expect(x).toBe(expected.shift());
}, done.fail, () => {
expect(expected.length).toBe(0);
done();
});
});

it('should take all element when try to take exact', (done: DoneSignature) => {
const expected = [0, 1, 2];

Observable.of(0, 1, 2).takeLast(3).subscribe((x) => {
expect(x).toBe(expected.shift());
}, done.fail, () => {
expect(expected.length).toBe(0);
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
44 changes: 16 additions & 28 deletions src/operator/takeLast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,52 +29,40 @@ class TakeLastOperator<T> implements Operator<T, T> {
}

class TakeLastSubscriber<T> extends Subscriber<T> {
private ring: T[];
private ring: Array<T> = new Array();
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;
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;
if (ring.length < total) {
ring.push(value);
} else {
const index = count % total;
ring[index] = value;
}

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 total = this.count >= this.total ? this.total : this.count;
const ring = this.ring;

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 5c7a473

Please sign in to comment.