1
0
mirror of https://github.com/videojs/video.js.git synced 2025-07-17 01:42:41 +02:00

test: memory leak fixes in tests (#5861)

This commit is contained in:
Brandon Casey
2019-03-18 15:49:48 -04:00
committed by Gary Katsevman
parent f01d6f4e23
commit 23a36f338b
27 changed files with 226 additions and 58 deletions

View File

@ -37,6 +37,8 @@ QUnit.test('should allow setting the controlText_ property as an option', functi
assert.expect(1);
assert.strictEqual(btn.controlText_, text, 'set the controlText_ property');
btn.dispose();
});
QUnit.test('should trigger an event on activation', function(assert) {

View File

@ -259,7 +259,8 @@ QUnit.test('should do a deep merge of child options', function(assert) {
});
QUnit.test('should init child components from component options', function(assert) {
const testComp = new TestComponent1(TestHelpers.makePlayer(), {
const player = TestHelpers.makePlayer();
const testComp = new TestComponent1(player, {
testComponent2: false,
testComponent4: {}
});
@ -267,6 +268,7 @@ QUnit.test('should init child components from component options', function(asser
assert.ok(!testComp.childNameIndex_.TestComponent2, 'we do not have testComponent2');
assert.ok(testComp.childNameIndex_.TestComponent4, 'we have a testComponent4');
player.dispose();
testComp.dispose();
});
@ -344,6 +346,7 @@ QUnit.test('should dispose of component and children', function(assert) {
});
comp.dispose();
child.dispose();
assert.ok(hasDisposed, 'component fired dispose event');
assert.ok(bubbles === false, 'dispose event does not bubble');
@ -764,6 +767,7 @@ QUnit.test('should use a defined content el for appending children', function(as
'Child el should be removed.'
);
child.dispose();
comp.dispose();
});
@ -1059,4 +1063,8 @@ QUnit.test('should remove child when the child moves to the other parent', funct
assert.strictEqual(parentComponent2.children()[0], childComponent, 'the first child of `parentComponent2` is `childComponent`');
assert.strictEqual(parentComponent2.el().childNodes.length, 1, 'the length of `childNodes` of `parentComponent2` is 1');
assert.strictEqual(parentComponent2.el().childNodes[0], childComponent.el(), '`parentComponent2` contains the DOM element of `childComponent`');
parentComponent1.dispose();
parentComponent2.dispose();
childComponent.dispose();
});

View File

@ -35,6 +35,8 @@ QUnit.test('should hide volume and mute toggle control if it\'s not supported',
assert.ok(muteToggle.hasClass('vjs-hidden'), 'muteToggle is not hidden');
player.dispose();
volumeControl.dispose();
muteToggle.dispose();
});
QUnit.test('should show replay icon when video playback ended', function(assert) {
@ -49,6 +51,7 @@ QUnit.test('should show replay icon when video playback ended', function(assert)
assert.ok(playToggle.hasClass('vjs-ended'), 'playToogle is in the ended state');
player.dispose();
playToggle.dispose();
});
QUnit.test('should show replay icon when video playback ended and replay option is set to true', function(assert) {
@ -63,6 +66,7 @@ QUnit.test('should show replay icon when video playback ended and replay option
assert.ok(playToggle.hasClass('vjs-ended'), 'playToogle is in the ended state');
player.dispose();
playToggle.dispose();
});
QUnit.test('should not show the replay icon when video playback ended', function(assert) {
@ -77,6 +81,7 @@ QUnit.test('should not show the replay icon when video playback ended', function
assert.equal(playToggle.hasClass('vjs-ended'), false, 'playToogle is not in the ended state');
player.dispose();
playToggle.dispose();
});
QUnit.test('should test and toggle volume control on `loadstart`', function(assert) {
@ -106,6 +111,8 @@ QUnit.test('should test and toggle volume control on `loadstart`', function(asse
assert.equal(muteToggle.hasClass('vjs-hidden'), false, 'muteToggle does not show itself');
player.dispose();
volumeControl.dispose();
muteToggle.dispose();
});
QUnit.test('calculateDistance should use changedTouches, if available', function(assert) {
@ -130,6 +137,7 @@ QUnit.test('calculateDistance should use changedTouches, if available', function
assert.equal(slider.calculateDistance(event), 0.5, 'we should have touched exactly in the center, so, the ratio should be half');
player.dispose();
slider.dispose();
});
QUnit.test('should hide playback rate control if it\'s not supported', function(assert) {
@ -141,6 +149,7 @@ QUnit.test('should hide playback rate control if it\'s not supported', function(
assert.ok(playbackRate.el().className.indexOf('vjs-hidden') >= 0, 'playbackRate is not hidden');
player.dispose();
playbackRate.dispose();
});
QUnit.test('Fullscreen control text should be correct when fullscreenchange is triggered', function(assert) {
@ -156,6 +165,7 @@ QUnit.test('Fullscreen control text should be correct when fullscreenchange is t
assert.equal(fullscreentoggle.controlText(), 'Fullscreen', 'Control Text is correct while switching back to normal mode');
player.dispose();
fullscreentoggle.dispose();
});
QUnit.test('Clicking MuteToggle when volume is above 0 should toggle muted property and not change volume', function(assert) {
@ -171,6 +181,7 @@ QUnit.test('Clicking MuteToggle when volume is above 0 should toggle muted prope
assert.equal(player.muted(), true, 'player is muted');
player.dispose();
muteToggle.dispose();
});
QUnit.test('Clicking MuteToggle when volume is 0 and muted is false should set volume to lastVolume and keep muted false', function(assert) {
@ -187,6 +198,7 @@ QUnit.test('Clicking MuteToggle when volume is 0 and muted is false should set v
assert.equal(player.muted(), false, 'muted remains false');
player.dispose();
muteToggle.dispose();
});
QUnit.test('Clicking MuteToggle when volume is 0 and muted is true should set volume to lastVolume and sets muted to false', function(assert) {
@ -203,6 +215,7 @@ QUnit.test('Clicking MuteToggle when volume is 0 and muted is true should set vo
assert.equal(player.muted(), false, 'muted is set to false');
player.dispose();
muteToggle.dispose();
});
QUnit.test('Clicking MuteToggle when volume is 0, lastVolume is less than 0.1, and muted is true sets volume to 0.1 and muted to false', function(assert) {
@ -220,6 +233,7 @@ QUnit.test('Clicking MuteToggle when volume is 0, lastVolume is less than 0.1, a
assert.equal(player.muted(), false, 'muted is set to false');
player.dispose();
muteToggle.dispose();
});
QUnit.test('ARIA value of VolumeBar should start at 100', function(assert) {
@ -231,6 +245,7 @@ QUnit.test('ARIA value of VolumeBar should start at 100', function(assert) {
assert.equal(volumeBar.el_.getAttribute('aria-valuenow'), 100, 'ARIA value of VolumeBar is 100');
player.dispose();
volumeBar.dispose();
});
QUnit.test('Muting with MuteToggle should set ARIA value of VolumeBar to 0', function(assert) {
@ -256,6 +271,8 @@ QUnit.test('Muting with MuteToggle should set ARIA value of VolumeBar to 0', fun
assert.equal(volumeBar.el_.getAttribute('aria-valuenow'), 0, 'ARIA value of VolumeBar is 0');
player.dispose();
muteToggle.dispose();
volumeBar.dispose();
});
QUnit.test('controlbar children to false individually, does not cause an assertion', function(assert) {

View File

@ -27,6 +27,7 @@ test('EventTarget queueTrigger queues the event', function(t) {
this.clock.tick(1);
t.equal(changes, 1, 'EventTarget triggered a change event once the clock ticked');
et.off('change', changeHandler);
});
test('EventTarget will only trigger event once with queueTrigger', function(t) {
@ -48,4 +49,6 @@ test('EventTarget will only trigger event once with queueTrigger', function(t) {
this.clock.tick(100);
t.equal(changes, 1, 'EventTarget *only* triggered a change event once');
et.off('change', changeHandler);
});

View File

@ -48,6 +48,8 @@ QUnit.test('should add and remove multiple event listeners to an element with a
Events.off(el, 'event2', listener);
// No event2 should happen.
Events.trigger(el, 'event2');
Events.off(el, ['click', 'event1', 'event2'], listener);
});
QUnit.test('should be possible to pass data when you trigger an event', function(assert) {
@ -66,6 +68,7 @@ QUnit.test('should be possible to pass data when you trigger an event', function
Events.trigger(el, 'event1', { d1: fakeData1, d2: fakeData2});
Events.trigger(el, 'event2', { d1: fakeData1, d2: fakeData2});
Events.off(el, ['event1', 'event2'], listener);
});
QUnit.test('should remove all listeners of a type', function(assert) {
@ -142,6 +145,9 @@ QUnit.test('should remove all listeners from an element', function(assert) {
// No listener should happen.
Events.trigger(el, 'fake1');
Events.trigger(el, 'fake2');
Events.off(el, 'fake1', listener);
Events.off(el, 'fake2', listener2);
});
QUnit.test('should listen only once', function(assert) {
@ -197,6 +203,7 @@ QUnit.test('should stop immediate propagtion', function(assert) {
});
Events.trigger(el, 'test');
Events.off(el, 'test');
});
QUnit.test('should bubble up DOM unless bubbles == false', function(assert) {
@ -222,6 +229,11 @@ QUnit.test('should bubble up DOM unless bubbles == false', function(assert) {
assert.ok(false, 'Outer listener fired');
});
Events.trigger(inner, { type: 'nobub', target: inner, bubbles: false });
Events.off(inner, 'bubbles');
Events.off(outer, 'bubbles');
Events.off(inner, 'nobub');
Events.off(outer, 'nobub');
});
QUnit.test('should have a defaultPrevented property on an event that was prevent from doing default action', function(assert) {
@ -239,6 +251,7 @@ QUnit.test('should have a defaultPrevented property on an event that was prevent
});
Events.trigger(el, 'test');
Events.off(el, 'test');
});
QUnit.test('should have relatedTarget correctly set on the event', function(assert) {
@ -259,6 +272,9 @@ QUnit.test('should have relatedTarget correctly set on the event', function(asse
});
Events.trigger(el2, { type: 'click', relatedTarget: undefined });
Events.off(el1, 'click');
Events.off(el2, 'click');
});
QUnit.test('should execute remaining handlers after an exception in an event handler', function(assert) {
@ -283,6 +299,8 @@ QUnit.test('should execute remaining handlers after an exception in an event han
Events.trigger(el, 'click');
log.error = oldLogError;
Events.off(el, 'click');
});
QUnit.test('trigger with an object should set the correct target property', function(assert) {
@ -292,6 +310,8 @@ QUnit.test('trigger with an object should set the correct target property', func
assert.equal(e.target, el, 'the event object target should be our element');
});
Events.trigger(el, { type: 'click'});
Events.off(el, 'click');
});
QUnit.test('retrigger with a string should use the new element as target', function(assert) {
@ -306,6 +326,9 @@ QUnit.test('retrigger with a string should use the new element as target', funct
});
Events.trigger(el1, 'click');
Events.trigger(el1, {type: 'click'});
Events.off(el1, 'click');
Events.off(el2, 'click');
});
QUnit.test('retrigger with an object should use the old element as target', function(assert) {
@ -320,4 +343,7 @@ QUnit.test('retrigger with an object should use the old element as target', func
});
Events.trigger(el1, 'click');
Events.trigger(el1, {type: 'click'});
Events.off(el1, 'click');
Events.off(el2, 'click');
});

View File

@ -24,6 +24,7 @@ QUnit.test('should not throw an error when there is no children', function(asser
}
player.dispose();
menuButton.dispose();
});
QUnit.test('should place title list item into ul', function(assert) {
@ -109,6 +110,11 @@ QUnit.test('should keep all the added menu items', function(assert) {
assert.strictEqual(menuButton.children()[1].children()[1], menuItem2, 'the second child of the menu is `menuItem2` after second update');
assert.ok(menuButton.el().contains(menuItem1.el()), 'the menu button contains the DOM element of `menuItem1` after second update');
assert.ok(menuButton.el().contains(menuItem2.el()), 'the menu button contains the DOM element of `menuItem2` after second update');
menuButton.dispose();
menuItem1.dispose();
menuItem2.dispose();
player.dispose();
});
QUnit.test('should remove old event listeners when the menu item adds to the new menu', function(assert) {
@ -190,8 +196,14 @@ QUnit.test('should remove old event listeners when the menu item adds to the new
});
newMenu.addItem(captionMenuItem);
TestHelpers.triggerDomEvent(captionMenuItem.el(), 'click');
assert.ok(!focusSpy.called, '`menuButton`.`focus` should never be called');
focusSpy.restore();
player.dispose();
newMenu.dispose();
oldMenu.dispose();
menuButton.dispose();
});

View File

@ -31,7 +31,7 @@ QUnit.module('mixins: evented', {
},
afterEach() {
Object.keys(this.targets).forEach(k => this.targets[k].trigger('dispose'));
Object.keys(this.targets).forEach((k) => this.targets[k].trigger('dispose'));
}
});
@ -62,28 +62,32 @@ QUnit.test('evented() with custom element', function(assert) {
});
QUnit.test('on() and one() errors', function(assert) {
const target = this.targets.a = evented({});
const targeta = this.targets.a = evented({});
const targetb = this.targets.b = evented({});
['on', 'one'].forEach(method => {
assert.throws(() => target[method](), errors.type, 'the expected error is thrown');
assert.throws(() => target[method](' '), errors.type, 'the expected error is thrown');
assert.throws(() => target[method]([]), errors.type, 'the expected error is thrown');
assert.throws(() => target[method]('x'), errors.listener, 'the expected error is thrown');
assert.throws(() => target[method]({}, 'x', () => {}), errors.target, 'the expected error is thrown');
assert.throws(() => target[method](evented({}), 'x', null), errors.listener, 'the expected error is thrown');
assert.throws(() => targeta[method](), errors.type, 'the expected error is thrown');
assert.throws(() => targeta[method](' '), errors.type, 'the expected error is thrown');
assert.throws(() => targeta[method]([]), errors.type, 'the expected error is thrown');
assert.throws(() => targeta[method]('x'), errors.listener, 'the expected error is thrown');
assert.throws(() => targeta[method]({}, 'x', () => {}), errors.target, 'the expected error is thrown');
assert.throws(() => targeta[method](targetb, 'x', null), errors.listener, 'the expected error is thrown');
});
});
QUnit.test('off() errors', function(assert) {
const target = this.targets.a = evented({});
const targeta = this.targets.a = evented({});
const targetb = this.targets.b = evented({});
const targetc = this.targets.c = evented({});
const targetd = this.targets.d = evented({});
// An invalid event actually causes an invalid target error because it
// gets passed into code that assumes the first argument is the target.
assert.throws(() => target.off([]), errors.target, 'the expected error is thrown');
assert.throws(() => target.off({}, 'x', () => {}), errors.target, 'the expected error is thrown');
assert.throws(() => target.off(evented({}), '', () => {}), errors.type, 'the expected error is thrown');
assert.throws(() => target.off(evented({}), [], () => {}), errors.type, 'the expected error is thrown');
assert.throws(() => target.off(evented({}), 'x', null), errors.listener, 'the expected error is thrown');
assert.throws(() => targeta.off([]), errors.target, 'the expected error is thrown');
assert.throws(() => targeta.off({}, 'x', () => {}), errors.target, 'the expected error is thrown');
assert.throws(() => targeta.off(targetb, '', () => {}), errors.type, 'the expected error is thrown');
assert.throws(() => targeta.off(targetc, [], () => {}), errors.type, 'the expected error is thrown');
assert.throws(() => targeta.off(targetd, 'x', null), errors.listener, 'the expected error is thrown');
});
QUnit.test('on() can add a listener to one event type on this object', function(assert) {

View File

@ -56,6 +56,8 @@ QUnit.test('setState() works as expected', function(assert) {
assert.strictEqual(event.type, 'statechanged', 'the event had the expected type');
assert.strictEqual(event.changes, changes, 'the changes object is sent along with the event');
target.trigger('dispose');
});
QUnit.test('setState() without changes does not trigger the "statechanged" event', function(assert) {
@ -68,6 +70,7 @@ QUnit.test('setState() without changes does not trigger the "statechanged" event
assert.strictEqual(changes, undefined, 'no changes were returned');
assert.strictEqual(spy.callCount, 0, 'no event was triggered');
target.trigger('dispose');
});
QUnit.test('handleStateChanged() is automatically bound to "statechanged" event', function(assert) {
@ -84,4 +87,5 @@ QUnit.test('handleStateChanged() is automatically bound to "statechanged" event'
assert.strictEqual(event.type, 'statechanged', 'the event had the expected type');
assert.strictEqual(event.changes, changes, 'the handleStateChanged() method was called');
target.trigger('dispose');
});

View File

@ -452,6 +452,7 @@ QUnit.test('"content" option (fills on first open() invocation)', function(asser
assert.strictEqual(modal.content(), modal.options_.content, 'has the expected content');
assert.strictEqual(spy.callCount, 1, 'auto-fills only once');
assert.strictEqual(modal.contentEl().firstChild, modal.options_.content, 'has the expected content in the DOM');
modal.dispose();
});
QUnit.test('"temporary" option', function(assert) {
@ -470,6 +471,9 @@ QUnit.test('"temporary" option', function(assert) {
assert.expect(2);
assert.strictEqual(tempSpy.callCount, 1, 'temporary modals are disposed');
assert.strictEqual(permSpy.callCount, 0, 'permanent modals are not disposed');
temp.dispose();
perm.dispose();
});
QUnit.test('"fillAlways" option', function(assert) {
@ -488,6 +492,7 @@ QUnit.test('"fillAlways" option', function(assert) {
assert.expect(1);
assert.strictEqual(spy.callCount, 2, 'the modal was filled on each open call');
modal.dispose();
});
QUnit.test('"label" option', function(assert) {
@ -496,6 +501,7 @@ QUnit.test('"label" option', function(assert) {
assert.expect(1);
assert.strictEqual(modal.el().getAttribute('aria-label'), label, 'uses the label as the aria-label');
modal.dispose();
});
QUnit.test('"uncloseable" option', function(assert) {
@ -515,6 +521,7 @@ QUnit.test('"uncloseable" option', function(assert) {
modal.open();
modal.handleKeyPress({which: ESC});
assert.strictEqual(spy.callCount, 0, 'ESC did not close the modal');
modal.dispose();
});
QUnit.test('handleKeyDown traps tab focus', function(assert) {

View File

@ -62,6 +62,7 @@ QUnit.test('setting breakpoints/responsive via option', function(assert) {
// Player should be 300x150 by default.
assert.strictEqual(player.currentBreakpoint(), 'tiny', 'current breakpoint set');
assert.strictEqual(player.currentBreakpointClass(), 'vjs-layout-tiny', 'current breakpoint set');
player.dispose();
});
QUnit.test('changing the player size triggers breakpoints', function(assert) {

View File

@ -444,13 +444,13 @@ if (Html5.supportsNativeTextTracks()) {
el.textTracks = tt;
/* eslint-disable no-unused-vars */
const htmlTech = new Html5({el});
/* eslint-enable no-unused-vars */
assert.equal(adds[0][0], 'change', 'change event handler added');
assert.equal(adds[1][0], 'addtrack', 'addtrack event handler added');
assert.equal(adds[2][0], 'removetrack', 'removetrack event handler added');
htmlTech.dispose();
});
QUnit.test('does not add native textTrack listeners when disabled', function(assert) {
@ -466,17 +466,16 @@ if (Html5.supportsNativeTextTracks()) {
get: () => tt
});
/* eslint-disable no-unused-vars */
const htmlTech = new Html5({el, nativeTextTracks: false});
/* eslint-enable no-unused-vars */
assert.equal(events.length, 0, 'no listeners added');
/* eslint-disable no-unused-vars */
const htmlTechAlternate = new Html5({el, nativeCaptions: false});
/* eslint-enable no-unused-vars */
assert.equal(events.length, 0, 'no listeners added');
htmlTech.dispose();
htmlTechAlternate.dispose();
});
QUnit.test('remove all tracks from emulated list on dispose', function(assert) {
@ -520,13 +519,13 @@ if (Html5.supportsNativeAudioTracks()) {
el.audioTracks = at;
/* eslint-disable no-unused-vars */
const htmlTech = new Html5({el});
/* eslint-enable no-unused-vars */
assert.equal(adds[0][0], 'change', 'change event handler added');
assert.equal(adds[1][0], 'addtrack', 'addtrack event handler added');
assert.equal(adds[2][0], 'removetrack', 'removetrack event handler added');
htmlTech.dispose();
});
QUnit.test('does not add native audioTrack listeners when disabled', function(assert) {
@ -540,11 +539,11 @@ if (Html5.supportsNativeAudioTracks()) {
el.audioTracks = at;
/* eslint-disable no-unused-vars */
const htmlTech = new Html5({el, nativeAudioTracks: false});
/* eslint-enable no-unused-vars */
assert.equal(events.length, 0, 'no listeners added');
htmlTech.dispose();
});
QUnit.test('remove all tracks from emulated list on dispose', function(assert) {
@ -654,13 +653,13 @@ if (Html5.supportsNativeVideoTracks()) {
el.videoTracks = vt;
/* eslint-disable no-unused-vars */
const htmlTech = new Html5({el});
/* eslint-enable no-unused-vars */
assert.equal(adds[0][0], 'change', 'change event handler added');
assert.equal(adds[1][0], 'addtrack', 'addtrack event handler added');
assert.equal(adds[2][0], 'removetrack', 'removetrack event handler added');
htmlTech.dispose();
});
QUnit.test('does not add native audioTrack listeners when disabled', function(assert) {
@ -674,11 +673,11 @@ if (Html5.supportsNativeVideoTracks()) {
el.videoTracks = vt;
/* eslint-disable no-unused-vars */
const htmlTech = new Html5({el, nativeVideoTracks: false});
/* eslint-enable no-unused-vars */
assert.equal(events.length, 0, 'no listeners added');
htmlTech.dispose();
});
QUnit.test('remove all tracks from emulated list on dispose', function(assert) {

View File

@ -70,6 +70,8 @@ QUnit.test('should synthesize timeupdate events by default', function(assert) {
this.clock.tick(250);
assert.equal(timeupdates, 1, 'triggered at least one timeupdate');
tech.dispose();
});
QUnit.test('stops manual timeupdates while paused', function(assert) {
@ -92,6 +94,7 @@ QUnit.test('stops manual timeupdates while paused', function(assert) {
tech.trigger('play');
this.clock.tick(10 * 250);
assert.ok(timeupdates > 0, 'timeupdates fire when playback resumes');
tech.dispose();
});
QUnit.test('should synthesize progress events by default', function(assert) {
@ -117,6 +120,7 @@ QUnit.test('should synthesize progress events by default', function(assert) {
bufferedPercent = 0.75;
this.clock.tick(500);
assert.equal(progresses, 2, 'repeated readies are ok');
tech.dispose();
});
QUnit.test('dispose() should stop time tracking', function(assert) {
@ -300,6 +304,7 @@ QUnit.test('switching sources should clear all remote tracks that are added with
);
log.warn = oldLogWarn;
tech.dispose();
});
QUnit.test('should add the source handler interface to a tech', function(assert) {
@ -525,6 +530,7 @@ QUnit.test('should handle unsupported sources with the source handler API', func
usedNative,
'native source handler was used when an unsupported source was set'
);
tech.dispose();
});
QUnit.test('should allow custom error events to be set', function(assert) {
@ -544,6 +550,7 @@ QUnit.test('should allow custom error events to be set', function(assert) {
tech.error(2);
assert.equal(errors.length, 2, 'triggered an error event');
assert.equal(errors[1].code, 2, 'wrapped the error code');
tech.dispose();
});
QUnit.test('should track whether a video has played', function(assert) {
@ -552,6 +559,7 @@ QUnit.test('should track whether a video has played', function(assert) {
assert.equal(tech.played().length, 0, 'starts with zero length');
tech.trigger('playing');
assert.equal(tech.played().length, 1, 'has length after playing');
tech.dispose();
});
QUnit.test('delegates deferrables to the source handler', function(assert) {
@ -601,6 +609,7 @@ QUnit.test('delegates deferrables to the source handler', function(assert) {
assert.equal(seekableCount, 1, 'called the source handler');
assert.equal(seekingCount, 1, 'called the source handler');
assert.equal(durationCount, 1, 'called the source handler');
tech.dispose();
});
QUnit.test('delegates only deferred deferrables to the source handler', function(assert) {
@ -647,19 +656,25 @@ QUnit.test('delegates only deferred deferrables to the source handler', function
assert.equal(seekableCount, 1, 'called the source handler');
assert.equal(seekingCount, 1, 'called the tech itself');
assert.equal(durationCount, 1, 'called the source handler');
tech.dispose();
});
QUnit.test('Tech.isTech returns correct answers for techs and components', function(assert) {
const isTech = Tech.isTech;
const tech = new Html5({}, {});
const button = new Button({}, {});
assert.ok(isTech(Tech), 'Tech is a Tech');
assert.ok(isTech(Html5), 'Html5 is a Tech');
assert.ok(isTech(new Html5({}, {})), 'An html5 instance is a Tech');
assert.ok(isTech(tech), 'An html5 instance is a Tech');
assert.ok(!isTech(5), 'A number is not a Tech');
assert.ok(!isTech('this is a tech'), 'A string is not a Tech');
assert.ok(!isTech(Button), 'A Button is not a Tech');
assert.ok(!isTech(new Button({}, {})), 'A Button instance is not a Tech');
assert.ok(!isTech(button), 'A Button instance is not a Tech');
assert.ok(!isTech(isTech), 'A function is not a Tech');
tech.dispose();
button.dispose();
});
QUnit.test('setSource after tech dispose should dispose source handler once', function(assert) {
@ -703,6 +718,7 @@ QUnit.test('setSource after tech dispose should dispose source handler once', fu
tech.setSource('test');
assert.equal(disposeCount, 2, 'did dispose on second setSource');
tech.dispose();
});
@ -740,6 +756,7 @@ QUnit.test('setSource after previous setSource should dispose source handler onc
tech.setSource('test');
assert.equal(disposeCount, 2, 'did dispose for third setSource');
tech.dispose();
});
@ -747,4 +764,5 @@ QUnit.test('returns an empty object for getVideoPlaybackQuality', function(asser
const tech = new Tech();
assert.deepEqual(tech.getVideoPlaybackQuality(), {}, 'returns an empty object');
tech.dispose();
});

View File

@ -24,6 +24,9 @@ QUnit.test('trigger "change" when "enabledchange" is fired on a track', function
track.trigger('enabledchange');
assert.equal(changes, 2, 'one change events for another trigger');
audioTrackList.removeTrack(track);
audioTrackList.off('change');
});
QUnit.test('only one track is ever enabled', function(assert) {
@ -56,17 +59,19 @@ QUnit.test('only one track is ever enabled', function(assert) {
assert.equal(track3.enabled, false, 'track3 is disabled');
assert.equal(track4.enabled, false, 'track4 is disabled');
list.removeTrack(track);
list.removeTrack(track2);
list.removeTrack(track3);
list.removeTrack(track4);
});
QUnit.test('all tracks can be disabled', function(assert) {
const track = new AudioTrack();
const track2 = new AudioTrack();
/* eslint-disable no-unused-vars */
// we need audiotracklist here to verify that it does not
// re-enable a track
const list = new AudioTrackList([track, track2]);
/* eslint-enable no-unused-vars */
assert.equal(track.enabled, false, 'track is disabled');
assert.equal(track2.enabled, false, 'track2 is disabled');
@ -78,6 +83,9 @@ QUnit.test('all tracks can be disabled', function(assert) {
track.enabled = false;
assert.equal(track.enabled, false, 'track is disabled');
assert.equal(track2.enabled, false, 'track2 is disabled');
list.removeTrack(track);
list.removeTrack(track2);
});
QUnit.test('trigger a change event per enabled change', function(assert) {
@ -104,4 +112,9 @@ QUnit.test('trigger a change event per enabled change', function(assert) {
list.addTrack(track4);
assert.equal(change, 4, 'no change triggered by adding a disabled track');
list.removeTrack(track);
list.removeTrack(track2);
list.removeTrack(track3);
list.removeTrack(track4);
list.off();
});

View File

@ -119,4 +119,6 @@ QUnit.test('when enabled is changed enabledchange event is fired', function(asse
track.enabled = true;
track.enabled = true;
assert.equal(eventsTriggered, 3, 'still three enabled changes');
track.off();
});

View File

@ -64,9 +64,7 @@ QUnit.test('listen to remove and add track events in native audio tracks', funct
player.player_ = player;
player.options_ = {};
/* eslint-disable no-unused-vars */
const html = new Html5({});
/* eslint-enable no-unused-vars */
assert.ok(events.removetrack, 'removetrack listener was added');
assert.ok(events.addtrack, 'addtrack listener was added');

View File

@ -39,6 +39,8 @@ QUnit.test('can create a html track element with various properties', function(a
assert.equal(htmlTrackElement.label, label, 'we have a label');
assert.equal(htmlTrackElement.readyState, 0, 'we have a readyState');
assert.equal(htmlTrackElement.srclang, language, 'we have a srclang');
htmlTrackElement.track.off();
});
QUnit.test('defaults when items not provided', function(assert) {
@ -53,6 +55,8 @@ QUnit.test('defaults when items not provided', function(assert) {
assert.equal(typeof htmlTrackElement.src, 'undefined', 'we have a src');
assert.equal(htmlTrackElement.srclang, '', 'we have a srclang');
assert.equal(htmlTrackElement.track.cues.length, 0, 'we have a track');
htmlTrackElement.track.off();
});
QUnit.test('fires loadeddata when track cues become populated', function(assert) {
@ -71,4 +75,7 @@ QUnit.test('fires loadeddata when track cues become populated', function(assert)
assert.equal(changes, 1, 'a loadeddata event trigger addEventListener');
assert.equal(htmlTrackElement.readyState, 2, 'readyState is loaded');
htmlTrackElement.track.off();
htmlTrackElement.off('load');
});

View File

@ -364,6 +364,8 @@ QUnit.test('menu items should polyfill mode change events', function(assert) {
assert.equal(changes, 2, 'clicks trigger change events');
player.dispose();
trackMenuItem.dispose();
player.textTracks().off('change');
});
const chaptersTrack = {

View File

@ -124,6 +124,7 @@ if (!Html5.supportsNativeTextTracks()) {
assert.strictEqual(spy.callCount, 1, 'selectedlanguagechange event was fired');
player.dispose();
player.textTracks().removeEventListener('selectedlanguagechange', selectedLanguageHandler);
});
QUnit.test("if user-selected language is unavailable, don't pick a track to show", function(assert) {

View File

@ -87,6 +87,9 @@ if (Html5.supportsNativeTextTracks()) {
language: 'en',
mode: 'disabled'
}], 'the output is correct');
tt.removeTrack(nativeTrack.track);
tt.removeTrack(emulatedTrack);
});
QUnit.test('jsonToTextTracks calls addRemoteTextTrack on the tech with mixed tracks', function(assert) {
@ -210,6 +213,9 @@ QUnit.test('textTracksToJson produces good json output for emulated only', funct
language: 'en',
mode: 'disabled'
}], 'the output is correct');
tt.removeTrack(anotherTrack);
tt.removeTrack(emulatedTrack);
});
QUnit.test('jsonToTextTracks calls addRemoteTextTrack on the tech with emulated tracks only', function(assert) {
@ -261,4 +267,7 @@ QUnit.test('jsonToTextTracks calls addRemoteTextTrack on the tech with emulated
c.jsonToTextTracks(cleanup(c.textTracksToJson(tech)), tech);
assert.equal(addRemotes, 2, 'we added two text tracks');
tt.removeTrack(anotherTrack);
tt.removeTrack(emulatedTrack);
});

View File

@ -32,10 +32,13 @@ QUnit.test('trigger "change" event when "modechange" is fired on a track', funct
tt.trigger('modechange');
this.clock.tick(1);
assert.equal(changes, 2, 'two change events should have fired');
ttl.removeTrack(tt);
});
QUnit.test('trigger "change" event when mode changes on a TextTrack', function(assert) {
const tt = new TextTrack({tech: new TechFaker()});
const tech = new TechFaker();
const tt = new TextTrack({tech});
const ttl = new TextTrackList([tt]);
let changes = 0;
const changeHandler = function() {
@ -54,4 +57,6 @@ QUnit.test('trigger "change" event when mode changes on a TextTrack', function(a
this.clock.tick(1);
assert.equal(changes, 2, 'two change events should have fired');
ttl.removeTrack(tt);
tech.dispose();
});

View File

@ -24,8 +24,9 @@ TrackBaseline(TextTrack, {
kind: 'subtitles',
mode: 'disabled',
label: 'English',
language: 'en',
tech: new TechFaker()
language: 'en'
// tech is added in baseline
// tech: new TechFaker()
});
QUnit.test('requires a tech', function(assert) {
@ -280,6 +281,7 @@ QUnit.test('does not fire cuechange before Tech is ready', function(assert) {
assert.equal(changes, 2, 'a cuechange event trigger addEventListener and oncuechange');
tt.off();
player.dispose();
done();
});
@ -322,6 +324,7 @@ QUnit.test('fires cuechange when cues become active and inactive', function(asse
assert.equal(changes, 4, 'a cuechange event trigger addEventListener and oncuechange');
tt.off();
player.dispose();
});
@ -362,6 +365,7 @@ QUnit.test('enabled and disabled cuechange handler when changing mode to hidden'
assert.equal(changes, 0, 'NO cuechange event trigger');
tt.off();
player.dispose();
});
@ -402,6 +406,7 @@ QUnit.test('enabled and disabled cuechange handler when changing mode to showing
assert.equal(changes, 0, 'NO cuechange event trigger');
tt.off();
player.dispose();
});
@ -428,18 +433,17 @@ QUnit.test('tracks are parsed if vttjs is loaded', function(assert) {
};
};
/* eslint-disable no-unused-vars */
const tt = new TextTrack({
tech: this.tech,
src: 'http://example.com'
});
/* eslint-enable no-unused-vars */
reqs.pop().respond(200, null, 'WEBVTT\n');
assert.ok(parserCreated, 'WebVTT is loaded, so we can just parse');
clock.restore();
tt.off();
window.WebVTT = oldVTT;
});
@ -460,12 +464,10 @@ QUnit.test('tracks are parsed once vttjs is loaded', function(assert) {
testTech.textTracks = () => {};
testTech.currentTime = () => {};
/* eslint-disable no-unused-vars */
const tt = new TextTrack({
tech: testTech,
src: 'http://example.com'
});
/* eslint-enable no-unused-vars */
reqs.pop().respond(200, null, 'WEBVTT\n');
@ -491,6 +493,8 @@ QUnit.test('tracks are parsed once vttjs is loaded', function(assert) {
assert.ok(parserCreated, 'WebVTT is loaded, so we can parse now');
clock.restore();
tt.off();
testTech.off();
window.WebVTT = oldVTT;
});
@ -518,12 +522,10 @@ QUnit.test('stops processing if vttjs loading errored out', function(assert) {
sinon.stub(testTech, 'off');
testTech.off.withArgs('vttjsloaded');
/* eslint-disable no-unused-vars */
const tt = new TextTrack({
tech: testTech,
src: 'http://example.com'
});
/* eslint-enable no-unused-vars */
reqs.pop().respond(200, null, 'WEBVTT\n');
@ -544,5 +546,8 @@ QUnit.test('stops processing if vttjs loading errored out', function(assert) {
clock.restore();
window.WebVTT = oldVTT;
tt.off();
testTech.off.restore();
testTech.off();
log.error = oldLogError;
});

View File

@ -34,6 +34,7 @@ QUnit.test('should place title list item into ul', function(assert) {
assert.ok(titleElement.innerHTML === 'Chapters', 'title element placed in ul');
player.dispose();
chaptersButton.dispose();
});
QUnit.test('Player track methods call the tech', function(assert) {
@ -57,7 +58,6 @@ QUnit.test('Player track methods call the tech', function(assert) {
QUnit.test('TextTrackDisplay initializes tracks on player ready', function(assert) {
let calls = 0;
/* eslint-disable no-unused-vars */
const ttd = new TextTrackDisplay({
on() {},
addTextTracks() {
@ -70,9 +70,10 @@ QUnit.test('TextTrackDisplay initializes tracks on player ready', function(asser
calls++;
}
}, {});
/* eslint-enable no-unused-vars */
assert.equal(calls, 1, 'only a player.ready call was made');
ttd.dispose();
});
QUnit.test('listen to remove and add track events in native text tracks', function(assert) {
@ -113,9 +114,7 @@ QUnit.test('listen to remove and add track events in native text tracks', functi
player.player_ = player;
player.options_ = {};
/* eslint-disable no-unused-vars */
const html = new Html5({});
/* eslint-enable no-unused-vars */
assert.ok(events.removetrack, 'removetrack listener was added');
assert.ok(events.addtrack, 'addtrack listener was added');

View File

@ -1,4 +1,5 @@
/* eslint-env qunit */
import TechFaker from '../tech/tech-faker';
/**
* Tests baseline functionality for all tracks
@ -9,16 +10,20 @@
const TrackBaseline = function(TrackClass, options) {
QUnit.test('is setup with id, kind, label, and language', function(assert) {
const track = new TrackClass(options);
const tech = new TechFaker();
const track = new TrackClass(Object.assign({tech}, options));
assert.equal(track.kind, options.kind, 'we have a kind');
assert.equal(track.label, options.label, 'we have a label');
assert.equal(track.language, options.language, 'we have a language');
assert.equal(track.id, options.id, 'we have a id');
tech.dispose();
});
QUnit.test('kind, label, language, id, are read only', function(assert) {
const track = new TrackClass(options);
const tech = new TechFaker();
const track = new TrackClass(Object.assign({tech}, options));
track.kind = 'subtitles';
track.label = 'Spanish';
@ -29,12 +34,17 @@ const TrackBaseline = function(TrackClass, options) {
assert.equal(track.label, options.label, 'we have a label');
assert.equal(track.language, options.language, 'we have a language');
assert.equal(track.id, options.id, 'we have an id');
tech.dispose();
});
QUnit.test('returns an instance of itself on non ie8 browsers', function(assert) {
const track = new TrackClass(options);
const tech = new TechFaker();
const track = new TrackClass(Object.assign({tech}, options));
assert.ok(track instanceof TrackClass, 'returns an instance');
tech.dispose();
});
};

View File

@ -1,5 +1,4 @@
/* eslint-env qunit */
import TechFaker from '../tech/tech-faker';
import TrackBaseline from './track-baseline';
import Track from '../../../src/js/tracks/track.js';
import TextTrackList from '../../../src/js/tracks/text-track-list.js';
@ -21,8 +20,9 @@ TrackBaseline(Track, {
kind: 'subtitles',
mode: 'disabled',
label: 'English',
language: 'en',
tech: new TechFaker()
language: 'en'
// tech is added in baseline
// tech: new TechFaker()
});
QUnit.test('defaults when items not provided', function(assert) {

View File

@ -24,6 +24,9 @@ QUnit.test('trigger "change" when "selectedchange" is fired on a track', functio
track.trigger('selectedchange');
assert.equal(changes, 2, 'one change events for another trigger');
videoTrackList.removeTrack(track);
videoTrackList.off('change');
});
QUnit.test('only one track is ever selected', function(assert) {
@ -56,14 +59,16 @@ QUnit.test('only one track is ever selected', function(assert) {
assert.equal(track3.selected, false, 'track3 is unselected');
assert.equal(track4.selected, false, 'track4 is unselected');
list.removeTrack(track);
list.removeTrack(track2);
list.removeTrack(track3);
list.removeTrack(track4);
});
QUnit.test('all tracks can be unselected', function(assert) {
const track = new VideoTrack();
const track2 = new VideoTrack();
/* eslint-disable no-unused-vars */
const list = new VideoTrackList([track, track2]);
/* eslint-enable no-unused-vars */
assert.equal(track.selected, false, 'track is unselected');
assert.equal(track2.selected, false, 'track2 is unselected');
@ -75,6 +80,9 @@ QUnit.test('all tracks can be unselected', function(assert) {
track.selected = false;
assert.equal(track.selected, false, 'track is unselected');
assert.equal(track2.selected, false, 'track2 is unselected');
list.removeTrack(track);
list.removeTrack(track2);
});
QUnit.test('trigger a change event per selected change', function(assert) {
@ -100,4 +108,10 @@ QUnit.test('trigger a change event per selected change', function(assert) {
list.addTrack(track4);
assert.equal(change, 4, 'no change triggered by adding a unselected track');
list.removeTrack(track);
list.removeTrack(track2);
list.removeTrack(track3);
list.removeTrack(track4);
list.off('change');
});

View File

@ -115,4 +115,6 @@ QUnit.test('when selected is changed selectedchange event is fired', function(as
// one event
track.selected = true;
assert.equal(eventsTriggered, 3, 'three selected changes');
track.off();
});

View File

@ -64,15 +64,15 @@ QUnit.test('listen to remove and add track events in native video tracks', funct
player.player_ = player;
player.options_ = {};
/* eslint-disable no-unused-vars */
const html = new Html5({});
/* eslint-enable no-unused-vars */
assert.ok(events.removetrack, 'removetrack listener was added');
assert.ok(events.addtrack, 'addtrack listener was added');
Html5.TEST_VID = oldTestVid;
Html5.prototype.videoTracks = oldVideoTracks;
html.dispose();
});
QUnit.test('html5 tech supports native video tracks if the video supports it', function(assert) {