Skip to content

Commit

Permalink
feat(delayWhen): add delayWhen operator
Browse files Browse the repository at this point in the history
  • Loading branch information
kwonoj committed Feb 2, 2016
1 parent a55f459 commit 17122f9
Show file tree
Hide file tree
Showing 8 changed files with 366 additions and 0 deletions.
211 changes: 211 additions & 0 deletions spec/operators/delayWhen-spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
/* globals describe, it, expect, expectObservable, expectSubscriptions, hot, cold, rxTestScheduler */
var Rx = require('../../dist/cjs/Rx');
var Observable = Rx.Observable;

describe('Observable.prototype.delayWhen()', function () {
it.asDiagram('delay(durationSelector)')('should delay by duration selector', function () {
var e1 = hot('---a---b---c--|');
var expected = '-----a------c----(b|)';
var subs = '^ !';
var selector = [cold( '--x--|'),
cold( '----------x-|'),
cold( '-x--|')];
var selectorSubs = [' ^ ! ',
' ^ !',
' ^! '];

var idx = 0;
function durationSelector(x) {
return selector[idx++];
}

var result = e1.delayWhen(durationSelector);

expectObservable(result).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(subs);
expectSubscriptions(selector[0].subscriptions).toBe(selectorSubs[0]);
expectSubscriptions(selector[1].subscriptions).toBe(selectorSubs[1]);
expectSubscriptions(selector[2].subscriptions).toBe(selectorSubs[2]);
});

it('should delay by selector', function () {
var e1 = hot('--a--b--|');
var expected = '---a--b-|';
var subs = '^ !';
var selector = cold( '-x--|');
var selectorSubs = [' ^! ',
' ^! '];

var result = e1.delayWhen(function (x) { return selector; });

expectObservable(result).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(subs);
expectSubscriptions(selector.subscriptions).toBe(selectorSubs);
});

it('should raise error if source raises error', function () {
var e1 = hot('--a--#');
var expected = '---a-#';
var subs = '^ !';
var selector = cold( '-x--|');
var selectorSubs = ' ^! ';

var result = e1.delayWhen(function (x) { return selector; });

expectObservable(result).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(subs);
expectSubscriptions(selector.subscriptions).toBe(selectorSubs);
});

it('should raise error if selector raises error', function () {
var e1 = hot('--a--b--|');
var expected = '---#';
var subs = '^ !';
var selector = cold( '-#');
var selectorSubs = ' ^! ';

var result = e1.delayWhen(function (x) { return selector; });

expectObservable(result).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(subs);
expectSubscriptions(selector.subscriptions).toBe(selectorSubs);
});

it('should delay by selector and completes after value emits', function () {
var e1 = hot('--a--b--|');
var expected = '---------a--(b|)';
var subs = '^ !';
var selector = cold('-------x--|');
var selectorSubs = [' ^ !',
' ^ !'];

var result = e1.delayWhen(function (x) { return selector; });

expectObservable(result).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(subs);
expectSubscriptions(selector.subscriptions).toBe(selectorSubs);
});

it('should delay by selector completes if selector does not emits', function () {
var e1 = hot('--a--b--|');
var expected = '------a--(b|)';
var subs = '^ !';
var selector = cold( '----|');
var selectorSubs = [' ^ !',
' ^ !'];

var result = e1.delayWhen(function (x) { return selector; });

expectObservable(result).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(subs);
expectSubscriptions(selector.subscriptions).toBe(selectorSubs);
});

it('should not emit if selector never emits', function () {
var e1 = hot('--a--b--|');
var expected = '-';
var subs = '^ ';
var selector = cold( '-');
var selectorSubs = [' ^ ',
' ^ '];

var result = e1.delayWhen(function (x) { return selector; });

expectObservable(result).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(subs);
expectSubscriptions(selector.subscriptions).toBe(selectorSubs);
});

it('should delay by first value from selector', function () {
var e1 = hot('--a--b--|');
var expected = '------a--(b|)';
var subs = '^ !';
var selector = cold( '----x--y--|');
var selectorSubs = [' ^ !',
' ^ !'];

var result = e1.delayWhen(function (x) { return selector; });

expectObservable(result).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(subs);
expectSubscriptions(selector.subscriptions).toBe(selectorSubs);
});

it('should delay by selector does not completes', function () {
var e1 = hot('--a--b--|');
var expected = '------a--(b|)';
var subs = '^ !';
var selector = cold( '----x-----y---');
var selectorSubs = [' ^ !',
' ^ !'];

var result = e1.delayWhen(function (x) { return selector; });

expectObservable(result).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(subs);
expectSubscriptions(selector.subscriptions).toBe(selectorSubs);
});

it('should raise error if selector throws', function () {
var e1 = hot('--a--b--|');
var expected = '--#';
var subs = '^ !';

var err = new Error('error');
var result = e1.delayWhen(function (x) { throw err; });

expectObservable(result).toBe(expected, null, err);
expectSubscriptions(e1.subscriptions).toBe(subs);
});

it('should start subscription when subscription delay emits', function () {
var e1 = hot('-----a---b---|');
var expected = ' -----a---b-|';
var subs = ' ^ !';
var selector = cold( '--x--|');
var selectorSubs = [' ^ !',
' ^ !'];
var subDelay = cold('--x--|');
var subDelaySub = '^ !';

var result = e1.delayWhen(function (x) { return selector; }, subDelay);

expectObservable(result).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(subs);
expectSubscriptions(selector.subscriptions).toBe(selectorSubs);
expectSubscriptions(subDelay.subscriptions).toBe(subDelaySub);
});

it('should start subscription when subscription delay completes without emit value', function () {
var e1 = hot('-----a---b---|');
var expected = ' -----a---b-|';
var subs = ' ^ !';
var selector = cold( '--x--|');
var selectorSubs = [' ^ !',
' ^ !'];
var subDelay = cold('--|');
var subDelaySub = '^ !';

var result = e1.delayWhen(function (x) { return selector; }, subDelay);

expectObservable(result).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe(subs);
expectSubscriptions(selector.subscriptions).toBe(selectorSubs);
expectSubscriptions(subDelay.subscriptions).toBe(subDelaySub);
});

it('should raise error when subscription delay raises error', function () {
var e1 = hot('-----a---b---|');
var expected = ' # ';
var selector = cold( '--x--|');
var subDelay = cold('---#');
var subDelaySub = '^ !';

var result = e1.delayWhen(function (x) { return selector; }, subDelay);

expectObservable(result).toBe(expected);
expectSubscriptions(e1.subscriptions).toBe([]);
expectSubscriptions(selector.subscriptions).toBe([]);
expectSubscriptions(subDelay.subscriptions).toBe(subDelaySub);
});
});
1 change: 1 addition & 0 deletions src/CoreOperators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export interface CoreOperators<T> {
debounceTime?: <R>(dueTime: number, scheduler?: Scheduler) => Observable<R>;
defaultIfEmpty?: <R>(defaultValue?: T | R) => Observable<T> | Observable<R>;
delay?: (delay: number, scheduler?: Scheduler) => Observable<T>;
delayWhen?: (delayDurationSelector: (value: T) => Observable<any>, subscriptionDelay?: Observable<any>) => Observable<T>;
distinctUntilChanged?: (compare?: (x: T, y: T) => boolean) => Observable<T>;
do?: (next?: (x: T) => void, error?: (e: any) => void, complete?: () => void) => Observable<T>;
expand?: <R>(project: (x: T, ix: number) => Observable<R>, concurrent: number, scheduler: Scheduler) => Observable<R>;
Expand Down
1 change: 1 addition & 0 deletions src/Observable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ export class Observable<T> implements CoreOperators<T> {
debounceTime: <R>(dueTime: number, scheduler?: Scheduler) => Observable<R>;
defaultIfEmpty: <R>(defaultValue?: T | R) => Observable<T> | Observable<R>;
delay: (delay: number, scheduler?: Scheduler) => Observable<T>;
delayWhen: (delayDurationSelector: (value: T) => Observable<any>, subscriptionDelay?: Observable<any>) => Observable<T>;
distinctUntilChanged: (compare?: (x: T, y: T) => boolean) => Observable<T>;
do: (next?: (x: T) => void, error?: (e: any) => void, complete?: () => void) => Observable<T>;
expand: <R>(project: (x: T, ix: number) => Observable<R>, concurrent: number, scheduler: Scheduler) => Observable<R>;
Expand Down
1 change: 1 addition & 0 deletions src/Rx.DOM.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import './add/operator/debounce';
import './add/operator/debounceTime';
import './add/operator/defaultIfEmpty';
import './add/operator/delay';
import './add/operator/delayWhen';
import './add/operator/distinctUntilChanged';
import './add/operator/do';
import './add/operator/expand';
Expand Down
1 change: 1 addition & 0 deletions src/Rx.KitchenSink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ import './add/operator/debounce';
import './add/operator/debounceTime';
import './add/operator/defaultIfEmpty';
import './add/operator/delay';
import './add/operator/delayWhen';
import './add/operator/distinct';
import './add/operator/distinctKey';
import './add/operator/distinctUntilChanged';
Expand Down
1 change: 1 addition & 0 deletions src/Rx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ import './add/operator/debounce';
import './add/operator/debounceTime';
import './add/operator/defaultIfEmpty';
import './add/operator/delay';
import './add/operator/delayWhen';
import './add/operator/distinctUntilChanged';
import './add/operator/do';
import './add/operator/expand';
Expand Down
6 changes: 6 additions & 0 deletions src/add/operator/delayWhen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import {Observable} from '../../Observable';
import {delayWhen} from '../../operator/delayWhen';

Observable.prototype.delayWhen = delayWhen;

export var _void: void;
Loading

0 comments on commit 17122f9

Please sign in to comment.