UNPKG

shaka-player

Version:
224 lines (193 loc) 7.16 kB
/** * @license * Copyright 2016 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ describe('CancelableChain', function() { /** @type {!shaka.util.CancelableChain} */ var chain; beforeEach(function() { chain = new shaka.util.CancelableChain(); }); it('functions like a simple Promise chain', function(done) { var delayStart; chain.then(function(data) { expect(data).toBe(undefined); return 1; }).then(function(data) { expect(data).toEqual(1); return 'abc'; }).then(function(data) { expect(data).toEqual('abc'); return true; }).then(function(data) { expect(data).toBe(true); return { 'testing': 'complex' }; }).then(function(data) { expect(data).toEqual({ 'testing': 'complex' }); return ['a', 5, false]; }).then(function(data) { expect(data).toEqual(['a', 5, false]); return Promise.resolve(73); }).then(function(data) { expect(data).toEqual(73); delayStart = Date.now(); var p = new shaka.util.PublicPromise(); setTimeout(p.resolve.bind(p, 'delayed'), 200); return p; }).then(function(data) { var delay = Date.now() - delayStart; expect(data).toEqual('delayed'); expect(delay).toBeGreaterThan(198); }).finalize().catch(fail).then(done); }); it('must be finalized to catch failures', function() { // compiler workaround var catchMethod = /** @type {Object} */(chain)['catch']; // no chain.catch expect(catchMethod).toBe(undefined); // no second argument on chain.then expect(chain.then.length).toBe(1); // finalize returns the final Promise, where errors are received. expect(chain.finalize().catch).toEqual(jasmine.any(Function)); }); it('stops accepting new stages after being finalized', function(done) { chain.then(function() { return shaka.test.Util.delay(0.5); }); var p = chain.finalize(); expect(chain.then).toThrow(jasmine.any(TypeError)); p.catch(fail).then(done); }); it('returns the same promise after being finalized', function() { var p = chain.then(function() { return 1; }).finalize(); expect(chain.finalize()).toBe(p); }); describe('cancel', function() { var cannedError; beforeAll(function() { cannedError = new shaka.util.Error( shaka.util.Error.Severity.CRITICAL, shaka.util.Error.Category.PLAYER, shaka.util.Error.Code.LOAD_INTERRUPTED); }); it('stops executing subsequent stages', function(done) { var block = new shaka.util.PublicPromise(); var firstStageComplete = false; var secondStageComplete = false; var p = chain.then(function() { firstStageComplete = true; // Now block the chain. return block; }).then(function() { secondStageComplete = true; }).finalize(); // The following "then(fail)" won't execute because we cancel the chain. p.then(fail).catch(function(reason) { expect(firstStageComplete).toBe(true); expect(secondStageComplete).toBe(false); expect(reason).toBe(cannedError); }).then(done); // Now cancel the chain. chain.cancel(cannedError); // The cancelation won't be processed until the chain is unblocked. block.resolve(); }); it('multiple calls result in the same Promise', function(done) { var block = new shaka.util.PublicPromise(); var p = chain.then(function() { return block; }).finalize(); var ownerDone = p.then(fail).catch(function(reason) { expect(reason).toBe(cannedError); }); var chainDone1 = chain.cancel(cannedError); var chainDone2 = chain.cancel(cannedError); // These are the same Promise. expect(chainDone1).toBe(chainDone2); // The cancelation won't be processed until the chain is unblocked. block.resolve(); Promise.all([ownerDone, chainDone1, chainDone2]).catch(fail).then(done); }); it('works even during the final stage', function(done) { var block = new shaka.util.PublicPromise(); var stageComplete = false; var p = chain.then(function() { stageComplete = true; return block; }).finalize(); p.then(fail).catch(function(reason) { expect(stageComplete).toBe(true); expect(reason).toBe(cannedError); }).then(done); chain.cancel(cannedError); // The cancelation won't be processed until the chain is unblocked. block.resolve(); }); it('works even if stage is rejected after being canceled', function(done) { var p = new shaka.util.PublicPromise(); var finalComplete = false; chain.then(function() { return p; }).finalize().then(fail).catch(function(err) { finalComplete = true; shaka.test.Util.expectToEqualError(err, cannedError); }); chain.cancel(cannedError).catch(fail).then(function() { // Delay so the catch block above can run. return shaka.test.Util.delay(0.1); }).then(function() { expect(finalComplete).toBe(true); done(); }); p.reject(new shaka.util.Error( shaka.util.Error.Severity.CRITICAL, shaka.util.Error.Category.MANIFEST, shaka.util.Error.Code.UNABLE_TO_GUESS_MANIFEST_TYPE)); }); it('resolves even after the finalized chain is resolved', function(done) { var stageComplete = false; var finalComplete = false; chain.then(function() { stageComplete = true; }).finalize().then(function() { finalComplete = true; }).catch(fail); shaka.test.Util.delay(0.5).then(function() { // The whole chain is done before we cancel. expect(stageComplete).toBe(true); expect(finalComplete).toBe(true); // Cancel should still resolve. return chain.cancel(cannedError); }).catch(fail).then(done); }); it('resolves even after the finalized chain is rejected', function(done) { var stageComplete = false; var finalComplete = false; chain.then(function() { stageComplete = true; return Promise.reject(null); }).finalize().then(fail).catch(function() { finalComplete = true; }); shaka.test.Util.delay(0.5).then(function() { // The whole chain is done before we cancel. expect(stageComplete).toBe(true); expect(finalComplete).toBe(true); // Cancel should still resolve. return chain.cancel(cannedError); }).catch(fail).then(done); }); }); });