Skip to content

Commit

Permalink
refactor(tap): Use a tuple for the index.
Browse files Browse the repository at this point in the history
  • Loading branch information
cartant committed Jul 20, 2018
1 parent 0f9c523 commit a1f9af4
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 99 deletions.
2 changes: 1 addition & 1 deletion source/operators/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,6 @@ export * from "./reschedule";
export * from "./subsequent";
export * from "./switchMapUntil";
export * from "./takeWhileInclusive";
export * from "./tapIndex";
export * from "./tapWithIndex";
export * from "./throttleAfter";
export * from "./unsubscribeOn";
98 changes: 0 additions & 98 deletions source/operators/tapIndex.ts

This file was deleted.

97 changes: 97 additions & 0 deletions source/operators/tapWithIndex-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/**
* @license Use of this source code is governed by an MIT-style license that
* can be found in the LICENSE file at https://github.com/cartant/rxjs-etc
*/
/*tslint:disable:no-unused-expression*/

import { expect } from "chai";
import { from } from "rxjs";
import { marbles } from "rxjs-marbles";
import { tapWithIndex } from "./tapWithIndex";

describe("tapWithIndex", () => {

it("should mirror multiple values and complete", marbles((m) => {

const source = m.cold("--1--2--3--|");
const subs = "^----------!";
const expected = m.cold("--1--2--3--|");

const destination = source.pipe(tapWithIndex(() => {}));
m.expect(destination).toBeObservable(expected);
m.expect(source).toHaveSubscriptions(subs);
}));

it("should mirror multiple values and terminate with error", marbles((m) => {

const source = m.cold("--1--2--3--#");
const subs = "^----------!";
const expected = m.cold("--1--2--3--#");

const destination = source.pipe(tapWithIndex(() => {}));
m.expect(destination).toBeObservable(expected);
m.expect(source).toHaveSubscriptions(subs);
}));

it("should pass the index", () => {

let seen: { index: number, value: string }[] = [];

from(["alice", "bob"]).pipe(
tapWithIndex(([value, index]) => seen.push({ index, value }))
).subscribe();

expect(seen).to.deep.equal([{
index: 0,
value: "alice"
}, {
index: 1,
value: "bob"
}]);
});

it("should reset the index for each subscription", () => {

let seen: { index: number, value: string }[] = [];

let observable = from(["alice", "bob"]).pipe(
tapWithIndex(([value, index]) => seen.push({ index, value }))
);

observable.subscribe();
observable.subscribe();

expect(seen).to.deep.equal([{
index: 0,
value: "alice"
}, {
index: 1,
value: "bob"
}, {
index: 0,
value: "alice"
}, {
index: 1,
value: "bob"
}]);
});

it("should support a partial observer", () => {

let seen: { index: number, value: string }[] = [];

from(["alice", "bob"]).pipe(
tapWithIndex({
next: ([value, index]) => seen.push({ index, value })
})
).subscribe();

expect(seen).to.deep.equal([{
index: 0,
value: "alice"
}, {
index: 1,
value: "bob"
}]);
});
});
32 changes: 32 additions & 0 deletions source/operators/tapWithIndex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* @license Use of this source code is governed by an MIT-style license that
* can be found in the LICENSE file at https://github.com/cartant/rxjs-etc
*/

import { defer, MonoTypeOperatorFunction, PartialObserver } from "rxjs";
import { tap } from "rxjs/operators";

export function tapWithIndex<T>(
next?: (tuple: [T, number]) => void,
error?: (error: any) => void,
complete?: () => void
): MonoTypeOperatorFunction<T>;
export function tapWithIndex<T>(
observer: PartialObserver<[T, number]>
): MonoTypeOperatorFunction<T>;
export function tapWithIndex<T>(
nextOrObserver?: ((tuple: [T, number]) => void) | PartialObserver<[T, number]>,
error?: (error: any) => void,
complete?: () => void
): MonoTypeOperatorFunction<T> {
return source => defer(() => {
/*tslint:disable-next-line:no-unused-declaration*/
let index = -1;
const observer = nextOrObserver && (typeof nextOrObserver !== "function") ?
{ next: () => {}, ...nextOrObserver } :
{ complete, error, next: nextOrObserver || (() => {}) };
return source.pipe(
tap<T>({ ...observer, next: value => observer.next([value, ++index]) })
);
});
}

0 comments on commit a1f9af4

Please sign in to comment.