mirror of
https://github.com/jquery/jquery.git
synced 2024-12-09 08:04:24 +00:00
Convert testrunner to an AMD module and ensure jQuery is on the page when executing the testrunner (another race condition amplified by swarm)
This commit is contained in:
parent
4ca5a0c691
commit
5093b89f08
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
"globals": {
|
"globals": {
|
||||||
"require": false,
|
"require": false,
|
||||||
|
"define": false,
|
||||||
"DOMParser": false,
|
"DOMParser": false,
|
||||||
"QUnit": false,
|
"QUnit": false,
|
||||||
"ok": false,
|
"ok": false,
|
||||||
|
@ -259,9 +259,13 @@ this.iframeCallback = undefined;
|
|||||||
QUnit.config.autostart = false;
|
QUnit.config.autostart = false;
|
||||||
this.loadTests = function() {
|
this.loadTests = function() {
|
||||||
var loadSwarm,
|
var loadSwarm,
|
||||||
url = window.location.search,
|
url = window.location.search;
|
||||||
tests = [
|
url = decodeURIComponent( url.slice( url.indexOf("swarmURL=") + "swarmURL=".length ) );
|
||||||
"data/testrunner.js",
|
loadSwarm = url && url.indexOf("http") === 0;
|
||||||
|
|
||||||
|
// Get testSubproject from testrunner first
|
||||||
|
require([ "data/testrunner.js" ], function( testSubproject ) {
|
||||||
|
var tests = [
|
||||||
"unit/core.js",
|
"unit/core.js",
|
||||||
"unit/callbacks.js",
|
"unit/callbacks.js",
|
||||||
"unit/deferred.js",
|
"unit/deferred.js",
|
||||||
@ -281,8 +285,6 @@ this.loadTests = function() {
|
|||||||
"unit/offset.js",
|
"unit/offset.js",
|
||||||
"unit/dimensions.js"
|
"unit/dimensions.js"
|
||||||
];
|
];
|
||||||
url = decodeURIComponent( url.slice( url.indexOf("swarmURL=") + "swarmURL=".length ) );
|
|
||||||
loadSwarm = url && url.indexOf("http") === 0;
|
|
||||||
|
|
||||||
// Ensure load order (to preserve test numbers)
|
// Ensure load order (to preserve test numbers)
|
||||||
(function loadDep() {
|
(function loadDep() {
|
||||||
@ -291,19 +293,10 @@ this.loadTests = function() {
|
|||||||
require( [ dep ], loadDep );
|
require( [ dep ], loadDep );
|
||||||
} else {
|
} else {
|
||||||
// Subproject tests must be last because they replace our test fixture
|
// Subproject tests must be last because they replace our test fixture
|
||||||
window.testSubproject( "Sizzle", "../bower_components/sizzle/test/", /^unit\/.*\.js$/, function() {
|
testSubproject( "Sizzle", "../bower_components/sizzle/test/", /^unit\/.*\.js$/, function() {
|
||||||
// Call load to build module filter select element
|
// Call load to build module filter select element
|
||||||
QUnit.load();
|
QUnit.load();
|
||||||
|
|
||||||
// Load the TestSwarm listener if swarmURL is in the address.
|
|
||||||
if ( loadSwarm ) {
|
|
||||||
require( [ "http://swarm.jquery.org/js/inject.js?" + (new Date()).getTime() ], function() {
|
|
||||||
QUnit.start();
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
QUnit.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run in noConflict mode
|
* Run in noConflict mode
|
||||||
*/
|
*/
|
||||||
@ -317,7 +310,17 @@ this.loadTests = function() {
|
|||||||
supportjQuery.each( [ jQuery.expando, "getInterface", "Packages", "java", "netscape" ], function( i, name ) {
|
supportjQuery.each( [ jQuery.expando, "getInterface", "Packages", "java", "netscape" ], function( i, name ) {
|
||||||
window[ name ] = window[ name ];
|
window[ name ] = window[ name ];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Load the TestSwarm listener if swarmURL is in the address.
|
||||||
|
if ( loadSwarm ) {
|
||||||
|
require( [ "http://swarm.jquery.org/js/inject.js?" + (new Date()).getTime() ], function() {
|
||||||
|
QUnit.start();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
QUnit.start();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,236 @@
|
|||||||
|
define(function() {
|
||||||
|
|
||||||
// Allow subprojects to test against their own fixtures
|
// Allow subprojects to test against their own fixtures
|
||||||
var qunitModule = QUnit.module,
|
var oldStart = window.start,
|
||||||
qunitTest = QUnit.test;
|
qunitModule = QUnit.module,
|
||||||
|
qunitTest = QUnit.test,
|
||||||
|
// Store the old counts so that we only assert on tests that have actually leaked,
|
||||||
|
// instead of asserting every time a test has leaked sometime in the past
|
||||||
|
oldCacheLength = 0,
|
||||||
|
oldFragmentsLength = 0,
|
||||||
|
oldActive = 0,
|
||||||
|
|
||||||
|
expectedDataKeys = {},
|
||||||
|
|
||||||
|
splice = [].splice,
|
||||||
|
reset = QUnit.reset,
|
||||||
|
ajaxSettings = jQuery.ajaxSettings;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* QUnit configuration
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Max time for stop() and asyncTest() until it aborts test
|
||||||
|
// and start()'s the next test.
|
||||||
|
QUnit.config.testTimeout = 20 * 1000; // 20 seconds
|
||||||
|
|
||||||
|
// Enforce an "expect" argument or expect() call in all test bodies.
|
||||||
|
QUnit.config.requireExpects = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* QUnit hooks
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Sandbox start for great justice
|
||||||
|
window.start = function() {
|
||||||
|
oldStart();
|
||||||
|
};
|
||||||
|
|
||||||
|
function keys(o) {
|
||||||
|
var ret, key;
|
||||||
|
if ( Object.keys ) {
|
||||||
|
ret = Object.keys( o );
|
||||||
|
} else {
|
||||||
|
ret = [];
|
||||||
|
for ( key in o ) {
|
||||||
|
ret.push( key );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret.sort();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {jQuery|HTMLElement|Object|Array} elems Target (or array of targets) for jQuery.data.
|
||||||
|
* @param {string} key
|
||||||
|
*/
|
||||||
|
QUnit.expectJqData = function( elems, key ) {
|
||||||
|
var i, elem, expando;
|
||||||
|
|
||||||
|
// As of jQuery 2.0, there will be no "cache"-data is
|
||||||
|
// stored and managed completely below the API surface
|
||||||
|
if ( jQuery.cache ) {
|
||||||
|
QUnit.current_testEnvironment.checkJqData = true;
|
||||||
|
|
||||||
|
if ( elems.jquery && elems.toArray ) {
|
||||||
|
elems = elems.toArray();
|
||||||
|
}
|
||||||
|
if ( !supportjQuery.isArray( elems ) ) {
|
||||||
|
elems = [ elems ];
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( i = 0; i < elems.length; i++ ) {
|
||||||
|
elem = elems[i];
|
||||||
|
|
||||||
|
// jQuery.data only stores data for nodes in jQuery.cache,
|
||||||
|
// for other data targets the data is stored in the object itself,
|
||||||
|
// in that case we can't test that target for memory leaks.
|
||||||
|
// But we don't have to since in that case the data will/must will
|
||||||
|
// be available as long as the object is not garbage collected by
|
||||||
|
// the js engine, and when it is, the data will be removed with it.
|
||||||
|
if ( !elem.nodeType ) {
|
||||||
|
// Fixes false positives for dataTests(window), dataTests({}).
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
expando = elem[ jQuery.expando ];
|
||||||
|
|
||||||
|
if ( expando === undefined ) {
|
||||||
|
// In this case the element exists fine, but
|
||||||
|
// jQuery.data (or internal data) was never (in)directly
|
||||||
|
// called.
|
||||||
|
// Since this method was called it means some data was
|
||||||
|
// expected to be found, but since there is nothing, fail early
|
||||||
|
// (instead of in teardown).
|
||||||
|
notStrictEqual( expando, undefined, "Target for expectJqData must have an expando, for else there can be no data to expect." );
|
||||||
|
} else {
|
||||||
|
if ( expectedDataKeys[expando] ) {
|
||||||
|
expectedDataKeys[expando].push( key );
|
||||||
|
} else {
|
||||||
|
expectedDataKeys[expando] = [ key ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
QUnit.config.urlConfig.push({
|
||||||
|
id: "jqdata",
|
||||||
|
label: "Always check jQuery.data",
|
||||||
|
tooltip: "Trigger QUnit.expectJqData detection for all tests instead of just the ones that call it"
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures that tests have cleaned up properly after themselves. Should be passed as the
|
||||||
|
* teardown function on all modules' lifecycle object.
|
||||||
|
*/
|
||||||
|
window.moduleTeardown = function() {
|
||||||
|
var i,
|
||||||
|
expectedKeys, actualKeys,
|
||||||
|
fragmentsLength = 0,
|
||||||
|
cacheLength = 0;
|
||||||
|
|
||||||
|
// Only look for jQuery data problems if this test actually
|
||||||
|
// provided some information to compare against.
|
||||||
|
if ( QUnit.urlParams.jqdata || this.checkJqData ) {
|
||||||
|
for ( i in jQuery.cache ) {
|
||||||
|
expectedKeys = expectedDataKeys[i];
|
||||||
|
actualKeys = jQuery.cache[i] ? keys( jQuery.cache[i] ) : jQuery.cache[i];
|
||||||
|
if ( !QUnit.equiv( expectedKeys, actualKeys ) ) {
|
||||||
|
deepEqual( actualKeys, expectedKeys, "Expected keys exist in jQuery.cache" );
|
||||||
|
}
|
||||||
|
delete jQuery.cache[i];
|
||||||
|
delete expectedDataKeys[i];
|
||||||
|
}
|
||||||
|
// In case it was removed from cache before (or never there in the first place)
|
||||||
|
for ( i in expectedDataKeys ) {
|
||||||
|
deepEqual( expectedDataKeys[i], undefined, "No unexpected keys were left in jQuery.cache (#" + i + ")" );
|
||||||
|
delete expectedDataKeys[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset data register
|
||||||
|
expectedDataKeys = {};
|
||||||
|
|
||||||
|
// Check for (and clean up, if possible) incomplete animations/requests/etc.
|
||||||
|
if ( jQuery.timers && jQuery.timers.length !== 0 ) {
|
||||||
|
equal( jQuery.timers.length, 0, "No timers are still running" );
|
||||||
|
splice.call( jQuery.timers, 0, jQuery.timers.length );
|
||||||
|
jQuery.fx.stop();
|
||||||
|
}
|
||||||
|
if ( jQuery.active !== undefined && jQuery.active !== oldActive ) {
|
||||||
|
equal( jQuery.active, oldActive, "No AJAX requests are still active" );
|
||||||
|
if ( ajaxTest.abort ) {
|
||||||
|
ajaxTest.abort("active requests");
|
||||||
|
}
|
||||||
|
oldActive = jQuery.active;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow QUnit.reset to clean up any attached elements before checking for leaks
|
||||||
|
QUnit.reset();
|
||||||
|
|
||||||
|
for ( i in jQuery.cache ) {
|
||||||
|
++cacheLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
jQuery.fragments = {};
|
||||||
|
|
||||||
|
for ( i in jQuery.fragments ) {
|
||||||
|
++fragmentsLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Because QUnit doesn't have a mechanism for retrieving the number of expected assertions for a test,
|
||||||
|
// if we unconditionally assert any of these, the test will fail with too many assertions :|
|
||||||
|
if ( cacheLength !== oldCacheLength ) {
|
||||||
|
equal( cacheLength, oldCacheLength, "No unit tests leak memory in jQuery.cache" );
|
||||||
|
oldCacheLength = cacheLength;
|
||||||
|
}
|
||||||
|
if ( fragmentsLength !== oldFragmentsLength ) {
|
||||||
|
equal( fragmentsLength, oldFragmentsLength, "No unit tests leak memory in jQuery.fragments" );
|
||||||
|
oldFragmentsLength = fragmentsLength;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
QUnit.done(function() {
|
||||||
|
// Remove our own fixtures outside #qunit-fixture
|
||||||
|
supportjQuery("#qunit ~ *").remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
// jQuery-specific QUnit.reset
|
||||||
|
QUnit.reset = function() {
|
||||||
|
|
||||||
|
// Ensure jQuery events and data on the fixture are properly removed
|
||||||
|
jQuery("#qunit-fixture").empty();
|
||||||
|
// ...even if the jQuery under test has a broken .empty()
|
||||||
|
supportjQuery("#qunit-fixture").empty();
|
||||||
|
|
||||||
|
// Reset internal jQuery state
|
||||||
|
jQuery.event.global = {};
|
||||||
|
if ( ajaxSettings ) {
|
||||||
|
jQuery.ajaxSettings = jQuery.extend( true, {}, ajaxSettings );
|
||||||
|
} else {
|
||||||
|
delete jQuery.ajaxSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cleanup globals
|
||||||
|
Globals.cleanup();
|
||||||
|
|
||||||
|
// Let QUnit reset the fixture
|
||||||
|
reset.apply( this, arguments );
|
||||||
|
};
|
||||||
|
|
||||||
|
// Register globals for cleanup and the cleanup code itself
|
||||||
|
// Explanation at http://perfectionkills.com/understanding-delete/#ie_bugs
|
||||||
|
window.Globals = (function() {
|
||||||
|
var globals = {};
|
||||||
|
return {
|
||||||
|
register: function( name ) {
|
||||||
|
globals[ name ] = true;
|
||||||
|
supportjQuery.globalEval( "var " + name + " = undefined;" );
|
||||||
|
},
|
||||||
|
cleanup: function() {
|
||||||
|
var name,
|
||||||
|
current = globals;
|
||||||
|
globals = {};
|
||||||
|
for ( name in current ) {
|
||||||
|
supportjQuery.globalEval( "try { " +
|
||||||
|
"delete " + ( supportjQuery.support.deleteExpando ? "window['" + name + "']" : name ) +
|
||||||
|
"; } catch( x ) {}" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test a subproject with its own fixture
|
* Test a subproject with its own fixture
|
||||||
@ -9,7 +238,7 @@ var qunitModule = QUnit.module,
|
|||||||
* @param {String} url Test folder location
|
* @param {String} url Test folder location
|
||||||
* @param {RegExp} risTests To filter script sources
|
* @param {RegExp} risTests To filter script sources
|
||||||
*/
|
*/
|
||||||
this.testSubproject = function( label, url, risTests, complete ) {
|
function testSubproject( label, url, risTests, complete ) {
|
||||||
var sub, fixture, fixtureHTML,
|
var sub, fixture, fixtureHTML,
|
||||||
fixtureReplaced = false;
|
fixtureReplaced = false;
|
||||||
|
|
||||||
@ -131,236 +360,8 @@ this.testSubproject = function( label, url, risTests, complete ) {
|
|||||||
fn.apply( this, arguments );
|
fn.apply( this, arguments );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
// Register globals for cleanup and the cleanup code itself
|
|
||||||
// Explanation at http://perfectionkills.com/understanding-delete/#ie_bugs
|
|
||||||
this.Globals = (function() {
|
|
||||||
var globals = {};
|
|
||||||
return {
|
|
||||||
register: function( name ) {
|
|
||||||
globals[ name ] = true;
|
|
||||||
supportjQuery.globalEval( "var " + name + " = undefined;" );
|
|
||||||
},
|
|
||||||
cleanup: function() {
|
|
||||||
var name,
|
|
||||||
current = globals;
|
|
||||||
globals = {};
|
|
||||||
for ( name in current ) {
|
|
||||||
supportjQuery.globalEval( "try { " +
|
|
||||||
"delete " + ( supportjQuery.support.deleteExpando ? "window['" + name + "']" : name ) +
|
|
||||||
"; } catch( x ) {}" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* QUnit hooks
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Sandbox start for great justice
|
|
||||||
(function() {
|
|
||||||
var oldStart = window.start;
|
|
||||||
window.start = function() {
|
|
||||||
oldStart();
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
// Store the old counts so that we only assert on tests that have actually leaked,
|
|
||||||
// instead of asserting every time a test has leaked sometime in the past
|
|
||||||
var oldCacheLength = 0,
|
|
||||||
oldFragmentsLength = 0,
|
|
||||||
oldActive = 0,
|
|
||||||
|
|
||||||
expectedDataKeys = {},
|
|
||||||
|
|
||||||
splice = [].splice,
|
|
||||||
reset = QUnit.reset,
|
|
||||||
ajaxSettings = jQuery.ajaxSettings;
|
|
||||||
|
|
||||||
function keys(o) {
|
|
||||||
var ret, key;
|
|
||||||
if ( Object.keys ) {
|
|
||||||
ret = Object.keys( o );
|
|
||||||
} else {
|
|
||||||
ret = [];
|
|
||||||
for ( key in o ) {
|
|
||||||
ret.push( key );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ret.sort();
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
return testSubproject;
|
||||||
* @param {jQuery|HTMLElement|Object|Array} elems Target (or array of targets) for jQuery.data.
|
|
||||||
* @param {string} key
|
|
||||||
*/
|
|
||||||
QUnit.expectJqData = function( elems, key ) {
|
|
||||||
var i, elem, expando;
|
|
||||||
|
|
||||||
// As of jQuery 2.0, there will be no "cache"-data is
|
|
||||||
// stored and managed completely below the API surface
|
|
||||||
if ( jQuery.cache ) {
|
|
||||||
QUnit.current_testEnvironment.checkJqData = true;
|
|
||||||
|
|
||||||
if ( elems.jquery && elems.toArray ) {
|
|
||||||
elems = elems.toArray();
|
|
||||||
}
|
|
||||||
if ( !supportjQuery.isArray( elems ) ) {
|
|
||||||
elems = [ elems ];
|
|
||||||
}
|
|
||||||
|
|
||||||
for ( i = 0; i < elems.length; i++ ) {
|
|
||||||
elem = elems[i];
|
|
||||||
|
|
||||||
// jQuery.data only stores data for nodes in jQuery.cache,
|
|
||||||
// for other data targets the data is stored in the object itself,
|
|
||||||
// in that case we can't test that target for memory leaks.
|
|
||||||
// But we don't have to since in that case the data will/must will
|
|
||||||
// be available as long as the object is not garbage collected by
|
|
||||||
// the js engine, and when it is, the data will be removed with it.
|
|
||||||
if ( !elem.nodeType ) {
|
|
||||||
// Fixes false positives for dataTests(window), dataTests({}).
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
expando = elem[ jQuery.expando ];
|
|
||||||
|
|
||||||
if ( expando === undefined ) {
|
|
||||||
// In this case the element exists fine, but
|
|
||||||
// jQuery.data (or internal data) was never (in)directly
|
|
||||||
// called.
|
|
||||||
// Since this method was called it means some data was
|
|
||||||
// expected to be found, but since there is nothing, fail early
|
|
||||||
// (instead of in teardown).
|
|
||||||
notStrictEqual( expando, undefined, "Target for expectJqData must have an expando, for else there can be no data to expect." );
|
|
||||||
} else {
|
|
||||||
if ( expectedDataKeys[expando] ) {
|
|
||||||
expectedDataKeys[expando].push( key );
|
|
||||||
} else {
|
|
||||||
expectedDataKeys[expando] = [ key ];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
QUnit.config.urlConfig.push({
|
|
||||||
id: "jqdata",
|
|
||||||
label: "Always check jQuery.data",
|
|
||||||
tooltip: "Trigger QUnit.expectJqData detection for all tests instead of just the ones that call it"
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensures that tests have cleaned up properly after themselves. Should be passed as the
|
|
||||||
* teardown function on all modules' lifecycle object.
|
|
||||||
*/
|
|
||||||
this.moduleTeardown = function() {
|
|
||||||
var i,
|
|
||||||
expectedKeys, actualKeys,
|
|
||||||
fragmentsLength = 0,
|
|
||||||
cacheLength = 0;
|
|
||||||
|
|
||||||
// Only look for jQuery data problems if this test actually
|
|
||||||
// provided some information to compare against.
|
|
||||||
if ( QUnit.urlParams.jqdata || this.checkJqData ) {
|
|
||||||
for ( i in jQuery.cache ) {
|
|
||||||
expectedKeys = expectedDataKeys[i];
|
|
||||||
actualKeys = jQuery.cache[i] ? keys( jQuery.cache[i] ) : jQuery.cache[i];
|
|
||||||
if ( !QUnit.equiv( expectedKeys, actualKeys ) ) {
|
|
||||||
deepEqual( actualKeys, expectedKeys, "Expected keys exist in jQuery.cache" );
|
|
||||||
}
|
|
||||||
delete jQuery.cache[i];
|
|
||||||
delete expectedDataKeys[i];
|
|
||||||
}
|
|
||||||
// In case it was removed from cache before (or never there in the first place)
|
|
||||||
for ( i in expectedDataKeys ) {
|
|
||||||
deepEqual( expectedDataKeys[i], undefined, "No unexpected keys were left in jQuery.cache (#" + i + ")" );
|
|
||||||
delete expectedDataKeys[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset data register
|
|
||||||
expectedDataKeys = {};
|
|
||||||
|
|
||||||
// Check for (and clean up, if possible) incomplete animations/requests/etc.
|
|
||||||
if ( jQuery.timers && jQuery.timers.length !== 0 ) {
|
|
||||||
equal( jQuery.timers.length, 0, "No timers are still running" );
|
|
||||||
splice.call( jQuery.timers, 0, jQuery.timers.length );
|
|
||||||
jQuery.fx.stop();
|
|
||||||
}
|
|
||||||
if ( jQuery.active !== undefined && jQuery.active !== oldActive ) {
|
|
||||||
equal( jQuery.active, oldActive, "No AJAX requests are still active" );
|
|
||||||
if ( ajaxTest.abort ) {
|
|
||||||
ajaxTest.abort("active requests");
|
|
||||||
}
|
|
||||||
oldActive = jQuery.active;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow QUnit.reset to clean up any attached elements before checking for leaks
|
|
||||||
QUnit.reset();
|
|
||||||
|
|
||||||
for ( i in jQuery.cache ) {
|
|
||||||
++cacheLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
jQuery.fragments = {};
|
|
||||||
|
|
||||||
for ( i in jQuery.fragments ) {
|
|
||||||
++fragmentsLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Because QUnit doesn't have a mechanism for retrieving the number of expected assertions for a test,
|
|
||||||
// if we unconditionally assert any of these, the test will fail with too many assertions :|
|
|
||||||
if ( cacheLength !== oldCacheLength ) {
|
|
||||||
equal( cacheLength, oldCacheLength, "No unit tests leak memory in jQuery.cache" );
|
|
||||||
oldCacheLength = cacheLength;
|
|
||||||
}
|
|
||||||
if ( fragmentsLength !== oldFragmentsLength ) {
|
|
||||||
equal( fragmentsLength, oldFragmentsLength, "No unit tests leak memory in jQuery.fragments" );
|
|
||||||
oldFragmentsLength = fragmentsLength;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
QUnit.done(function() {
|
|
||||||
// Remove our own fixtures outside #qunit-fixture
|
|
||||||
supportjQuery("#qunit ~ *").remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
// jQuery-specific QUnit.reset
|
|
||||||
QUnit.reset = function() {
|
|
||||||
|
|
||||||
// Ensure jQuery events and data on the fixture are properly removed
|
|
||||||
jQuery("#qunit-fixture").empty();
|
|
||||||
// ...even if the jQuery under test has a broken .empty()
|
|
||||||
supportjQuery("#qunit-fixture").empty();
|
|
||||||
|
|
||||||
// Reset internal jQuery state
|
|
||||||
jQuery.event.global = {};
|
|
||||||
if ( ajaxSettings ) {
|
|
||||||
jQuery.ajaxSettings = jQuery.extend( true, {}, ajaxSettings );
|
|
||||||
} else {
|
|
||||||
delete jQuery.ajaxSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cleanup globals
|
|
||||||
Globals.cleanup();
|
|
||||||
|
|
||||||
// Let QUnit reset the fixture
|
|
||||||
reset.apply( this, arguments );
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* QUnit configuration
|
|
||||||
*/
|
|
||||||
// Max time for stop() and asyncTest() until it aborts test
|
|
||||||
// and start()'s the next test.
|
|
||||||
QUnit.config.testTimeout = 20 * 1000; // 20 seconds
|
|
||||||
|
|
||||||
// Enforce an "expect" argument or expect() call in all test bodies.
|
|
||||||
QUnit.config.requireExpects = true;
|
|
||||||
|
@ -29,6 +29,13 @@
|
|||||||
).replace(/\w+/g, function(n) {
|
).replace(/\w+/g, function(n) {
|
||||||
document.createElement(n);
|
document.createElement(n);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Load tests if they have not been loaded
|
||||||
|
// This is in a different script tag to ensure that
|
||||||
|
// jQuery is on the page when the testrunner executes
|
||||||
|
if ( !QUnit.urlParams.amd ) {
|
||||||
|
loadTests();
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
6
test/jquery.js
vendored
6
test/jquery.js
vendored
@ -54,11 +54,9 @@
|
|||||||
// Load jQuery
|
// Load jQuery
|
||||||
document.write( "<script id='jquery-js' src='" + path + src + "'><\x2Fscript>" );
|
document.write( "<script id='jquery-js' src='" + path + src + "'><\x2Fscript>" );
|
||||||
|
|
||||||
// Load tests if available
|
|
||||||
// These can be loaded async as QUnit won't start until finished
|
|
||||||
if ( typeof loadTests !== "undefined" ) {
|
|
||||||
loadTests();
|
|
||||||
// Synchronous-only tests
|
// Synchronous-only tests
|
||||||
|
// Other tests are loaded from the test page
|
||||||
|
if ( typeof loadTests !== "undefined" ) {
|
||||||
document.write( "<script src='" + path + "test/unit/ready.js'><\x2Fscript>");
|
document.write( "<script src='" + path + "test/unit/ready.js'><\x2Fscript>");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user