UNPKG

@reactivex/rxjs

Version:

Reactive Extensions for modern JavaScript

243 lines 11.6 kB
"use strict"; var chai_1 = require('chai'); var Rx = require('../../dist/cjs/Rx'); var Observable = Rx.Observable; /** @test {first} */ describe('Observable.prototype.first', function () { asDiagram('first')('should take the first value of an observable with many values', function () { var e1 = hot('-----a--b--c---d---|'); var expected = '-----(a|) '; var sub = '^ ! '; expectObservable(e1.first()).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(sub); }); it('should take the first value of an observable with one value', function () { var e1 = hot('---(a|)'); var expected = '---(a|)'; var sub = '^ !'; expectObservable(e1.first()).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(sub); }); it('should error on empty', function () { var e1 = hot('--a--^----|'); var expected = '-----#'; var sub = '^ !'; expectObservable(e1.first()).toBe(expected, null, new Rx.EmptyError()); expectSubscriptions(e1.subscriptions).toBe(sub); }); it('should return the default value if source observable was empty', function () { var e1 = hot('-----^----|'); var expected = '-----(a|)'; var sub = '^ !'; expectObservable(e1.first(null, null, 'a')).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(sub); }); it('should only emit one value in recursive cases', function () { var subject = new Rx.Subject(); var results = []; subject.first().subscribe(function (x) { results.push(x); subject.next(x + 1); }); subject.next(0); chai_1.expect(results).to.deep.equal([0]); }); it('should propagate error from the source observable', function () { var e1 = hot('---^---#'); var expected = '----#'; var sub = '^ !'; expectObservable(e1.first()).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(sub); }); it('should go on forever on never', function () { var e1 = hot('--^-------'); var expected = '--------'; var sub = '^ '; expectObservable(e1.first()).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(sub); }); it('should allow unsubscribing early and explicitly', function () { var e1 = hot('--a--^-----b----c---d--|'); var e1subs = '^ ! '; var expected = '---- '; var unsub = ' ! '; expectObservable(e1.first(), unsub).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); it('should not break unsubscription chains when result is unsubscribed explicitly', function () { var e1 = hot('--a--^-----b----c---d--|'); var e1subs = '^ ! '; var expected = '---- '; var unsub = ' ! '; var result = e1 .mergeMap(function (x) { return Observable.of(x); }) .first() .mergeMap(function (x) { return Observable.of(x); }); expectObservable(result, unsub).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); it('should return first value that matches a predicate', function () { var e1 = hot('--a-^--b--c--a--c--|'); var expected = '------(c|)'; var sub = '^ !'; var predicate = function (value) { return value === 'c'; }; expectObservable(e1.first(predicate)).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(sub); }); it('should return first value that matches a predicate for odd numbers', function () { var e1 = hot('--a-^--b--c--d--e--|', { a: 1, b: 2, c: 3, d: 4, e: 5 }); var expected = '------(c|)'; var sub = '^ !'; var predicate = function (value) { return value % 2 === 1; }; expectObservable(e1.first(predicate)).toBe(expected, { c: 3 }); expectSubscriptions(e1.subscriptions).toBe(sub); }); it('should error when no value matches the predicate', function () { var e1 = hot('--a-^--b--c--a--c--|'); var expected = '---------------#'; var sub = '^ !'; var predicate = function (value) { return value === 's'; }; expectObservable(e1.first(predicate)).toBe(expected, null, new Rx.EmptyError()); expectSubscriptions(e1.subscriptions).toBe(sub); }); it('should return the default value when no value matches the predicate', function () { var e1 = hot('--a-^--b--c--a--c--|'); var expected = '---------------(d|)'; var sub = '^ !'; var predicate = function (value) { return value === 's'; }; expectObservable(e1.first(predicate, null, 'd')).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(sub); }); it('should propagate error when no value matches the predicate', function () { var e1 = hot('--a-^--b--c--a--#'); var expected = '------------#'; var sub = '^ !'; var predicate = function (value) { return value === 's'; }; expectObservable(e1.first(predicate)).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(sub); }); it('should return first value that matches the index in the predicate', function () { var e1 = hot('--a-^--b--c--a--c--|'); var expected = '---------(a|)'; var sub = '^ !'; var predicate = function (value, index) { return index === 2; }; expectObservable(e1.first(predicate)).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(sub); }); it('should propagate error from predicate', function () { var e1 = hot('--a-^--b--c--d--e--|', { a: 1, b: 2, c: 3, d: 4, e: 5 }); var expected = '---------#'; var sub = '^ !'; var predicate = function (value) { if (value < 4) { return false; } else { throw 'error'; } }; expectObservable(e1.first(predicate)).toBe(expected, null, 'error'); expectSubscriptions(e1.subscriptions).toBe(sub); }); it('should support a result selector argument', function () { var e1 = hot('--a--^---b---c---d---e--|'); var expected = '--------(x|)'; var sub = '^ !'; var predicate = function (x) { return x === 'c'; }; var resultSelector = function (x, i) { chai_1.expect(i).to.equal(1); chai_1.expect(x).to.equal('c'); return 'x'; }; expectObservable(e1.first(predicate, resultSelector)).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(sub); }); it('should raise error when result selector throws', function () { var e1 = hot('--a--^---b---c---d---e--|'); var expected = '--------#'; var sub = '^ !'; var predicate = function (x) { return x === 'c'; }; var resultSelector = function (x, i) { throw 'error'; }; expectObservable(e1.first(predicate, resultSelector)).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(sub); }); it('should support type guards without breaking previous behavior', function () { // tslint:disable no-unused-variable // type guards with interfaces and classes { var Foo = (function () { function Foo(bar, baz) { if (bar === void 0) { bar = 'name'; } if (baz === void 0) { baz = 42; } this.bar = bar; this.baz = baz; } return Foo; }()); var isBar = function (x) { return x && x.bar !== undefined; }; var isBaz = function (x) { return x && x.baz !== undefined; }; var foo = new Foo(); Observable.of(foo).first() .subscribe(function (x) { return x.baz; }); // x is Foo Observable.of(foo).first(function (foo) { return foo.bar === 'name'; }) .subscribe(function (x) { return x.baz; }); // x is still Foo Observable.of(foo).first(isBar) .subscribe(function (x) { return x.bar; }); // x is Bar! var foobar = new Foo(); // type is the interface, not the class Observable.of(foobar).first() .subscribe(function (x) { return x.bar; }); // x is Bar Observable.of(foobar).first(function (foobar) { return foobar.bar === 'name'; }) .subscribe(function (x) { return x.bar; }); // x is still Bar Observable.of(foobar).first(isBaz) .subscribe(function (x) { return x.baz; }); // x is Baz! var barish = { bar: 'quack', baz: 42 }; // type can quack like a Bar Observable.of(barish).first() .subscribe(function (x) { return x.baz; }); // x is still { bar: string; baz: number; } Observable.of(barish).first(function (x) { return x.bar === 'quack'; }) .subscribe(function (x) { return x.bar; }); // x is still { bar: string; baz: number; } Observable.of(barish).first(isBar) .subscribe(function (x) { return x.bar; }); // x is Bar! } // type guards with primitive types { var xs = Observable.from([1, 'aaa', 3, 'bb']); // This type guard will narrow a `string | number` to a string in the examples below var isString = function (x) { return typeof x === 'string'; }; // missing predicate preserves the type xs.first().subscribe(function (x) { return x; }); // x is still string | number // After the type guard `first` predicates, the type is narrowed to string xs.first(isString) .subscribe(function (s) { return s.length; }); // s is string xs.first(isString, function (s) { return s.substr(0); }) // s is string in predicate .subscribe(function (s) { return s.length; }); // s is string // boolean predicates preserve the type xs.first(function (x) { return typeof x === 'string'; }) .subscribe(function (x) { return x; }); // x is still string | number xs.first(function (x) { return !!x; }, function (x) { return x; }) .subscribe(function (x) { return x; }); // x is still string | number xs.first(function (x) { return typeof x === 'string'; }, function (x) { return x; }, '') // default is string; x remains string | number .subscribe(function (x) { return x; }); // x is still string | number // `first` still uses the `resultSelector` return type, if it exists. xs.first(function (x) { return typeof x === 'string'; }, function (x) { return ({ str: "" + x }); }) // x remains string | number .subscribe(function (o) { return o.str; }); // o is { str: string } xs.first(function (x) { return typeof x === 'string'; }, function (x) { return ({ str: "" + x }); }, { str: '' }) .subscribe(function (o) { return o.str; }); // o is { str: string } } // tslint:disable enable }); }); //# sourceMappingURL=first-spec.js.map