Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tests: memory leak fixes in tests #5861

Merged
merged 2 commits into from Mar 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions test/unit/close-button.test.js
Expand Up @@ -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) {
Expand Down
10 changes: 9 additions & 1 deletion test/unit/component.test.js
Expand Up @@ -259,14 +259,16 @@ 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: {}
});

assert.ok(!testComp.childNameIndex_.TestComponent2, 'we do not have testComponent2');
assert.ok(testComp.childNameIndex_.TestComponent4, 'we have a testComponent4');

player.dispose();
testComp.dispose();
});

Expand Down Expand Up @@ -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');
Expand Down Expand Up @@ -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();
});

Expand Down Expand Up @@ -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();
});
17 changes: 17 additions & 0 deletions test/unit/controls.test.js
Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand Down
3 changes: 3 additions & 0 deletions test/unit/event-target.test.js
Expand Up @@ -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) {
Expand All @@ -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);
});
26 changes: 26 additions & 0 deletions test/unit/events.test.js
Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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) {
Expand All @@ -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');
});
12 changes: 12 additions & 0 deletions test/unit/menu.test.js
Expand Up @@ -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) {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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();
});
32 changes: 18 additions & 14 deletions test/unit/mixins/evented.test.js
Expand Up @@ -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'));
}
});

Expand Down Expand Up @@ -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) {
Expand Down
4 changes: 4 additions & 0 deletions test/unit/mixins/stateful.test.js
Expand Up @@ -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) {
Expand All @@ -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) {
Expand All @@ -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');
});