UNPKG

@reactivex/rxjs

Version:

Reactive Extensions for modern JavaScript

183 lines 9.09 kB
"use strict"; var chai_1 = require('chai'); var Rx = require('../../dist/cjs/Rx'); var Observable = Rx.Observable; /** @test {last} */ describe('Observable.prototype.last', function () { asDiagram('last')('should take the last value of an observable', function () { var e1 = hot('--a----b--c--|'); var e1subs = '^ !'; var expected = '-------------(c|)'; expectObservable(e1.last()).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); it('should error on nothing sent but completed', function () { var e1 = hot('--a--^----|'); var e1subs = '^ !'; var expected = '-----#'; expectObservable(e1.last()).toBe(expected, null, new Rx.EmptyError()); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); it('should error on empty', function () { var e1 = cold('|'); var e1subs = '(^!)'; var expected = '#'; expectObservable(e1.last()).toBe(expected, null, new Rx.EmptyError()); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); it('should go on forever on never', function () { var e1 = cold('-'); var e1subs = '^'; var expected = '-'; expectObservable(e1.last()).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); it('should return last element matches with predicate', function () { var e1 = hot('--a--b--a--b--|'); var e1subs = '^ !'; var expected = '--------------(b|)'; var predicate = function (value) { return value === 'b'; }; expectObservable(e1.last(predicate)).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); it('should allow unsubscribing explicitly and early', function () { var e1 = hot('--a--b--c--d--|'); var unsub = ' ! '; var e1subs = '^ ! '; var expected = '-------- '; expectObservable(e1.last(), 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 Rx.Observable.of(x); }) .last() .mergeMap(function (x) { return Rx.Observable.of(x); }); expectObservable(result, unsub).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); it('should return a default value if no element found', function () { var e1 = cold('|'); var e1subs = '(^!)'; var expected = '(a|)'; expectObservable(e1.last(null, null, 'a')).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); it('should not return default value if an element is found', function () { var e1 = hot('--a---^---b---c---d---|'); var e1subs = '^ !'; var expected = '----------------(d|)'; expectObservable(e1.last(null, null, 'x')).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); it('should support a result selector argument', function () { var e1 = hot('--a--^---b---c---d---e--|'); var e1subs = '^ !'; var expected = '-------------------(x|)'; 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.last(predicate, resultSelector)).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); it('should raise error when predicate throws', function () { var e1 = hot('--a--^---b---c---d---e--|'); var e1subs = '^ ! '; var expected = '--------# '; var predicate = function (x) { if (x === 'c') { throw 'error'; } else { return false; } }; expectObservable(e1.last(predicate)).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); it('should raise error when result selector throws', function () { var e1 = hot('--a--^---b---c---d---e--|'); var e1subs = '^ ! '; var expected = '--------# '; var predicate = function (x) { return x === 'c'; }; var resultSelector = function (x, i) { throw 'error'; }; expectObservable(e1.last(predicate, resultSelector)).toBe(expected); expectSubscriptions(e1.subscriptions).toBe(e1subs); }); 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).last() .subscribe(function (x) { return x.baz; }); // x is Foo Observable.of(foo).last(function (foo) { return foo.bar === 'name'; }) .subscribe(function (x) { return x.baz; }); // x is still Foo Observable.of(foo).last(isBar) .subscribe(function (x) { return x.bar; }); // x is Bar! var foobar = new Foo(); // type is the interface, not the class Observable.of(foobar).last() .subscribe(function (x) { return x.bar; }); // x is Bar Observable.of(foobar).last(function (foobar) { return foobar.bar === 'name'; }) .subscribe(function (x) { return x.bar; }); // x is still Bar Observable.of(foobar).last(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).last() .subscribe(function (x) { return x.baz; }); // x is still { bar: string; baz: number; } Observable.of(barish).last(function (x) { return x.bar === 'quack'; }) .subscribe(function (x) { return x.bar; }); // x is still { bar: string; baz: number; } Observable.of(barish).last(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.last().subscribe(function (x) { return x; }); // x is still string | number // After the type guard `last` predicates, the type is narrowed to string xs.last(isString) .subscribe(function (s) { return s.length; }); // s is string xs.last(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.last(function (x) { return typeof x === 'string'; }) .subscribe(function (x) { return x; }); // x is still string | number xs.last(function (x) { return !!x; }, function (x) { return x; }) .subscribe(function (x) { return x; }); // x is still string | number xs.last(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 // `last` still uses the `resultSelector` return type, if it exists. xs.last(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.last(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=last-spec.js.map