From 80f72c5f512ed9d6dc58486d9e18d68f394e1340 Mon Sep 17 00:00:00 2001 From: kwonoj Date: Fri, 18 Sep 2015 00:42:06 -0700 Subject: [PATCH] feat(operator): add isEmpty operator --- .../immediate-scheduler/operators/isempty.js | 20 +++++++++++ spec/operators/isEmpty-spec.js | 31 ++++++++++++++++ src/Observable.ts | 1 + src/Rx.ts | 3 ++ src/operators/isEmpty.ts | 35 +++++++++++++++++++ 5 files changed, 90 insertions(+) create mode 100644 perf/micro/immediate-scheduler/operators/isempty.js create mode 100644 spec/operators/isEmpty-spec.js create mode 100644 src/operators/isEmpty.ts diff --git a/perf/micro/immediate-scheduler/operators/isempty.js b/perf/micro/immediate-scheduler/operators/isempty.js new file mode 100644 index 0000000000..5f57e89490 --- /dev/null +++ b/perf/micro/immediate-scheduler/operators/isempty.js @@ -0,0 +1,20 @@ +var RxOld = require("rx"); +var RxNew = require("../../../../index"); + +module.exports = function (suite) { + + var oldIsEmptyNoArgs = RxOld.Observable.of(25, RxOld.Scheduler.immediate).isEmpty(); + var newIsEmptyNoArgs = RxNew.Observable.of(25).isEmpty(); + + return suite + .add('old isEmpty with immediate scheduler', function () { + oldIsEmptyNoArgs.subscribe(_next, _error, _complete); + }) + .add('new isEmpty with immediate scheduler', function () { + newIsEmptyNoArgs.subscribe(_next, _error, _complete); + }); + + function _next(x) { } + function _error(e){ } + function _complete(){ } +}; \ No newline at end of file diff --git a/spec/operators/isEmpty-spec.js b/spec/operators/isEmpty-spec.js new file mode 100644 index 0000000000..36df0c5295 --- /dev/null +++ b/spec/operators/isEmpty-spec.js @@ -0,0 +1,31 @@ +/* globals describe, it, expect, expectObservable, hot */ +var Rx = require('../../dist/cjs/Rx'); + +describe('Observable.prototype.isEmpty()', function(){ + it('should return true if source is empty', function () { + var source = hot('-----|'); + var expected = '-----(x|)'; + + expectObservable(source.isEmpty()).toBe(expected, { x: true }); + }); + + it('should return false if source emits element', function () { + var source = hot('--a--^--b--|'); + var expected = '---(x|)'; + + expectObservable(source.isEmpty()).toBe(expected, { x: false }); + }); + + it('should raise error if source raise error', function () { + var source = hot('--#'); + var expected = '--#'; + + expectObservable(source.isEmpty()).toBe(expected); + }); + + it('should not completes if source never emits', function () { + var expected = '-'; + + expectObservable(Rx.Observable.never().isEmpty()).toBe(expected); + }); +}); \ No newline at end of file diff --git a/src/Observable.ts b/src/Observable.ts index c7dcd0e17f..fae584a53b 100644 --- a/src/Observable.ts +++ b/src/Observable.ts @@ -203,6 +203,7 @@ export default class Observable { startWith: (x: T) => Observable; debounce: (dueTime: number, scheduler?: Scheduler) => Observable; + isEmpty: () => Observable; elementAt: (index: number, defaultValue?: any) => Observable; last: (predicate?: (value: T, index:number) => boolean, thisArg?: any, defaultValue?: any) => Observable; single: (predicate?: (value: T, index:number) => boolean, thisArg?: any) => Observable; diff --git a/src/Rx.ts b/src/Rx.ts index 0300246813..3609825631 100644 --- a/src/Rx.ts +++ b/src/Rx.ts @@ -221,8 +221,11 @@ import sampleTime from './operators/sampleTime'; observableProto.sample = sample; observableProto.sampleTime = sampleTime; +import isEmpty from './operators/isEmpty'; import last from './operators/last'; import single from './operators/single'; + +observableProto.isEmpty = isEmpty; observableProto.last = last; observableProto.single = single diff --git a/src/operators/isEmpty.ts b/src/operators/isEmpty.ts new file mode 100644 index 0000000000..ea34b340ed --- /dev/null +++ b/src/operators/isEmpty.ts @@ -0,0 +1,35 @@ +import Operator from '../Operator'; +import Observable from '../Observable'; +import Subscriber from '../Subscriber'; + +export default function isEmpty() { + return this.lift(new IsEmptyOperator()); +} + +class IsEmptyOperator implements Operator { + call (observer: Subscriber): Subscriber { + return new IsEmptySubscriber(observer); + } +} + +class IsEmptySubscriber extends Subscriber { + + constructor(destination: Subscriber) { + super(destination); + } + + private notifyComplete(isEmpty: boolean): void { + const destination = this.destination; + + destination.next(isEmpty); + destination.complete(); + } + + _next(value: T) { + this.notifyComplete(false); + } + + _complete() { + this.notifyComplete(true); + } +} \ No newline at end of file