Home Manual Reference Source Test Repository

spec-js/operators/catch-spec.js

"use strict";
var chai_1 = require('chai');
var Rx = require('../../dist/package/Rx');
var sinon = require('sinon');
var test_helper_1 = require('../helpers/test-helper');
var Observable = Rx.Observable;
/** @test {catch} */
describe('Observable.prototype.catch', function () {
    asDiagram('catch')('should catch error and replace with a cold Observable', function () {
        var e1 = hot('--a--b--#       ');
        var e2 = cold('-1-2-3-|');
        var expected = '--a--b---1-2-3-|';
        var result = e1.catch(function (err) { return e2; });
        expectObservable(result).toBe(expected);
    });
    it('should catch error and replace it with Observable.of()', function () {
        var e1 = hot('--a--b--c--------|');
        var subs = '^       !';
        var expected = '--a--b--(XYZ|)';
        var result = e1
            .map(function (n) {
            if (n === 'c') {
                throw 'bad';
            }
            return n;
        })
            .catch(function (err) {
            return Observable.of('X', 'Y', 'Z');
        });
        expectObservable(result).toBe(expected);
        expectSubscriptions(e1.subscriptions).toBe(subs);
    });
    it('should catch error and replace it with a cold Observable', function () {
        var e1 = hot('--a--b--#          ');
        var e1subs = '^       !          ';
        var e2 = cold('1-2-3-4-5-|');
        var e2subs = '        ^         !';
        var expected = '--a--b--1-2-3-4-5-|';
        var result = e1.catch(function (err) { return e2; });
        expectObservable(result).toBe(expected);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
    });
    it('should allow unsubscribing explicitly and early', function () {
        var e1 = hot('--1-2-3-4-5-6---#');
        var e1subs = '^      !         ';
        var expected = '--1-2-3-         ';
        var unsub = '       !         ';
        var result = e1.catch(function () {
            return Observable.of('X', 'Y', 'Z');
        });
        expectObservable(result, unsub).toBe(expected);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
    });
    it('should not break unsubscription chain when unsubscribed explicitly', function () {
        var e1 = hot('--1-2-3-4-5-6---#');
        var e1subs = '^      !         ';
        var expected = '--1-2-3-         ';
        var unsub = '       !         ';
        var result = e1
            .mergeMap(function (x) { return Observable.of(x); })
            .catch(function () {
            return Observable.of('X', 'Y', 'Z');
        })
            .mergeMap(function (x) { return Observable.of(x); });
        expectObservable(result, unsub).toBe(expected);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
    });
    it('should unsubscribe from a caught hot caught observable when unsubscribed explicitly', function () {
        var e1 = hot('-1-2-3-#          ');
        var e1subs = '^      !          ';
        var e2 = hot('---3-4-5-6-7-8-9-|');
        var e2subs = '       ^    !     ';
        var expected = '-1-2-3-5-6-7-     ';
        var unsub = '            !     ';
        var result = e1.catch(function () { return e2; });
        expectObservable(result, unsub).toBe(expected);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
    });
    it('should unsubscribe from a caught cold caught observable when unsubscribed explicitly', function () {
        var e1 = hot('-1-2-3-#          ');
        var e1subs = '^      !          ';
        var e2 = cold('5-6-7-8-9-|');
        var e2subs = '       ^    !     ';
        var expected = '-1-2-3-5-6-7-     ';
        var unsub = '            !     ';
        var result = e1.catch(function () { return e2; });
        expectObservable(result, unsub).toBe(expected);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
    });
    it('should catch error and replace it with a hot Observable', function () {
        var e1 = hot('--a--b--#          ');
        var e1subs = '^       !          ';
        var e2 = hot('1-2-3-4-5-6-7-8-9-|');
        var e2subs = '        ^         !';
        var expected = '--a--b--5-6-7-8-9-|';
        var result = e1.catch(function (err) { return e2; });
        expectObservable(result).toBe(expected);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
    });
    it('should catch and allow the cold observable to be repeated with the third ' +
        '(caught) argument', function () {
        var e1 = cold('--a--b--c--------|       ');
        var subs = ['^       !                ',
            '        ^       !        ',
            '                ^       !'];
        var expected = '--a--b----a--b----a--b--#';
        var retries = 0;
        var result = e1
            .map(function (n) {
            if (n === 'c') {
                throw 'bad';
            }
            return n;
        })
            .catch(function (err, caught) {
            if (retries++ === 2) {
                throw 'done';
            }
            return caught;
        });
        expectObservable(result).toBe(expected, undefined, 'done');
        expectSubscriptions(e1.subscriptions).toBe(subs);
    });
    it('should catch and allow the hot observable to proceed with the third ' +
        '(caught) argument', function () {
        var e1 = hot('--a--b--c----d---|');
        var subs = ['^       !         ',
            '        ^        !'];
        var expected = '--a--b-------d---|';
        var retries = 0;
        var result = e1
            .map(function (n) {
            if (n === 'c') {
                throw 'bad';
            }
            return n;
        })
            .catch(function (err, caught) {
            if (retries++ === 2) {
                throw 'done';
            }
            return caught;
        });
        expectObservable(result).toBe(expected, undefined, 'done');
        expectSubscriptions(e1.subscriptions).toBe(subs);
    });
    it('should catch and replace a Observable.throw() as the source', function () {
        var e1 = cold('#');
        var subs = '(^!)';
        var expected = '(abc|)';
        var result = e1.catch(function (err) { return Observable.of('a', 'b', 'c'); });
        expectObservable(result).toBe(expected);
        expectSubscriptions(e1.subscriptions).toBe(subs);
    });
    it('should mirror the source if it does not raise errors', function () {
        var e1 = cold('--a--b--c--|');
        var subs = '^          !';
        var expected = '--a--b--c--|';
        var result = e1.catch(function (err) { return Observable.of('x', 'y', 'z'); });
        expectObservable(result).toBe(expected);
        expectSubscriptions(e1.subscriptions).toBe(subs);
    });
    it('should complete if you return Observable.empty()', function () {
        var e1 = hot('--a--b--#');
        var e1subs = '^       !';
        var e2 = cold('|');
        var e2subs = '        (^!)';
        var expected = '--a--b--|';
        var result = e1.catch(function () { return e2; });
        expectObservable(result).toBe(expected);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
    });
    it('should raise error if you return Observable.throw()', function () {
        var e1 = hot('--a--b--#');
        var e1subs = '^       !';
        var e2 = cold('#');
        var e2subs = '        (^!)';
        var expected = '--a--b--#';
        var result = e1.catch(function () { return e2; });
        expectObservable(result).toBe(expected);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
    });
    it('should never terminate if you return Observable.never()', function () {
        var e1 = hot('--a--b--#');
        var e1subs = '^       !';
        var e2 = cold('-');
        var e2subs = '        ^';
        var expected = '--a--b---';
        var result = e1.catch(function () { return e2; });
        expectObservable(result).toBe(expected);
        expectSubscriptions(e1.subscriptions).toBe(e1subs);
        expectSubscriptions(e2.subscriptions).toBe(e2subs);
    });
    it('should pass the error as the first argument', function (done) {
        Observable.throw('bad')
            .catch(function (err) {
            chai_1.expect(err).to.equal('bad');
            return Observable.empty();
        })
            .subscribe(function () {
            //noop
        }, function (err) {
            done(new Error('should not be called'));
        }, function () {
            done();
        });
    });
    it('should accept selector returns any ObservableInput', function (done) {
        var input$ = test_helper_1.createObservableInputs(42);
        input$.mergeMap(function (input) {
            return Observable.throw('bad').catch(function (err) { return input; });
        }).subscribe(function (x) {
            chai_1.expect(x).to.be.equal(42);
        }, function (err) {
            done(new Error('should not be called'));
        }, function () {
            done();
        });
    });
    context('fromPromise', function () {
        var trueSetTimeout;
        var sandbox;
        var timers;
        beforeEach(function () {
            trueSetTimeout = global.setTimeout;
            sandbox = sinon.sandbox.create();
            timers = sandbox.useFakeTimers();
        });
        afterEach(function () {
            sandbox.restore();
        });
        it('should chain a throw from a promise using throw', function (done) {
            var subscribeSpy = sinon.spy();
            var testError = new Error('BROKEN PROMISE');
            Observable.fromPromise(Promise.reject(testError)).catch(function (err) {
                throw new Error('BROKEN THROW');
            }).subscribe(subscribeSpy);
            trueSetTimeout(function () {
                try {
                    timers.tick(1);
                }
                catch (e) {
                    chai_1.expect(subscribeSpy).not.to.be.called;
                    chai_1.expect(e.message).to.equal('BROKEN THROW');
                    return done();
                }
                done(new Error('This should have thrown an error'));
            }, 0);
        });
        it('should chain a throw from a promise using Observable.throw', function (done) {
            var subscribeSpy = sinon.spy();
            var testError = new Error('BROKEN PROMISE');
            Observable.fromPromise(Promise.reject(testError)).catch(function (err) {
                return Observable.throw(new Error('BROKEN THROW'));
            }).subscribe(subscribeSpy);
            trueSetTimeout(function () {
                try {
                    timers.tick(1);
                }
                catch (e) {
                    chai_1.expect(subscribeSpy).not.to.be.called;
                    chai_1.expect(e.message).to.equal('BROKEN THROW');
                    return done();
                }
                done(new Error('This should have thrown an error'));
            }, 0);
        });
        it('should chain a throw from a promise using Observable.throw', function (done) {
            var subscribeSpy = sinon.spy();
            var errorSpy = sinon.spy();
            var thrownError = new Error('BROKEN THROW');
            var testError = new Error('BROKEN PROMISE');
            Observable.fromPromise(Promise.reject(testError)).catch(function (err) {
                return Observable.throw(thrownError);
            }).subscribe(subscribeSpy, errorSpy);
            trueSetTimeout(function () {
                try {
                    timers.tick(1);
                }
                catch (e) {
                    return done(new Error('This should not have thrown an error'));
                }
                chai_1.expect(subscribeSpy).not.to.be.called;
                chai_1.expect(errorSpy).to.have.been.called;
                chai_1.expect(errorSpy).to.have.been.calledWith(thrownError);
                done();
            }, 0);
        });
    });
});
//# sourceMappingURL=catch-spec.js.map