From 4eefaa44cb5f41a3ce47ce938eb19ecf05230f74 Mon Sep 17 00:00:00 2001 From: Joey Parrish Date: Tue, 28 Apr 2020 20:50:34 -0700 Subject: [PATCH] Correct type info in tests In many places in the tests, we used "Object" or "*" or just no type at all for various fakes. These were all flagged by the new Closure Compiler version we are adopting. In some other places, we mixed up similar types or had the wrong nullability on a type. In still others, types were missing fields. These issues were caught by a compiler upgrade. Issue #2528 Change-Id: I324e0b28f7e30a4102aa26ec2c9901fa9732211b --- test/cast/cast_receiver_integration.js | 4 ++-- test/cast/cast_receiver_unit.js | 10 ++++++---- test/hls/hls_parser_unit.js | 2 +- test/media/drm_engine_unit.js | 5 +++-- test/media/media_source_engine_unit.js | 2 +- test/media/playhead_unit.js | 5 ++++- test/offline/offline_integration.js | 4 ++-- test/offline/storage_integration.js | 2 +- test/player_unit.js | 10 +++++----- test/routing/walker_unit.js | 4 ++-- test/test/externs/jasmine.js | 18 ++++++++++------- test/test/util/canned_idb.js | 8 +++++--- test/test/util/jasmine_fetch.js | 18 ++++++++--------- test/test/util/ui_utils.js | 6 ++++-- test/test/util/util.js | 27 ++++++++++++++------------ test/ui/ad_ui_unit.js | 4 ++-- test/ui/text_displayer_unit.js | 2 +- test/ui/ui_customization_unit.js | 4 ++-- test/ui/ui_integration.js | 8 +++++--- test/ui/ui_unit.js | 4 ++-- 20 files changed, 83 insertions(+), 64 deletions(-) diff --git a/test/cast/cast_receiver_integration.js b/test/cast/cast_receiver_integration.js index dd6ed3c4e..b1f41ebd6 100644 --- a/test/cast/cast_receiver_integration.js +++ b/test/cast/cast_receiver_integration.js @@ -329,8 +329,8 @@ filterDescribe('CastReceiver', castReceiverIntegrationSupport, () => { } /** - * @param {?} message - * @param {!Object} bus + * @param {*} message + * @param {!cast.receiver.CastMessageBus} bus * @param {string=} senderId */ function fakeIncomingMessage(message, bus, senderId) { diff --git a/test/cast/cast_receiver_unit.js b/test/cast/cast_receiver_unit.js index 2493c76d0..5bb45ff8a 100644 --- a/test/cast/cast_receiver_unit.js +++ b/test/cast/cast_receiver_unit.js @@ -271,6 +271,8 @@ filterDescribe('CastReceiver', castReceiverSupport, () => { mockVideo, mockPlayer, Util.spyFunc(mockAppDataCallback)); fakeInitState = { + manifest: null, + startTime: null, player: { configure: fakeConfig, }, @@ -307,7 +309,7 @@ filterDescribe('CastReceiver', castReceiverSupport, () => { // The rest is done async: await shaka.test.Util.shortDelay(); expect(mockPlayer.setTextTrackVisibility).toHaveBeenCalledWith( - fakeInitState['playerAfterLoad'].setTextTrackVisibility); + fakeInitState.playerAfterLoad.setTextTrackVisibility); expect(mockVideo.loop).toBe(fakeInitState.video.loop); expect(mockVideo.playbackRate).toBe(fakeInitState.video.playbackRate); }); @@ -418,7 +420,7 @@ filterDescribe('CastReceiver', castReceiverSupport, () => { // State was still transferred, though: expect(mockPlayer.setTextTrackVisibility).toHaveBeenCalledWith( - fakeInitState['playerAfterLoad'].setTextTrackVisibility); + fakeInitState.playerAfterLoad.setTextTrackVisibility); expect(mockVideo.loop).toBe(fakeInitState.video.loop); expect(mockVideo.playbackRate).toBe(fakeInitState.video.playbackRate); }); @@ -988,8 +990,8 @@ filterDescribe('CastReceiver', castReceiverSupport, () => { } /** - * @param {?} message - * @param {!Object} bus + * @param {*} message + * @param {!cast.receiver.CastMessageBus} bus * @param {string=} senderId */ function fakeIncomingMessage(message, bus, senderId) { diff --git a/test/hls/hls_parser_unit.js b/test/hls/hls_parser_unit.js index 7bc89adac..9beca24b1 100644 --- a/test/hls/hls_parser_unit.js +++ b/test/hls/hls_parser_unit.js @@ -2061,7 +2061,7 @@ describe('HlsParser', () => { // We are assuming that the time will be pulled out of the main mp4 // segment, so if we see a request that has a range header, we will stop // the parser. - /** @type {!Map.} */ + /** @type {!Map.} */ const responses = new Map(); responses.set('test:/main.mp4', segmentData); responses.set('test:/init.mp4', initSegmentData); diff --git a/test/media/drm_engine_unit.js b/test/media/drm_engine_unit.js index bfb4d6d5b..5648c91bd 100644 --- a/test/media/drm_engine_unit.js +++ b/test/media/drm_engine_unit.js @@ -758,8 +758,9 @@ describe('DrmEngine', () => { expect(session.generateRequest) .toHaveBeenCalledWith('keyids', jasmine.any(Uint8Array)); - const initData = JSON.parse(shaka.util.StringUtils.fromUTF8( - session.generateRequest.calls.argsFor(0)[1])); + const initData = /** @type {{kids: !Array.}} */(JSON.parse( + shaka.util.StringUtils.fromUTF8( + session.generateRequest.calls.argsFor(0)[1]))); const keyId1 = Uint8ArrayUtils.toHex( Uint8ArrayUtils.fromBase64(initData.kids[0])); const keyId2 = Uint8ArrayUtils.toHex( diff --git a/test/media/media_source_engine_unit.js b/test/media/media_source_engine_unit.js index 35bd748f2..77c85105d 100644 --- a/test/media/media_source_engine_unit.js +++ b/test/media/media_source_engine_unit.js @@ -1183,7 +1183,7 @@ describe('MediaSourceEngine', () => { function createMockTextEngineCtor() { const ctor = jasmine.createSpy('TextEngine'); - ctor.isTypeSupported = () => true; + ctor['isTypeSupported'] = () => true; ctor.and.callFake(() => { expect(mockTextEngine).toBeFalsy(); mockTextEngine = jasmine.createSpyObj('TextEngine', [ diff --git a/test/media/playhead_unit.js b/test/media/playhead_unit.js index d9f730597..de9e989d6 100644 --- a/test/media/playhead_unit.js +++ b/test/media/playhead_unit.js @@ -58,7 +58,8 @@ let PlayingTestInfo; * seekTo: number, * expectedEndTime: number, * expectEvent: boolean, - * jumpLargeGaps: (boolean|undefined) + * jumpLargeGaps: (boolean|undefined), + * preventDefault: (boolean|undefined) * }} * * @description @@ -83,6 +84,8 @@ let PlayingTestInfo; * If true, expect the 'largegap' event to be fired. * @property {(boolean|undefined)} jumpLargeGaps * If given, set this field of the Playhead configuration. + * @property {(boolean|undefined)} preventDefault + * If true, call preventDefault() on the 'largegap' event. */ let SeekTestInfo; diff --git a/test/offline/offline_integration.js b/test/offline/offline_integration.js index af86d9b22..aed5cdc05 100644 --- a/test/offline/offline_integration.js +++ b/test/offline/offline_integration.js @@ -58,9 +58,9 @@ filterDescribe('Offline', supportsStorage, () => { const contentUri = content.offlineUri; goog.asserts.assert( - contentUri, 'Stored content should have an offline uri.'); + contentUri != null, 'Stored content should have an offline uri.'); - await player.load(content.offlineUri); + await player.load(contentUri); video.play(); await playTo(/* end= */ 3, /* timeout= */ 10); diff --git a/test/offline/storage_integration.js b/test/offline/storage_integration.js index 1144deb90..97906a87a 100644 --- a/test/offline/storage_integration.js +++ b/test/offline/storage_integration.js @@ -16,7 +16,7 @@ async function drmStorageSupport() { const support = await shaka.Player.probeSupport(); const widevineSupport = support.drm['com.widevine.alpha']; - return widevineSupport && widevineSupport.persistentState; + return !!(widevineSupport && widevineSupport.persistentState); } filterDescribe('Storage', storageSupport, () => { diff --git a/test/player_unit.js b/test/player_unit.js index a7b48e47a..454cd5c2b 100644 --- a/test/player_unit.js +++ b/test/player_unit.js @@ -734,14 +734,14 @@ describe('Player', () => { it('does not pollute other advanced DRM configs', () => { player.configure('drm.advanced.foo', {}); player.configure('drm.advanced.bar', {}); - const fooConfig1 = player.getConfiguration().drm.advanced.foo; - const barConfig1 = player.getConfiguration().drm.advanced.bar; + const fooConfig1 = player.getConfiguration().drm.advanced['foo']; + const barConfig1 = player.getConfiguration().drm.advanced['bar']; expect(fooConfig1.distinctiveIdentifierRequired).toBe(false); expect(barConfig1.distinctiveIdentifierRequired).toBe(false); player.configure('drm.advanced.foo.distinctiveIdentifierRequired', true); - const fooConfig2 = player.getConfiguration().drm.advanced.foo; - const barConfig2 = player.getConfiguration().drm.advanced.bar; + const fooConfig2 = player.getConfiguration().drm.advanced['foo']; + const barConfig2 = player.getConfiguration().drm.advanced['bar']; expect(fooConfig2.distinctiveIdentifierRequired).toBe(true); expect(barConfig2.distinctiveIdentifierRequired).toBe(false); }); @@ -1585,7 +1585,7 @@ describe('Player', () => { // choices are limited only by channel count and key status. for (const variant of manifest.variants) { const keyId = (variant.audio.id % 2) ? 'aaa' : 'bbb'; - variant.audio.keyId = keyId; + variant.audio.keyIds = new Set([keyId]); variant.video.roles = []; variant.audio.roles = []; } diff --git a/test/routing/walker_unit.js b/test/routing/walker_unit.js index ab450238c..c8a49e6b1 100644 --- a/test/routing/walker_unit.js +++ b/test/routing/walker_unit.js @@ -289,11 +289,11 @@ describe('Walker', () => { const goToC = startNewRoute(nodeC, /* interruptible= */ false); const goToB = startNewRoute(nodeB, /* interruptible= */ true); - /** @type {jasmine.Spy} */ + /** @type {!jasmine.Spy} */ const canceledCSpy = jasmine.createSpy('cancel c'); goToC.onCancel = shaka.test.Util.spyFunc(canceledCSpy); - /** @type {jasmine.Spy} */ + /** @type {!jasmine.Spy} */ const canceledBSpy = jasmine.createSpy('cancel b'); goToB.onCancel = shaka.test.Util.spyFunc(canceledBSpy); diff --git a/test/test/externs/jasmine.js b/test/test/externs/jasmine.js index 14d8b8235..323ef9c83 100644 --- a/test/test/externs/jasmine.js +++ b/test/test/externs/jasmine.js @@ -223,7 +223,7 @@ jasmine.SpyStrategy = function() {}; /** * @param {...*} varArgs - * @return {*} + * @return {?} */ jasmine.SpyStrategy.prototype.exec = function(varArgs) {}; @@ -271,15 +271,15 @@ jasmine.SpyStrategy.prototype.stub = function() {}; jasmine.CallContext = function() {}; -/** @const {*} */ +/** @const {?} */ jasmine.CallContext.prototype.object; -/** @const {!Array.<*>} */ +/** @const {!Array.} */ jasmine.CallContext.prototype.args; -/** @const {*} */ +/** @const {?} */ jasmine.CallContext.prototype.returnValue; @@ -300,12 +300,12 @@ jasmine.CallTracker.prototype.count = function() {}; /** * @param {number} i - * @return {!Array.<*>} + * @return {!Array.} */ jasmine.CallTracker.prototype.argsFor = function(i) {}; -/** @return {!Array.>} */ +/** @return {!Array.>} */ jasmine.CallTracker.prototype.allArgs = function() {}; @@ -375,9 +375,13 @@ jasmine.any = function(factory) {}; jasmine.anything = function() {}; +/** @typedef {{ sample: ? }} */ +jasmine.ObjectContainingType; + + /** * @param {!Object} value - * @return {!Object} + * @return {jasmine.ObjectContainingType} */ jasmine.objectContaining = function(value) {}; diff --git a/test/test/util/canned_idb.js b/test/test/util/canned_idb.js index 59f8a8533..cebec087d 100644 --- a/test/test/util/canned_idb.js +++ b/test/test/util/canned_idb.js @@ -29,7 +29,7 @@ shaka.test.CannedIDB = class { static async dumpJSON(name, dummyArrayBuffers) { const savedDatabase = await this.dump(name); const replacer = - (key, value) => this.replacer_(dummyArrayBuffers, key, value); + (key, value) => this.replacer_(dummyArrayBuffers || false, key, value); return JSON.stringify(savedDatabase, replacer); } @@ -72,7 +72,9 @@ shaka.test.CannedIDB = class { * @return {!Promise} Resolved when the operation is complete. */ static async restoreJSON(name, savedDatabaseJson, wipeDatabase) { - const savedDatabase = JSON.parse(savedDatabaseJson, this.reviver_); + const savedDatabase = + /** @type {shaka.test.CannedIDB.SavedDatabase} */(JSON.parse( + savedDatabaseJson, this.reviver_)); await this.restore(name, savedDatabase, wipeDatabase); } @@ -153,7 +155,7 @@ shaka.test.CannedIDB = class { /** * @param {string} name The name of the database to open. - * @return {!Promise.} Resolved when the named DB has been + * @return {!Promise.} Resolved when the named DB has been * opened. * @private */ diff --git a/test/test/util/jasmine_fetch.js b/test/test/util/jasmine_fetch.js index 0526a67c4..23b29c88c 100644 --- a/test/test/util/jasmine_fetch.js +++ b/test/test/util/jasmine_fetch.js @@ -57,11 +57,11 @@ jasmine.Fetch = class { * @private */ static makeAbortError_() { - // As per the spec, this should be a DOMException, but - // there is not a public constructor for this + // According to the spec, this should be a DOMException, but there is not a + // public constructor for that. So we make this look-alike instead. const exception = new Error('The operation was aborted. '); exception.name = 'AbortError'; - exception.code = 20; + exception['code'] = DOMException['ABORT_ERR']; return exception; } @@ -211,13 +211,13 @@ jasmine.Fetch.requests = class { }; jasmine.Fetch.ReadableStream = class { - /** @param {!Object} underlyingSource */ + /** @param {!ReadableStreamSource} underlyingSource */ constructor(underlyingSource) { - const noop = () => {}; - const controller = { - close: noop, - enqueue: noop, - }; + const controller = /** @type {!ReadableByteStreamController} */({ + close: () => {}, + enqueue: (chunk) => {}, + error: (err) => {}, + }); underlyingSource.start(controller); } }; diff --git a/test/test/util/ui_utils.js b/test/test/util/ui_utils.js index ccdea0339..694b02053 100644 --- a/test/test/util/ui_utils.js +++ b/test/test/util/ui_utils.js @@ -19,7 +19,9 @@ shaka.test.UiUtils = class { // Create UI config = config || {}; const ui = new shaka.ui.Overlay(player, videoContainer, video); - ui.getControls().addEventListener('error', (/** * */ e) => fail(e.detail)); + // TODO: generate externs automatically from @event types + // This event should be a shaka.Player.ErrorEvent + ui.getControls().addEventListener('error', (e) => fail(e['detail'])); ui.configure(config); return ui; } @@ -126,7 +128,7 @@ shaka.test.UiUtils = class { /** - * @param {!Element} cssLink + * @param {!HTMLLinkElement} cssLink */ static async setupCSS(cssLink) { const head = document.head; diff --git a/test/test/util/util.js b/test/test/util/util.js index 28e11910d..3ded25c6a 100644 --- a/test/test/util/util.js +++ b/test/test/util/util.js @@ -20,13 +20,14 @@ shaka.test.StatusPromise = class { this.status; // TODO: investigate using expectAsync() for this when possible. - p.status = 'pending'; - p.then(() => { - p.status = 'resolved'; + const p2 = /** @type {!shaka.test.StatusPromise} */(p); + p2.status = 'pending'; + p2.then(() => { + p2.status = 'resolved'; }, () => { - p.status = 'rejected'; + p2.status = 'rejected'; }); - return /** @type {!shaka.test.StatusPromise} */(p); + return p2; } }; @@ -104,7 +105,7 @@ shaka.test.Util = class { /** * @param {!shaka.util.Error} error - * @return {!Object} + * @return {jasmine.ObjectContainingType} */ static jasmineError(error) { // NOTE: Safari will add extra properties to any thrown object, and some of @@ -213,8 +214,10 @@ shaka.test.Util = class { const isInit = first instanceof shaka.media.InitSegmentReference && second instanceof shaka.media.InitSegmentReference; if (isSegment || isInit) { - const a = first.getUris(); - const b = second.getUris(); + const firstRef = /** @type {shaka.media.AnySegmentReference} */(first); + const secondRef = /** @type {shaka.media.AnySegmentReference} */(second); + const a = firstRef.getUris(); + const b = secondRef.getUris(); if (typeof a !== 'object' || typeof b !== 'object' || typeof a.length != 'number' || typeof b.length !== 'number') { return false; @@ -225,10 +228,10 @@ shaka.test.Util = class { } // Make shallow copies of each, without their getUris fields. - const trimmedFirst = Object.assign({}, /** @type {Object} */(first)); - delete trimmedFirst.getUris; - const trimmedSecond = Object.assign({}, /** @type {Object} */(second)); - delete trimmedSecond.getUris; + const trimmedFirst = Object.assign({}, /** @type {Object} */(firstRef)); + delete trimmedFirst['getUris']; + const trimmedSecond = Object.assign({}, /** @type {Object} */(secondRef)); + delete trimmedSecond['getUris']; // Compare those using Jasmine's utility, which will compare the fields of // an object and the items of an array. diff --git a/test/ui/ad_ui_unit.js b/test/ui/ad_ui_unit.js index 634746a3e..67cc36f70 100644 --- a/test/ui/ad_ui_unit.js +++ b/test/ui/ad_ui_unit.js @@ -5,7 +5,7 @@ describe('Ad UI', () => { const UiUtils = shaka.test.UiUtils; - /** @type {!Element} */ + /** @type {!HTMLLinkElement} */ let cssLink; /** @type {!HTMLElement} */ let container; @@ -19,7 +19,7 @@ describe('Ad UI', () => { beforeAll(async () => { // Add css file - cssLink = document.createElement('link'); + cssLink = /** @type {!HTMLLinkElement} */(document.createElement('link')); await UiUtils.setupCSS(cssLink); shaka.Player.setAdManagerFactory(() => new shaka.test.FakeAdManager()); }); diff --git a/test/ui/text_displayer_unit.js b/test/ui/text_displayer_unit.js index 9e61b94fe..6468ff2dc 100644 --- a/test/ui/text_displayer_unit.js +++ b/test/ui/text_displayer_unit.js @@ -23,7 +23,7 @@ describe('UITextDisplayer', () => { * font-size: '10px', * } * @param {string} cssStr - * @return {Object.} + * @return {!Object.} */ function parseCssText(cssStr) { // Remove the white spaces in the string. diff --git a/test/ui/ui_customization_unit.js b/test/ui/ui_customization_unit.js index d80c06bce..e373d294b 100644 --- a/test/ui/ui_customization_unit.js +++ b/test/ui/ui_customization_unit.js @@ -5,7 +5,7 @@ describe('UI Customization', () => { const UiUtils = shaka.test.UiUtils; - /** @type {!Element} */ + /** @type {!HTMLLinkElement} */ let cssLink; /** @type {!HTMLElement} */ let container; @@ -14,7 +14,7 @@ describe('UI Customization', () => { beforeAll(async () => { // Add css file - cssLink = document.createElement('link'); + cssLink = /** @type {!HTMLLinkElement} */(document.createElement('link')); await UiUtils.setupCSS(cssLink); }); diff --git a/test/ui/ui_integration.js b/test/ui/ui_integration.js index 96387f5bc..dd1d6dd64 100644 --- a/test/ui/ui_integration.js +++ b/test/ui/ui_integration.js @@ -20,7 +20,7 @@ describe('UI', () => { let eventManager; /** @type {shaka.test.Waiter} */ let waiter; - /** @type {!Element} */ + /** @type {!HTMLLinkElement} */ let cssLink; /** @type {!shaka.ui.Controls} */ let controls; @@ -28,7 +28,7 @@ describe('UI', () => { let compiledShaka; beforeAll(async () => { - cssLink = document.createElement('link'); + cssLink = /** @type {!HTMLLinkElement} */(document.createElement('link')); await UiUtils.setupCSS(cssLink); compiledShaka = await Util.loadShaka(getClientArg('uncompiled')); @@ -72,7 +72,9 @@ describe('UI', () => { eventManager = new shaka.util.EventManager(); waiter = new shaka.test.Waiter(eventManager); - controls = ui.getControls(); + const tempControls = ui.getControls(); + goog.asserts.assert(tempControls != null, 'Controls are null!'); + controls = tempControls; onErrorSpy = jasmine.createSpy('onError'); onErrorSpy.and.callFake((event) => { diff --git a/test/ui/ui_unit.js b/test/ui/ui_unit.js index c8ce300e6..a513ee19b 100644 --- a/test/ui/ui_unit.js +++ b/test/ui/ui_unit.js @@ -11,12 +11,12 @@ describe('UI', () => { /** @type {shaka.Player} */ let player; - /** @type {!Element} */ + /** @type {!HTMLLinkElement} */ let cssLink; beforeAll(async () => { // Add css file - cssLink = document.createElement('link'); + cssLink = /** @type {!HTMLLinkElement} */(document.createElement('link')); await UiUtils.setupCSS(cssLink); });