Skip to content

Commit e7a10c7

Browse files
authored
Tests: Ensure no timers are running at the end of each test (#1920)
This helps fix issues that make tooltip tests sometimes fail when run against jQuery 3.2 or newer due to timing differences. Details: * Add the `moduleAfterEach` function ensuring no timers are running. * Attach this function via `common.testWidget`. * Attach this function to most test suites. * Add a tooltip test helper cleaning up leftover timers. * Rename legacy `setup`/`teardown` hooks to `beforeEach`/`afterEach`. Closes gh-1920
1 parent f4ef03e commit e7a10c7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+352
-175
lines changed

tests/lib/common.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
define( [
22
"qunit",
3-
"jquery" ],
4-
function( QUnit, $ ) {
3+
"jquery",
4+
"lib/helper"
5+
], function( QUnit, $, helper ) {
56

67
var exports = {};
78

@@ -66,7 +67,7 @@ function testBasicUsage( widget ) {
6667
}
6768

6869
exports.testWidget = function( widget, settings ) {
69-
QUnit.module( widget + ": common widget" );
70+
QUnit.module( widget + ": common widget", { afterEach: helper.moduleAfterEach } );
7071

7172
exports.testJshint( "/widgets/" + widget );
7273
testWidgetDefaults( widget, settings.defaults );

tests/lib/helper.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ define( [
22
"jquery"
33
], function( $ ) {
44

5-
var exports = {};
5+
var exports = {},
6+
7+
// Store the old count so that we only assert on tests that have actually leaked,
8+
// instead of asserting every time a test has leaked sometime in the past
9+
oldActive = 0,
10+
splice = [].splice;
611

712
exports.forceScrollableWindow = function( appendTo ) {
813

@@ -28,6 +33,24 @@ exports.onFocus = function( element, onFocus ) {
2833
element.on( "focus", fn )[ 0 ].focus();
2934
};
3035

36+
/**
37+
* Ensures that tests have cleaned up properly after themselves. Should be passed as the
38+
* afterEach function on all modules' lifecycle object.
39+
*/
40+
exports.moduleAfterEach = function( assert ) {
41+
42+
// Check for (and clean up, if possible) incomplete animations/requests/etc.
43+
if ( jQuery.timers && jQuery.timers.length !== 0 ) {
44+
assert.equal( jQuery.timers.length, 0, "No timers are still running" );
45+
splice.call( jQuery.timers, 0, jQuery.timers.length );
46+
jQuery.fx.stop();
47+
}
48+
if ( jQuery.active !== undefined && jQuery.active !== oldActive ) {
49+
assert.equal( jQuery.active, oldActive, "No AJAX requests are still active" );
50+
oldActive = jQuery.active;
51+
}
52+
};
53+
3154
return exports;
3255

3356
} );

tests/unit/accordion/core.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ define( [
55
"ui/widgets/accordion"
66
], function( QUnit, $, testHelper ) {
77

8-
var setupTeardown = testHelper.setupTeardown,
8+
var beforeAfterEach = testHelper.beforeAfterEach,
99
state = testHelper.state;
1010

11-
QUnit.module( "accordion: core", setupTeardown() );
11+
QUnit.module( "accordion: core", beforeAfterEach() );
1212

1313
$.each( { div: "#list1", ul: "#navigation", dl: "#accordion-dl" }, function( type, selector ) {
1414
QUnit.test( "markup structure: " + type, function( assert ) {

tests/unit/accordion/events.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ define( [
55
"ui/widgets/accordion"
66
], function( QUnit, $, testHelper ) {
77

8-
var setupTeardown = testHelper.setupTeardown,
8+
var beforeAfterEach = testHelper.beforeAfterEach,
99
state = testHelper.state;
1010

11-
QUnit.module( "accordion: events", setupTeardown() );
11+
QUnit.module( "accordion: events", beforeAfterEach() );
1212

1313
QUnit.test( "create", function( assert ) {
1414
assert.expect( 10 );

tests/unit/accordion/helper.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,15 @@ return $.extend( helper, {
1212
} );
1313
},
1414

15-
setupTeardown: function() {
15+
beforeAfterEach: function() {
1616
var animate = $.ui.accordion.prototype.options.animate;
1717
return {
18-
setup: function() {
18+
beforeEach: function() {
1919
$.ui.accordion.prototype.options.animate = false;
2020
},
21-
teardown: function() {
21+
afterEach: function() {
2222
$.ui.accordion.prototype.options.animate = animate;
23+
return helper.moduleAfterEach.apply( this, arguments );
2324
}
2425
};
2526
},

tests/unit/accordion/methods.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ define( [
66
], function( QUnit, $, testHelper ) {
77

88
var equalHeight = testHelper.equalHeight,
9-
setupTeardown = testHelper.setupTeardown,
9+
beforeAfterEach = testHelper.beforeAfterEach,
1010
state = testHelper.state;
1111

12-
QUnit.module( "accordion: methods", setupTeardown() );
12+
QUnit.module( "accordion: methods", beforeAfterEach() );
1313

1414
QUnit.test( "destroy", function( assert ) {
1515
assert.expect( 1 );

tests/unit/accordion/options.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ define( [
66
], function( QUnit, $, testHelper ) {
77

88
var equalHeight = testHelper.equalHeight,
9-
setupTeardown = testHelper.setupTeardown,
9+
beforeAfterEach = testHelper.beforeAfterEach,
1010
state = testHelper.state;
1111

12-
QUnit.module( "accordion: options", setupTeardown() );
12+
QUnit.module( "accordion: options", beforeAfterEach() );
1313

1414
QUnit.test( "{ active: default }", function( assert ) {
1515
assert.expect( 2 );

tests/unit/autocomplete/core.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
define( [
22
"qunit",
33
"jquery",
4+
"lib/helper",
45
"ui/widgets/autocomplete"
5-
], function( QUnit, $ ) {
6+
], function( QUnit, $, helper ) {
67

7-
QUnit.module( "autocomplete: core" );
8+
QUnit.module( "autocomplete: core", { afterEach: helper.moduleAfterEach } );
89

910
QUnit.test( "markup structure", function( assert ) {
1011
assert.expect( 2 );

tests/unit/autocomplete/events.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
define( [
22
"qunit",
33
"jquery",
4+
"lib/helper",
45
"ui/widgets/autocomplete"
5-
], function( QUnit, $ ) {
6+
], function( QUnit, $, helper ) {
67

7-
QUnit.module( "autocomplete: events" );
8+
QUnit.module( "autocomplete: events", { afterEach: helper.moduleAfterEach } );
89

910
var data = [ "Clojure", "COBOL", "ColdFusion", "Java", "JavaScript", "Scala", "Scheme" ];
1011

tests/unit/autocomplete/methods.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
define( [
22
"qunit",
33
"jquery",
4+
"lib/helper",
45
"ui/widgets/autocomplete"
5-
], function( QUnit, $ ) {
6+
], function( QUnit, $, helper ) {
67

7-
QUnit.module( "autocomplete: methods" );
8+
QUnit.module( "autocomplete: methods", { afterEach: helper.moduleAfterEach } );
89

910
QUnit.test( "destroy", function( assert ) {
1011
assert.expect( 1 );

tests/unit/autocomplete/options.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
define( [
22
"qunit",
33
"jquery",
4+
"lib/helper",
45
"ui/widgets/autocomplete"
5-
], function( QUnit, $ ) {
6+
], function( QUnit, $, helper ) {
67

7-
QUnit.module( "autocomplete: options" );
8+
QUnit.module( "autocomplete: options", { afterEach: helper.moduleAfterEach } );
89

910
var data = [ "c++", "java", "php", "coldfusion", "javascript", "asp", "ruby",
1011
"python", "c", "scala", "groovy", "haskell", "perl" ];

tests/unit/button/core.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
define( [
22
"qunit",
33
"jquery",
4+
"lib/helper",
45
"ui/safe-active-element",
56
"ui/widgets/button"
6-
], function( QUnit, $ ) {
7+
], function( QUnit, $, helper ) {
78

8-
QUnit.module( "Button: core" );
9+
QUnit.module( "Button: core", { afterEach: helper.moduleAfterEach } );
910

1011
QUnit.test( "Disabled button loses focus", function( assert ) {
1112
var ready = assert.async();

tests/unit/button/deprecated.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
define( [
22
"qunit",
33
"jquery",
4+
"lib/helper",
45
"ui/widgets/button"
5-
], function( QUnit, $ ) {
6+
], function( QUnit, $, helper ) {
67

7-
QUnit.module( "Button (deprecated): core" );
8+
QUnit.module( "Button (deprecated): core", { afterEach: helper.moduleAfterEach } );
89

910
QUnit.test( "Calling button on a checkbox input calls checkboxradio widget", function( assert ) {
1011
var checkbox = $( "#checkbox01" );
@@ -27,7 +28,7 @@ QUnit.test( "Calling buttonset calls controlgroup", function( assert ) {
2728
assert.ok( controlgroup.is( ":ui-controlgroup" ), "Calling buttonset creates controlgroup instance" );
2829
} );
2930

30-
QUnit.module( "Button (deprecated): methods" );
31+
QUnit.module( "Button (deprecated): methods", { afterEach: helper.moduleAfterEach } );
3132

3233
QUnit.test( "destroy", function( assert ) {
3334
assert.expect( 1 );
@@ -59,7 +60,7 @@ QUnit.test( "refresh: Ensure disabled state is preserved correctly.", function(
5960

6061
} );
6162

62-
QUnit.module( "button (deprecated): options" );
63+
QUnit.module( "button (deprecated): options", { afterEach: helper.moduleAfterEach } );
6364

6465
QUnit.test( "Setting items option on buttonset sets the button properties on the items option", function( assert ) {
6566
assert.expect( 2 );

tests/unit/button/events.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
define( [
22
"qunit",
33
"jquery",
4+
"lib/helper",
45
"ui/widgets/button"
5-
], function( QUnit, $ ) {
6+
], function( QUnit, $, helper ) {
67

7-
QUnit.module( "Button: events" );
8+
QUnit.module( "Button: events", { afterEach: helper.moduleAfterEach } );
89

910
QUnit.test( "Anchor recieves click event when spacebar is pressed", function( assert ) {
1011
var ready = assert.async();

tests/unit/button/methods.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
define( [
22
"qunit",
33
"jquery",
4+
"lib/helper",
45
"ui/widgets/button"
5-
], function( QUnit, $ ) {
6+
], function( QUnit, $, helper ) {
67

7-
QUnit.module( "Button: methods" );
8+
QUnit.module( "Button: methods", { afterEach: helper.moduleAfterEach } );
89

910
QUnit.test( "destroy", function( assert ) {
1011
assert.expect( 1 );

tests/unit/button/options.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
define( [
22
"qunit",
33
"jquery",
4+
"lib/helper",
45
"ui/widgets/button"
5-
], function( QUnit, $ ) {
6+
], function( QUnit, $, helper ) {
67

7-
QUnit.module( "button: options" );
8+
QUnit.module( "button: options", { afterEach: helper.moduleAfterEach } );
89

910
QUnit.test( "disabled, explicit value", function( assert ) {
1011
assert.expect( 8 );

tests/unit/checkboxradio/core.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
define( [
22
"qunit",
33
"jquery",
4+
"lib/helper",
45
"ui/widgets/checkboxradio"
5-
], function( QUnit, $ ) {
6+
], function( QUnit, $, helper ) {
67

7-
QUnit.module( "Checkboxradio: core" );
8+
QUnit.module( "Checkboxradio: core", { afterEach: helper.moduleAfterEach } );
89

910
QUnit.test( "Checkbox - Initial class structure", function( assert ) {
1011
assert.expect( 2 );

tests/unit/checkboxradio/events.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
define( [
22
"qunit",
33
"jquery",
4+
"lib/helper",
45
"ui/widgets/checkboxradio"
5-
], function( QUnit, $ ) {
6+
], function( QUnit, $, helper ) {
67

7-
QUnit.module( "Checkboxradio: events" );
8+
QUnit.module( "Checkboxradio: events", { afterEach: helper.moduleAfterEach } );
89

910
QUnit.test(
1011
"Resetting a checkbox's form should refresh the visual state of the checkbox",

tests/unit/checkboxradio/methods.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
define( [
22
"qunit",
33
"jquery",
4+
"lib/helper",
45
"ui/widgets/checkboxradio"
5-
], function( QUnit, $ ) {
6+
], function( QUnit, $, helper ) {
67

7-
QUnit.module( "Checkboxradio: methods" );
8+
QUnit.module( "Checkboxradio: methods", { afterEach: helper.moduleAfterEach } );
89

910
$.each( [ "checkbox", "radio" ], function( index, value ) {
1011
QUnit.test( value + ": refresh", function( assert ) {

tests/unit/checkboxradio/options.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
define( [
22
"qunit",
33
"jquery",
4+
"lib/helper",
45
"ui/widgets/checkboxradio"
5-
], function( QUnit, $ ) {
6+
], function( QUnit, $, helper ) {
67

7-
QUnit.module( "Checkboxradio: options" );
8+
QUnit.module( "Checkboxradio: options", { afterEach: helper.moduleAfterEach } );
89

910
function assertDisabled( checkbox, assert ) {
1011
assert.hasClasses( checkbox.checkboxradio( "widget" ), "ui-state-disabled",

tests/unit/controlgroup/core.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
define( [
22
"qunit",
33
"jquery",
4+
"lib/helper",
45
"ui/widgets/controlgroup",
56
"ui/widgets/checkboxradio",
67
"ui/widgets/selectmenu",
78
"ui/widgets/button",
89
"ui/widgets/spinner"
9-
], function( QUnit, $ ) {
10+
], function( QUnit, $, helper ) {
1011

11-
QUnit.module( "Controlgroup: Core" );
12+
QUnit.module( "Controlgroup: Core", { afterEach: helper.moduleAfterEach } );
1213

1314
QUnit.test( "selectmenu: open/close corners", function( assert ) {
1415
assert.expect( 12 );
@@ -161,12 +162,12 @@ QUnit.test( "Single controlgroup button - vertical", function( assert ) {
161162
} );
162163

163164
QUnit.module( "Controlgroup: Non-empty class key", {
164-
setup: function() {
165+
beforeEach: function() {
165166
this.classKey = $.ui.selectmenu.prototype.options.classes[ "ui-selectmenu-button-closed" ];
166167
$.ui.selectmenu.prototype.options.classes[ "ui-selectmenu-button-closed" ] =
167168
"something-custom";
168169
},
169-
teardown: function() {
170+
afterEach: function() {
170171
$.ui.selectmenu.prototype.options.classes[ "ui-selectmenu-button-closed" ] = this.classKey;
171172
}
172173
} );

tests/unit/controlgroup/methods.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
define( [
22
"qunit",
33
"jquery",
4+
"lib/helper",
45
"ui/widgets/controlgroup",
56
"ui/widgets/checkboxradio",
67
"ui/widgets/selectmenu",
78
"ui/widgets/button",
89
"ui/widgets/spinner"
9-
], function( QUnit, $ ) {
10+
], function( QUnit, $, helper ) {
1011

11-
QUnit.module( "Controlgroup: methods" );
12+
QUnit.module( "Controlgroup: methods", { afterEach: helper.moduleAfterEach } );
1213

1314
QUnit.test( "destroy", function( assert ) {
1415
assert.expect( 1 );

tests/unit/controlgroup/options.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
define( [
22
"qunit",
33
"jquery",
4+
"lib/helper",
45
"ui/widgets/controlgroup",
56
"ui/widgets/checkboxradio",
67
"ui/widgets/selectmenu",
78
"ui/widgets/button",
89
"ui/widgets/spinner"
9-
], function( QUnit, $ ) {
10+
], function( QUnit, $, helper ) {
1011

11-
QUnit.module( "Controlgroup: options" );
12+
QUnit.module( "Controlgroup: options", { afterEach: helper.moduleAfterEach } );
1213

1314
QUnit.test( "disabled", function( assert ) {
1415
assert.expect( 4 );

0 commit comments

Comments
 (0)