aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--test/.jshintrc1
-rw-r--r--test/data/testinit.js113
-rw-r--r--test/data/testrunner.js469
-rw-r--r--test/index.html7
-rw-r--r--test/jquery.js6
5 files changed, 303 insertions, 293 deletions
diff --git a/test/.jshintrc b/test/.jshintrc
index 34f8a5b2d..b702f6fa5 100644
--- a/test/.jshintrc
+++ b/test/.jshintrc
@@ -22,6 +22,7 @@
"globals": {
"require": false,
+ "define": false,
"DOMParser": false,
"QUnit": false,
"ok": false,
diff --git a/test/data/testinit.js b/test/data/testinit.js
index 2a3c33d76..c35383c6b 100644
--- a/test/data/testinit.js
+++ b/test/data/testinit.js
@@ -259,65 +259,68 @@ this.iframeCallback = undefined;
QUnit.config.autostart = false;
this.loadTests = function() {
var loadSwarm,
- url = window.location.search,
- tests = [
- "data/testrunner.js",
- "unit/core.js",
- "unit/callbacks.js",
- "unit/deferred.js",
- "unit/support.js",
- "unit/data.js",
- "unit/queue.js",
- "unit/attributes.js",
- "unit/event.js",
- "unit/selector.js",
- "unit/traversing.js",
- "unit/manipulation.js",
- "unit/wrap.js",
- "unit/css.js",
- "unit/serialize.js",
- "unit/ajax.js",
- "unit/effects.js",
- "unit/offset.js",
- "unit/dimensions.js"
- ];
+ url = window.location.search;
url = decodeURIComponent( url.slice( url.indexOf("swarmURL=") + "swarmURL=".length ) );
loadSwarm = url && url.indexOf("http") === 0;
- // Ensure load order (to preserve test numbers)
- (function loadDep() {
- var dep = tests.shift();
- if ( dep ) {
- require( [ dep ], loadDep );
- } else {
- // Subproject tests must be last because they replace our test fixture
- window.testSubproject( "Sizzle", "../bower_components/sizzle/test/", /^unit\/.*\.js$/, function() {
- // Call load to build module filter select element
- 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();
+ // Get testSubproject from testrunner first
+ require([ "data/testrunner.js" ], function( testSubproject ) {
+ var tests = [
+ "unit/core.js",
+ "unit/callbacks.js",
+ "unit/deferred.js",
+ "unit/support.js",
+ "unit/data.js",
+ "unit/queue.js",
+ "unit/attributes.js",
+ "unit/event.js",
+ "unit/selector.js",
+ "unit/traversing.js",
+ "unit/manipulation.js",
+ "unit/wrap.js",
+ "unit/css.js",
+ "unit/serialize.js",
+ "unit/ajax.js",
+ "unit/effects.js",
+ "unit/offset.js",
+ "unit/dimensions.js"
+ ];
+
+ // Ensure load order (to preserve test numbers)
+ (function loadDep() {
+ var dep = tests.shift();
+ if ( dep ) {
+ require( [ dep ], loadDep );
+ } else {
+ // Subproject tests must be last because they replace our test fixture
+ testSubproject( "Sizzle", "../bower_components/sizzle/test/", /^unit\/.*\.js$/, function() {
+ // Call load to build module filter select element
+ QUnit.load();
+
+ /**
+ * Run in noConflict mode
+ */
+ jQuery.noConflict();
+
+ // Expose Sizzle for Sizzle's selector tests
+ // We remove Sizzle's globalization in jQuery
+ window.Sizzle = window.Sizzle || jQuery.find;
+
+ // For checking globals pollution despite auto-created globals in various environments
+ supportjQuery.each( [ jQuery.expando, "getInterface", "Packages", "java", "netscape" ], function( i, name ) {
+ window[ name ] = window[ name ];
});
- } else {
- QUnit.start();
- }
-
- /**
- * Run in noConflict mode
- */
- jQuery.noConflict();
- // Expose Sizzle for Sizzle's selector tests
- // We remove Sizzle's globalization in jQuery
- window.Sizzle = window.Sizzle || jQuery.find;
-
- // For checking globals pollution despite auto-created globals in various environments
- supportjQuery.each( [ jQuery.expando, "getInterface", "Packages", "java", "netscape" ], function( i, 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();
+ }
});
- });
- }
- })();
+ }
+ })();
+ });
};
diff --git a/test/data/testrunner.js b/test/data/testrunner.js
index c766e13ca..3f1a85a03 100644
--- a/test/data/testrunner.js
+++ b/test/data/testrunner.js
@@ -1,7 +1,236 @@
+define(function() {
// Allow subprojects to test against their own fixtures
-var qunitModule = QUnit.module,
- qunitTest = QUnit.test;
+var oldStart = window.start,
+ 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
@@ -9,7 +238,7 @@ var qunitModule = QUnit.module,
* @param {String} url Test folder location
* @param {RegExp} risTests To filter script sources
*/
-this.testSubproject = function( label, url, risTests, complete ) {
+function testSubproject( label, url, risTests, complete ) {
var sub, fixture, fixtureHTML,
fixtureReplaced = false;
@@ -131,236 +360,8 @@ this.testSubproject = function( label, url, risTests, complete ) {
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;
- }
-
- /**
- * @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();
+return testSubproject;
- // 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;
+});
diff --git a/test/index.html b/test/index.html
index 070624036..1b5e33a3b 100644
--- a/test/index.html
+++ b/test/index.html
@@ -29,6 +29,13 @@
).replace(/\w+/g, function(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>
</head>
diff --git a/test/jquery.js b/test/jquery.js
index 3c937d598..fd0be6759 100644
--- a/test/jquery.js
+++ b/test/jquery.js
@@ -54,11 +54,9 @@
// Load jQuery
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
+ // Synchronous-only tests
+ // Other tests are loaded from the test page
if ( typeof loadTests !== "undefined" ) {
- loadTests();
- // Synchronous-only tests
document.write( "<script src='" + path + "test/unit/ready.js'><\x2Fscript>");
}