diff --git a/test/ui/ui_unit.js b/test/ui/ui_unit.js index 34b78e45a..5a6356391 100644 --- a/test/ui/ui_unit.js +++ b/test/ui/ui_unit.js @@ -136,10 +136,10 @@ describe('UI', () => { }); it('has all the basic elements', () => { - videos.forEach((video) => { + for (const video of videos) { checkBasicUIElements( /** @type {!HTMLVideoElement} */ (video.parentElement)); - }); + } }); }); @@ -559,13 +559,13 @@ describe('UI', () => { * @suppress {visibility} */ function createUIThroughDOMAutoSetup(containers, videos) { - containers.forEach((container) => { + for (const container of containers) { container.setAttribute('data-shaka-player-container', ''); - }); + } - videos.forEach((video) => { + for (const video of videos) { video.setAttribute('data-shaka-player', ''); - }); + } // Call UI's private method to scan the page for shaka // elements and create the UI. @@ -592,4 +592,3 @@ describe('UI', () => { expect(elements.length).toBe(0); } }); - diff --git a/test/util/abortable_operation_unit.js b/test/util/abortable_operation_unit.js index 09ea04aa0..836dd17ae 100644 --- a/test/util/abortable_operation_unit.js +++ b/test/util/abortable_operation_unit.js @@ -16,18 +16,18 @@ */ describe('AbortableOperation', () => { + const Util = shaka.test.Util; + describe('promise', () => { - it('is resolved by the constructor argument', (done) => { + it('is resolved by the constructor argument', async () => { const promise = new shaka.util.PublicPromise(); const abort = () => Promise.resolve(); const operation = new shaka.util.AbortableOperation(promise, abort); promise.resolve(100); - operation.promise.catch(fail).then((value) => { - expect(value).toEqual(100); - done(); - }); + const value = await operation.promise; + expect(value).toEqual(100); }); }); @@ -43,7 +43,8 @@ describe('AbortableOperation', () => { expect(abort).toHaveBeenCalled(); }); - it('is resolved when the underlying abort() is resolved', (done) => { + it('is resolved when the underlying abort() is resolved', async () => { + /** @type {!shaka.util.PublicPromise} */ const p = new shaka.util.PublicPromise(); const abort = jasmine.createSpy('abort').and.returnValue(p); @@ -51,63 +52,57 @@ describe('AbortableOperation', () => { new shaka.util.PublicPromise(), shaka.test.Util.spyFunc(abort)); const abortComplete = jasmine.createSpy('abort complete'); - operation.abort() - .catch(fail).then(shaka.test.Util.spyFunc(abortComplete)); + operation.abort().then(shaka.test.Util.spyFunc(abortComplete), fail); expect(abortComplete).not.toHaveBeenCalled(); - shaka.test.Util.delay(0.1).then(() => { - // Nothing has happened yet, so abort is not complete. - expect(abortComplete).not.toHaveBeenCalled(); - // Resolve the underlying Promise. - p.resolve(); - return shaka.test.Util.delay(0.1); - }).then(() => { - // The abort is now complete. - expect(abortComplete).toHaveBeenCalled(); - }).catch(fail).then(done); + await shaka.test.Util.delay(0.1); + // Nothing has happened yet, so abort is not complete. + expect(abortComplete).not.toHaveBeenCalled(); + // Resolve the underlying Promise. + p.resolve(); + + await shaka.test.Util.delay(0.1); + // The abort is now complete. + expect(abortComplete).toHaveBeenCalled(); }); }); describe('failed', () => { - it('creates a failed operation with the given error', (done) => { + it('creates a failed operation with the given error', async () => { const error = new shaka.util.Error( shaka.util.Error.Severity.RECOVERABLE, shaka.util.Error.Category.NETWORK, shaka.util.Error.Code.MALFORMED_DATA_URI); const operation = shaka.util.AbortableOperation.failed(error); - operation.promise.then(fail).catch((e) => { - shaka.test.Util.expectToEqualError(e, error); - }).then(done); + await expectAsync(operation.promise) + .toBeRejectedWith(Util.jasmineError(error)); }); }); describe('aborted', () => { - it('creates a failed operation with OPERATION_ABORTED', (done) => { - const error = new shaka.util.Error( + it('creates a failed operation with OPERATION_ABORTED', async () => { + const error = Util.jasmineError(new shaka.util.Error( shaka.util.Error.Severity.CRITICAL, shaka.util.Error.Category.PLAYER, - shaka.util.Error.Code.OPERATION_ABORTED); + shaka.util.Error.Code.OPERATION_ABORTED)); const operation = shaka.util.AbortableOperation.aborted(); - operation.promise.then(fail).catch((e) => { - shaka.test.Util.expectToEqualError(e, error); - }).then(done); + await expectAsync(operation.promise).toBeRejectedWith(error); }); }); describe('completed', () => { - it('creates a completed operation with the given value', (done) => { + it('creates a completed operation with the given value', async () => { const operation = shaka.util.AbortableOperation.completed(100); - operation.promise.catch(fail).then((value) => { - expect(value).toEqual(100); - done(); - }); + const value = await operation.promise; + expect(value).toEqual(100); }); }); describe('notAbortable', () => { - it('creates an operation from the given promise', (done) => { + it('creates an operation from the given promise', async () => { + /** @type {!shaka.util.PublicPromise} */ const promise = new shaka.util.PublicPromise(); const operation = shaka.util.AbortableOperation.notAbortable(promise); @@ -122,29 +117,72 @@ describe('AbortableOperation', () => { expect(value).toEqual(100); }); - shaka.test.Util.delay(0.1).then(() => { - // Even though we called abort(), the operation hasn't completed - // because it isn't abortable. The abort() Promise hasn't been - // resolved yet, either. - expect(isComplete).toBe(false); - expect(isAborted).toBe(false); + await shaka.test.Util.delay(0.1); + // Even though we called abort(), the operation hasn't completed + // because it isn't abortable. The abort() Promise hasn't been + // resolved yet, either. + expect(isComplete).toBe(false); + expect(isAborted).toBe(false); - promise.resolve(100); - return shaka.test.Util.delay(0.1); - }).then(() => { - // Now that we resolved the underlying promise, the operation is - // complete, and so is the abort() Promise. - expect(isComplete).toBe(true); - expect(isAborted).toBe(true); - }).catch(fail).then(done); + promise.resolve(100); + await shaka.test.Util.delay(0.1); + + // Now that we resolved the underlying promise, the operation is + // complete, and so is the abort() Promise. + expect(isComplete).toBe(true); + expect(isAborted).toBe(true); }); }); // describe('notAbortable') describe('all', () => { - it('creates a successful operation when all succeed', (done) => { + it('creates a successful operation when all succeed', async () => { + /** @type {!shaka.util.PublicPromise} */ const p1 = new shaka.util.PublicPromise(); const op1 = shaka.util.AbortableOperation.notAbortable(p1); + /** @type {!shaka.util.PublicPromise} */ + const p2 = new shaka.util.PublicPromise(); + const op2 = shaka.util.AbortableOperation.notAbortable(p2); + + /** @type {!shaka.util.PublicPromise} */ + const p3 = new shaka.util.PublicPromise(); + const op3 = shaka.util.AbortableOperation.notAbortable(p3); + + const all = shaka.util.AbortableOperation.all([op1, op2, op3]); + + const onSuccessSpy = jasmine.createSpy('onSuccess'); + const onSuccess = shaka.test.Util.spyFunc(onSuccessSpy); + const onErrorSpy = jasmine.createSpy('onError'); + const onError = shaka.test.Util.spyFunc(onErrorSpy); + + all.promise.then(onSuccess, onError); + + await shaka.test.Util.delay(0.1); + expect(onSuccessSpy).not.toHaveBeenCalled(); + expect(onErrorSpy).not.toHaveBeenCalled(); + p1.resolve(); + await shaka.test.Util.delay(0.1); + + expect(onSuccessSpy).not.toHaveBeenCalled(); + expect(onErrorSpy).not.toHaveBeenCalled(); + p2.resolve(); + await shaka.test.Util.delay(0.1); + + expect(onSuccessSpy).not.toHaveBeenCalled(); + expect(onErrorSpy).not.toHaveBeenCalled(); + p3.resolve(); + await shaka.test.Util.delay(0.1); + + expect(onSuccessSpy).toHaveBeenCalled(); + expect(onErrorSpy).not.toHaveBeenCalled(); + }); + + it('creates a failed operation when any fail', async () => { + /** @type {!shaka.util.PublicPromise} */ + const p1 = new shaka.util.PublicPromise(); + const op1 = shaka.util.AbortableOperation.notAbortable(p1); + + /** @type {!shaka.util.PublicPromise} */ const p2 = new shaka.util.PublicPromise(); const op2 = shaka.util.AbortableOperation.notAbortable(p2); @@ -158,83 +196,46 @@ describe('AbortableOperation', () => { const onErrorSpy = jasmine.createSpy('onError'); const onError = shaka.test.Util.spyFunc(onErrorSpy); - all.promise.then(onSuccess, onError).catch(fail); + all.promise.then(onSuccess, onError); - shaka.test.Util.delay(0.1).then(() => { - expect(onSuccessSpy).not.toHaveBeenCalled(); - expect(onErrorSpy).not.toHaveBeenCalled(); - p1.resolve(); - return shaka.test.Util.delay(0.1); - }).then(() => { - expect(onSuccessSpy).not.toHaveBeenCalled(); - expect(onErrorSpy).not.toHaveBeenCalled(); - p2.resolve(); - return shaka.test.Util.delay(0.1); - }).then(() => { - expect(onSuccessSpy).not.toHaveBeenCalled(); - expect(onErrorSpy).not.toHaveBeenCalled(); - p3.resolve(); - return shaka.test.Util.delay(0.1); - }).then(() => { - expect(onSuccessSpy).toHaveBeenCalled(); - expect(onErrorSpy).not.toHaveBeenCalled(); - }).catch(fail).then(done); + await shaka.test.Util.delay(0.1); + expect(onSuccessSpy).not.toHaveBeenCalled(); + expect(onErrorSpy).not.toHaveBeenCalled(); + p1.resolve(); + await shaka.test.Util.delay(0.1); + + expect(onSuccessSpy).not.toHaveBeenCalled(); + expect(onErrorSpy).not.toHaveBeenCalled(); + p2.reject('error'); + await shaka.test.Util.delay(0.1); + + expect(onSuccessSpy).not.toHaveBeenCalled(); + expect(onErrorSpy).toHaveBeenCalledWith('error'); }); - it('creates a failed operation when any fail', (done) => { - const p1 = new shaka.util.PublicPromise(); - const op1 = shaka.util.AbortableOperation.notAbortable(p1); - - const p2 = new shaka.util.PublicPromise(); - const op2 = shaka.util.AbortableOperation.notAbortable(p2); - - const p3 = new shaka.util.PublicPromise(); - const op3 = shaka.util.AbortableOperation.notAbortable(p3); - - const all = shaka.util.AbortableOperation.all([op1, op2, op3]); - - const onSuccessSpy = jasmine.createSpy('onSuccess'); - const onSuccess = shaka.test.Util.spyFunc(onSuccessSpy); - const onErrorSpy = jasmine.createSpy('onError'); - const onError = shaka.test.Util.spyFunc(onErrorSpy); - - all.promise.then(onSuccess, onError).catch(fail); - - shaka.test.Util.delay(0.1).then(() => { - expect(onSuccessSpy).not.toHaveBeenCalled(); - expect(onErrorSpy).not.toHaveBeenCalled(); - p1.resolve(); - return shaka.test.Util.delay(0.1); - }).then(() => { - expect(onSuccessSpy).not.toHaveBeenCalled(); - expect(onErrorSpy).not.toHaveBeenCalled(); - p2.reject('error'); - return shaka.test.Util.delay(0.1); - }).then(() => { - expect(onSuccessSpy).not.toHaveBeenCalled(); - expect(onErrorSpy).toHaveBeenCalledWith('error'); - }).catch(fail).then(done); - }); - - it('aborts all operations on abort', (done) => { + it('aborts all operations on abort', async () => { + /** @type {!shaka.util.PublicPromise} */ const p1 = new shaka.util.PublicPromise(); const abort1Spy = jasmine.createSpy('abort1') .and.callFake(() => p1.reject()); const abort1 = shaka.test.Util.spyFunc(abort1Spy); const op1 = new shaka.util.AbortableOperation(p1, abort1); + /** @type {!shaka.util.PublicPromise} */ const p2 = new shaka.util.PublicPromise(); const abort2Spy = jasmine.createSpy('abort2') .and.callFake(() => p2.reject()); const abort2 = shaka.test.Util.spyFunc(abort2Spy); const op2 = new shaka.util.AbortableOperation(p2, abort2); + /** @type {!shaka.util.PublicPromise} */ const p3 = new shaka.util.PublicPromise(); const abort3Spy = jasmine.createSpy('abort3') .and.callFake(() => p3.reject()); const abort3 = shaka.test.Util.spyFunc(abort3Spy); const op3 = new shaka.util.AbortableOperation(p3, abort3); + /** @type {!shaka.util.AbortableOperation} */ const all = shaka.util.AbortableOperation.all([op1, op2, op3]); const onSuccessSpy = jasmine.createSpy('onSuccess'); @@ -242,32 +243,32 @@ describe('AbortableOperation', () => { const onErrorSpy = jasmine.createSpy('onError'); const onError = shaka.test.Util.spyFunc(onErrorSpy); - all.promise.then(onSuccess, onError).catch(fail); + all.promise.then(onSuccess, onError); - shaka.test.Util.delay(0.1).then(() => { - expect(onSuccessSpy).not.toHaveBeenCalled(); - expect(onErrorSpy).not.toHaveBeenCalled(); + await shaka.test.Util.delay(0.1); + expect(onSuccessSpy).not.toHaveBeenCalled(); + expect(onErrorSpy).not.toHaveBeenCalled(); - expect(abort1Spy).not.toHaveBeenCalled(); - expect(abort2Spy).not.toHaveBeenCalled(); - expect(abort3Spy).not.toHaveBeenCalled(); + expect(abort1Spy).not.toHaveBeenCalled(); + expect(abort2Spy).not.toHaveBeenCalled(); + expect(abort3Spy).not.toHaveBeenCalled(); - all.abort(); - return shaka.test.Util.delay(0.1); - }).then(() => { - expect(onSuccessSpy).not.toHaveBeenCalled(); - expect(onErrorSpy).toHaveBeenCalled(); + all.abort(); + await shaka.test.Util.delay(0.1); - expect(abort1Spy).toHaveBeenCalled(); - expect(abort2Spy).toHaveBeenCalled(); - expect(abort3Spy).toHaveBeenCalled(); - }).catch(fail).then(done); + expect(onSuccessSpy).not.toHaveBeenCalled(); + expect(onErrorSpy).toHaveBeenCalled(); + + expect(abort1Spy).toHaveBeenCalled(); + expect(abort2Spy).toHaveBeenCalled(); + expect(abort3Spy).toHaveBeenCalled(); }); }); // describe('all') describe('finally', () => { - it('executes after the operation is successful', (done) => { + it('executes after the operation is successful', async () => { let isDone = false; + /** @type {!shaka.util.PublicPromise} */ const promise = new shaka.util.PublicPromise(); shaka.util.AbortableOperation.notAbortable(promise).finally((ok) => { @@ -275,18 +276,17 @@ describe('AbortableOperation', () => { isDone = true; }); - shaka.test.Util.delay(0.1).then(() => { - expect(isDone).toBe(false); - promise.resolve(100); - return shaka.test.Util.delay(0.1); - }).then(() => { - expect(isDone).toBe(true); - done(); - }); + await shaka.test.Util.delay(0.1); + expect(isDone).toBe(false); + promise.resolve(100); + + await shaka.test.Util.delay(0.1); + expect(isDone).toBe(true); }); - it('executes after the operation fails', (done) => { + it('executes after the operation fails', async () => { let isDone = false; + /** @type {!shaka.util.PublicPromise} */ const promise = new shaka.util.PublicPromise(); shaka.util.AbortableOperation.notAbortable(promise).finally((ok) => { @@ -294,19 +294,19 @@ describe('AbortableOperation', () => { isDone = true; }); - shaka.test.Util.delay(0.1).then(() => { - expect(isDone).toBe(false); - promise.reject(0); - return shaka.test.Util.delay(0.1); - }).then(() => { - expect(isDone).toBe(true); - done(); - }); + await shaka.test.Util.delay(0.1); + expect(isDone).toBe(false); + promise.reject(0); + + await shaka.test.Util.delay(0.1); + expect(isDone).toBe(true); }); - it('executes after the chain is successful', (done) => { + it('executes after the chain is successful', async () => { let isDone = false; + /** @type {!shaka.util.PublicPromise} */ const promise1 = new shaka.util.PublicPromise(); + /** @type {!shaka.util.PublicPromise} */ const promise2 = new shaka.util.PublicPromise(); shaka.util.AbortableOperation.notAbortable(promise1).chain(() => { @@ -316,22 +316,21 @@ describe('AbortableOperation', () => { isDone = true; }); - shaka.test.Util.delay(0.1).then(() => { - expect(isDone).toBe(false); - promise1.resolve(); - return shaka.test.Util.delay(0.1); - }).then(() => { - expect(isDone).toBe(false); - promise2.resolve(); - return shaka.test.Util.delay(0.1); - }).then(() => { - expect(isDone).toBe(true); - done(); - }); + await shaka.test.Util.delay(0.1); + expect(isDone).toBe(false); + promise1.resolve(); + await shaka.test.Util.delay(0.1); + + expect(isDone).toBe(false); + promise2.resolve(); + await shaka.test.Util.delay(0.1); + + expect(isDone).toBe(true); }); - it('executes after the chain fails', (done) => { + it('executes after the chain fails', async () => { let isDone = false; + /** @type {!shaka.util.PublicPromise} */ const promise1 = new shaka.util.PublicPromise(); const promise2 = new shaka.util.PublicPromise(); @@ -342,17 +341,15 @@ describe('AbortableOperation', () => { isDone = true; }); - shaka.test.Util.delay(0.1).then(() => { - expect(isDone).toBe(false); - promise1.reject(0); - return shaka.test.Util.delay(0.1); - }).then(() => { - expect(isDone).toBe(true); - done(); - }); + await shaka.test.Util.delay(0.1); + expect(isDone).toBe(false); + promise1.reject(0); + await shaka.test.Util.delay(0.1); + + expect(isDone).toBe(true); }); - it('executes after a complex chain', (done) => { + it('executes after a complex chain', async () => { let isDone = false; shaka.util.AbortableOperation.completed(0).chain(() => { @@ -366,18 +363,17 @@ describe('AbortableOperation', () => { isDone = true; }); - shaka.test.Util.delay(0.1).then(() => { - expect(isDone).toBe(true); - done(); - }); + await shaka.test.Util.delay(0.1); + expect(isDone).toBe(true); }); }); // describe('finally') describe('chain', () => { - it('passes the value to the next operation on success', (done) => { + it('passes the value to the next operation on success', async () => { + /** @type {!Array.} */ const values = []; - shaka.util.AbortableOperation.completed(100).chain((value) => { + const op = shaka.util.AbortableOperation.completed(100).chain((value) => { values.push(value); expect(value).toBe(100); // Plain value @@ -407,31 +403,32 @@ describe('AbortableOperation', () => { // check, the test would pass, even though the bug shows up first in the // basic functionality of 'chain'. expect(values).toEqual([100, 200, 300, 400, 500]); - done(); }); + await op.promise; }); - it('skips the onSuccess callbacks on error', (done) => { + it('skips the onSuccess callbacks on error', async () => { const error = new shaka.util.Error( shaka.util.Error.Severity.RECOVERABLE, shaka.util.Error.Category.NETWORK, shaka.util.Error.Code.MALFORMED_DATA_URI); - shaka.util.AbortableOperation.failed(error).chain(fail, (e) => { - shaka.test.Util.expectToEqualError(e, error); - throw error; // rethrow - }).chain(fail, (e) => { - shaka.test.Util.expectToEqualError(e, error); - throw error; // rethrow - }).chain(fail, (e) => { - shaka.test.Util.expectToEqualError(e, error); - }).finally((ok) => { - expect(ok).toBe(true); // Last stage did not rethrow - done(); - }); + const op = shaka.util.AbortableOperation.failed(error) + .chain(fail, (e) => { + shaka.test.Util.expectToEqualError(e, error); + throw error; // rethrow + }).chain(fail, (e) => { + shaka.test.Util.expectToEqualError(e, error); + throw error; // rethrow + }).chain(fail, (e) => { + shaka.test.Util.expectToEqualError(e, error); + }).finally((ok) => { + expect(ok).toBe(true); // Last stage did not rethrow + }); + await op.promise; }); - it('can fall back to other operations in onError callback', (done) => { + it('can fall back to other operations in onError callback', async () => { const error1 = new shaka.util.Error( shaka.util.Error.Severity.RECOVERABLE, shaka.util.Error.Category.NETWORK, @@ -445,24 +442,25 @@ describe('AbortableOperation', () => { shaka.util.Error.Category.MEDIA, shaka.util.Error.Code.EBML_BAD_FLOATING_POINT_SIZE); - shaka.util.AbortableOperation.failed(error1).chain(fail, (e) => { - shaka.test.Util.expectToEqualError(e, error1); - return shaka.util.AbortableOperation.failed(error2); - }).chain(fail, (e) => { - shaka.test.Util.expectToEqualError(e, error2); - return shaka.util.AbortableOperation.failed(error3); - }).chain(fail, (e) => { - shaka.test.Util.expectToEqualError(e, error3); - return shaka.util.AbortableOperation.completed(400); - }).chain((value) => { - expect(value).toEqual(400); - }).finally((ok) => { - expect(ok).toBe(true); - done(); - }); + const op = shaka.util.AbortableOperation.failed(error1) + .chain(fail, (e) => { + shaka.test.Util.expectToEqualError(e, error1); + return shaka.util.AbortableOperation.failed(error2); + }).chain(fail, (e) => { + shaka.test.Util.expectToEqualError(e, error2); + return shaka.util.AbortableOperation.failed(error3); + }).chain(fail, (e) => { + shaka.test.Util.expectToEqualError(e, error3); + return shaka.util.AbortableOperation.completed(400); + }).chain((value) => { + expect(value).toEqual(400); + }).finally((ok) => { + expect(ok).toBe(true); + }); + await op.promise; }); - it('fails when an error is thrown', (done) => { + it('fails when an error is thrown', async () => { const error1 = new shaka.util.Error( shaka.util.Error.Severity.RECOVERABLE, shaka.util.Error.Category.NETWORK, @@ -472,7 +470,7 @@ describe('AbortableOperation', () => { shaka.util.Error.Category.TEXT, shaka.util.Error.Code.INVALID_XML); - shaka.util.AbortableOperation.completed(100).chain((value) => { + const op = shaka.util.AbortableOperation.completed(100).chain((value) => { throw error1; }).chain(fail, (e) => { shaka.test.Util.expectToEqualError(e, error1); @@ -481,74 +479,76 @@ describe('AbortableOperation', () => { shaka.test.Util.expectToEqualError(e, error2); }).finally((ok) => { expect(ok).toBe(true); // Last stage did not rethrow - done(); }); + await op.promise; }); - it('goes to success state when onError returns undefined', (done) => { + it('goes to success state when onError returns undefined', async () => { const error = new shaka.util.Error( shaka.util.Error.Severity.RECOVERABLE, shaka.util.Error.Category.NETWORK, shaka.util.Error.Code.MALFORMED_DATA_URI); - shaka.util.AbortableOperation.failed(error).chain(fail, (e) => { - shaka.test.Util.expectToEqualError(e, error); - // no return value - }).chain((value) => { - expect(value).toBe(undefined); - }, fail).finally((ok) => { - expect(ok).toBe(true); - done(); - }); + const op = shaka.util.AbortableOperation.failed(error) + .chain(fail, (e) => { + shaka.test.Util.expectToEqualError(e, error); + // no return value + }).chain((value) => { + expect(value).toBe(undefined); + }, fail).finally((ok) => { + expect(ok).toBe(true); + }); + await op.promise; }); - it('does not need return when onSuccess omitted', (done) => { - const operation = shaka.util.AbortableOperation.completed(100); - operation.chain(undefined, fail).chain(undefined, fail).chain((value) => { - expect(value).toEqual(100); - }).finally((ok) => { - expect(ok).toBe(true); - done(); - }); + it('does not need return when onSuccess omitted', async () => { + const operation = shaka.util.AbortableOperation.completed(100) + .chain(undefined, fail).chain(undefined, fail).chain((value) => { + expect(value).toEqual(100); + }).finally((ok) => { + expect(ok).toBe(true); + }); + await operation.promise; }); - it('does not need rethrow when onError omitted', (done) => { + it('does not need rethrow when onError omitted', async () => { const error = new shaka.util.Error( shaka.util.Error.Severity.RECOVERABLE, shaka.util.Error.Category.NETWORK, shaka.util.Error.Code.MALFORMED_DATA_URI); - const operation = shaka.util.AbortableOperation.failed(error); - operation.chain(fail).chain(fail).chain(fail).chain(fail, (e) => { - shaka.test.Util.expectToEqualError(e, error); - }).finally((ok) => { - expect(ok).toBe(true); // Last stage did not rethrow - done(); - }); + const operation = shaka.util.AbortableOperation.failed(error) + .chain(fail).chain(fail).chain(fail).chain(fail, (e) => { + shaka.test.Util.expectToEqualError(e, error); + }).finally((ok) => { + expect(ok).toBe(true); // Last stage did not rethrow + }); + await operation.promise; }); - it('ensures abort is called with the correct "this"', (done) => { + it('ensures abort is called with the correct "this"', async () => { // During testing and development, an early version of chain() would // sometimes unbind an abort method from an earlier stage of the chain. // Make sure this doesn't happen. let innerOperation; + /** @type {!shaka.util.PublicPromise} */ const p = new shaka.util.PublicPromise(); let abortCalled = false; /** - * @this {shaka.util.AbortableOperation} - * @return {!Promise} - * * NOTE: This is a subtle thing, but this must be an ES5 anonymous * function for the test to work. ES6 arrow functions would always be * called with the "this" of the test itself, regardless of what the * library is doing. + * + * @this {shaka.util.AbortableOperation} + * @return {!Promise} */ - const abort = function() { + function abort() { expect(this).toBe(innerOperation); abortCalled = true; return Promise.resolve(); - }; + } // Since the issue was with the calling of operation.abort, rather than // the onAbort_ callback, we make an operation-like thing instead of using @@ -570,8 +570,8 @@ describe('AbortableOperation', () => { // We resolved the non-abortable inner operation expect(ok).toBe(true); expect(abortCalled).toBe(true); - done(); }); + await operation.promise; }); }); // describe('chain') }); // describe('AbortableOperation') diff --git a/test/util/data_view_reader_unit.js b/test/util/data_view_reader_unit.js index 29991aeae..d7522d310 100644 --- a/test/util/data_view_reader_unit.js +++ b/test/util/data_view_reader_unit.js @@ -16,7 +16,7 @@ */ describe('DataViewReader', () => { - const Code = shaka.util.Error.Code; + const Util = shaka.test.Util; // |data| as interpreted as a 64 bit integer must not be larger than 2^53-1. // decimal digits. @@ -249,40 +249,21 @@ describe('DataViewReader', () => { }); function runTest(test) { - try { - test(); - fail('Should throw exception'); - } catch (e) { - expect(e).not.toBeNull(); - expect(e instanceof shaka.util.Error).toBe(true); - expect(e.code).toBe(Code.BUFFER_READ_OUT_OF_BOUNDS); - } + const expected = Util.jasmineError(new shaka.util.Error( + shaka.util.Error.Severity.CRITICAL, + shaka.util.Error.Category.MEDIA, + shaka.util.Error.Code.BUFFER_READ_OUT_OF_BOUNDS)); + expect(test).toThrow(expected); } }); it('detects uint64s too large for JavaScript', () => { - let exception = null; + const expected = Util.jasmineError(new shaka.util.Error( + shaka.util.Error.Severity.CRITICAL, + shaka.util.Error.Category.MEDIA, + shaka.util.Error.Code.JS_INTEGER_OVERFLOW)); - try { - littleEndianReader.readUint64(); - } catch (e) { - exception = e; - } - - expect(exception).not.toBe(null); - expect(exception instanceof shaka.util.Error).toBe(true); - expect(exception.code).toBe(Code.JS_INTEGER_OVERFLOW); - - exception = null; - - try { - bigEndianReader2.readUint64(); - } catch (e) { - exception = e; - } - - expect(exception).not.toBe(null); - expect(exception instanceof shaka.util.Error).toBe(true); - expect(exception.code).toBe(Code.JS_INTEGER_OVERFLOW); + expect(() => littleEndianReader.readUint64()).toThrow(expected); + expect(() => bigEndianReader2.readUint64()).toThrow(expected); }); }); diff --git a/test/util/ebml_parser_unit.js b/test/util/ebml_parser_unit.js index 87c577210..8fde4c3f2 100644 --- a/test/util/ebml_parser_unit.js +++ b/test/util/ebml_parser_unit.js @@ -16,7 +16,7 @@ */ describe('EbmlParser', /** @suppress {accessControls} */ () => { - const Code = shaka.util.Error.Code; + const Util = shaka.test.Util; it('parses one element', () => { // Set ID to 0x1. @@ -173,9 +173,12 @@ describe('EbmlParser', /** @suppress {accessControls} */ () => { }); it('detects vints with too many bytes', () => { - let exception = null; + const expected = Util.jasmineError(new shaka.util.Error( + shaka.util.Error.Severity.CRITICAL, + shaka.util.Error.Category.MEDIA, + shaka.util.Error.Code.EBML_OVERFLOW)); - try { + expect(() => { // 63-bit: 0000 0000, 1|000 0001, 0001 0001, 0001 0001, 0001 0001, // 0001 0001, 0001 0001, 0001 0001, // 0001 0001 @@ -183,63 +186,38 @@ describe('EbmlParser', /** @suppress {accessControls} */ () => { [0x00, 0x81, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11]); const parser = new shaka.util.EbmlParser(new DataView(data.buffer)); parser.parseVint_(); - } catch (e) { - exception = e; - } - - expect(exception).not.toBeNull(); - expect(exception instanceof shaka.util.Error).toBe(true); - expect(exception.code).toBe(Code.EBML_OVERFLOW); + }).toThrow(expected); }); it('detects vint values with too many bits', () => { - let exception = null; + const expected = Util.jasmineError(new shaka.util.Error( + shaka.util.Error.Severity.CRITICAL, + shaka.util.Error.Category.MEDIA, + shaka.util.Error.Code.JS_INTEGER_OVERFLOW)); - try { + expect(() => { // 56-bit: 0000 0001 | 1000 0001, 0001 0001, 0001 0001, 0001 0001, // 0001 0001, 0001 0001, 0001 0001 const data = new Uint8Array( [0x01, 0x81, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11]); shaka.util.EbmlParser.getVintValue_(data); - } catch (e) { - exception = e; - } + }).toThrow(expected); - expect(exception).not.toBeNull(); - expect(exception instanceof shaka.util.Error).toBe(true); - expect(exception.code).toBe(Code.JS_INTEGER_OVERFLOW); - - exception = null; - - try { + expect(() => { // 56-bit: 0000 0001 | 0100 0001, 0001 0001, 0001 0001, 0001 0001, // 0001 0001, 0001 0001, 0001 0001 const data = new Uint8Array( [0x01, 0x41, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11]); shaka.util.EbmlParser.getVintValue_(data); - } catch (e) { - exception = e; - } + }).toThrow(expected); - expect(exception).not.toBeNull(); - expect(exception instanceof shaka.util.Error).toBe(true); - expect(exception.code).toBe(Code.JS_INTEGER_OVERFLOW); - - exception = null; - - try { + expect(() => { // 56-bit: 0000 0001 | 0010 0001, 0001 0001, 0001 0001, 0001 0001, // 0001 0001, 0001 0001, 0001 0001 const data = new Uint8Array( [0x01, 0x21, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11]); shaka.util.EbmlParser.getVintValue_(data); - } catch (e) { - exception = e; - } - - expect(exception).not.toBeNull(); - expect(exception instanceof shaka.util.Error).toBe(true); - expect(exception.code).toBe(Code.JS_INTEGER_OVERFLOW); + }).toThrow(expected); }); it('detects the end of input while reading a vint', () => { @@ -247,17 +225,11 @@ describe('EbmlParser', /** @suppress {accessControls} */ () => { const data = new Uint8Array([0x61]); const parser = new shaka.util.EbmlParser(new DataView(data.buffer)); - let exception = null; - - try { - parser.parseVint_(); - } catch (e) { - exception = e; - } - - expect(exception).not.toBeNull(); - expect(exception instanceof shaka.util.Error).toBe(true); - expect(exception.code).toBe(Code.BUFFER_READ_OUT_OF_BOUNDS); + const expected = Util.jasmineError(new shaka.util.Error( + shaka.util.Error.Severity.CRITICAL, + shaka.util.Error.Category.MEDIA, + shaka.util.Error.Code.BUFFER_READ_OUT_OF_BOUNDS)); + expect(() => parser.parseVint_()).toThrow(expected); }); it('parses a uint', () => { @@ -283,17 +255,11 @@ describe('EbmlParser', /** @suppress {accessControls} */ () => { const elem = parser.parseElement(); expect(elem.id).toBe(0x81); - let exception = null; - - try { - elem.getUint(); - } catch (e) { - exception = e; - } - - expect(exception).not.toBeNull(); - expect(exception instanceof shaka.util.Error).toBe(true); - expect(exception.code).toBe(Code.EBML_OVERFLOW); + const expected = Util.jasmineError(new shaka.util.Error( + shaka.util.Error.Severity.CRITICAL, + shaka.util.Error.Category.MEDIA, + shaka.util.Error.Code.EBML_OVERFLOW)); + expect(() => elem.getUint()).toThrow(expected); }); it('detects uints with too many bits', () => { @@ -307,17 +273,11 @@ describe('EbmlParser', /** @suppress {accessControls} */ () => { const elem = parser.parseElement(); expect(elem.id).toBe(0x81); - let exception = null; - - try { - elem.getUint(); - } catch (e) { - exception = e; - } - - expect(exception).not.toBeNull(); - expect(exception instanceof shaka.util.Error).toBe(true); - expect(exception.code).toBe(Code.JS_INTEGER_OVERFLOW); + const expected = Util.jasmineError(new shaka.util.Error( + shaka.util.Error.Severity.CRITICAL, + shaka.util.Error.Category.MEDIA, + shaka.util.Error.Code.JS_INTEGER_OVERFLOW)); + expect(() => elem.getUint()).toThrow(expected); }); it('recognizes dynamic-sized values', () => { diff --git a/test/util/fake_event_target_unit.js b/test/util/fake_event_target_unit.js index b4c8936af..4c662ed28 100644 --- a/test/util/fake_event_target_unit.js +++ b/test/util/fake_event_target_unit.js @@ -36,17 +36,19 @@ describe('FakeEventTarget', () => { shaka.log.error = originalLogError; }); - it('sets target on dispatched events', (done) => { - target.addEventListener('event', (event) => { - expect(event.target).toBe(target); - expect(event.currentTarget).toBe(target); - done(); - }); + it('sets target on dispatched events', () => { + return new Promise((resolve) => { + target.addEventListener('event', (event) => { + expect(event.target).toBe(target); + expect(event.currentTarget).toBe(target); + resolve(); + }); - target.dispatchEvent(new shaka.util.FakeEvent('event')); + target.dispatchEvent(new shaka.util.FakeEvent('event')); + }); }); - it('calls all event listeners', (done) => { + it('calls all event listeners', async () => { const listener1 = jasmine.createSpy('listener1'); const listener2 = jasmine.createSpy('listener2'); @@ -55,14 +57,12 @@ describe('FakeEventTarget', () => { target.dispatchEvent(new shaka.util.FakeEvent('event')); - shaka.test.Util.delay(0.1).then(() => { - expect(listener1).toHaveBeenCalled(); - expect(listener2).toHaveBeenCalled(); - done(); - }); + await shaka.test.Util.delay(0.1); + expect(listener1).toHaveBeenCalled(); + expect(listener2).toHaveBeenCalled(); }); - it('stops processing on stopImmediatePropagation', (done) => { + it('stops processing on stopImmediatePropagation', async () => { const listener1 = jasmine.createSpy('listener1'); const listener2 = jasmine.createSpy('listener2'); @@ -75,14 +75,12 @@ describe('FakeEventTarget', () => { target.dispatchEvent(new shaka.util.FakeEvent('event')); - shaka.test.Util.delay(0.1).then(() => { - expect(listener1).toHaveBeenCalled(); - expect(listener2).not.toHaveBeenCalled(); - done(); - }); + await shaka.test.Util.delay(0.1); + expect(listener1).toHaveBeenCalled(); + expect(listener2).not.toHaveBeenCalled(); }); - it('catches exceptions thrown from listeners', (done) => { + it('catches exceptions thrown from listeners', async () => { const listener1 = jasmine.createSpy('listener1'); const listener2 = jasmine.createSpy('listener2'); @@ -94,21 +92,20 @@ describe('FakeEventTarget', () => { target.dispatchEvent(new shaka.util.FakeEvent('event')); - shaka.test.Util.delay(0.1).then(() => { - expect(listener1).toHaveBeenCalled(); - expect(logErrorSpy).toHaveBeenCalled(); - expect(listener2).toHaveBeenCalled(); - done(); - }); + await shaka.test.Util.delay(0.1); + expect(listener1).toHaveBeenCalled(); + expect(logErrorSpy).toHaveBeenCalled(); + expect(listener2).toHaveBeenCalled(); }); - it('allows events to be re-dispatched', (done) => { + it('allows events to be re-dispatched', async () => { const listener1 = jasmine.createSpy('listener1'); const listener2 = jasmine.createSpy('listener2'); target.addEventListener('event', Util.spyFunc(listener1)); target.addEventListener('event', Util.spyFunc(listener2)); + /** @type {!shaka.util.FakeEventTarget} */ const target2 = new shaka.util.FakeEventTarget(); const target2Listener = jasmine.createSpy('target2Listener'); @@ -129,11 +126,9 @@ describe('FakeEventTarget', () => { target.dispatchEvent(new shaka.util.FakeEvent('event')); - shaka.test.Util.delay(0.1).then(() => { - expect(listener1).toHaveBeenCalled(); - expect(listener2).toHaveBeenCalled(); - expect(target2Listener).toHaveBeenCalled(); - done(); - }); + await shaka.test.Util.delay(0.1); + expect(listener1).toHaveBeenCalled(); + expect(listener2).toHaveBeenCalled(); + expect(target2Listener).toHaveBeenCalled(); }); }); diff --git a/test/util/mp4_parser_unit.js b/test/util/mp4_parser_unit.js index bd20f58ac..c02ad791f 100644 --- a/test/util/mp4_parser_unit.js +++ b/test/util/mp4_parser_unit.js @@ -303,18 +303,16 @@ describe('Mp4Parser', () => { box.parser.stop(); }); - try { + const expected = Util.jasmineError(new shaka.util.Error( + shaka.util.Error.Severity.CRITICAL, + shaka.util.Error.Category.MEDIA, + shaka.util.Error.Code.BUFFER_READ_OUT_OF_BOUNDS)); + expect(() => { new shaka.util.Mp4Parser() .box('b003', Util.spyFunc(parentBox)) .box('b032', Util.spyFunc(childBox1)) .parse(partialBoxWithSampleDescription, false /* partialOkay */); - fail('Should not have been able to parse!'); - } catch (error) { - Util.expectToEqualError(error, new shaka.util.Error( - shaka.util.Error.Severity.CRITICAL, - shaka.util.Error.Category.MEDIA, - shaka.util.Error.Code.BUFFER_READ_OUT_OF_BOUNDS)); - } + }).toThrow(expected); parentBox.calls.reset(); childBox1.calls.reset(); diff --git a/test/util/pssh_unit.js b/test/util/pssh_unit.js index 43fefadba..26502c2b2 100644 --- a/test/util/pssh_unit.js +++ b/test/util/pssh_unit.js @@ -107,16 +107,12 @@ describe('Pssh', () => { fromHex(GENERIC_PSSH + TRUNCATED_PLAYREADY_PSSH), ]; - for (let i = 0; i < psshs.length; ++i) { - try { - const pssh = new shaka.util.Pssh(psshs[i]); - expect(pssh).toBeTruthy(); // Closure: don't complain about unused vars - fail(); - } catch (error) { - expect(error instanceof shaka.util.Error).toBe(true); - expect(error.code).toBe( - shaka.util.Error.Code.BUFFER_READ_OUT_OF_BOUNDS); - } + for (const pssh of psshs) { + const expected = shaka.test.Util.jasmineError(new shaka.util.Error( + shaka.util.Error.Severity.CRITICAL, + shaka.util.Error.Category.MEDIA, + shaka.util.Error.Code.BUFFER_READ_OUT_OF_BOUNDS)); + expect(() => new shaka.util.Pssh(pssh)).toThrow(expected); } }); diff --git a/test/util/string_utils_unit.js b/test/util/string_utils_unit.js index dc4b1479d..6bdbd244e 100644 --- a/test/util/string_utils_unit.js +++ b/test/util/string_utils_unit.js @@ -89,15 +89,13 @@ describe('StringUtils', () => { }); it('fails if unable to guess', () => { - try { - const arr = [0x01, 0x02, 0x03, 0x04]; - const buffer = new Uint8Array(arr).buffer; - StringUtils.fromBytesAutoDetect(buffer); - fail('Should not be able to guess'); - } catch (e) { - expect(e.category).toBe(shaka.util.Error.Category.TEXT); - expect(e.code).toBe(shaka.util.Error.Code.UNABLE_TO_DETECT_ENCODING); - } + const expected = shaka.test.Util.jasmineError(new shaka.util.Error( + shaka.util.Error.Severity.CRITICAL, + shaka.util.Error.Category.TEXT, + shaka.util.Error.Code.UNABLE_TO_DETECT_ENCODING)); + const arr = [0x01, 0x02, 0x03, 0x04]; + const buffer = new Uint8Array(arr).buffer; + expect(() => StringUtils.fromBytesAutoDetect(buffer)).toThrow(expected); }); });