aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml2
-rw-r--r--Gruntfile.js84
-rw-r--r--README.md10
-rw-r--r--build/tasks/qunit_fixture.js22
-rw-r--r--external/qunit/qunit.css12
-rw-r--r--external/qunit/qunit.js2478
-rw-r--r--package.json16
-rw-r--r--test/data/ajax/content-type.php5
-rw-r--r--test/data/ajax/evalScript.php1
-rw-r--r--test/data/ajax/method.php1
-rw-r--r--test/data/ajax/unreleasedXHR.html2
-rw-r--r--test/data/atom+xml.php4
-rw-r--r--test/data/core/dont_return.php3
-rw-r--r--test/data/core/dynamic_ready.html2
-rw-r--r--test/data/csp.include.html14
-rw-r--r--test/data/echoData.php1
-rw-r--r--test/data/echoQuery.php1
-rw-r--r--test/data/errorWithJSON.php6
-rw-r--r--test/data/errorWithText.php5
-rw-r--r--test/data/etag.php24
-rw-r--r--test/data/event/interactiveReady.html2
-rw-r--r--test/data/event/syncReady.html2
-rw-r--r--test/data/headers.php23
-rw-r--r--test/data/if_modified_since.php20
-rw-r--r--test/data/json.php13
-rw-r--r--test/data/jsonp.php14
-rw-r--r--test/data/longLoadScript.php4
-rw-r--r--test/data/mock.php244
-rw-r--r--test/data/name.php24
-rw-r--r--test/data/nocontent.php5
-rw-r--r--test/data/params_html.php12
-rw-r--r--test/data/qunit-fixture.html237
-rw-r--r--test/data/qunit-fixture.js4
-rw-r--r--test/data/script.php11
-rw-r--r--test/data/statusText.php5
-rw-r--r--test/data/support/csp-clean.php3
-rw-r--r--test/data/support/csp-log.php3
-rw-r--r--test/data/support/csp.php19
-rw-r--r--test/data/test.include.html (renamed from test/data/test.html)4
-rw-r--r--test/data/test.php7
-rw-r--r--test/data/testbar.php3
-rw-r--r--test/data/testinit.js37
-rw-r--r--test/data/text.txt (renamed from test/data/text.php)0
-rw-r--r--test/data/with_fries_over_jsonp.php7
-rw-r--r--test/index.html247
-rw-r--r--test/karma.context.html45
-rw-r--r--test/karma.debug.html47
-rw-r--r--test/middleware-mockserver.js284
-rw-r--r--test/unit/ajax.js350
-rw-r--r--test/unit/attributes.js4
-rw-r--r--test/unit/basic.js6
-rw-r--r--test/unit/core.js6
-rw-r--r--test/unit/css.js5
-rw-r--r--test/unit/data.js2
-rw-r--r--test/unit/effects.js2
-rw-r--r--test/unit/event.js5
-rw-r--r--test/unit/manipulation.js4
-rw-r--r--test/unit/offset.js6
-rw-r--r--test/unit/support.js6
-rw-r--r--test/unit/traversing.js10
60 files changed, 2566 insertions, 1859 deletions
diff --git a/.travis.yml b/.travis.yml
index aaae4185b..317c3a854 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,3 +5,5 @@ node_js:
- "6"
- "8"
- "9"
+addons:
+ chrome: stable
diff --git a/Gruntfile.js b/Gruntfile.js
index edcdb4f15..19e94fad7 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -147,6 +147,88 @@ module.exports = function( grunt ) {
"tween"
]
},
+ karma: {
+ options: {
+ customContextFile: "test/karma.context.html",
+ customDebugFile: "test/karma.debug.html",
+ frameworks: [ "qunit" ],
+ middleware: [ "mockserver" ],
+ plugins: [
+ "karma-*",
+ {
+ "middleware:mockserver": [
+ "factory",
+ require( "./test/middleware-mockserver.js" )
+ ]
+ }
+ ],
+ files: [
+ "test/data/jquery-1.9.1.js",
+ "external/qunit-assert-step/qunit-assert-step.js",
+ "external/sinon/sinon.js",
+ "external/npo/npo.js",
+ "external/requirejs/require.js",
+ "test/data/testinit.js",
+
+ "dist/jquery.min.js",
+
+ // Replacement for testinit.js#loadTests()
+ "test/data/testrunner.js",
+ "test/unit/basic.js",
+ "test/unit/core.js",
+ "test/unit/callbacks.js",
+ "test/unit/deferred.js",
+ "test/unit/deprecated.js",
+ "test/unit/support.js",
+ "test/unit/data.js",
+ "test/unit/queue.js",
+ "test/unit/attributes.js",
+ "test/unit/event.js",
+ "test/unit/selector.js",
+ "test/unit/traversing.js",
+ "test/unit/manipulation.js",
+ "test/unit/wrap.js",
+ "test/unit/css.js",
+ "test/unit/serialize.js",
+ "test/unit/ajax.js",
+ "test/unit/effects.js",
+ "test/unit/offset.js",
+ "test/unit/dimensions.js",
+ "test/unit/animation.js",
+ "test/unit/tween.js",
+ "test/unit/ready.js",
+
+ { pattern: "dist/jquery.js", included: false, served: true },
+ { pattern: "dist/*.map", included: false, served: true },
+ { pattern: "external/qunit/qunit.css", included: false, served: true },
+ {
+ pattern: "test/**/*.@(js|css|jpg|html|xml)",
+ included: false,
+ served: true
+ }
+ ],
+ reporters: [ "dots" ],
+ autoWatch: false,
+ concurrency: 3,
+ captureTimeout: 20 * 1000,
+
+ // To debug tests with Karma:
+ // - Run 'grunt karma:chrome' or 'grunt karma:firefox'
+ // (any karma subtask that has singleRun=false)
+ // - Press "Debug" in the opened browser window.
+ singleRun: false
+ },
+ main: {
+ browsers: [ "ChromeHeadless" ],
+ singleRun: true
+ },
+ chrome: {
+ browsers: [ "Chrome" ]
+ },
+ firefox: {
+ browsers: [ "Firefox" ]
+ }
+ },
watch: {
files: [ "<%= eslint.dev.src %>" ],
tasks: [ "dev" ]
@@ -222,6 +304,7 @@ module.exports = function( grunt ) {
"newer:uglify",
"remove_map_comment",
"dist:*",
+ "qunit_fixture",
"compare_size"
] );
@@ -231,6 +314,7 @@ module.exports = function( grunt ) {
"uglify",
"remove_map_comment",
"dist:*",
+ "qunit_fixture",
"eslint:dist",
"test:fast",
"compare_size"
diff --git a/README.md b/README.md
index 9e5b130c4..71ed006c1 100644
--- a/README.md
+++ b/README.md
@@ -323,20 +323,20 @@ fireNative( jQuery("#elem")[0], "click" );
### Add random number to url to stop caching ###
```js
-url( "some/url.php" );
+url( "some/url" );
```
Example:
```js
-url("data/test.html");
+url("index.html");
-=> "data/test.html?10538358428943"
+=> "data/index.html?10538358428943"
-url("data/test.php?foo=bar");
+url("mock.php?foo=bar");
-=> "data/test.php?foo=bar&10538358345554"
+=> "data/mock.php?foo=bar&10538358345554"
```
diff --git a/build/tasks/qunit_fixture.js b/build/tasks/qunit_fixture.js
new file mode 100644
index 000000000..ebf0b220c
--- /dev/null
+++ b/build/tasks/qunit_fixture.js
@@ -0,0 +1,22 @@
+var fs = require( "fs" );
+
+module.exports = function( grunt ) {
+ grunt.registerTask( "qunit_fixture", function() {
+ var dest = "./test/data/qunit-fixture.js";
+ fs.writeFileSync(
+ dest,
+ "// Generated by build/tasks/qunit_fixture.js\n" +
+ "QUnit.config.fixture = " +
+ JSON.stringify(
+ fs.readFileSync(
+ "./test/data/qunit-fixture.html",
+ "utf8"
+ ).toString()
+ ) +
+ ";\n" +
+ "// Compat with QUnit 1.x:\n" +
+ "document.getElementById( \"qunit-fixture\" ).innerHTML = QUnit.config.fixture;\n"
+ );
+ grunt.log.ok( "Updated " + dest + "." );
+ } );
+};
diff --git a/external/qunit/qunit.css b/external/qunit/qunit.css
index a59e2824c..ae68fc412 100644
--- a/external/qunit/qunit.css
+++ b/external/qunit/qunit.css
@@ -1,12 +1,12 @@
/*!
- * QUnit 1.20.0
- * http://qunitjs.com/
+ * QUnit 1.23.1
+ * https://qunitjs.com/
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license
- * http://jquery.org/license
+ * https://jquery.org/license
*
- * Date: 2015-10-27T17:53Z
+ * Date: 2016-04-12T17:29Z
*/
/** Font Family and Sizes */
@@ -120,6 +120,10 @@
display: list-item;
}
+#qunit-tests.hidepass {
+ position: relative;
+}
+
#qunit-tests.hidepass li.running,
#qunit-tests.hidepass li.pass {
visibility: hidden;
diff --git a/external/qunit/qunit.js b/external/qunit/qunit.js
index 904943f08..5df0822ea 100644
--- a/external/qunit/qunit.js
+++ b/external/qunit/qunit.js
@@ -1,15 +1,15 @@
/*!
- * QUnit 1.20.0
- * http://qunitjs.com/
+ * QUnit 1.23.1
+ * https://qunitjs.com/
*
* Copyright jQuery Foundation and other contributors
* Released under the MIT license
- * http://jquery.org/license
+ * https://jquery.org/license
*
- * Date: 2015-10-27T17:53Z
+ * Date: 2016-04-12T17:29Z
*/
-(function( global ) {
+( function( global ) {
var QUnit = {};
@@ -27,7 +27,7 @@ var window = global.window;
var defined = {
document: window && window.document !== undefined,
setTimeout: setTimeout !== undefined,
- sessionStorage: (function() {
+ sessionStorage: ( function() {
var x = "qunit-test-string";
try {
sessionStorage.setItem( x, x );
@@ -46,7 +46,7 @@ var runStarted = false;
var toString = Object.prototype.toString,
hasOwn = Object.prototype.hasOwnProperty;
-// returns a new Array with the elements that are in a but not in b
+// Returns a new Array with the elements that are in a but not in b
function diff( a, b ) {
var i, j,
result = a.slice();
@@ -63,7 +63,7 @@ function diff( a, b ) {
return result;
}
-// from jquery.js
+// From jquery.js
function inArray( elem, array ) {
if ( array.indexOf ) {
return array.indexOf( elem );
@@ -157,31 +157,6 @@ function is( type, obj ) {
return QUnit.objectType( obj ) === type;
}
-var getUrlParams = function() {
- var i, current;
- var urlParams = {};
- var location = window.location;
- var params = location.search.slice( 1 ).split( "&" );
- var length = params.length;
-
- if ( params[ 0 ] ) {
- for ( i = 0; i < length; i++ ) {
- current = params[ i ].split( "=" );
- current[ 0 ] = decodeURIComponent( current[ 0 ] );
-
- // allow just a key to turn on a flag, e.g., test.html?noglobals
- current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
- if ( urlParams[ current[ 0 ] ] ) {
- urlParams[ current[ 0 ] ] = [].concat( urlParams[ current[ 0 ] ], current[ 1 ] );
- } else {
- urlParams[ current[ 0 ] ] = current[ 1 ];
- }
- }
- }
-
- return urlParams;
-};
-
// Doesn't support IE6 to IE9, it will return undefined on these browsers
// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
function extractStacktrace( e, offset ) {
@@ -211,12 +186,12 @@ function extractStacktrace( e, offset ) {
// Support: Safari <=6 only
} else if ( e.sourceURL ) {
- // exclude useless self-reference for generated Error objects
+ // Exclude useless self-reference for generated Error objects
if ( /qunit.js$/.test( e.sourceURL ) ) {
return;
}
- // for actual exceptions, this is useful
+ // For actual exceptions, this is useful
return e.sourceURL + ":" + e.line;
}
}
@@ -243,53 +218,35 @@ function sourceFromStacktrace( offset ) {
* `config` initialized at top of scope
*/
var config = {
+
// The queue of tests to run
queue: [],
- // block until document ready
+ // Block until document ready
blocking: true,
- // by default, run previously failed tests first
+ // By default, run previously failed tests first
// very useful in combination with "Hide passed tests" checked
reorder: true,
- // by default, modify document.title when suite is done
+ // By default, modify document.title when suite is done
altertitle: true,
// HTML Reporter: collapse every test except the first failing test
// If false, all failing tests will be expanded
collapse: true,
- // by default, scroll to top of the page when suite is done
+ // By default, scroll to top of the page when suite is done
scrolltop: true,
- // depth up-to which object will be dumped
+ // Depth up-to which object will be dumped
maxDepth: 5,
- // when enabled, all tests must call expect()
+ // When enabled, all tests must call expect()
requireExpects: false,
- // add checkboxes that are persisted in the query-string
- // when enabled, the id is set to `true` as a `QUnit.config` property
- urlConfig: [
- {
- id: "hidepassed",
- label: "Hide passed tests",
- tooltip: "Only show tests and assertions that fail. Stored as query-strings."
- },
- {
- id: "noglobals",
- label: "Check for Globals",
- tooltip: "Enabling this will test if any test introduces new properties on the " +
- "global object (`window` in Browsers). Stored as query-strings."
- },
- {
- id: "notrycatch",
- label: "No try-catch",
- tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging " +
- "exceptions in IE reasonable. Stored as query-strings."
- }
- ],
+ // Placeholder for user-configurable form-exposed URL parameters
+ urlConfig: [],
// Set of all modules.
modules: [],
@@ -306,27 +263,9 @@ var config = {
callbacks: {}
};
-var urlParams = defined.document ? getUrlParams() : {};
-
// Push a loose unnamed module to the modules collection
config.modules.push( config.currentModule );
-if ( urlParams.filter === true ) {
- delete urlParams.filter;
-}
-
-// String search anywhere in moduleName+testName
-config.filter = urlParams.filter;
-
-config.testId = [];
-if ( urlParams.testId ) {
- // Ensure that urlParams.testId is an array
- urlParams.testId = decodeURIComponent( urlParams.testId ).split( "," );
- for (var i = 0; i < urlParams.testId.length; i++ ) {
- config.testId.push( urlParams.testId[ i ] );
- }
-}
-
var loggingCallbacks = {};
// Register logging callbacks
@@ -396,7 +335,7 @@ function verifyLoggingCallbacks() {
global.console.warn(
"QUnit." + loggingCallback + " was replaced with a new value.\n" +
"Please, check out the documentation on how to apply logging callbacks.\n" +
- "Reference: http://api.qunitjs.com/category/callbacks/"
+ "Reference: https://api.qunitjs.com/category/callbacks/"
);
}
}
@@ -430,7 +369,7 @@ function verifyLoggingCallbacks() {
}
QUnit.pushFailure( error, filePath + ":" + linerNr );
} else {
- QUnit.test( "global failure", extend(function() {
+ QUnit.test( "global failure", extend( function() {
QUnit.pushFailure( error, filePath + ":" + linerNr );
}, { validTest: true } ) );
}
@@ -439,25 +378,23 @@ function verifyLoggingCallbacks() {
return ret;
};
-} )();
-
-QUnit.urlParams = urlParams;
+}() );
// Figure out if we're running the tests from a server or not
QUnit.isLocal = !( defined.document && window.location.protocol !== "file:" );
// Expose the current QUnit version
-QUnit.version = "1.20.0";
+QUnit.version = "1.23.1";
extend( QUnit, {
- // call on start of module test to prepend name to all tests
+ // Call on start of module test to prepend name to all tests
module: function( name, testEnvironment, executeNow ) {
var module, moduleFns;
var currentModule = config.currentModule;
if ( arguments.length === 2 ) {
- if ( testEnvironment instanceof Function ) {
+ if ( objectType( testEnvironment ) === "function" ) {
executeNow = testEnvironment;
testEnvironment = undefined;
}
@@ -481,7 +418,7 @@ extend( QUnit, {
afterEach: setHook( module, "afterEach" )
};
- if ( executeNow instanceof Function ) {
+ if ( objectType( executeNow ) === "function" ) {
config.moduleStack.push( module );
setCurrentModule( module );
executeNow.call( module.testEnvironment, moduleFns );
@@ -499,7 +436,8 @@ extend( QUnit, {
var module = {
name: moduleName,
parentModule: parentModule,
- tests: []
+ tests: [],
+ moduleId: generateHash( moduleName )
};
var env = {};
@@ -572,7 +510,7 @@ extend( QUnit, {
return;
}
- // throw an Error if start is called more often than stop
+ // Throw an Error if start is called more often than stop
if ( config.current.semaphore < 0 ) {
config.current.semaphore = 0;
@@ -633,7 +571,7 @@ extend( QUnit, {
offset = ( offset || 0 ) + 2;
return sourceFromStacktrace( offset );
}
-});
+} );
registerLoggingCallbacks( QUnit );
@@ -656,17 +594,17 @@ function begin() {
// Avoid unnecessary information by not logging modules' test environments
for ( i = 0, l = config.modules.length; i < l; i++ ) {
- modulesLog.push({
+ modulesLog.push( {
name: config.modules[ i ].name,
tests: config.modules[ i ].tests
- });
+ } );
}
// The test run is officially beginning now
runLoggingCallbacks( "begin", {
totalTests: Test.count,
modules: modulesLog
- });
+ } );
}
config.blocking = false;
@@ -705,7 +643,7 @@ function pauseProcessing() {
if ( config.testTimeout && defined.setTimeout ) {
clearTimeout( config.timeout );
- config.timeout = setTimeout(function() {
+ config.timeout = setTimeout( function() {
if ( config.current ) {
config.current.semaphore = 0;
QUnit.pushFailure( "Test timed out", sourceFromStacktrace( 2 ) );
@@ -722,7 +660,7 @@ function resumeProcessing() {
// A slight delay to allow this iteration of the event loop to finish (more assertions, etc.)
if ( defined.setTimeout ) {
- setTimeout(function() {
+ setTimeout( function() {
if ( config.current && config.current.semaphore > 0 ) {
return;
}
@@ -751,7 +689,7 @@ function done() {
passed: config.moduleStats.all - config.moduleStats.bad,
total: config.moduleStats.all,
runtime: now() - config.moduleStats.started
- });
+ } );
}
delete config.previousModule;
@@ -763,7 +701,7 @@ function done() {
passed: passed,
total: config.stats.all,
runtime: runtime
- });
+ } );
}
function setHook( module, hookName ) {
@@ -777,6 +715,8 @@ function setHook( module, hookName ) {
}
var focused = false;
+var priorityCount = 0;
+var unitSampler;
function Test( settings ) {
var i, l;
@@ -799,10 +739,10 @@ function Test( settings ) {
this.testId = generateHash( this.module.name, this.testName );
- this.module.tests.push({
+ this.module.tests.push( {
name: this.testName,
testId: this.testId
- });
+ } );
if ( settings.skip ) {
@@ -838,14 +778,14 @@ Test.prototype = {
passed: config.moduleStats.all - config.moduleStats.bad,
total: config.moduleStats.all,
runtime: now() - config.moduleStats.started
- });
+ } );
}
config.previousModule = this.module;
config.moduleStats = { all: 0, bad: 0, started: now() };
runLoggingCallbacks( "moduleStart", {
name: this.module.name,
tests: this.module.tests
- });
+ } );
}
config.current = this;
@@ -861,7 +801,7 @@ Test.prototype = {
name: this.testName,
module: this.module.name,
testId: this.testId
- });
+ } );
if ( !config.pollution ) {
saveGlobal();
@@ -890,7 +830,7 @@ Test.prototype = {
this.pushFailure( "Died on test #" + ( this.assertions.length + 1 ) + " " +
this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) );
- // else next test will carry the responsibility
+ // Else next test will carry the responsibility
saveGlobal();
// Restart the tests if they're blocking
@@ -999,7 +939,7 @@ Test.prototype = {
// DEPRECATED: this property will be removed in 2.0.0, use runtime instead
duration: this.runtime
- });
+ } );
// QUnit.reset() is deprecated and will be replaced for a new
// fixture reset function on QUnit 2.0/2.1.
@@ -1019,8 +959,8 @@ Test.prototype = {
function run() {
- // each of these can by async
- synchronize([
+ // Each of these can by async
+ synchronize( [
function() {
test.before();
},
@@ -1038,31 +978,33 @@ Test.prototype = {
function() {
test.finish();
}
- ]);
+ ] );
}
// Prioritize previously failed tests, detected from sessionStorage
priority = QUnit.config.reorder && defined.sessionStorage &&
+sessionStorage.getItem( "qunit-test-" + this.module.name + "-" + this.testName );
- return synchronize( run, priority );
+ return synchronize( run, priority, config.seed );
},
- push: function( result, actual, expected, message, negative ) {
+ pushResult: function( resultInfo ) {
+
+ // Destructure of resultInfo = { result, actual, expected, message, negative }
var source,
details = {
module: this.module.name,
name: this.testName,
- result: result,
- message: message,
- actual: actual,
- expected: expected,
+ result: resultInfo.result,
+ message: resultInfo.message,
+ actual: resultInfo.actual,
+ expected: resultInfo.expected,
testId: this.testId,
- negative: negative || false,
+ negative: resultInfo.negative || false,
runtime: now() - this.started
};
- if ( !result ) {
+ if ( !resultInfo.result ) {
source = sourceFromStacktrace();
if ( source ) {
@@ -1072,10 +1014,10 @@ Test.prototype = {
runLoggingCallbacks( "log", details );
- this.assertions.push({
- result: !!result,
- message: message
- });
+ this.assertions.push( {
+ result: !!resultInfo.result,
+ message: resultInfo.message
+ } );
},
pushFailure: function( message, source, actual ) {
@@ -1100,10 +1042,10 @@ Test.prototype = {
runLoggingCallbacks( "log", details );
- this.assertions.push({
+ this.assertions.push( {
result: false,
message: message
- });
+ } );
},
resolvePromise: function( promise, phase ) {
@@ -1122,7 +1064,7 @@ Test.prototype = {
" " + test.testName + ": " + ( error.message || error );
test.pushFailure( message, extractStacktrace( error, 0 ) );
- // else next test will carry the responsibility
+ // Else next test will carry the responsibility
saveGlobal();
// Unblock
@@ -1134,32 +1076,45 @@ Test.prototype = {
},
valid: function() {
- var include,
- filter = config.filter && config.filter.toLowerCase(),
- module = QUnit.urlParams.module && QUnit.urlParams.module.toLowerCase(),
- fullName = ( this.module.name + ": " + this.testName ).toLowerCase();
+ var filter = config.filter,
+ regexFilter = /^(!?)\/([\w\W]*)\/(i?$)/.exec( filter ),
+ module = config.module && config.module.toLowerCase(),
+ fullName = ( this.module.name + ": " + this.testName );
- function testInModuleChain( testModule ) {
+ function moduleChainNameMatch( testModule ) {
var testModuleName = testModule.name ? testModule.name.toLowerCase() : null;
if ( testModuleName === module ) {
return true;
} else if ( testModule.parentModule ) {
- return testInModuleChain( testModule.parentModule );
+ return moduleChainNameMatch( testModule.parentModule );
} else {
return false;
}
}
+ function moduleChainIdMatch( testModule ) {
+ return inArray( testModule.moduleId, config.moduleId ) > -1 ||
+ testModule.parentModule && moduleChainIdMatch( testModule.parentModule );
+ }
+
// Internally-generated tests are always valid
if ( this.callback && this.callback.validTest ) {
return true;
}
- if ( config.testId.length > 0 && inArray( this.testId, config.testId ) < 0 ) {
+ if ( config.moduleId && config.moduleId.length > 0 &&
+ !moduleChainIdMatch( this.module ) ) {
+
+ return false;
+ }
+
+ if ( config.testId && config.testId.length > 0 &&
+ inArray( this.testId, config.testId ) < 0 ) {
+
return false;
}
- if ( module && !testInModuleChain( this.module ) ) {
+ if ( module && !moduleChainNameMatch( this.module ) ) {
return false;
}
@@ -1167,7 +1122,23 @@ Test.prototype = {
return true;
}
- include = filter.charAt( 0 ) !== "!";
+ return regexFilter ?
+ this.regexFilter( !!regexFilter[ 1 ], regexFilter[ 2 ], regexFilter[ 3 ], fullName ) :
+ this.stringFilter( filter, fullName );
+ },
+
+ regexFilter: function( exclude, pattern, flags, fullName ) {
+ var regex = new RegExp( pattern, flags );
+ var match = regex.test( fullName );
+
+ return match !== exclude;
+ },
+
+ stringFilter: function( filter, fullName ) {
+ filter = filter.toLowerCase();
+ fullName = fullName.toLowerCase();
+
+ var include = filter.charAt( 0 ) !== "!";
if ( !include ) {
filter = filter.slice( 1 );
}
@@ -1240,8 +1211,9 @@ function generateHash( module, testName ) {
return hex.slice( -8 );
}
-function synchronize( callback, priority ) {
- var last = !priority;
+function synchronize( callback, priority, seed ) {
+ var last = !priority,
+ index;
if ( QUnit.objectType( callback ) === "array" ) {
while ( callback.length ) {
@@ -1251,7 +1223,15 @@ function synchronize( callback, priority ) {
}
if ( priority ) {
- priorityFill( callback );
+ config.queue.splice( priorityCount++, 0, callback );
+ } else if ( seed ) {
+ if ( !unitSampler ) {
+ unitSampler = unitSamplerGenerator( seed );
+ }
+
+ // Insert into a random position after all priority items
+ index = Math.floor( unitSampler() * ( config.queue.length - priorityCount + 1 ) );
+ config.queue.splice( priorityCount + index, 0, callback );
} else {
config.queue.push( callback );
}
@@ -1261,21 +1241,24 @@ function synchronize( callback, priority ) {
}
}
-// Place previously failed tests on a queue priority line, respecting the order they get assigned.
-function priorityFill( callback ) {
- var queue, prioritizedQueue;
-
- queue = config.queue.slice( priorityFill.pos );
- prioritizedQueue = config.queue.slice( 0, -config.queue.length + priorityFill.pos );
+function unitSamplerGenerator( seed ) {
- queue.unshift( callback );
- queue.unshift.apply( queue, prioritizedQueue );
+ // 32-bit xorshift, requires only a nonzero seed
+ // http://excamera.com/sphinx/article-xorshift.html
+ var sample = parseInt( generateHash( seed ), 16 ) || -1;
+ return function() {
+ sample ^= sample << 13;
+ sample ^= sample >>> 17;
+ sample ^= sample << 5;
- config.queue = queue;
+ // ECMAScript has no unsigned number type
+ if ( sample < 0 ) {
+ sample += 0x100000000;
+ }
- priorityFill.pos += 1;
+ return sample / 0x100000000;
+ };
}
-priorityFill.pos = 0;
function saveGlobal() {
config.pollution = [];
@@ -1284,7 +1267,7 @@ function saveGlobal() {
for ( var key in global ) {
if ( hasOwn.call( global, key ) ) {
- // in Opera sometimes DOM element ids show up here, ignore them
+ // In Opera sometimes DOM element ids show up here, ignore them
if ( /^qunit-test-output/.test( key ) ) {
continue;
}
@@ -1333,12 +1316,12 @@ function test( testName, expected, callback, async ) {
expected = null;
}
- newTest = new Test({
+ newTest = new Test( {
testName: testName,
expected: expected,
async: async,
callback: callback
- });
+ } );
newTest.queue();
}
@@ -1347,10 +1330,10 @@ function test( testName, expected, callback, async ) {
function skip( testName ) {
if ( focused ) { return; }
- var test = new Test({
+ var test = new Test( {
testName: testName,
skip: true
- });
+ } );
test.queue();
}
@@ -1369,12 +1352,12 @@ function only( testName, expected, callback, async ) {
expected = null;
}
- newTest = new Test({
+ newTest = new Test( {
testName: testName,
expected: expected,
async: async,
callback: callback
- });
+ } );
newTest.queue();
}
@@ -1430,7 +1413,21 @@ QUnit.assert = Assert.prototype = {
},
// Exports test.push() to the user API
- push: function( /* result, actual, expected, message, negative */ ) {
+ // Alias of pushResult.
+ push: function( result, actual, expected, message, negative ) {
+ var currentAssert = this instanceof Assert ? this : QUnit.config.current.assert;
+ return currentAssert.pushResult( {
+ result: result,
+ actual: actual,
+ expected: expected,
+ message: message,
+ negative: negative
+ } );
+ },
+
+ pushResult: function( resultInfo ) {
+
+ // Destructure of resultInfo = { result, actual, expected, message, negative }
var assert = this,
currentTest = ( assert instanceof Assert && assert.test ) || QUnit.config.current;
@@ -1453,57 +1450,112 @@ QUnit.assert = Assert.prototype = {
if ( !( assert instanceof Assert ) ) {
assert = currentTest.assert;
}
- return assert.test.push.apply( assert.test, arguments );
+
+ return assert.test.pushResult( resultInfo );
},
ok: function( result, message ) {
message = message || ( result ? "okay" : "failed, expected argument to be truthy, was: " +
QUnit.dump.parse( result ) );
- this.push( !!result, result, true, message );
+ this.pushResult( {
+ result: !!result,
+ actual: result,
+ expected: true,
+ message: message
+ } );
},
notOk: function( result, message ) {
message = message || ( !result ? "okay" : "failed, expected argument to be falsy, was: " +
QUnit.dump.parse( result ) );
- this.push( !result, result, false, message, true );
+ this.pushResult( {
+ result: !result,
+ actual: result,
+ expected: false,
+ message: message
+ } );
},
equal: function( actual, expected, message ) {
/*jshint eqeqeq:false */
- this.push( expected == actual, actual, expected, message );
+ this.pushResult( {
+ result: expected == actual,
+ actual: actual,
+ expected: expected,
+ message: message
+ } );
},
notEqual: function( actual, expected, message ) {
/*jshint eqeqeq:false */
- this.push( expected != actual, actual, expected, message, true );
+ this.pushResult( {
+ result: expected != actual,
+ actual: actual,
+ expected: expected,
+ message: message,
+ negative: true
+ } );
},
propEqual: function( actual, expected, message ) {
actual = objectValues( actual );
expected = objectValues( expected );
- this.push( QUnit.equiv( actual, expected ), actual, expected, message );
+ this.pushResult( {
+ result: QUnit.equiv( actual, expected ),
+ actual: actual,
+ expected: expected,
+ message: message
+ } );
},
notPropEqual: function( actual, expected, message ) {
actual = objectValues( actual );
expected = objectValues( expected );
- this.push( !QUnit.equiv( actual, expected ), actual, expected, message, true );
+ this.pushResult( {
+ result: !QUnit.equiv( actual, expected ),
+ actual: actual,
+ expected: expected,
+ message: message,
+ negative: true
+ } );
},
deepEqual: function( actual, expected, message ) {
- this.push( QUnit.equiv( actual, expected ), actual, expected, message );
+ this.pushResult( {
+ result: QUnit.equiv( actual, expected ),
+ actual: actual,
+ expected: expected,
+ message: message
+ } );
},
notDeepEqual: function( actual, expected, message ) {
- this.push( !QUnit.equiv( actual, expected ), actual, expected, message, true );
+ this.pushResult( {
+ result: !QUnit.equiv( actual, expected ),
+ actual: actual,
+ expected: expected,
+ message: message,
+ negative: true
+ } );
},
strictEqual: function( actual, expected, message ) {
- this.push( expected === actual, actual, expected, message );
+ this.pushResult( {
+ result: expected === actual,
+ actual: actual,
+ expected: expected,
+ message: message
+ } );
},
notStrictEqual: function( actual, expected, message ) {
- this.push( expected !== actual, actual, expected, message, true );
+ this.pushResult( {
+ result: expected !== actual,
+ actual: actual,
+ expected: expected,
+ message: message,
+ negative: true
+ } );
},
"throws": function( block, expected, message ) {
@@ -1521,7 +1573,7 @@ QUnit.assert = Assert.prototype = {
currentTest.ignoreGlobalErrors = true;
try {
block.call( currentTest.testEnvironment );
- } catch (e) {
+ } catch ( e ) {
actual = e;
}
currentTest.ignoreGlobalErrors = false;
@@ -1529,46 +1581,51 @@ QUnit.assert = Assert.prototype = {
if ( actual ) {
expectedType = QUnit.objectType( expected );
- // we don't want to validate thrown error
+ // We don't want to validate thrown error
if ( !expected ) {
ok = true;
expectedOutput = null;
- // expected is a regexp
+ // Expected is a regexp
} else if ( expectedType === "regexp" ) {
ok = expected.test( errorString( actual ) );
- // expected is a string
+ // Expected is a string
} else if ( expectedType === "string" ) {
ok = expected === errorString( actual );
- // expected is a constructor, maybe an Error constructor
+ // Expected is a constructor, maybe an Error constructor
} else if ( expectedType === "function" && actual instanceof expected ) {
ok = true;
- // expected is an Error object
+ // Expected is an Error object
} else if ( expectedType === "object" ) {
ok = actual instanceof expected.constructor &&
actual.name === expected.name &&
actual.message === expected.message;
- // expected is a validation function which returns true if validation passed
+ // Expected is a validation function which returns true if validation passed
} else if ( expectedType === "function" && expected.call( {}, actual ) === true ) {
expectedOutput = null;
ok = true;
}
}
- currentTest.assert.push( ok, actual, expectedOutput, message );
+ currentTest.assert.pushResult( {
+ result: ok,
+ actual: actual,
+ expected: expectedOutput,
+ message: message
+ } );
}
};
// Provide an alternative to assert.throws(), for environments that consider throws a reserved word
// Known to us are: Closure Compiler, Narwhal
-(function() {
+( function() {
/*jshint sub:true */
- Assert.prototype.raises = Assert.prototype[ "throws" ];
-}());
+ Assert.prototype.raises = Assert.prototype [ "throws" ]; //jscs:ignore requireDotNotation
+}() );
function errorString( error ) {
var name, message,
@@ -1592,7 +1649,7 @@ function errorString( error ) {
// Test for equality any JavaScript type.
// Author: Philippe Rathé <prathe@gmail.com>
-QUnit.equiv = (function() {
+QUnit.equiv = ( function() {
// Stack to decide between skip/abort functions
var callers = [];
@@ -1601,26 +1658,28 @@ QUnit.equiv = (function() {
var parents = [];
var parentsB = [];
- function useStrictEquality( b, a ) {
+ var getProto = Object.getPrototypeOf || function( obj ) {
- /*jshint eqeqeq:false */
- if ( b instanceof a.constructor || a instanceof b.constructor ) {
+ /*jshint proto: true */
+ return obj.__proto__;
+ };
- // To catch short annotation VS 'new' annotation of a declaration. e.g.:
- // `var i = 1;`
- // `var j = new Number(1);`
- return a == b;
- } else {
- return a === b;
+ function useStrictEquality( b, a ) {
+
+ // To catch short annotation VS 'new' annotation of a declaration. e.g.:
+ // `var i = 1;`
+ // `var j = new Number(1);`
+ if ( typeof a === "object" ) {
+ a = a.valueOf();
+ }
+ if ( typeof b === "object" ) {
+ b = b.valueOf();
}
+
+ return a === b;
}
function compareConstructors( a, b ) {
- var getProto = Object.getPrototypeOf || function( obj ) {
-
- /*jshint proto: true */
- return obj.__proto__;
- };
var protoA = getProto( a );
var protoB = getProto( b );
@@ -1649,6 +1708,10 @@ QUnit.equiv = (function() {
return false;
}
+ function getRegExpFlags( regexp ) {
+ return "flags" in regexp ? regexp.flags : regexp.toString().match( /[gimuy]*$/ )[ 0 ];
+ }
+
var callbacks = {
"string": useStrictEquality,
"boolean": useStrictEquality,
@@ -1656,28 +1719,17 @@ QUnit.equiv = (function() {
"null": useStrictEquality,
"undefined": useStrictEquality,
"symbol": useStrictEquality,
+ "date": useStrictEquality,
- "nan": function( b ) {
- return isNaN( b );
- },
-
- "date": function( b, a ) {
- return QUnit.objectType( b ) === "date" && a.valueOf() === b.valueOf();
+ "nan": function() {
+ return true;
},
"regexp": function( b, a ) {
- return QUnit.objectType( b ) === "regexp" &&
-
- // The regex itself
- a.source === b.source &&
-
- // And its modifiers
- a.global === b.global &&
+ return a.source === b.source &&
- // (gmi) ...
- a.ignoreCase === b.ignoreCase &&
- a.multiline === b.multiline &&
- a.sticky === b.sticky;
+ // Include flags in the comparison
+ getRegExpFlags( a ) === getRegExpFlags( b );
},
// - skip when the property is a method of an instance (OOP)
@@ -1691,14 +1743,10 @@ QUnit.equiv = (function() {
"array": function( b, a ) {
var i, j, len, loop, aCircular, bCircular;
- // b could be an object literal here
- if ( QUnit.objectType( b ) !== "array" ) {
- return false;
- }
-
len = a.length;
if ( len !== b.length ) {
- // safe and faster
+
+ // Safe and faster
return false;
}
@@ -1732,43 +1780,53 @@ QUnit.equiv = (function() {
},
"set": function( b, a ) {
- var aArray, bArray;
+ var innerEq,
+ outerEq = true;
- // `b` could be any object here
- if ( QUnit.objectType( b ) !== "set" ) {
+ if ( a.size !== b.size ) {
return false;
}
- aArray = [];
- a.forEach( function( v ) {
- aArray.push( v );
- });
- bArray = [];
- b.forEach( function( v ) {
- bArray.push( v );
- });
+ a.forEach( function( aVal ) {
+ innerEq = false;
+
+ b.forEach( function( bVal ) {
+ if ( innerEquiv( bVal, aVal ) ) {
+ innerEq = true;
+ }
+ } );
+
+ if ( !innerEq ) {
+ outerEq = false;
+ }
+ } );
- return innerEquiv( bArray, aArray );
+ return outerEq;
},
"map": function( b, a ) {
- var aArray, bArray;
+ var innerEq,
+ outerEq = true;
- // `b` could be any object here
- if ( QUnit.objectType( b ) !== "map" ) {
+ if ( a.size !== b.size ) {
return false;
}
- aArray = [];
- a.forEach( function( v, k ) {
- aArray.push( [ k, v ] );
- });
- bArray = [];
- b.forEach( function( v, k ) {
- bArray.push( [ k, v ] );
- });
+ a.forEach( function( aVal, aKey ) {
+ innerEq = false;
+
+ b.forEach( function( bVal, bKey ) {
+ if ( innerEquiv( [ bVal, bKey ], [ aVal, aKey ] ) ) {
+ innerEq = true;
+ }
+ } );
- return innerEquiv( bArray, aArray );
+ if ( !innerEq ) {
+ outerEq = false;
+ }
+ } );
+
+ return outerEq;
},
"object": function( b, a ) {
@@ -1830,45 +1888,31 @@ QUnit.equiv = (function() {
};
function typeEquiv( a, b ) {
- var prop = QUnit.objectType( a );
- return callbacks[ prop ]( b, a );
+ var type = QUnit.objectType( a );
+ return QUnit.objectType( b ) === type && callbacks[ type ]( b, a );
}
// The real equiv function
- function innerEquiv() {
- var args = [].slice.apply( arguments );
- if ( args.length < 2 ) {
+ function innerEquiv( a, b ) {
- // End transition
+ // We're done when there's nothing more to compare
+ if ( arguments.length < 2 ) {
return true;
}
- return ( (function( a, b ) {
- if ( a === b ) {
+ // Require type-specific equality
+ return ( a === b || typeEquiv( a, b ) ) &&
- // Catch the most you can
- return true;
- } else if ( a === null || b === null || typeof a === "undefined" ||
- typeof b === "undefined" ||
- QUnit.objectType( a ) !== QUnit.objectType( b ) ) {
-
- // Don't lose time with error prone cases
- return false;
- } else {
- return typeEquiv( a, b );
- }
-
- // Apply transition with (1..n) arguments
- }( args[ 0 ], args[ 1 ] ) ) &&
- innerEquiv.apply( this, args.splice( 1, args.length - 1 ) ) );
+ // ...across all consecutive argument pairs
+ ( arguments.length === 2 || innerEquiv.apply( this, [].slice.call( arguments, 1 ) ) );
}
return innerEquiv;
-}());
+}() );
// Based on jsDump by Ariel Flesler
// http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html
-QUnit.dump = (function() {
+QUnit.dump = ( function() {
function quote( str ) {
return "\"" + str.toString().replace( /\\/g, "\\\\" ).replace( /"/g, "\\\"" ) + "\"";
}
@@ -1906,7 +1950,7 @@ QUnit.dump = (function() {
var reName = /^function (\w+)/,
dump = {
- // objType is used mostly internally, you can fix a (custom) type in advance
+ // The objType is used mostly internally, you can fix a (custom) type in advance
parse: function( obj, objType, stack ) {
stack = stack || [];
var res, parser, parserType,
@@ -1950,7 +1994,7 @@ QUnit.dump = (function() {
type = "node";
} else if (
- // native arrays
+ // Native arrays
toString.call( obj ) === "[object Array]" ||
// NodeList objects
@@ -1966,10 +2010,12 @@ QUnit.dump = (function() {
}
return type;
},
+
separator: function() {
return this.multiline ? this.HTML ? "<br />" : "\n" : this.HTML ? "&#160;" : " ";
},
- // extra can be a number, shortcut for increasing-calling-decreasing
+
+ // Extra can be a number, shortcut for increasing-calling-decreasing
indent: function( extra ) {
if ( !this.multiline ) {
return "";
@@ -1989,11 +2035,11 @@ QUnit.dump = (function() {
setParser: function( name, parser ) {
this.parsers[ name ] = parser;
},
+
// The next 3 are exposed so you can use them
quote: quote,
literal: literal,
join: join,
- //
depth: 1,
maxDepth: QUnit.config.maxDepth,
@@ -2010,13 +2056,13 @@ QUnit.dump = (function() {
"function": function( fn ) {
var ret = "function",
- // functions never have name in IE
+ // Functions never have name in IE
name = "name" in fn ? fn.name : ( reName.exec( fn ) || [] )[ 1 ];
if ( name ) {
ret += " " + name;
}
- ret += "( ";
+ ret += "(";
ret = [ ret, dump.parse( fn, "functionArgs" ), "){" ].join( "" );
return join( ret, dump.parse( fn, "functionCode" ), "}" );
@@ -2087,7 +2133,7 @@ QUnit.dump = (function() {
return ret + open + "/" + tag + close;
},
- // function calls it internally, it's the arguments part of the function
+ // Function calls it internally, it's the arguments part of the function
functionArgs: function( fn ) {
var args,
l = fn.length;
@@ -2104,11 +2150,14 @@ QUnit.dump = (function() {
}
return " " + args.join( ", " ) + " ";
},
- // object calls it internally, the key part of an item in a map
+
+ // Object calls it internally, the key part of an item in a map
key: quote,
- // function calls it internally, it's the content of the function
+
+ // Function calls it internally, it's the content of the function
functionCode: "[code]",
- // node calls it internally, it's an html attribute value
+
+ // Node calls it internally, it's a html attribute value
attribute: quote,
string: quote,
date: quote,
@@ -2116,42 +2165,45 @@ QUnit.dump = (function() {
number: literal,
"boolean": literal
},
- // if true, entities are escaped ( <, >, \t, space and \n )
+
+ // If true, entities are escaped ( <, >, \t, space and \n )
HTML: false,
- // indentation unit
+
+ // Indentation unit
indentChar: " ",
- // if true, items in a collection, are separated by a \n, else just a space.
+
+ // If true, items in a collection, are separated by a \n, else just a space.
multiline: true
};
return dump;
-}());
+}() );
-// back compat
+// Back compat
QUnit.jsDump = QUnit.dump;
-// For browser, export only select globals
-if ( defined.document ) {
+// Deprecated
+// Extend assert methods to QUnit for Backwards compatibility
+( function() {
+ var i,
+ assertions = Assert.prototype;
- // Deprecated
- // Extend assert methods to QUnit and Global scope through Backwards compatibility
- (function() {
- var i,
- assertions = Assert.prototype;
+ function applyCurrent( current ) {
+ return function() {
+ var assert = new Assert( QUnit.config.current );
+ current.apply( assert, arguments );
+ };
+ }
- function applyCurrent( current ) {
- return function() {
- var assert = new Assert( QUnit.config.current );
- current.apply( assert, arguments );
- };
- }
+ for ( i in assertions ) {
+ QUnit[ i ] = applyCurrent( assertions[ i ] );
+ }
+}() );
- for ( i in assertions ) {
- QUnit[ i ] = applyCurrent( assertions[ i ] );
- }
- })();
+// For browser, export only select globals
+if ( defined.document ) {
- (function() {
+ ( function() {
var i, l,
keys = [
"test",
@@ -2177,7 +2229,7 @@ if ( defined.document ) {
for ( i = 0, l = keys.length; i < l; i++ ) {
window[ keys[ i ] ] = QUnit[ keys[ i ] ];
}
- })();
+ }() );
window.QUnit = QUnit;
}
@@ -2202,6 +2254,916 @@ if ( typeof define === "function" && define.amd ) {
QUnit.config.autostart = false;
}
+// Get a reference to the global object, like window in browsers
+}( ( function() {
+ return this;
+}() ) ) );
+
+( function() {
+
+// Only interact with URLs via window.location
+var location = typeof window !== "undefined" && window.location;
+if ( !location ) {
+ return;
+}
+
+var urlParams = getUrlParams();
+
+QUnit.urlParams = urlParams;
+
+// Match module/test by inclusion in an array
+QUnit.config.moduleId = [].concat( urlParams.moduleId || [] );
+QUnit.config.testId = [].concat( urlParams.testId || [] );
+
+// Exact case-insensitive match of the module name
+QUnit.config.module = urlParams.module;
+
+// Regular expression or case-insenstive substring match against "moduleName: testName"
+QUnit.config.filter = urlParams.filter;
+
+// Test order randomization
+if ( urlParams.seed === true ) {
+
+ // Generate a random seed if the option is specified without a value
+ QUnit.config.seed = Math.random().toString( 36 ).slice( 2 );
+} else if ( urlParams.seed ) {
+ QUnit.config.seed = urlParams.seed;
+}
+
+// Add URL-parameter-mapped config values with UI form rendering data
+QUnit.config.urlConfig.push(
+ {
+ id: "hidepassed",
+ label: "Hide passed tests",
+ tooltip: "Only show tests and assertions that fail. Stored as query-strings."
+ },
+ {
+ id: "noglobals",
+ label: "Check for Globals",
+ tooltip: "Enabling this will test if any test introduces new properties on the " +
+ "global object (`window` in Browsers). Stored as query-strings."
+ },
+ {
+ id: "notrycatch",
+ label: "No try-catch",
+ tooltip: "Enabling this will run tests outside of a try-catch block. Makes debugging " +
+ "exceptions in IE reasonable. Stored as query-strings."
+ }
+);
+
+QUnit.begin( function() {
+ var i, option,
+ urlConfig = QUnit.config.urlConfig;
+
+ for ( i = 0; i < urlConfig.length; i++ ) {
+
+ // Options can be either strings or objects with nonempty "id" properties
+ option = QUnit.config.urlConfig[ i ];
+ if ( typeof option !== "string" ) {
+ option = option.id;
+ }
+
+ if ( QUnit.config[ option ] === undefined ) {
+ QUnit.config[ option ] = urlParams[ option ];
+ }
+ }
+} );
+
+function getUrlParams() {
+ var i, param, name, value;
+ var urlParams = {};
+ var params = location.search.slice( 1 ).split( "&" );
+ var length = params.length;
+
+ for ( i = 0; i < length; i++ ) {
+ if ( params[ i ] ) {
+ param = params[ i ].split( "=" );
+ name = decodeURIComponent( param[ 0 ] );
+
+ // Allow just a key to turn on a flag, e.g., test.html?noglobals
+ value = param.length === 1 ||
+ decodeURIComponent( param.slice( 1 ).join( "=" ) ) ;
+ if ( urlParams[ name ] ) {
+ urlParams[ name ] = [].concat( urlParams[ name ], value );
+ } else {
+ urlParams[ name ] = value;
+ }
+ }
+ }
+
+ return urlParams;
+}
+
+// Don't load the HTML Reporter on non-browser environments
+if ( typeof window === "undefined" || !window.document ) {
+ return;
+}
+
+// Deprecated QUnit.init - Ref #530
+// Re-initialize the configuration options
+QUnit.init = function() {
+ var config = QUnit.config;
+
+ config.stats = { all: 0, bad: 0 };
+ config.moduleStats = { all: 0, bad: 0 };
+ config.started = 0;
+ config.updateRate = 1000;
+ config.blocking = false;
+ config.autostart = true;
+ config.autorun = false;
+ config.filter = "";
+ config.queue = [];
+
+ appendInterface();
+};
+
+var config = QUnit.config,
+ document = window.document,
+ collapseNext = false,
+ hasOwn = Object.prototype.hasOwnProperty,
+ unfilteredUrl = setUrl( { filter: undefined, module: undefined,
+ moduleId: undefined, testId: undefined } ),
+ defined = {
+ sessionStorage: ( function() {
+ var x = "qunit-test-string";
+ try {
+ sessionStorage.setItem( x, x );
+ sessionStorage.removeItem( x );
+ return true;
+ } catch ( e ) {
+ return false;
+ }
+ }() )
+ },
+ modulesList = [];
+
+/**
+* Escape text for attribute or text content.
+*/
+function escapeText( s ) {
+ if ( !s ) {
+ return "";
+ }
+ s = s + "";
+
+ // Both single quotes and double quotes (for attributes)
+ return s.replace( /['"<>&]/g, function( s ) {
+ switch ( s ) {
+ case "'":
+ return "&#039;";
+ case "\"":
+ return "&quot;";
+ case "<":
+ return "&lt;";
+ case ">":
+ return "&gt;";
+ case "&":
+ return "&amp;";
+ }
+ } );
+}
+
+/**
+ * @param {HTMLElement} elem
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvent( elem, type, fn ) {
+ if ( elem.addEventListener ) {
+
+ // Standards-based browsers
+ elem.addEventListener( type, fn, false );
+ } else if ( elem.attachEvent ) {
+
+ // Support: IE <9
+ elem.attachEvent( "on" + type, function() {
+ var event = window.event;
+ if ( !event.target ) {
+ event.target = event.srcElement || document;
+ }
+
+ fn.call( elem, event );
+ } );
+ }
+}
+
+/**
+ * @param {Array|NodeList} elems
+ * @param {string} type
+ * @param {Function} fn
+ */
+function addEvents( elems, type, fn ) {
+ var i = elems.length;
+ while ( i-- ) {
+ addEvent( elems[ i ], type, fn );
+ }
+}
+
+function hasClass( elem, name ) {
+ return ( " " + elem.className + " " ).indexOf( " " + name + " " ) >= 0;
+}
+
+function addClass( elem, name ) {
+ if ( !hasClass( elem, name ) ) {
+ elem.className += ( elem.className ? " " : "" ) + name;
+ }
+}
+
+function toggleClass( elem, name, force ) {
+ if ( force || typeof force === "undefined" && !hasClass( elem, name ) ) {
+ addClass( elem, name );
+ } else {
+ removeClass( elem, name );
+ }
+}
+
+function removeClass( elem, name ) {
+ var set = " " + elem.className + " ";
+
+ // Class name may appear multiple times
+ while ( set.indexOf( " " + name + " " ) >= 0 ) {
+ set = set.replace( " " + name + " ", " " );
+ }
+
+ // Trim for prettiness
+ elem.className = typeof set.trim === "function" ? set.trim() : set.replace( /^\s+|\s+$/g, "" );
+}
+
+function id( name ) {
+ return document.getElementById && document.getElementById( name );
+}
+
+function getUrlConfigHtml() {
+ var i, j, val,
+ escaped, escapedTooltip,
+ selection = false,
+ urlConfig = config.urlConfig,
+ urlConfigHtml = "";
+
+ for ( i = 0; i < urlConfig.length; i++ ) {
+
+ // Options can be either strings or objects with nonempty "id" properties
+ val = config.urlConfig[ i ];
+ if ( typeof val === "string" ) {
+ val = {
+ id: val,
+ label: val
+ };
+ }
+
+ escaped = escapeText( val.id );
+ escapedTooltip = escapeText( val.tooltip );
+
+ if ( !val.value || typeof val.value === "string" ) {
+ urlConfigHtml += "<input id='qunit-urlconfig-" + escaped +
+ "' name='" + escaped + "' type='checkbox'" +
+ ( val.value ? " value='" + escapeText( val.value ) + "'" : "" ) +
+ ( config[ val.id ] ? " checked='checked'" : "" ) +
+ " title='" + escapedTooltip + "' /><label for='qunit-urlconfig-" + escaped +
+ "' title='" + escapedTooltip + "'>" + val.label + "</label>";
+ } else {
+ urlConfigHtml += "<label for='qunit-urlconfig-" + escaped +
+ "' title='" + escapedTooltip + "'>" + val.label +
+ ": </label><select id='qunit-urlconfig-" + escaped +
+ "' name='" + escaped + "' title='" + escapedTooltip + "'><option></option>";
+
+ if ( QUnit.is( "array", val.value ) ) {
+ for ( j = 0; j < val.value.length; j++ ) {
+ escaped = escapeText( val.value[ j ] );
+ urlConfigHtml += "<option value='" + escaped + "'" +
+ ( config[ val.id ] === val.value[ j ] ?
+ ( selection = true ) && " selected='selected'" : "" ) +
+ ">" + escaped + "</option>";
+ }
+ } else {
+ for ( j in val.value ) {
+ if ( hasOwn.call( val.value, j ) ) {
+ urlConfigHtml += "<option value='" + escapeText( j ) + "'" +
+ ( config[ val.id ] === j ?
+ ( selection = true ) && " selected='selected'" : "" ) +
+ ">" + escapeText( val.value[ j ] ) + "</option>";
+ }
+ }
+ }
+ if ( config[ val.id ] && !selection ) {
+ escaped = escapeText( config[ val.id ] );
+ urlConfigHtml += "<option value='" + escaped +
+ "' selected='selected' disabled='disabled'>" + escaped + "</option>";
+ }
+ urlConfigHtml += "</select>";
+ }
+ }
+
+ return urlConfigHtml;
+}
+
+// Handle "click" events on toolbar checkboxes and "change" for select menus.
+// Updates the URL with the new state of `config.urlConfig` values.
+function toolbarChanged() {
+ var updatedUrl, value, tests,
+ field = this,
+ params = {};
+
+ // Detect if field is a select menu or a checkbox
+ if ( "selectedIndex" in field ) {
+ value = field.options[ field.selectedIndex ].value || undefined;
+ } else {
+ value = field.checked ? ( field.defaultValue || true ) : undefined;
+ }
+
+ params[ field.name ] = value;
+ updatedUrl = setUrl( params );
+
+ // Check if we can apply the change without a page refresh
+ if ( "hidepassed" === field.name && "replaceState" in window.history ) {
+ QUnit.urlParams[ field.name ] = value;
+ config[ field.name ] = value || false;
+ tests = id( "qunit-tests" );
+ if ( tests ) {
+ toggleClass( tests, "hidepass", value || false );
+ }
+ window.history.replaceState( null, "", updatedUrl );
+ } else {
+ window.location = updatedUrl;
+ }
+}
+
+function setUrl( params ) {
+ var key, arrValue, i,
+ querystring = "?",
+ location = window.location;
+
+ params = QUnit.extend( QUnit.extend( {}, QUnit.urlParams ), params );
+
+ for ( key in params ) {
+
+ // Skip inherited or undefined properties
+ if ( hasOwn.call( params, key ) && params[ key ] !== undefined ) {
+
+ // Output a parameter for each value of this key (but usually just one)
+ arrValue = [].concat( params[ key ] );
+ for ( i = 0; i < arrValue.length; i++ ) {
+ querystring += encodeURIComponent( key );
+ if ( arrValue[ i ] !== true ) {
+ querystring += "=" + encodeURIComponent( arrValue[ i ] );
+ }
+ querystring += "&";
+ }
+ }
+ }
+ return location.protocol + "//" + location.host +
+ location.pathname + querystring.slice( 0, -1 );
+}
+
+function applyUrlParams() {
+ var selectedModule,
+ modulesList = id( "qunit-modulefilter" ),
+ filter = id( "qunit-filter-input" ).value;
+
+ selectedModule = modulesList ?
+ decodeURIComponent( modulesList.options[ modulesList.selectedIndex ].value ) :
+ undefined;
+
+ window.location = setUrl( {
+ module: ( selectedModule === "" ) ? undefined : selectedModule,
+ filter: ( filter === "" ) ? undefined : filter,
+
+ // Remove moduleId and testId filters
+ moduleId: undefined,
+ testId: undefined
+ } );
+}
+
+function toolbarUrlConfigContainer() {
+ var urlConfigContainer = document.createElement( "span" );
+
+ urlConfigContainer.innerHTML = getUrlConfigHtml();
+ addClass( urlConfigContainer, "qunit-url-config" );
+
+ // For oldIE support:
+ // * Add handlers to the individual elements instead of the container
+ // * Use "click" instead of "change" for checkboxes
+ addEvents( urlConfigContainer.getElementsByTagName( "input" ), "click", toolbarChanged );
+ addEvents( urlConfigContainer.getElementsByTagName( "select" ), "change", toolbarChanged );
+
+ return urlConfigContainer;
+}
+
+function toolbarLooseFilter() {
+ var filter = document.createElement( "form" ),
+ label = document.createElement( "label" ),
+ input = document.createElement( "input" ),
+ button = document.createElement( "button" );
+
+ addClass( filter, "qunit-filter" );
+
+ label.innerHTML = "Filter: ";
+
+ input.type = "text";
+ input.value = config.filter || "";
+ input.name = "filter";
+ input.id = "qunit-filter-input";
+
+ button.innerHTML = "Go";
+
+ label.appendChild( input );
+
+ filter.appendChild( label );
+ filter.appendChild( button );
+ addEvent( filter, "submit", function( ev ) {
+ applyUrlParams();
+
+ if ( ev && ev.preventDefault ) {
+ ev.preventDefault();
+ }
+
+ return false;
+ } );
+
+ return filter;
+}
+
+function toolbarModuleFilterHtml() {
+ var i,
+ moduleFilterHtml = "";
+
+ if ( !modulesList.length ) {
+ return false;
+ }
+
+ moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label>" +
+ "<select id='qunit-modulefilter' name='modulefilter'><option value='' " +
+ ( QUnit.urlParams.module === undefined ? "selected='selected'" : "" ) +
+ ">< All Modules ></option>";
+
+ for ( i = 0; i < modulesList.length; i++ ) {
+ moduleFilterHtml += "<option value='" +
+ escapeText( encodeURIComponent( modulesList[ i ] ) ) + "' " +
+ ( QUnit.urlParams.module === modulesList[ i ] ? "selected='selected'" : "" ) +
+ ">" + escapeText( modulesList[ i ] ) + "</option>";
+ }
+ moduleFilterHtml += "</select>";
+
+ return moduleFilterHtml;
+}
+
+function toolbarModuleFilter() {
+ var toolbar = id( "qunit-testrunner-toolbar" ),
+ moduleFilter = document.createElement( "span" ),
+ moduleFilterHtml = toolbarModuleFilterHtml();
+
+ if ( !toolbar || !moduleFilterHtml ) {
+ return false;
+ }
+
+ moduleFilter.setAttribute( "id", "qunit-modulefilter-container" );
+ moduleFilter.innerHTML = moduleFilterHtml;
+
+ addEvent( moduleFilter.lastChild, "change", applyUrlParams );
+
+ toolbar.appendChild( moduleFilter );
+}
+
+function appendToolbar() {
+ var toolbar = id( "qunit-testrunner-toolbar" );
+
+ if ( toolbar ) {
+ toolbar.appendChild( toolbarUrlConfigContainer() );
+ toolbar.appendChild( toolbarLooseFilter() );
+ toolbarModuleFilter();
+ }
+}
+
+function appendHeader() {
+ var header = id( "qunit-header" );
+
+ if ( header ) {
+ header.innerHTML = "<a href='" + escapeText( unfilteredUrl ) + "'>" + header.innerHTML +
+ "</a> ";
+ }
+}
+
+function appendBanner() {
+ var banner = id( "qunit-banner" );
+
+ if ( banner ) {
+ banner.className = "";
+ }
+}
+
+function appendTestResults() {
+ var tests = id( "qunit-tests" ),
+ result = id( "qunit-testresult" );
+
+ if ( result ) {
+ result.parentNode.removeChild( result );
+ }
+
+ if ( tests ) {
+ tests.innerHTML = "";
+ result = document.createElement( "p" );
+ result.id = "qunit-testresult";
+ result.className = "result";
+ tests.parentNode.insertBefore( result, tests );
+ result.innerHTML = "Running...<br />&#160;";
+ }
+}
+
+function storeFixture() {
+ var fixture = id( "qunit-fixture" );
+ if ( fixture ) {
+ config.fixture = fixture.innerHTML;
+ }
+}
+
+function appendFilteredTest() {
+ var testId = QUnit.config.testId;
+ if ( !testId || testId.length <= 0 ) {
+ return "";
+ }
+ return "<div id='qunit-filteredTest'>Rerunning selected tests: " +
+ escapeText( testId.join( ", " ) ) +
+ " <a id='qunit-clearFilter' href='" +
+ escapeText( unfilteredUrl ) +
+ "'>Run all tests</a></div>";
+}
+
+function appendUserAgent() {
+ var userAgent = id( "qunit-userAgent" );
+
+ if ( userAgent ) {
+ userAgent.innerHTML = "";
+ userAgent.appendChild(
+ document.createTextNode(
+ "QUnit " + QUnit.version + "; " + navigator.userAgent
+ )
+ );
+ }
+}
+
+function appendInterface() {
+ var qunit = id( "qunit" );
+
+ if ( qunit ) {
+ qunit.innerHTML =
+ "<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
+ "<h2 id='qunit-banner'></h2>" +
+ "<div id='qunit-testrunner-toolbar'></div>" +
+ appendFilteredTest() +
+ "<h2 id='qunit-userAgent'></h2>" +
+ "<ol id='qunit-tests'></ol>";
+ }
+
+ appendHeader();
+ appendBanner();
+ appendTestResults();
+ appendUserAgent();
+ appendToolbar();
+}
+
+function appendTestsList( modules ) {
+ var i, l, x, z, test, moduleObj;
+
+ for ( i = 0, l = modules.length; i < l; i++ ) {
+ moduleObj = modules[ i ];
+
+ for ( x = 0, z = moduleObj.tests.length; x < z; x++ ) {
+ test = moduleObj.tests[ x ];
+
+ appendTest( test.name, test.testId, moduleObj.name );
+ }
+ }
+}
+
+function appendTest( name, testId, moduleName ) {
+ var title, rerunTrigger, testBlock, assertList,
+ tests = id( "qunit-tests" );
+
+ if ( !tests ) {
+ return;
+ }
+
+ title = document.createElement( "strong" );
+ title.innerHTML = getNameHtml( name, moduleName );
+
+ rerunTrigger = document.createElement( "a" );
+ rerunTrigger.innerHTML = "Rerun";
+ rerunTrigger.href = setUrl( { testId: testId } );
+
+ testBlock = document.createElement( "li" );
+ testBlock.appendChild( title );
+ testBlock.appendChild( rerunTrigger );
+ testBlock.id = "qunit-test-output-" + testId;
+
+ assertList = document.createElement( "ol" );
+ assertList.className = "qunit-assert-list";
+
+ testBlock.appendChild( assertList );
+
+ tests.appendChild( testBlock );
+}
+
+// HTML Reporter initialization and load
+QUnit.begin( function( details ) {
+ var i, moduleObj, tests;
+
+ // Sort modules by name for the picker
+ for ( i = 0; i < details.modules.length; i++ ) {
+ moduleObj = details.modules[ i ];
+ if ( moduleObj.name ) {
+ modulesList.push( moduleObj.name );
+ }
+ }
+ modulesList.sort( function( a, b ) {
+ return a.localeCompare( b );
+ } );
+
+ // Capture fixture HTML from the page
+ storeFixture();
+
+ // Initialize QUnit elements
+ appendInterface();
+ appendTestsList( details.modules );
+ tests = id( "qunit-tests" );
+ if ( tests && config.hidepassed ) {
+ addClass( tests, "hidepass" );
+ }
+} );
+
+QUnit.done( function( details ) {
+ var i, key,
+ banner = id( "qunit-banner" ),
+ tests = id( "qunit-tests" ),
+ html = [
+ "Tests completed in ",
+ details.runtime,
+ " milliseconds.<br />",
+ "<span class='passed'>",
+ details.passed,
+ "</span> assertions of <span class='total'>",
+ details.total,
+ "</span> passed, <span class='failed'>",
+ details.failed,
+ "</span> failed."
+ ].join( "" );
+
+ if ( banner ) {
+ banner.className = details.failed ? "qunit-fail" : "qunit-pass";
+ }
+
+ if ( tests ) {
+ id( "qunit-testresult" ).innerHTML = html;
+ }
+
+ if ( config.altertitle && document.title ) {
+
+ // Show ✖ for good, ✔ for bad suite result in title
+ // use escape sequences in case file gets loaded with non-utf-8-charset
+ document.title = [
+ ( details.failed ? "\u2716" : "\u2714" ),
+ document.title.replace( /^[\u2714\u2716] /i, "" )
+ ].join( " " );
+ }
+
+ // Clear own sessionStorage items if all tests passed
+ if ( config.reorder && defined.sessionStorage && details.failed === 0 ) {
+ for ( i = 0; i < sessionStorage.length; i++ ) {
+ key = sessionStorage.key( i++ );
+ if ( key.indexOf( "qunit-test-" ) === 0 ) {
+ sessionStorage.removeItem( key );
+ }
+ }
+ }
+
+ // Scroll back to top to show results
+ if ( config.scrolltop && window.scrollTo ) {
+ window.scrollTo( 0, 0 );
+ }
+} );
+
+function getNameHtml( name, module ) {
+ var nameHtml = "";
+
+ if ( module ) {
+ nameHtml = "<span class='module-name'>" + escapeText( module ) + "</span>: ";
+ }
+
+ nameHtml += "<span class='test-name'>" + escapeText( name ) + "</span>";
+
+ return nameHtml;
+}
+
+QUnit.testStart( function( details ) {
+ var running, testBlock, bad;
+
+ testBlock = id( "qunit-test-output-" + details.testId );
+ if ( testBlock ) {
+ testBlock.className = "running";
+ } else {
+
+ // Report later registered tests
+ appendTest( details.name, details.testId, details.module );
+ }
+
+ running = id( "qunit-testresult" );
+ if ( running ) {
+ bad = QUnit.config.reorder && defined.sessionStorage &&
+ +sessionStorage.getItem( "qunit-test-" + details.module + "-" + details.name );
+
+ running.innerHTML = ( bad ?
+ "Rerunning previously failed test: <br />" :
+ "Running: <br />" ) +
+ getNameHtml( details.name, details.module );
+ }
+
+} );
+
+function stripHtml( string ) {
+
+ // Strip tags, html entity and whitespaces
+ return string.replace( /<\/?[^>]+(>|$)/g, "" ).replace( /\&quot;/g, "" ).replace( /\s+/g, "" );
+}
+
+QUnit.log( function( details ) {
+ var assertList, assertLi,
+ message, expected, actual, diff,
+ showDiff = false,
+ testItem = id( "qunit-test-output-" + details.testId );
+
+ if ( !testItem ) {
+ return;
+ }
+
+ message = escapeText( details.message ) || ( details.result ? "okay" : "failed" );
+ message = "<span class='test-message'>" + message + "</span>";
+ message += "<span class='runtime'>@ " + details.runtime + " ms</span>";
+
+ // The pushFailure doesn't provide details.expected
+ // when it calls, it's implicit to also not show expected and diff stuff
+ // Also, we need to check details.expected existence, as it can exist and be undefined
+ if ( !details.result && hasOwn.call( details, "expected" ) ) {
+ if ( details.negative ) {
+ expected = "NOT " + QUnit.dump.parse( details.expected );
+ } else {
+ expected = QUnit.dump.parse( details.expected );
+ }
+
+ actual = QUnit.dump.parse( details.actual );
+ message += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" +
+ escapeText( expected ) +
+ "</pre></td></tr>";
+
+ if ( actual !== expected ) {
+
+ message += "<tr class='test-actual'><th>Result: </th><td><pre>" +
+ escapeText( actual ) + "</pre></td></tr>";
+
+ // Don't show diff if actual or expected are booleans
+ if ( !( /^(true|false)$/.test( actual ) ) &&
+ !( /^(true|false)$/.test( expected ) ) ) {
+ diff = QUnit.diff( expected, actual );
+ showDiff = stripHtml( diff ).length !==
+ stripHtml( expected ).length +
+ stripHtml( actual ).length;
+ }
+
+ // Don't show diff if expected and actual are totally different
+ if ( showDiff ) {
+ message += "<tr class='test-diff'><th>Diff: </th><td><pre>" +
+ diff + "</pre></td></tr>";
+ }
+ } else if ( expected.indexOf( "[object Array]" ) !== -1 ||
+ expected.indexOf( "[object Object]" ) !== -1 ) {
+ message += "<tr class='test-message'><th>Message: </th><td>" +
+ "Diff suppressed as the depth of object is more than current max depth (" +
+ QUnit.config.maxDepth + ").<p>Hint: Use <code>QUnit.dump.maxDepth</code> to " +
+ " run with a higher max depth or <a href='" +
+ escapeText( setUrl( { maxDepth: -1 } ) ) + "'>" +
+ "Rerun</a> without max depth.</p></td></tr>";
+ } else {
+ message += "<tr class='test-message'><th>Message: </th><td>" +
+ "Diff suppressed as the expected and actual results have an equivalent" +
+ " serialization</td></tr>";
+ }
+
+ if ( details.source ) {
+ message += "<tr class='test-source'><th>Source: </th><td><pre>" +
+ escapeText( details.source ) + "</pre></td></tr>";
+ }
+
+ message += "</table>";
+
+ // This occurs when pushFailure is set and we have an extracted stack trace
+ } else if ( !details.result && details.source ) {
+ message += "<table>" +
+ "<tr class='test-source'><th>Source: </th><td><pre>" +
+ escapeText( details.source ) + "</pre></td></tr>" +
+ "</table>";
+ }
+
+ assertList = testItem.getElementsByTagName( "ol" )[ 0 ];
+
+ assertLi = document.createElement( "li" );
+ assertLi.className = details.result ? "pass" : "fail";
+ assertLi.innerHTML = message;
+ assertList.appendChild( assertLi );
+} );
+
+QUnit.testDone( function( details ) {
+ var testTitle, time, testItem, assertList,
+ good, bad, testCounts, skipped, sourceName,
+ tests = id( "qunit-tests" );
+
+ if ( !tests ) {
+ return;
+ }
+
+ testItem = id( "qunit-test-output-" + details.testId );
+
+ assertList = testItem.getElementsByTagName( "ol" )[ 0 ];
+
+ good = details.passed;
+ bad = details.failed;
+
+ // Store result when possible
+ if ( config.reorder && defined.sessionStorage ) {
+ if ( bad ) {
+ sessionStorage.setItem( "qunit-test-" + details.module + "-" + details.name, bad );
+ } else {
+ sessionStorage.removeItem( "qunit-test-" + details.module + "-" + details.name );
+ }
+ }
+
+ if ( bad === 0 ) {
+
+ // Collapse the passing tests
+ addClass( assertList, "qunit-collapsed" );
+ } else if ( bad && config.collapse && !collapseNext ) {
+
+ // Skip collapsing the first failing test
+ collapseNext = true;
+ } else {
+
+ // Collapse remaining tests
+ addClass( assertList, "qunit-collapsed" );
+ }
+
+ // The testItem.firstChild is the test name
+ testTitle = testItem.firstChild;
+
+ testCounts = bad ?
+ "<b class='failed'>" + bad + "</b>, " + "<b class='passed'>" + good + "</b>, " :
+ "";
+
+ testTitle.innerHTML += " <b class='counts'>(" + testCounts +
+ details.assertions.length + ")</b>";
+
+ if ( details.skipped ) {
+ testItem.className = "skipped";
+ skipped = document.createElement( "em" );
+ skipped.className = "qunit-skipped-label";
+ skipped.innerHTML = "skipped";
+ testItem.insertBefore( skipped, testTitle );
+ } else {
+ addEvent( testTitle, "click", function() {
+ toggleClass( assertList, "qunit-collapsed" );
+ } );
+
+ testItem.className = bad ? "fail" : "pass";
+
+ time = document.createElement( "span" );
+ time.className = "runtime";
+ time.innerHTML = details.runtime + " ms";
+ testItem.insertBefore( time, assertList );
+ }
+
+ // Show the source of the test when showing assertions
+ if ( details.source ) {
+ sourceName = document.createElement( "p" );
+ sourceName.innerHTML = "<strong>Source: </strong>" + details.source;
+ addClass( sourceName, "qunit-source" );
+ if ( bad === 0 ) {
+ addClass( sourceName, "qunit-collapsed" );
+ }
+ addEvent( testTitle, "click", function() {
+ toggleClass( sourceName, "qunit-collapsed" );
+ } );
+ testItem.appendChild( sourceName );
+ }
+} );
+
+// Avoid readyState issue with phantomjs
+// Ref: #818
+var notPhantom = ( function( p ) {
+ return !( p && p.version && p.version.major > 0 );
+} )( window.phantom );
+
+if ( notPhantom && document.readyState === "complete" ) {
+ QUnit.load();
+} else {
+ addEvent( window, "load", QUnit.load );
+}
+
/*
* This file is a modified version of google-diff-match-patch's JavaScript implementation
* (https://code.google.com/p/google-diff-match-patch/source/browse/trunk/javascript/diff_match_patch_uncompressed.js),
@@ -2210,13 +3172,13 @@ if ( typeof define === "function" && define.amd ) {
* The original source of google-diff-match-patch is attributable and licensed as follows:
*
* Copyright 2006 Google Inc.
- * http://code.google.com/p/google-diff-match-patch/
+ * https://code.google.com/p/google-diff-match-patch/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -2321,14 +3283,19 @@ QUnit.diff = ( function() {
equalitiesLength = 0; // Keeping our own length var is faster in JS.
/** @type {?string} */
lastequality = null;
+
// Always equal to diffs[equalities[equalitiesLength - 1]][1]
pointer = 0; // Index of current position.
+
// Is there an insertion operation before the last equality.
preIns = false;
+
// Is there a deletion operation before the last equality.
preDel = false;
+
// Is there an insertion operation after the last equality.
postIns = false;
+
// Is there a deletion operation after the last equality.
postDel = false;
while ( pointer < diffs.length ) {
@@ -2383,6 +3350,7 @@ QUnit.diff = ( function() {
equalitiesLength--; // Throw away the equality we just deleted;
lastequality = null;
if ( preIns && preDel ) {
+
// No changes made which could affect previous entry, keep going.
postIns = postDel = true;
equalitiesLength = 0;
@@ -2416,13 +3384,13 @@ QUnit.diff = ( function() {
data = diffs[ x ][ 1 ]; // Text of change.
switch ( op ) {
case DIFF_INSERT:
- html[ x ] = "<ins>" + data + "</ins>";
+ html[ x ] = "<ins>" + escapeText( data ) + "</ins>";
break;
case DIFF_DELETE:
- html[ x ] = "<del>" + data + "</del>";
+ html[ x ] = "<del>" + escapeText( data ) + "</del>";
break;
case DIFF_EQUAL:
- html[ x ] = "<span>" + data + "</span>";
+ html[ x ] = "<span>" + escapeText( data ) + "</span>";
break;
}
}
@@ -2438,12 +3406,14 @@ QUnit.diff = ( function() {
*/
DiffMatchPatch.prototype.diffCommonPrefix = function( text1, text2 ) {
var pointermid, pointermax, pointermin, pointerstart;
+
// Quick check for common null cases.
if ( !text1 || !text2 || text1.charAt( 0 ) !== text2.charAt( 0 ) ) {
return 0;
}
+
// Binary search.
- // Performance analysis: http://neil.fraser.name/news/2007/10/09/
+ // Performance analysis: https://neil.fraser.name/news/2007/10/09/
pointermin = 0;
pointermax = Math.min( text1.length, text2.length );
pointermid = pointermax;
@@ -2469,14 +3439,16 @@ QUnit.diff = ( function() {
*/
DiffMatchPatch.prototype.diffCommonSuffix = function( text1, text2 ) {
var pointermid, pointermax, pointermin, pointerend;
+
// Quick check for common null cases.
if ( !text1 ||
!text2 ||
text1.charAt( text1.length - 1 ) !== text2.charAt( text2.length - 1 ) ) {
return 0;
}
+
// Binary search.
- // Performance analysis: http://neil.fraser.name/news/2007/10/09/
+ // Performance analysis: https://neil.fraser.name/news/2007/10/09/
pointermin = 0;
pointermax = Math.min( text1.length, text2.length );
pointermid = pointermax;
@@ -2512,6 +3484,7 @@ QUnit.diff = ( function() {
midCommon, diffsA, diffsB;
if ( !text1 ) {
+
// Just add some text (speedup).
return [
[ DIFF_INSERT, text2 ]
@@ -2519,6 +3492,7 @@ QUnit.diff = ( function() {
}
if ( !text2 ) {
+
// Just delete some text (speedup).
return [
[ DIFF_DELETE, text1 ]
@@ -2529,12 +3503,14 @@ QUnit.diff = ( function() {
shorttext = text1.length > text2.length ? text2 : text1;
i = longtext.indexOf( shorttext );
if ( i !== -1 ) {
+
// Shorter text is inside the longer text (speedup).
diffs = [
[ DIFF_INSERT, longtext.substring( 0, i ) ],
[ DIFF_EQUAL, shorttext ],
[ DIFF_INSERT, longtext.substring( i + shorttext.length ) ]
];
+
// Swap insertions for deletions if diff is reversed.
if ( text1.length > text2.length ) {
diffs[ 0 ][ 0 ] = diffs[ 2 ][ 0 ] = DIFF_DELETE;
@@ -2543,6 +3519,7 @@ QUnit.diff = ( function() {
}
if ( shorttext.length === 1 ) {
+
// Single character string.
// After the previous speedup, the character can't be an equality.
return [
@@ -2554,15 +3531,18 @@ QUnit.diff = ( function() {
// Check to see if the problem can be split in two.
hm = this.diffHalfMatch( text1, text2 );
if ( hm ) {
+
// A half-match was found, sort out the return data.
text1A = hm[ 0 ];
text1B = hm[ 1 ];
text2A = hm[ 2 ];
text2B = hm[ 3 ];
midCommon = hm[ 4 ];
+
// Send both pairs off for separate processing.
diffsA = this.DiffMain( text1A, text2A, checklines, deadline );
diffsB = this.DiffMain( text1B, text2B, checklines, deadline );
+
// Merge the results.
return diffsA.concat( [
[ DIFF_EQUAL, midCommon ]
@@ -2614,6 +3594,7 @@ QUnit.diff = ( function() {
function diffHalfMatchI( longtext, shorttext, i ) {
var seed, j, bestCommon, prefixLength, suffixLength,
bestLongtextA, bestLongtextB, bestShorttextA, bestShorttextB;
+
// Start with a 1/4 length substring at position i as a seed.
seed = longtext.substring( i, i + Math.floor( longtext.length / 4 ) );
j = -1;
@@ -2644,6 +3625,7 @@ QUnit.diff = ( function() {
// First check if the second quarter is the seed for a half-match.
hm1 = diffHalfMatchI( longtext, shorttext,
Math.ceil( longtext.length / 4 ) );
+
// Check again based on the third quarter.
hm2 = diffHalfMatchI( longtext, shorttext,
Math.ceil( longtext.length / 2 ) );
@@ -2654,6 +3636,7 @@ QUnit.diff = ( function() {
} else if ( !hm1 ) {
hm = hm2;
} else {
+
// Both matched. Select the longest.
hm = hm1[ 4 ].length > hm2[ 4 ].length ? hm1 : hm2;
}
@@ -2688,6 +3671,7 @@ QUnit.diff = ( function() {
DiffMatchPatch.prototype.diffLineMode = function( text1, text2, deadline ) {
var a, diffs, linearray, pointer, countInsert,
countDelete, textInsert, textDelete, j;
+
// Scan the text on a line-by-line basis first.
a = this.diffLinesToChars( text1, text2 );
text1 = a.chars1;
@@ -2698,6 +3682,7 @@ QUnit.diff = ( function() {
// Convert the diff back to original text.
this.diffCharsToLines( diffs, linearray );
+
// Eliminate freak matches (e.g. blank lines)
this.diffCleanupSemantic( diffs );
@@ -2720,8 +3705,10 @@ QUnit.diff = ( function() {
textDelete += diffs[ pointer ][ 1 ];
break;
case DIFF_EQUAL:
+
// Upon reaching an equality, check for prior redundancies.
if ( countDelete >= 1 && countInsert >= 1 ) {
+
// Delete the offending records and add the merged ones.
diffs.splice( pointer - countDelete - countInsert,
countDelete + countInsert );
@@ -2759,6 +3746,7 @@ QUnit.diff = ( function() {
var text1Length, text2Length, maxD, vOffset, vLength,
v1, v2, x, delta, front, k1start, k1end, k2start,
k2end, k2Offset, k1Offset, x1, x2, y1, y2, d, k1, k2;
+
// Cache the text lengths to prevent multiple calls.
text1Length = text1.length;
text2Length = text2.length;
@@ -2767,6 +3755,7 @@ QUnit.diff = ( function() {
vLength = 2 * maxD;
v1 = new Array( vLength );
v2 = new Array( vLength );
+
// Setting all elements to -1 is faster in Chrome & Firefox than mixing
// integers and undefined.
for ( x = 0; x < vLength; x++ ) {
@@ -2776,9 +3765,11 @@ QUnit.diff = ( function() {
v1[ vOffset + 1 ] = 0;
v2[ vOffset + 1 ] = 0;
delta = text1Length - text2Length;
+
// If the total number of characters is odd, then the front path will collide
// with the reverse path.
front = ( delta % 2 !== 0 );
+
// Offsets for start and end of k loop.
// Prevents mapping of space beyond the grid.
k1start = 0;
@@ -2786,6 +3777,7 @@ QUnit.diff = ( function() {
k2start = 0;
k2end = 0;
for ( d = 0; d < maxD; d++ ) {
+
// Bail out if deadline is reached.
if ( ( new Date() ).getTime() > deadline ) {
break;
@@ -2807,17 +3799,21 @@ QUnit.diff = ( function() {
}
v1[ k1Offset ] = x1;
if ( x1 > text1Length ) {
+
// Ran off the right of the graph.
k1end += 2;
} else if ( y1 > text2Length ) {
+
// Ran off the bottom of the graph.
k1start += 2;
} else if ( front ) {
k2Offset = vOffset + delta - k1;
if ( k2Offset >= 0 && k2Offset < vLength && v2[ k2Offset ] !== -1 ) {
+
// Mirror x2 onto top-left coordinate system.
x2 = text1Length - v2[ k2Offset ];
if ( x1 >= x2 ) {
+
// Overlap detected.
return this.diffBisectSplit( text1, text2, x1, y1, deadline );
}
@@ -2842,9 +3838,11 @@ QUnit.diff = ( function() {
}
v2[ k2Offset ] = x2;
if ( x2 > text1Length ) {
+
// Ran off the left of the graph.
k2end += 2;
} else if ( y2 > text2Length ) {
+
// Ran off the top of the graph.
k2start += 2;
} else if ( !front ) {
@@ -2852,9 +3850,11 @@ QUnit.diff = ( function() {
if ( k1Offset >= 0 && k1Offset < vLength && v1[ k1Offset ] !== -1 ) {
x1 = v1[ k1Offset ];
y1 = vOffset + x1 - k1Offset;
+
// Mirror x2 onto top-left coordinate system.
x2 = text1Length - x2;
if ( x1 >= x2 ) {
+
// Overlap detected.
return this.diffBisectSplit( text1, text2, x1, y1, deadline );
}
@@ -2862,6 +3862,7 @@ QUnit.diff = ( function() {
}
}
}
+
// Diff took too long and hit the deadline or
// number of diffs equals number of characters, no commonality at all.
return [
@@ -2908,11 +3909,14 @@ QUnit.diff = ( function() {
equalitiesLength = 0; // Keeping our own length var is faster in JS.
/** @type {?string} */
lastequality = null;
+
// Always equal to diffs[equalities[equalitiesLength - 1]][1]
pointer = 0; // Index of current position.
+
// Number of characters that changed prior to the equality.
lengthInsertions1 = 0;
lengthDeletions1 = 0;
+
// Number of characters that changed after the equality.
lengthInsertions2 = 0;
lengthDeletions2 = 0;
@@ -2930,6 +3934,7 @@ QUnit.diff = ( function() {
} else {
lengthDeletions2 += diffs[ pointer ][ 1 ].length;
}
+
// Eliminate an equality that is smaller or equal to the edits on both
// sides of it.
if ( lastequality && ( lastequality.length <=
@@ -2988,6 +3993,7 @@ QUnit.diff = ( function() {
if ( overlapLength1 >= overlapLength2 ) {
if ( overlapLength1 >= deletion.length / 2 ||
overlapLength1 >= insertion.length / 2 ) {
+
// Overlap found. Insert an equality and trim the surrounding edits.
diffs.splice(
pointer,
@@ -3037,13 +4043,16 @@ QUnit.diff = ( function() {
DiffMatchPatch.prototype.diffCommonOverlap = function( text1, text2 ) {
var text1Length, text2Length, textLength,
best, length, pattern, found;
+
// Cache the text lengths to prevent multiple calls.
text1Length = text1.length;
text2Length = text2.length;
+
// Eliminate the null case.
if ( text1Length === 0 || text2Length === 0 ) {
return 0;
}
+
// Truncate the longer string.
if ( text1Length > text2Length ) {
text1 = text1.substring( text1Length - text2Length );
@@ -3051,6 +4060,7 @@ QUnit.diff = ( function() {
text2 = text2.substring( 0, text1Length );
}
textLength = Math.min( text1Length, text2Length );
+
// Quick check for the worst case.
if ( text1 === text2 ) {
return textLength;
@@ -3058,7 +4068,7 @@ QUnit.diff = ( function() {
// Start by looking for a single character match
// and increase length until no match is found.
- // Performance analysis: http://neil.fraser.name/news/2010/11/04/
+ // Performance analysis: https://neil.fraser.name/news/2010/11/04/
best = 0;
length = 1;
while ( true ) {
@@ -3089,8 +4099,8 @@ QUnit.diff = ( function() {
*/
DiffMatchPatch.prototype.diffLinesToChars = function( text1, text2 ) {
var lineArray, lineHash, chars1, chars2;
- lineArray = []; // e.g. lineArray[4] === 'Hello\n'
- lineHash = {}; // e.g. lineHash['Hello\n'] === 4
+ lineArray = []; // E.g. lineArray[4] === 'Hello\n'
+ lineHash = {}; // E.g. lineHash['Hello\n'] === 4
// '\x00' is a valid character, but various debuggers don't like it.
// So we'll insert a junk entry to avoid generating a null character.
@@ -3107,11 +4117,13 @@ QUnit.diff = ( function() {
function diffLinesToCharsMunge( text ) {
var chars, lineStart, lineEnd, lineArrayLength, line;
chars = "";
+
// Walk the text, pulling out a substring for each line.
// text.split('\n') would would temporarily double our memory footprint.
// Modifying text would create many large strings to garbage collect.
lineStart = 0;
lineEnd = -1;
+
// Keeping our own length variable is faster than looking it up.
lineArrayLength = lineArray.length;
while ( lineEnd < text.length - 1 ) {
@@ -3190,10 +4202,12 @@ QUnit.diff = ( function() {
pointer++;
break;
case DIFF_EQUAL:
+
// Upon reaching an equality, check for prior redundancies.
if ( countDelete + countInsert > 1 ) {
if ( countDelete !== 0 && countInsert !== 0 ) {
- // Factor out any common prefixies.
+
+ // Factor out any common prefixes.
commonlength = this.diffCommonPrefix( textInsert, textDelete );
if ( commonlength !== 0 ) {
if ( ( pointer - countDelete - countInsert ) > 0 &&
@@ -3210,6 +4224,7 @@ QUnit.diff = ( function() {
textInsert = textInsert.substring( commonlength );
textDelete = textDelete.substring( commonlength );
}
+
// Factor out any common suffixies.
commonlength = this.diffCommonSuffix( textInsert, textDelete );
if ( commonlength !== 0 ) {
@@ -3221,6 +4236,7 @@ QUnit.diff = ( function() {
commonlength );
}
}
+
// Delete the offending records and add the merged ones.
if ( countDelete === 0 ) {
diffs.splice( pointer - countInsert,
@@ -3297,6 +4313,7 @@ QUnit.diff = ( function() {
}
pointer++;
}
+
// If shifts were made, the diff needs reordering and another shift sweep.
if ( changes ) {
this.diffCleanupMerge( diffs );
@@ -3314,845 +4331,4 @@ QUnit.diff = ( function() {
};
}() );
-// Get a reference to the global object, like window in browsers
-}( (function() {
- return this;
-})() ));
-
-(function() {
-
-// Don't load the HTML Reporter on non-Browser environments
-if ( typeof window === "undefined" || !window.document ) {
- return;
-}
-
-// Deprecated QUnit.init - Ref #530
-// Re-initialize the configuration options
-QUnit.init = function() {
- var tests, banner, result, qunit,
- config = QUnit.config;
-
- config.stats = { all: 0, bad: 0 };
- config.moduleStats = { all: 0, bad: 0 };
- config.started = 0;
- config.updateRate = 1000;
- config.blocking = false;
- config.autostart = true;
- config.autorun = false;
- config.filter = "";
- config.queue = [];
-
- // Return on non-browser environments
- // This is necessary to not break on node tests
- if ( typeof window === "undefined" ) {
- return;
- }
-
- qunit = id( "qunit" );
- if ( qunit ) {
- qunit.innerHTML =
- "<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
- "<h2 id='qunit-banner'></h2>" +
- "<div id='qunit-testrunner-toolbar'></div>" +
- "<h2 id='qunit-userAgent'></h2>" +
- "<ol id='qunit-tests'></ol>";
- }
-
- tests = id( "qunit-tests" );
- banner = id( "qunit-banner" );
- result = id( "qunit-testresult" );
-
- if ( tests ) {
- tests.innerHTML = "";
- }
-
- if ( banner ) {
- banner.className = "";
- }
-
- if ( result ) {
- result.parentNode.removeChild( result );
- }
-
- if ( tests ) {
- result = document.createElement( "p" );
- result.id = "qunit-testresult";
- result.className = "result";
- tests.parentNode.insertBefore( result, tests );
- result.innerHTML = "Running...<br />&#160;";
- }
-};
-
-var config = QUnit.config,
- collapseNext = false,
- hasOwn = Object.prototype.hasOwnProperty,
- defined = {
- document: window.document !== undefined,
- sessionStorage: (function() {
- var x = "qunit-test-string";
- try {
- sessionStorage.setItem( x, x );
- sessionStorage.removeItem( x );
- return true;
- } catch ( e ) {
- return false;
- }
- }())
- },
- modulesList = [];
-
-/**
-* Escape text for attribute or text content.
-*/
-function escapeText( s ) {
- if ( !s ) {
- return "";
- }
- s = s + "";
-
- // Both single quotes and double quotes (for attributes)
- return s.replace( /['"<>&]/g, function( s ) {
- switch ( s ) {
- case "'":
- return "&#039;";
- case "\"":
- return "&quot;";
- case "<":
- return "&lt;";
- case ">":
- return "&gt;";
- case "&":
- return "&amp;";
- }
- });
-}
-
-/**
- * @param {HTMLElement} elem
- * @param {string} type
- * @param {Function} fn
- */
-function addEvent( elem, type, fn ) {
- if ( elem.addEventListener ) {
-
- // Standards-based browsers
- elem.addEventListener( type, fn, false );
- } else if ( elem.attachEvent ) {
-
- // support: IE <9
- elem.attachEvent( "on" + type, function() {
- var event = window.event;
- if ( !event.target ) {
- event.target = event.srcElement || document;
- }
-
- fn.call( elem, event );
- });
- }
-}
-
-/**
- * @param {Array|NodeList} elems
- * @param {string} type
- * @param {Function} fn
- */
-function addEvents( elems, type, fn ) {
- var i = elems.length;
- while ( i-- ) {
- addEvent( elems[ i ], type, fn );
- }
-}
-
-function hasClass( elem, name ) {
- return ( " " + elem.className + " " ).indexOf( " " + name + " " ) >= 0;
-}
-
-function addClass( elem, name ) {
- if ( !hasClass( elem, name ) ) {
- elem.className += ( elem.className ? " " : "" ) + name;
- }
-}
-
-function toggleClass( elem, name ) {
- if ( hasClass( elem, name ) ) {
- removeClass( elem, name );
- } else {
- addClass( elem, name );
- }
-}
-
-function removeClass( elem, name ) {
- var set = " " + elem.className + " ";
-
- // Class name may appear multiple times
- while ( set.indexOf( " " + name + " " ) >= 0 ) {
- set = set.replace( " " + name + " ", " " );
- }
-
- // trim for prettiness
- elem.className = typeof set.trim === "function" ? set.trim() : set.replace( /^\s+|\s+$/g, "" );
-}
-
-function id( name ) {
- return defined.document && document.getElementById && document.getElementById( name );
-}
-
-function getUrlConfigHtml() {
- var i, j, val,
- escaped, escapedTooltip,
- selection = false,
- len = config.urlConfig.length,
- urlConfigHtml = "";
-
- for ( i = 0; i < len; i++ ) {
- val = config.urlConfig[ i ];
- if ( typeof val === "string" ) {
- val = {
- id: val,
- label: val
- };
- }
-
- escaped = escapeText( val.id );
- escapedTooltip = escapeText( val.tooltip );
-
- if ( config[ val.id ] === undefined ) {
- config[ val.id ] = QUnit.urlParams[ val.id ];
- }
-
- if ( !val.value || typeof val.value === "string" ) {
- urlConfigHtml += "<input id='qunit-urlconfig-" + escaped +
- "' name='" + escaped + "' type='checkbox'" +
- ( val.value ? " value='" + escapeText( val.value ) + "'" : "" ) +
- ( config[ val.id ] ? " checked='checked'" : "" ) +
- " title='" + escapedTooltip + "' /><label for='qunit-urlconfig-" + escaped +
- "' title='" + escapedTooltip + "'>" + val.label + "</label>";
- } else {
- urlConfigHtml += "<label for='qunit-urlconfig-" + escaped +
- "' title='" + escapedTooltip + "'>" + val.label +
- ": </label><select id='qunit-urlconfig-" + escaped +
- "' name='" + escaped + "' title='" + escapedTooltip + "'><option></option>";
-
- if ( QUnit.is( "array", val.value ) ) {
- for ( j = 0; j < val.value.length; j++ ) {
- escaped = escapeText( val.value[ j ] );
- urlConfigHtml += "<option value='" + escaped + "'" +
- ( config[ val.id ] === val.value[ j ] ?
- ( selection = true ) && " selected='selected'" : "" ) +
- ">" + escaped + "</option>";
- }
- } else {
- for ( j in val.value ) {
- if ( hasOwn.call( val.value, j ) ) {
- urlConfigHtml += "<option value='" + escapeText( j ) + "'" +
- ( config[ val.id ] === j ?
- ( selection = true ) && " selected='selected'" : "" ) +
- ">" + escapeText( val.value[ j ] ) + "</option>";
- }
- }
- }
- if ( config[ val.id ] && !selection ) {
- escaped = escapeText( config[ val.id ] );
- urlConfigHtml += "<option value='" + escaped +
- "' selected='selected' disabled='disabled'>" + escaped + "</option>";
- }
- urlConfigHtml += "</select>";
- }
- }
-
- return urlConfigHtml;
-}
-
-// Handle "click" events on toolbar checkboxes and "change" for select menus.
-// Updates the URL with the new state of `config.urlConfig` values.
-function toolbarChanged() {
- var updatedUrl, value,
- field = this,
- params = {};
-
- // Detect if field is a select menu or a checkbox
- if ( "selectedIndex" in field ) {
- value = field.options[ field.selectedIndex ].value || undefined;
- } else {
- value = field.checked ? ( field.defaultValue || true ) : undefined;
- }
-
- params[ field.name ] = value;
- updatedUrl = setUrl( params );
-
- if ( "hidepassed" === field.name && "replaceState" in window.history ) {
- config[ field.name ] = value || false;
- if ( value ) {
- addClass( id( "qunit-tests" ), "hidepass" );
- } else {
- removeClass( id( "qunit-tests" ), "hidepass" );
- }
-
- // It is not necessary to refresh the whole page
- window.history.replaceState( null, "", updatedUrl );
- } else {
- window.location = updatedUrl;
- }
-}
-
-function setUrl( params ) {
- var key,
- querystring = "?";
-
- params = QUnit.extend( QUnit.extend( {}, QUnit.urlParams ), params );
-
- for ( key in params ) {
- if ( hasOwn.call( params, key ) ) {
- if ( params[ key ] === undefined ) {
- continue;
- }
- querystring += encodeURIComponent( key );
- if ( params[ key ] !== true ) {
- querystring += "=" + encodeURIComponent( params[ key ] );
- }
- querystring += "&";
- }
- }
- return location.protocol + "//" + location.host +
- location.pathname + querystring.slice( 0, -1 );
-}
-
-function applyUrlParams() {
- var selectedModule,
- modulesList = id( "qunit-modulefilter" ),
- filter = id( "qunit-filter-input" ).value;
-
- selectedModule = modulesList ?
- decodeURIComponent( modulesList.options[ modulesList.selectedIndex ].value ) :
- undefined;
-
- window.location = setUrl({
- module: ( selectedModule === "" ) ? undefined : selectedModule,
- filter: ( filter === "" ) ? undefined : filter,
-
- // Remove testId filter
- testId: undefined
- });
-}
-
-function toolbarUrlConfigContainer() {
- var urlConfigContainer = document.createElement( "span" );
-
- urlConfigContainer.innerHTML = getUrlConfigHtml();
- addClass( urlConfigContainer, "qunit-url-config" );
-
- // For oldIE support:
- // * Add handlers to the individual elements instead of the container
- // * Use "click" instead of "change" for checkboxes
- addEvents( urlConfigContainer.getElementsByTagName( "input" ), "click", toolbarChanged );
- addEvents( urlConfigContainer.getElementsByTagName( "select" ), "change", toolbarChanged );
-
- return urlConfigContainer;
-}
-
-function toolbarLooseFilter() {
- var filter = document.createElement( "form" ),
- label = document.createElement( "label" ),
- input = document.createElement( "input" ),
- button = document.createElement( "button" );
-
- addClass( filter, "qunit-filter" );
-
- label.innerHTML = "Filter: ";
-
- input.type = "text";
- input.value = config.filter || "";
- input.name = "filter";
- input.id = "qunit-filter-input";
-
- button.innerHTML = "Go";
-
- label.appendChild( input );
-
- filter.appendChild( label );
- filter.appendChild( button );
- addEvent( filter, "submit", function( ev ) {
- applyUrlParams();
-
- if ( ev && ev.preventDefault ) {
- ev.preventDefault();
- }
-
- return false;
- });
-
- return filter;
-}
-
-function toolbarModuleFilterHtml() {
- var i,
- moduleFilterHtml = "";
-
- if ( !modulesList.length ) {
- return false;
- }
-
- modulesList.sort(function( a, b ) {
- return a.localeCompare( b );
- });
-
- moduleFilterHtml += "<label for='qunit-modulefilter'>Module: </label>" +
- "<select id='qunit-modulefilter' name='modulefilter'><option value='' " +
- ( QUnit.urlParams.module === undefined ? "selected='selected'" : "" ) +
- ">< All Modules ></option>";
-
- for ( i = 0; i < modulesList.length; i++ ) {
- moduleFilterHtml += "<option value='" +
- escapeText( encodeURIComponent( modulesList[ i ] ) ) + "' " +
- ( QUnit.urlParams.module === modulesList[ i ] ? "selected='selected'" : "" ) +
- ">" + escapeText( modulesList[ i ] ) + "</option>";
- }
- moduleFilterHtml += "</select>";
-
- return moduleFilterHtml;
-}
-
-function toolbarModuleFilter() {
- var toolbar = id( "qunit-testrunner-toolbar" ),
- moduleFilter = document.createElement( "span" ),
- moduleFilterHtml = toolbarModuleFilterHtml();
-
- if ( !toolbar || !moduleFilterHtml ) {
- return false;
- }
-
- moduleFilter.setAttribute( "id", "qunit-modulefilter-container" );
- moduleFilter.innerHTML = moduleFilterHtml;
-
- addEvent( moduleFilter.lastChild, "change", applyUrlParams );
-
- toolbar.appendChild( moduleFilter );
-}
-
-function appendToolbar() {
- var toolbar = id( "qunit-testrunner-toolbar" );
-
- if ( toolbar ) {
- toolbar.appendChild( toolbarUrlConfigContainer() );
- toolbar.appendChild( toolbarLooseFilter() );
- }
-}
-
-function appendHeader() {
- var header = id( "qunit-header" );
-
- if ( header ) {
- header.innerHTML = "<a href='" +
- setUrl({ filter: undefined, module: undefined, testId: undefined }) +
- "'>" + header.innerHTML + "</a> ";
- }
-}
-
-function appendBanner() {
- var banner = id( "qunit-banner" );
-
- if ( banner ) {
- banner.className = "";
- }
-}
-
-function appendTestResults() {
- var tests = id( "qunit-tests" ),
- result = id( "qunit-testresult" );
-
- if ( result ) {
- result.parentNode.removeChild( result );
- }
-
- if ( tests ) {
- tests.innerHTML = "";
- result = document.createElement( "p" );
- result.id = "qunit-testresult";
- result.className = "result";
- tests.parentNode.insertBefore( result, tests );
- result.innerHTML = "Running...<br />&#160;";
- }
-}
-
-function storeFixture() {
- var fixture = id( "qunit-fixture" );
- if ( fixture ) {
- config.fixture = fixture.innerHTML;
- }
-}
-
-function appendFilteredTest() {
- var testId = QUnit.config.testId;
- if ( !testId || testId.length <= 0 ) {
- return "";
- }
- return "<div id='qunit-filteredTest'>Rerunning selected tests: " + testId.join(", ") +
- " <a id='qunit-clearFilter' href='" +
- setUrl({ filter: undefined, module: undefined, testId: undefined }) +
- "'>" + "Run all tests" + "</a></div>";
-}
-
-function appendUserAgent() {
- var userAgent = id( "qunit-userAgent" );
-
- if ( userAgent ) {
- userAgent.innerHTML = "";
- userAgent.appendChild(
- document.createTextNode(
- "QUnit " + QUnit.version + "; " + navigator.userAgent
- )
- );
- }
-}
-
-function appendTestsList( modules ) {
- var i, l, x, z, test, moduleObj;
-
- for ( i = 0, l = modules.length; i < l; i++ ) {
- moduleObj = modules[ i ];
-
- if ( moduleObj.name ) {
- modulesList.push( moduleObj.name );
- }
-
- for ( x = 0, z = moduleObj.tests.length; x < z; x++ ) {
- test = moduleObj.tests[ x ];
-
- appendTest( test.name, test.testId, moduleObj.name );
- }
- }
-}
-
-function appendTest( name, testId, moduleName ) {
- var title, rerunTrigger, testBlock, assertList,
- tests = id( "qunit-tests" );
-
- if ( !tests ) {
- return;
- }
-
- title = document.createElement( "strong" );
- title.innerHTML = getNameHtml( name, moduleName );
-
- rerunTrigger = document.createElement( "a" );
- rerunTrigger.innerHTML = "Rerun";
- rerunTrigger.href = setUrl({ testId: testId });
-
- testBlock = document.createElement( "li" );
- testBlock.appendChild( title );
- testBlock.appendChild( rerunTrigger );
- testBlock.id = "qunit-test-output-" + testId;
-
- assertList = document.createElement( "ol" );
- assertList.className = "qunit-assert-list";
-
- testBlock.appendChild( assertList );
-
- tests.appendChild( testBlock );
-}
-
-// HTML Reporter initialization and load
-QUnit.begin(function( details ) {
- var qunit = id( "qunit" );
-
- // Fixture is the only one necessary to run without the #qunit element
- storeFixture();
-
- if ( qunit ) {
- qunit.innerHTML =
- "<h1 id='qunit-header'>" + escapeText( document.title ) + "</h1>" +
- "<h2 id='qunit-banner'></h2>" +
- "<div id='qunit-testrunner-toolbar'></div>" +
- appendFilteredTest() +
- "<h2 id='qunit-userAgent'></h2>" +
- "<ol id='qunit-tests'></ol>";
- }
-
- appendHeader();
- appendBanner();
- appendTestResults();
- appendUserAgent();
- appendToolbar();
- appendTestsList( details.modules );
- toolbarModuleFilter();
-
- if ( qunit && config.hidepassed ) {
- addClass( qunit.lastChild, "hidepass" );
- }
-});
-
-QUnit.done(function( details ) {
- var i, key,
- banner = id( "qunit-banner" ),
- tests = id( "qunit-tests" ),
- html = [
- "Tests completed in ",
- details.runtime,
- " milliseconds.<br />",
- "<span class='passed'>",
- details.passed,
- "</span> assertions of <span class='total'>",
- details.total,
- "</span> passed, <span class='failed'>",
- details.failed,
- "</span> failed."
- ].join( "" );
-
- if ( banner ) {
- banner.className = details.failed ? "qunit-fail" : "qunit-pass";
- }
-
- if ( tests ) {
- id( "qunit-testresult" ).innerHTML = html;
- }
-
- if ( config.altertitle && defined.document && document.title ) {
-
- // show ✖ for good, ✔ for bad suite result in title
- // use escape sequences in case file gets loaded with non-utf-8-charset
- document.title = [
- ( details.failed ? "\u2716" : "\u2714" ),
- document.title.replace( /^[\u2714\u2716] /i, "" )
- ].join( " " );
- }
-
- // clear own sessionStorage items if all tests passed
- if ( config.reorder && defined.sessionStorage && details.failed === 0 ) {
- for ( i = 0; i < sessionStorage.length; i++ ) {
- key = sessionStorage.key( i++ );
- if ( key.indexOf( "qunit-test-" ) === 0 ) {
- sessionStorage.removeItem( key );
- }
- }
- }
-
- // scroll back to top to show results
- if ( config.scrolltop && window.scrollTo ) {
- window.scrollTo( 0, 0 );
- }
-});
-
-function getNameHtml( name, module ) {
- var nameHtml = "";
-
- if ( module ) {
- nameHtml = "<span class='module-name'>" + escapeText( module ) + "</span>: ";
- }
-
- nameHtml += "<span class='test-name'>" + escapeText( name ) + "</span>";
-
- return nameHtml;
-}
-
-QUnit.testStart(function( details ) {
- var running, testBlock, bad;
-
- testBlock = id( "qunit-test-output-" + details.testId );
- if ( testBlock ) {
- testBlock.className = "running";
- } else {
-
- // Report later registered tests
- appendTest( details.name, details.testId, details.module );
- }
-
- running = id( "qunit-testresult" );
- if ( running ) {
- bad = QUnit.config.reorder && defined.sessionStorage &&
- +sessionStorage.getItem( "qunit-test-" + details.module + "-" + details.name );
-
- running.innerHTML = ( bad ?
- "Rerunning previously failed test: <br />" :
- "Running: <br />" ) +
- getNameHtml( details.name, details.module );
- }
-
-});
-
-function stripHtml( string ) {
- // strip tags, html entity and whitespaces
- return string.replace(/<\/?[^>]+(>|$)/g, "").replace(/\&quot;/g, "").replace(/\s+/g, "");
-}
-
-QUnit.log(function( details ) {
- var assertList, assertLi,
- message, expected, actual, diff,
- showDiff = false,
- testItem = id( "qunit-test-output-" + details.testId );
-
- if ( !testItem ) {
- return;
- }
-
- message = escapeText( details.message ) || ( details.result ? "okay" : "failed" );
- message = "<span class='test-message'>" + message + "</span>";
- message += "<span class='runtime'>@ " + details.runtime + " ms</span>";
-
- // pushFailure doesn't provide details.expected
- // when it calls, it's implicit to also not show expected and diff stuff
- // Also, we need to check details.expected existence, as it can exist and be undefined
- if ( !details.result && hasOwn.call( details, "expected" ) ) {
- if ( details.negative ) {
- expected = escapeText( "NOT " + QUnit.dump.parse( details.expected ) );
- } else {
- expected = escapeText( QUnit.dump.parse( details.expected ) );
- }
-
- actual = escapeText( QUnit.dump.parse( details.actual ) );
- message += "<table><tr class='test-expected'><th>Expected: </th><td><pre>" +
- expected +
- "</pre></td></tr>";
-
- if ( actual !== expected ) {
-
- message += "<tr class='test-actual'><th>Result: </th><td><pre>" +
- actual + "</pre></td></tr>";
-
- // Don't show diff if actual or expected are booleans
- if ( !( /^(true|false)$/.test( actual ) ) &&
- !( /^(true|false)$/.test( expected ) ) ) {
- diff = QUnit.diff( expected, actual );
- showDiff = stripHtml( diff ).length !==
- stripHtml( expected ).length +
- stripHtml( actual ).length;
- }
-
- // Don't show diff if expected and actual are totally different
- if ( showDiff ) {
- message += "<tr class='test-diff'><th>Diff: </th><td><pre>" +
- diff + "</pre></td></tr>";
- }
- } else if ( expected.indexOf( "[object Array]" ) !== -1 ||
- expected.indexOf( "[object Object]" ) !== -1 ) {
- message += "<tr class='test-message'><th>Message: </th><td>" +
- "Diff suppressed as the depth of object is more than current max depth (" +
- QUnit.config.maxDepth + ").<p>Hint: Use <code>QUnit.dump.maxDepth</code> to " +
- " run with a higher max depth or <a href='" + setUrl({ maxDepth: -1 }) + "'>" +
- "Rerun</a> without max depth.</p></td></tr>";
- }
-
- if ( details.source ) {
- message += "<tr class='test-source'><th>Source: </th><td><pre>" +
- escapeText( details.source ) + "</pre></td></tr>";
- }
-
- message += "</table>";
-
- // this occours when pushFailure is set and we have an extracted stack trace
- } else if ( !details.result && details.source ) {
- message += "<table>" +
- "<tr class='test-source'><th>Source: </th><td><pre>" +
- escapeText( details.source ) + "</pre></td></tr>" +
- "</table>";
- }
-
- assertList = testItem.getElementsByTagName( "ol" )[ 0 ];
-
- assertLi = document.createElement( "li" );
- assertLi.className = details.result ? "pass" : "fail";
- assertLi.innerHTML = message;
- assertList.appendChild( assertLi );
-});
-
-QUnit.testDone(function( details ) {
- var testTitle, time, testItem, assertList,
- good, bad, testCounts, skipped, sourceName,
- tests = id( "qunit-tests" );
-
- if ( !tests ) {
- return;
- }
-
- testItem = id( "qunit-test-output-" + details.testId );
-
- assertList = testItem.getElementsByTagName( "ol" )[ 0 ];
-
- good = details.passed;
- bad = details.failed;
-
- // store result when possible
- if ( config.reorder && defined.sessionStorage ) {
- if ( bad ) {
- sessionStorage.setItem( "qunit-test-" + details.module + "-" + details.name, bad );
- } else {
- sessionStorage.removeItem( "qunit-test-" + details.module + "-" + details.name );
- }
- }
-
- if ( bad === 0 ) {
-
- // Collapse the passing tests
- addClass( assertList, "qunit-collapsed" );
- } else if ( bad && config.collapse && !collapseNext ) {
-
- // Skip collapsing the first failing test
- collapseNext = true;
- } else {
-
- // Collapse remaining tests
- addClass( assertList, "qunit-collapsed" );
- }
-
- // testItem.firstChild is the test name
- testTitle = testItem.firstChild;
-
- testCounts = bad ?
- "<b class='failed'>" + bad + "</b>, " + "<b class='passed'>" + good + "</b>, " :
- "";
-
- testTitle.innerHTML += " <b class='counts'>(" + testCounts +
- details.assertions.length + ")</b>";
-
- if ( details.skipped ) {
- testItem.className = "skipped";
- skipped = document.createElement( "em" );
- skipped.className = "qunit-skipped-label";
- skipped.innerHTML = "skipped";
- testItem.insertBefore( skipped, testTitle );
- } else {
- addEvent( testTitle, "click", function() {
- toggleClass( assertList, "qunit-collapsed" );
- });
-
- testItem.className = bad ? "fail" : "pass";
-
- time = document.createElement( "span" );
- time.className = "runtime";
- time.innerHTML = details.runtime + " ms";
- testItem.insertBefore( time, assertList );
- }
-
- // Show the source of the test when showing assertions
- if ( details.source ) {
- sourceName = document.createElement( "p" );
- sourceName.innerHTML = "<strong>Source: </strong>" + details.source;
- addClass( sourceName, "qunit-source" );
- if ( bad === 0 ) {
- addClass( sourceName, "qunit-collapsed" );
- }
- addEvent( testTitle, "click", function() {
- toggleClass( sourceName, "qunit-collapsed" );
- });
- testItem.appendChild( sourceName );
- }
-});
-
-if ( defined.document ) {
-
- // Avoid readyState issue with phantomjs
- // Ref: #818
- var notPhantom = ( function( p ) {
- return !( p && p.version && p.version.major > 0 );
- } )( window.phantom );
-
- if ( notPhantom && document.readyState === "complete" ) {
- QUnit.load();
- } else {
- addEvent( window, "load", QUnit.load );
- }
-} else {
- config.pageLoaded = true;
- config.autorun = true;
-}
-
-})();
+}() );
diff --git a/package.json b/package.json
index f273608b8..ba9883826 100644
--- a/package.json
+++ b/package.json
@@ -39,18 +39,25 @@
"grunt-eslint": "20.0.0",
"grunt-git-authors": "3.2.0",
"grunt-jsonlint": "1.1.0",
+ "grunt-karma": "2.0.0",
"grunt-newer": "1.3.0",
"grunt-npmcopy": "0.1.0",
"gzip-js": "0.3.2",
"husky": "0.14.3",
"insight": "0.8.4",
"jsdom": "5.6.1",
+ "karma": "1.7.0",
+ "karma-browserstack-launcher": "1.3.0",
+ "karma-chrome-launcher": "2.2.0",
+ "karma-firefox-launcher": "1.0.1",
+ "karma-qunit": "1.2.1",
"load-grunt-tasks": "3.5.2",
"native-promise-only": "0.8.1",
"promises-aplus-tests": "2.1.2",
"q": "1.5.0",
- "qunit-assert-step": "1.1.1",
- "qunitjs": "2.4.0",
+ "qunit-assert-step": "1.0.3",
+ "qunitjs": "1.23.1",
+ "raw-body": "2.2.0",
"requirejs": "2.3.3",
"sinon": "2.3.7",
"sizzle": "2.3.3",
@@ -61,8 +68,9 @@
"scripts": {
"build": "npm install && grunt",
"start": "grunt watch",
- "test": "grunt && grunt test:slow",
- "precommit": "grunt lint:newer",
+ "test": "grunt && grunt test:slow karma:main",
+ "jenkins": "grunt && grunt test:slow",
+ "precommit": "grunt lint:newer qunit_fixture",
"commitmsg": "node node_modules/commitplease"
},
"commitplease": {
diff --git a/test/data/ajax/content-type.php b/test/data/ajax/content-type.php
deleted file mode 100644
index 162e3636d..000000000
--- a/test/data/ajax/content-type.php
+++ /dev/null
@@ -1,5 +0,0 @@
-<?php
- $type = $_REQUEST['content-type'];
- header("Content-type: $type");
- echo $_REQUEST['response']
-?>
diff --git a/test/data/ajax/evalScript.php b/test/data/ajax/evalScript.php
deleted file mode 100644
index ea9b8c55f..000000000
--- a/test/data/ajax/evalScript.php
+++ /dev/null
@@ -1 +0,0 @@
-ok( "<?php echo $_SERVER['REQUEST_METHOD'] ?>" === "GET", "request method is <?php echo $_SERVER['REQUEST_METHOD'] ?>" ); \ No newline at end of file
diff --git a/test/data/ajax/method.php b/test/data/ajax/method.php
deleted file mode 100644
index d76ff964b..000000000
--- a/test/data/ajax/method.php
+++ /dev/null
@@ -1 +0,0 @@
-<?php echo $_SERVER['REQUEST_METHOD'] ?>
diff --git a/test/data/ajax/unreleasedXHR.html b/test/data/ajax/unreleasedXHR.html
index 3eedaabf8..51c5b9486 100644
--- a/test/data/ajax/unreleasedXHR.html
+++ b/test/data/ajax/unreleasedXHR.html
@@ -15,7 +15,7 @@ jQuery(function() {
}, 200 );
var number = 50;
while( number-- ) {
- jQuery.ajax("../name.php?wait=10");
+ jQuery.ajax("../mock.php?action=wait&wait=10");
}
});
</script>
diff --git a/test/data/atom+xml.php b/test/data/atom+xml.php
deleted file mode 100644
index 944591abf..000000000
--- a/test/data/atom+xml.php
+++ /dev/null
@@ -1,4 +0,0 @@
-<?php header("Content-type: atom+xml") ?>
-<root>
- <element />
-</root> \ No newline at end of file
diff --git a/test/data/core/dont_return.php b/test/data/core/dont_return.php
deleted file mode 100644
index 1eef33692..000000000
--- a/test/data/core/dont_return.php
+++ /dev/null
@@ -1,3 +0,0 @@
-<?php
-sleep(30);
-?>
diff --git a/test/data/core/dynamic_ready.html b/test/data/core/dynamic_ready.html
index 1db068b95..e8180cd2b 100644
--- a/test/data/core/dynamic_ready.html
+++ b/test/data/core/dynamic_ready.html
@@ -7,7 +7,7 @@
<script src="../iframeTest.js"></script>
</head>
<body>
-<iframe id="dont_return" src="dont_return.php"></iframe>
+<iframe id="dont_return" src="../mock.php?action=wait&wait=30"></iframe>
<script>
var timeoutId, $,
timeoutFired = false;
diff --git a/test/data/csp.include.html b/test/data/csp.include.html
new file mode 100644
index 000000000..17e2ef0d8
--- /dev/null
+++ b/test/data/csp.include.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>CSP Test Page</title>
+ <script src="../jquery.js"></script>
+ <script src="iframeTest.js"></script>
+ <script src="support/csp.js"></script>
+ <script src="support/getComputedSupport.js"></script>
+</head>
+<body>
+ <p>CSP Test Page</p>
+</body>
+</html>
diff --git a/test/data/echoData.php b/test/data/echoData.php
deleted file mode 100644
index a37ba515a..000000000
--- a/test/data/echoData.php
+++ /dev/null
@@ -1 +0,0 @@
-<?php echo file_get_contents('php://input'); ?>
diff --git a/test/data/echoQuery.php b/test/data/echoQuery.php
deleted file mode 100644
index b72f329c9..000000000
--- a/test/data/echoQuery.php
+++ /dev/null
@@ -1 +0,0 @@
-<?php echo $_SERVER['QUERY_STRING']; ?> \ No newline at end of file
diff --git a/test/data/errorWithJSON.php b/test/data/errorWithJSON.php
deleted file mode 100644
index 62b187ecc..000000000
--- a/test/data/errorWithJSON.php
+++ /dev/null
@@ -1,6 +0,0 @@
-<?php
-
-header("HTTP/1.0 400 Bad Request");
-header("Content-Type: application/json");
-
-echo '{ "code": 40, "message": "Bad Request" }'; \ No newline at end of file
diff --git a/test/data/errorWithText.php b/test/data/errorWithText.php
deleted file mode 100644
index abd873217..000000000
--- a/test/data/errorWithText.php
+++ /dev/null
@@ -1,5 +0,0 @@
-<?php
-
-header("HTTP/1.0 400 Bad Request");
-
-echo "plain text message"; \ No newline at end of file
diff --git a/test/data/etag.php b/test/data/etag.php
deleted file mode 100644
index 66eca4bb1..000000000
--- a/test/data/etag.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-error_reporting(0);
-
-$ts = $_REQUEST['ts'];
-$etag = md5($ts);
-
-$ifNoneMatch = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : "";
-preg_match('/"([^"]+)"/', $ifNoneMatch, $matches);
-$ifNoneMatch = isset($matches[1]) ? $matches[1] : false;
-
-if ($ifNoneMatch == $etag) {
- header('HTTP/1.0 304 Not Modified');
- die; // stop processing
-}
-
-header("Etag: W/\"" . $etag . "\"");
-
-if ( $ifNoneMatch ) {
- echo "OK: " . $etag;
-} else {
- echo "FAIL";
-}
-
-?>
diff --git a/test/data/event/interactiveReady.html b/test/data/event/interactiveReady.html
index 3fb25f907..a80b79467 100644
--- a/test/data/event/interactiveReady.html
+++ b/test/data/event/interactiveReady.html
@@ -18,7 +18,7 @@ jQuery( function () {
oldIE into thinking the dom is ready, but it's not...
leaving this check here for future trailblazers to attempt
fixing this...-->
-<script type="text/javascript" src="../longLoadScript.php?sleep=1"></script>
+<script type="text/javascript" src="../mock.php?action=wait&wait=1"></script>
<div id="container" style="height: 300px"></div>
</body>
</html>
diff --git a/test/data/event/syncReady.html b/test/data/event/syncReady.html
index 61a50e423..5aa510459 100644
--- a/test/data/event/syncReady.html
+++ b/test/data/event/syncReady.html
@@ -18,7 +18,7 @@ jQuery( document ).ready(function () {
oldIE into thinking the dom is ready, but it's not...
leaving this check here for future trailblazers to attempt
fixing this...-->
-<script type="text/javascript" src="../longLoadScript.php?sleep=1"></script>
+<script type="text/javascript" src="../mock.php?action=wait&wait=1"></script>
<div id="container" style="height: 300px"></div>
</body>
</html>
diff --git a/test/data/headers.php b/test/data/headers.php
deleted file mode 100644
index 79c183055..000000000
--- a/test/data/headers.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-
-header( "Sample-Header: Hello World" );
-header( "Empty-Header: " );
-header( "Sample-Header2: Hello World 2" );
-
-$headers = array();
-
-foreach( $_SERVER as $key => $value ) {
-
- $key = str_replace( "_" , "-" , substr( $key , 0 , 5 ) == "HTTP_" ? substr( $key , 5 ) : $key );
- $headers[ $key ] = $value;
-
-}
-
-foreach( explode( "_" , $_GET[ "keys" ] ) as $key ) {
-
- // Only echo if key exists in the header
- if ( isset( $headers[ strtoupper( $key ) ] ) ) {
- echo "$key: " . @$headers[ strtoupper( $key ) ] . "\n";
- }
-
-}
diff --git a/test/data/if_modified_since.php b/test/data/if_modified_since.php
deleted file mode 100644
index 098b7da85..000000000
--- a/test/data/if_modified_since.php
+++ /dev/null
@@ -1,20 +0,0 @@
-<?php
-error_reporting(0);
-
-$ts = $_REQUEST['ts'];
-
-$ifModifiedSince = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE']) : false;
-if ($ifModifiedSince == $ts) {
- header('HTTP/1.0 304 Not Modified');
- die; // stop processing
-}
-
-header("Last-Modified: " . $ts);
-
-if ( $ifModifiedSince ) {
- echo "OK: " . $ts;
-} else {
- echo "FAIL";
-}
-
-?>
diff --git a/test/data/json.php b/test/data/json.php
deleted file mode 100644
index d6e0f2fc7..000000000
--- a/test/data/json.php
+++ /dev/null
@@ -1,13 +0,0 @@
-<?php
-error_reporting(0);
-if ( $_REQUEST['header'] ) {
- header("Content-type: application/json");
-}
-
-$json = $_REQUEST['json'];
-if($json) {
- echo '[ {"name": "John", "age": 21}, {"name": "Peter", "age": 25 } ]';
-} else {
- echo '{ "data": {"lang": "en", "length": 25} }';
-}
-?>
diff --git a/test/data/jsonp.php b/test/data/jsonp.php
deleted file mode 100644
index 6c13d72e9..000000000
--- a/test/data/jsonp.php
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-error_reporting(0);
-$callback = $_REQUEST['callback'];
-if ( ! $callback ) {
- $callback = explode("?",end(explode("/",$_SERVER['REQUEST_URI'])));
- $callback = $callback[0];
-}
-$json = $_REQUEST['json'];
-if($json) {
- echo $callback . '([ {"name": "John", "age": 21}, {"name": "Peter", "age": 25 } ])';
-} else {
- echo $callback . '({ "data": {"lang": "en", "length": 25} })';
-}
-?>
diff --git a/test/data/longLoadScript.php b/test/data/longLoadScript.php
deleted file mode 100644
index ba47168b4..000000000
--- a/test/data/longLoadScript.php
+++ /dev/null
@@ -1,4 +0,0 @@
-<?php
-sleep((int)$_GET['sleep']);
-header('Content-type: text/javascript');
-?> \ No newline at end of file
diff --git a/test/data/mock.php b/test/data/mock.php
new file mode 100644
index 000000000..692c417e8
--- /dev/null
+++ b/test/data/mock.php
@@ -0,0 +1,244 @@
+<?php
+/**
+ * Keep in sync with /test/middleware-mockserver.js
+ */
+class MockServer {
+ protected function contentType( $req ) {
+ $type = $req->query['contentType'];
+ header("Content-type: $type");
+ echo $req->query['response'];
+ }
+
+ protected function wait( $req ) {
+ $wait = (int) $req->query['wait'];
+ sleep( $wait );
+ if ( isset( $req->query['script'] ) ) {
+ header( 'Content-type: text/javascript' );
+ } else {
+ header( 'Content-type: text/html' );
+ echo 'ERROR <script>ok( true, "mock executed" );</script>';
+ }
+ }
+
+ protected function name( $req ) {
+ if ( $req->query['name'] === 'foo' ) {
+ echo 'bar';
+ } elseif ( $_POST['name'] === 'peter' ) {
+ echo 'pan';
+ } else {
+ echo 'ERROR';
+ }
+ }
+
+ protected function xml( $req ) {
+ header( 'Content-type: text/xml' );
+ if ( $req->query['cal'] !== '5-2' && $_POST['cal'] !== '5-2' ) {
+ echo '<error>ERROR</error>';
+ return;
+ }
+ echo "<math><calculation>5-2</calculation><result>3</result></math>\n";
+ }
+
+ protected function atom( $req ) {
+ header( 'Content-type: atom+xml' );
+ echo '<root><element /></root>';
+ }
+
+ protected function script( $req ) {
+ if ( isset( $req->query['header'] ) ) {
+ if ( $req->query['header'] === 'ecma' ) {
+ header( 'Content-type: application/ecmascript' );
+ } else {
+ header( 'Content-type: text/javascript' );
+ }
+ } else {
+ header( 'Content-type: text/html' );
+ }
+ echo 'ok( true, "mock executed" );';
+ }
+
+ // Used to be in test.js, but was renamed to testbar.php
+ // https://github.com/jquery/jquery/commit/d89c278a33#commitcomment-23423165
+ protected function testbar( $req ) {
+ echo 'this.testBar = "bar";
+jQuery("#ap").html("bar");
+ok( true, "mock executed");';
+ }
+
+ protected function json( $req ) {
+ if ( isset( $req->query['header'] ) ) {
+ header( 'Content-type: application/json' );
+ }
+
+ if ( isset( $req->query['array'] ) ) {
+ echo '[ {"name": "John", "age": 21}, {"name": "Peter", "age": 25 } ]';
+ } else {
+ echo '{ "data": {"lang": "en", "length": 25} }';
+ }
+ }
+
+ protected function jsonp( $req ) {
+ if ( isset( $req->query['callback'] ) ) {
+ $callback = $req->query['callback'];
+ } elseif ( $req->method === 'GET' ) {
+ // Try REST-like path
+ preg_match( '/\/([^\/?]+)\?.+$/', $req->url, $m );
+ $callback = $m[1];
+ } else {
+ $callback = $_POST['callback'];
+ }
+ if ( isset( $req->query['array'] ) ) {
+ echo $callback . '([ {"name": "John", "age": 21}, {"name": "Peter", "age": 25 } ])';
+ } else {
+ echo $callback . '({ "data": {"lang": "en", "length": 25} })';
+ }
+ }
+
+ protected function xmlOverJsonp( $req ) {
+ $callback = $_REQUEST['callback'];
+ $text = json_encode( file_get_contents( __DIR__ . '/with_fries.xml' ) );
+ echo "$callback($text)\n";
+ }
+
+ protected function error( $req ) {
+ header( 'HTTP/1.0 400 Bad Request' );
+ if ( isset( $req->query['json'] ) ) {
+ header( 'Content-Type: application/json' );
+ echo '{ "code": 40, "message": "Bad Request" }';
+ } else {
+ echo 'plain text message';
+ }
+ }
+
+ protected function headers( $req ) {
+ header( 'Sample-Header: Hello World' );
+ header( 'Empty-Header: ' );
+ header( 'Sample-Header2: Hello World 2' );
+
+ foreach ( explode( '|' , $req->query[ 'keys' ] ) as $key ) {
+ // Only echo if key exists in the header
+ if ( isset( $req->headers[ strtoupper( $key ) ] ) ) {
+ echo "$key: " . $req->headers[ strtoupper( $key ) ] . "\n";
+ }
+ }
+
+ }
+
+ protected function echoData( $req ) {
+ echo file_get_contents('php://input');
+ }
+
+ protected function echoQuery( $req ) {
+ echo $_SERVER['QUERY_STRING'];
+ }
+
+ protected function echoMethod( $req ) {
+ echo $req->method;
+ }
+
+ protected function echoHtml( $req ) {
+ header( 'Content-type: text/html' );
+ echo '<div id="method">' . $req->method . '</div>';
+ echo '<div id="query">' . $_SERVER['QUERY_STRING'] . '</div>';
+ echo '<div id="data">' . file_get_contents('php://input') . '</div>';
+ }
+
+ protected function etag( $req ) {
+ $hash = md5( $req->query['ts'] );
+ $etag = 'W/"' . $hash . '"';
+
+ $ifNoneMatch = isset( $req->headers['IF-NONE-MATCH'] ) ? $req->headers['IF-NONE-MATCH'] : '';
+ if ($ifNoneMatch === $etag) {
+ header('HTTP/1.0 304 Not Modified');
+ return;
+ }
+
+ header("Etag: $etag");
+ echo "ETag: $etag\n";
+ if ( $ifNoneMatch ) {
+ echo "If-None-Match: $ifNoneMatch\n";
+ }
+ }
+
+ protected function ims( $req ) {
+ $ts = $req->query['ts'];
+
+ $ims = isset( $req->headers['IF-MODIFIED-SINCE'] ) ? $req->headers['IF-MODIFIED-SINCE'] : '';
+ if ($ims === $ts) {
+ header('HTTP/1.0 304 Not Modified');
+ return;
+ }
+
+ header("Last-Modified: $ts");
+ echo "Last-Modified: $ts\n";
+ if ( $ims ) {
+ echo "If-Modified-Since: $ims\n";
+ }
+ }
+
+ protected function status( $req ) {
+ header( "HTTP/1.0 {$req->query['code']} {$req->query['text']}" );
+ }
+
+ protected function testHTML( $req ) {
+ header( 'Content-type: text/html' );
+ $html = file_get_contents( __DIR__ . '/test.include.html' );
+ $html = str_replace( '{{baseURL}}', $req->query['baseURL'], $html );
+ echo $html;
+ }
+
+ protected function cspFrame( $req ) {
+ // This is CSP only for browsers with "Content-Security-Policy" header support
+ // i.e. no old WebKit or old Firefox
+ header( "Content-Security-Policy: default-src 'self'; report-uri ./mock.php?action=cspLog" );
+ header( 'Content-type: text/html' );
+ echo file_get_contents( __DIR__ . '/csp.include.html' );
+ }
+
+ protected function cspLog( $req ) {
+ file_put_contents( $this->cspFile, 'error' );
+ }
+
+ protected function cspClean( $req ) {
+ file_put_contents( $this->cspFile, '' );
+ unlink( $this->cspFile );
+ }
+
+ public function __construct() {
+ $this->cspFile = __DIR__ . '/support/csp.log';
+ }
+
+ public function respond( stdClass $req ) {
+ if ( !isset( $req->query['action'] ) || !method_exists( $this, $req->query['action'] ) ) {
+ header( "HTTP/1.0 400 Bad Request" );
+ echo "Invalid action query.\n";
+ return;
+ }
+ $this->{$req->query['action']}( $req );
+ }
+}
+
+// Don't include PHP errors in http response
+error_reporting( 0 );
+
+// Collect headers
+$headers = array();
+foreach ( $_SERVER as $name => $value ) {
+ if ( substr( $name, 0, 5 ) === 'HTTP_' ) {
+ $name = str_replace( '_', '-', substr( $name, 5 ) );
+ $headers[$name] = $value;
+ } elseif ( $name === 'CONTENT_LENGTH' ) {
+ $headers['CONTENT-LENGTH'] = $value;
+ } elseif ( $name === 'CONTENT_TYPE' ) {
+ $headers['CONTENT-TYPE'] = $value;
+ }
+}
+
+$mock = new MockServer();
+$req = (object) array(
+ 'query' => $_GET,
+ 'headers' => $headers,
+ 'method' => $_SERVER['REQUEST_METHOD'],
+ 'url' => $_SERVER['REQUEST_URI'],
+);
+$mock->respond( $req );
diff --git a/test/data/name.php b/test/data/name.php
deleted file mode 100644
index 64028585d..000000000
--- a/test/data/name.php
+++ /dev/null
@@ -1,24 +0,0 @@
-<?php
-error_reporting(0);
-$wait = $_REQUEST['wait'];
-if($wait) {
- sleep($wait);
-}
-$xml = $_REQUEST['xml'];
-if($xml) {
- header("Content-type: text/xml");
- $result = ($xml == "5-2") ? "3" : "?";
- echo "<math><calculation>$xml</calculation><result>$result</result></math>";
- die();
-}
-$name = $_REQUEST['name'];
-if($name == 'foo') {
- echo "bar";
- die();
-} else if($name == 'peter') {
- echo "pan";
- die();
-}
-
-echo 'ERROR <script type="text/javascript">ok( true, "name.php executed" );</script>';
-?> \ No newline at end of file
diff --git a/test/data/nocontent.php b/test/data/nocontent.php
deleted file mode 100644
index 9c8431bd7..000000000
--- a/test/data/nocontent.php
+++ /dev/null
@@ -1,5 +0,0 @@
-<?php
-
-header('HTTP/1.0 204 No Content');
-
-?> \ No newline at end of file
diff --git a/test/data/params_html.php b/test/data/params_html.php
deleted file mode 100644
index e88ef1521..000000000
--- a/test/data/params_html.php
+++ /dev/null
@@ -1,12 +0,0 @@
-<div id="post">
-<?php
- foreach( $_POST as $key=>$value )
- echo "<b id='$key'>$value</b>";
-?>
-</div>
-<div id="get">
-<?php
- foreach( $_GET as $key=>$value )
- echo "<b id='$key'>$value</b>";
-?>
-</div> \ No newline at end of file
diff --git a/test/data/qunit-fixture.html b/test/data/qunit-fixture.html
new file mode 100644
index 000000000..e0fd3e60e
--- /dev/null
+++ b/test/data/qunit-fixture.html
@@ -0,0 +1,237 @@
+<p id="firstp">See <a id="simon1" href="http://simon.incutio.com/archive/2003/03/25/#getElementsBySelector" rel="bookmark">this blog entry</a> for more information.</p>
+<p id="ap">
+ Here are some links in a normal paragraph: <a id="google" href="http://www.google.com/" title="Google!">Google</a>,
+ <a id="groups" href="http://groups.google.com/" class="GROUPS">Google Groups (Link)</a>.
+ This link has <code><a href="http://smin" id="anchor1">class="blog"</a></code>:
+ <a href="http://diveintomark.org/" class="blog" hreflang="en" id="mark">diveintomark</a>
+
+</p>
+<div id="foo">
+ <p id="sndp">Everything inside the red border is inside a div with <code>id="foo"</code>.</p>
+ <p lang="en" id="en">This is a normal link: <a id="yahoo" href="http://www.yahoo.com/" class="blogTest">Yahoo</a></p>
+ <p id="sap">This link has <code><a href="#2" id="anchor2">class="blog"</a></code>: <a href="http://simon.incutio.com/" class="blog link" id="simon">Simon Willison's Weblog</a></p>
+
+</div>
+<div id="nothiddendiv" style="height:1px;background:white;" class="nothiddendiv">
+ <div id="nothiddendivchild"></div>
+</div>
+<span id="name+value"></span>
+<p id="first">Try them out:</p>
+<ul id="firstUL"></ul>
+<ol id="empty"></ol>
+<form id="form" action="formaction">
+ <label for="action" id="label-for">Action:</label>
+ <input type="text" name="action" value="Test" id="text1" maxlength="30"/>
+ <input type="text" name="text2" value="Test" id="text2" disabled="disabled"/>
+ <input type="radio" name="radio1" id="radio1" value="on"/>
+
+ <input type="radio" name="radio2" id="radio2" checked="checked"/>
+ <input type="checkbox" name="check" id="check1" checked="checked"/>
+ <input type="checkbox" id="check2" value="on"/>
+
+ <input type="hidden" name="hidden" id="hidden1"/>
+ <input type="text" style="display:none;" name="foo[bar]" id="hidden2"/>
+
+ <input type="text" id="name" name="name" value="name" />
+ <input type="search" id="search" name="search" value="search" />
+
+ <button id="button" name="button" type="button">Button</button>
+
+ <textarea id="area1" maxlength="30">foobar</textarea>
+
+ <select name="select1" id="select1">
+ <option id="option1a" class="emptyopt" value="">Nothing</option>
+ <option id="option1b" value="1">1</option>
+ <option id="option1c" value="2">2</option>
+ <option id="option1d" value="3">3</option>
+ </select>
+ <select name="select2" id="select2">
+ <option id="option2a" class="emptyopt" value="">Nothing</option>
+ <option id="option2b" value="1">1</option>
+ <option id="option2c" value="2">2</option>
+ <option id="option2d" selected="selected" value="3">3</option>
+ </select>
+ <select name="select3" id="select3" multiple="multiple">
+ <option id="option3a" class="emptyopt" value="">Nothing</option>
+ <option id="option3b" selected="selected" value="1">1</option>
+ <option id="option3c" selected="selected" value="2">2</option>
+ <option id="option3d" value="3">3</option>
+ <option id="option3e">no value</option>
+ </select>
+ <select name="select4" id="select4" multiple="multiple">
+ <optgroup disabled="disabled">
+ <option id="option4a" class="emptyopt" value="">Nothing</option>
+ <option id="option4b" disabled="disabled" selected="selected" value="1">1</option>
+ <option id="option4c" selected="selected" value="2">2</option>
+ </optgroup>
+ <option selected="selected" disabled="disabled" id="option4d" value="3">3</option>
+ <option id="option4e">no value</option>
+ </select>
+ <select name="select5" id="select5">
+ <option id="option5a" value="3">1</option>
+ <option id="option5b" value="2">2</option>
+ <option id="option5c" value="1" data-attr="">3</option>
+ </select>
+
+ <object id="object1" codebase="stupid">
+ <param name="p1" value="x1" />
+ <param name="p2" value="x2" />
+ </object>
+
+ <span id="台北Táiběi"></span>
+ <span id="台北" lang="中文"></span>
+ <span id="utf8class1" class="台北Táiběi 台北"></span>
+ <span id="utf8class2" class="台北"></span>
+ <span id="foo:bar" class="foo:bar"></span>
+ <span id="test.foo[5]bar" class="test.foo[5]bar"></span>
+
+ <foo_bar id="foobar">test element</foo_bar>
+</form>
+<b id="floatTest">Float test.</b>
+<iframe id="iframe" name="iframe"></iframe>
+<form id="lengthtest">
+ <input type="text" id="length" name="test"/>
+ <input type="text" id="idTest" name="id"/>
+</form>
+<table id="table"></table>
+
+<form id="name-tests">
+ <!-- Inputs with a grouped name attribute. -->
+ <input name="types[]" id="types_all" type="checkbox" value="all" />
+ <input name="types[]" id="types_anime" type="checkbox" value="anime" />
+ <input name="types[]" id="types_movie" type="checkbox" value="movie" />
+</form>
+
+<form id="testForm" action="#" method="get">
+ <textarea name="T3" rows="2" cols="15">?
+Z</textarea>
+ <input type="hidden" name="H1" value="x" />
+ <input type="hidden" name="H2" />
+ <input name="PWD" type="password" value="" />
+ <input name="T1" type="text" />
+ <input name="T2" type="text" value="YES" readonly="readonly" />
+ <input type="checkbox" name="C1" value="1" />
+ <input type="checkbox" name="C2" />
+ <input type="radio" name="R1" value="1" />
+ <input type="radio" name="R1" value="2" />
+ <input type="text" name="My Name" value="me" />
+ <input type="reset" name="reset" value="NO" />
+ <select name="S1">
+ <option value="abc">ABC</option>
+ <option value="abc">ABC</option>
+ <option value="abc">ABC</option>
+ </select>
+ <select name="S2" multiple="multiple" size="3">
+ <option value="abc">ABC</option>
+ <option value="abc">ABC</option>
+ <option value="abc">ABC</option>
+ </select>
+ <select name="S3">
+ <option selected="selected">YES</option>
+ </select>
+ <select name="S4">
+ <option value="" selected="selected">NO</option>
+ </select>
+ <input type="submit" name="sub1" value="NO" />
+ <input type="submit" name="sub2" value="NO" />
+ <input type="image" name="sub3" value="NO" />
+ <button name="sub4" type="submit" value="NO">NO</button>
+ <input name="D1" type="text" value="NO" disabled="disabled" />
+ <input type="checkbox" checked="checked" disabled="disabled" name="D2" value="NO" />
+ <input type="radio" name="D3" value="NO" checked="checked" disabled="disabled" />
+ <select name="D4" disabled="disabled">
+ <option selected="selected" value="NO">NO</option>
+ </select>
+ <input id="list-test" type="text" />
+ <datalist id="datalist">
+ <option value="option"></option>
+ </datalist>
+</form>
+<div id="moretests">
+ <form>
+ <div id="checkedtest" style="display:none;">
+ <input type="radio" name="checkedtestradios" checked="checked"/>
+ <input type="radio" name="checkedtestradios" value="on"/>
+ <input type="checkbox" name="checkedtestcheckboxes" checked="checked"/>
+ <input type="checkbox" name="checkedtestcheckboxes" />
+ </div>
+ </form>
+ <div id="nonnodes"><span id="nonnodesElement">hi</span> there <!-- mon ami --></div>
+ <div id="t2037">
+ <div><div class="hidden">hidden</div></div>
+ </div>
+ <div id="t6652">
+ <div></div>
+ </div>
+ <div id="no-clone-exception"><object><embed></embed></object></div>
+</div>
+
+<div id="tabindex-tests">
+ <ol id="listWithTabIndex" tabindex="5">
+ <li id="foodWithNegativeTabIndex" tabindex="-1">Rice</li>
+ <li id="foodNoTabIndex">Beans</li>
+ <li>Blinis</li>
+ <li>Tofu</li>
+ </ol>
+
+ <div id="divWithNoTabIndex">I'm hungry. I should...</div>
+ <span>...</span><a href="#" id="linkWithNoTabIndex">Eat lots of food</a><span>...</span> |
+ <span>...</span><a href="#" id="linkWithTabIndex" tabindex="2">Eat a little food</a><span>...</span> |
+ <span>...</span><a href="#" id="linkWithNegativeTabIndex" tabindex="-1">Eat no food</a><span>...</span>
+ <span>...</span><a id="linkWithNoHrefWithNoTabIndex">Eat a burger</a><span>...</span>
+ <span>...</span><a id="linkWithNoHrefWithTabIndex" tabindex="1">Eat some funyuns</a><span>...</span>
+ <span>...</span><a id="linkWithNoHrefWithNegativeTabIndex" tabindex="-1">Eat some funyuns</a><span>...</span>
+ <input id="inputWithoutTabIndex"/>
+ <button id="buttonWithoutTabIndex"></button>
+ <textarea id="textareaWithoutTabIndex"></textarea>
+ <menu type="popup">
+ <menuitem id="menuitemWithoutTabIndex" command="submitbutton" default/>
+ </menu>
+</div>
+
+<div id="liveHandlerOrder">
+ <span id="liveSpan1"><a href="#" id="liveLink1"></a></span>
+ <span id="liveSpan2"><a href="#" id="liveLink2"></a></span>
+</div>
+
+<div id="siblingTest">
+ <em id="siblingfirst">1</em>
+ <em id="siblingnext">2</em>
+ <em id="siblingthird">
+ <em id="siblingchild">
+ <em id="siblinggrandchild">
+ <em id="siblinggreatgrandchild"></em>
+ </em>
+ </em>
+ </em>
+ <span id="siblingspan"></span>
+</div>
+<div id="fx-test-group" style="position: absolute; width: 1px; height: 1px; overflow: hidden;">
+ <div id="fx-queue" name="test">
+ <div id="fadein" class='chain-test' name='div'>fadeIn<div>fadeIn</div></div>
+ <div id="fadeout" class='chain-test chain-test-out'>fadeOut<div>fadeOut</div></div>
+
+ <div id="show" class='chain-test'>show<div>show</div></div>
+ <div id="hide" class='chain-test chain-test-out'>hide<div>hide</div></div>
+ <div id="easehide" class='chain-test chain-test-out'>hide<div>hide</div></div>
+
+ <div id="togglein" class='chain-test'>togglein<div>togglein</div></div>
+ <div id="toggleout" class='chain-test chain-test-out'>toggleout<div>toggleout</div></div>
+ <div id="easetoggleout" class='chain-test chain-test-out'>toggleout<div>toggleout</div></div>
+
+ <div id="slideup" class='chain-test'>slideUp<div>slideUp</div></div>
+ <div id="slidedown" class='chain-test chain-test-out'>slideDown<div>slideDown</div></div>
+ <div id="easeslideup" class='chain-test'>slideUp<div>slideUp</div></div>
+
+ <div id="slidetogglein" class='chain-test'>slideToggleIn<div>slideToggleIn</div></div>
+ <div id="slidetoggleout" class='chain-test chain-test-out'>slideToggleOut<div>slideToggleOut</div></div>
+
+ <div id="fadetogglein" class='chain-test'>fadeToggleIn<div>fadeToggleIn</div></div>
+ <div id="fadetoggleout" class='chain-test chain-test-out'>fadeToggleOut<div>fadeToggleOut</div></div>
+
+ <div id="fadeto" class='chain-test'>fadeTo<div>fadeTo</div></div>
+ </div>
+
+ <div id="fx-tests"></div>
+ <span id="display"></span>
+</div>
diff --git a/test/data/qunit-fixture.js b/test/data/qunit-fixture.js
new file mode 100644
index 000000000..6ea2f3b3d
--- /dev/null
+++ b/test/data/qunit-fixture.js
@@ -0,0 +1,4 @@
+// Generated by build/tasks/qunit_fixture.js
+QUnit.config.fixture = "<p id=\"firstp\">See <a id=\"simon1\" href=\"http://simon.incutio.com/archive/2003/03/25/#getElementsBySelector\" rel=\"bookmark\">this blog entry</a> for more information.</p>\n<p id=\"ap\">\n\tHere are some links in a normal paragraph: <a id=\"google\" href=\"http://www.google.com/\" title=\"Google!\">Google</a>,\n\t<a id=\"groups\" href=\"http://groups.google.com/\" class=\"GROUPS\">Google Groups (Link)</a>.\n\tThis link has <code><a href=\"http://smin\" id=\"anchor1\">class=\"blog\"</a></code>:\n\t<a href=\"http://diveintomark.org/\" class=\"blog\" hreflang=\"en\" id=\"mark\">diveintomark</a>\n\n</p>\n<div id=\"foo\">\n\t<p id=\"sndp\">Everything inside the red border is inside a div with <code>id=\"foo\"</code>.</p>\n\t<p lang=\"en\" id=\"en\">This is a normal link: <a id=\"yahoo\" href=\"http://www.yahoo.com/\" class=\"blogTest\">Yahoo</a></p>\n\t<p id=\"sap\">This link has <code><a href=\"#2\" id=\"anchor2\">class=\"blog\"</a></code>: <a href=\"http://simon.incutio.com/\" class=\"blog link\" id=\"simon\">Simon Willison's Weblog</a></p>\n\n</div>\n<div id=\"nothiddendiv\" style=\"height:1px;background:white;\" class=\"nothiddendiv\">\n\t<div id=\"nothiddendivchild\"></div>\n</div>\n<span id=\"name+value\"></span>\n<p id=\"first\">Try them out:</p>\n<ul id=\"firstUL\"></ul>\n<ol id=\"empty\"></ol>\n<form id=\"form\" action=\"formaction\">\n\t<label for=\"action\" id=\"label-for\">Action:</label>\n\t<input type=\"text\" name=\"action\" value=\"Test\" id=\"text1\" maxlength=\"30\"/>\n\t<input type=\"text\" name=\"text2\" value=\"Test\" id=\"text2\" disabled=\"disabled\"/>\n\t<input type=\"radio\" name=\"radio1\" id=\"radio1\" value=\"on\"/>\n\n\t<input type=\"radio\" name=\"radio2\" id=\"radio2\" checked=\"checked\"/>\n\t<input type=\"checkbox\" name=\"check\" id=\"check1\" checked=\"checked\"/>\n\t<input type=\"checkbox\" id=\"check2\" value=\"on\"/>\n\n\t<input type=\"hidden\" name=\"hidden\" id=\"hidden1\"/>\n\t<input type=\"text\" style=\"display:none;\" name=\"foo[bar]\" id=\"hidden2\"/>\n\n\t<input type=\"text\" id=\"name\" name=\"name\" value=\"name\" />\n\t<input type=\"search\" id=\"search\" name=\"search\" value=\"search\" />\n\n\t<button id=\"button\" name=\"button\" type=\"button\">Button</button>\n\n\t<textarea id=\"area1\" maxlength=\"30\">foobar</textarea>\n\n\t<select name=\"select1\" id=\"select1\">\n\t\t<option id=\"option1a\" class=\"emptyopt\" value=\"\">Nothing</option>\n\t\t<option id=\"option1b\" value=\"1\">1</option>\n\t\t<option id=\"option1c\" value=\"2\">2</option>\n\t\t<option id=\"option1d\" value=\"3\">3</option>\n\t</select>\n\t<select name=\"select2\" id=\"select2\">\n\t\t<option id=\"option2a\" class=\"emptyopt\" value=\"\">Nothing</option>\n\t\t<option id=\"option2b\" value=\"1\">1</option>\n\t\t<option id=\"option2c\" value=\"2\">2</option>\n\t\t<option id=\"option2d\" selected=\"selected\" value=\"3\">3</option>\n\t</select>\n\t<select name=\"select3\" id=\"select3\" multiple=\"multiple\">\n\t\t<option id=\"option3a\" class=\"emptyopt\" value=\"\">Nothing</option>\n\t\t<option id=\"option3b\" selected=\"selected\" value=\"1\">1</option>\n\t\t<option id=\"option3c\" selected=\"selected\" value=\"2\">2</option>\n\t\t<option id=\"option3d\" value=\"3\">3</option>\n\t\t<option id=\"option3e\">no value</option>\n\t</select>\n\t<select name=\"select4\" id=\"select4\" multiple=\"multiple\">\n\t\t<optgroup disabled=\"disabled\">\n\t\t\t<option id=\"option4a\" class=\"emptyopt\" value=\"\">Nothing</option>\n\t\t\t<option id=\"option4b\" disabled=\"disabled\" selected=\"selected\" value=\"1\">1</option>\n\t\t\t<option id=\"option4c\" selected=\"selected\" value=\"2\">2</option>\n\t\t</optgroup>\n\t\t<option selected=\"selected\" disabled=\"disabled\" id=\"option4d\" value=\"3\">3</option>\n\t\t<option id=\"option4e\">no value</option>\n\t</select>\n\t<select name=\"select5\" id=\"select5\">\n\t\t<option id=\"option5a\" value=\"3\">1</option>\n\t\t<option id=\"option5b\" value=\"2\">2</option>\n\t\t<option id=\"option5c\" value=\"1\" data-attr=\"\">3</option>\n\t</select>\n\n\t<object id=\"object1\" codebase=\"stupid\">\n\t\t<param name=\"p1\" value=\"x1\" />\n\t\t<param name=\"p2\" value=\"x2\" />\n\t</object>\n\n\t<span id=\"台北Táiběi\"></span>\n\t<span id=\"台北\" lang=\"中文\"></span>\n\t<span id=\"utf8class1\" class=\"台北Táiběi 台北\"></span>\n\t<span id=\"utf8class2\" class=\"台北\"></span>\n\t<span id=\"foo:bar\" class=\"foo:bar\"></span>\n\t<span id=\"test.foo[5]bar\" class=\"test.foo[5]bar\"></span>\n\n\t<foo_bar id=\"foobar\">test element</foo_bar>\n</form>\n<b id=\"floatTest\">Float test.</b>\n<iframe id=\"iframe\" name=\"iframe\"></iframe>\n<form id=\"lengthtest\">\n\t<input type=\"text\" id=\"length\" name=\"test\"/>\n\t<input type=\"text\" id=\"idTest\" name=\"id\"/>\n</form>\n<table id=\"table\"></table>\n\n<form id=\"name-tests\">\n\t<!-- Inputs with a grouped name attribute. -->\n\t<input name=\"types[]\" id=\"types_all\" type=\"checkbox\" value=\"all\" />\n\t<input name=\"types[]\" id=\"types_anime\" type=\"checkbox\" value=\"anime\" />\n\t<input name=\"types[]\" id=\"types_movie\" type=\"checkbox\" value=\"movie\" />\n</form>\n\n<form id=\"testForm\" action=\"#\" method=\"get\">\n\t<textarea name=\"T3\" rows=\"2\" cols=\"15\">?\nZ</textarea>\n\t<input type=\"hidden\" name=\"H1\" value=\"x\" />\n\t<input type=\"hidden\" name=\"H2\" />\n\t<input name=\"PWD\" type=\"password\" value=\"\" />\n\t<input name=\"T1\" type=\"text\" />\n\t<input name=\"T2\" type=\"text\" value=\"YES\" readonly=\"readonly\" />\n\t<input type=\"checkbox\" name=\"C1\" value=\"1\" />\n\t<input type=\"checkbox\" name=\"C2\" />\n\t<input type=\"radio\" name=\"R1\" value=\"1\" />\n\t<input type=\"radio\" name=\"R1\" value=\"2\" />\n\t<input type=\"text\" name=\"My Name\" value=\"me\" />\n\t<input type=\"reset\" name=\"reset\" value=\"NO\" />\n\t<select name=\"S1\">\n\t\t<option value=\"abc\">ABC</option>\n\t\t<option value=\"abc\">ABC</option>\n\t\t<option value=\"abc\">ABC</option>\n\t</select>\n\t<select name=\"S2\" multiple=\"multiple\" size=\"3\">\n\t\t<option value=\"abc\">ABC</option>\n\t\t<option value=\"abc\">ABC</option>\n\t\t<option value=\"abc\">ABC</option>\n\t</select>\n\t<select name=\"S3\">\n\t\t<option selected=\"selected\">YES</option>\n\t</select>\n\t<select name=\"S4\">\n\t\t<option value=\"\" selected=\"selected\">NO</option>\n\t</select>\n\t<input type=\"submit\" name=\"sub1\" value=\"NO\" />\n\t<input type=\"submit\" name=\"sub2\" value=\"NO\" />\n\t<input type=\"image\" name=\"sub3\" value=\"NO\" />\n\t<button name=\"sub4\" type=\"submit\" value=\"NO\">NO</button>\n\t<input name=\"D1\" type=\"text\" value=\"NO\" disabled=\"disabled\" />\n\t<input type=\"checkbox\" checked=\"checked\" disabled=\"disabled\" name=\"D2\" value=\"NO\" />\n\t<input type=\"radio\" name=\"D3\" value=\"NO\" checked=\"checked\" disabled=\"disabled\" />\n\t<select name=\"D4\" disabled=\"disabled\">\n\t\t<option selected=\"selected\" value=\"NO\">NO</option>\n\t</select>\n\t<input id=\"list-test\" type=\"text\" />\n\t<datalist id=\"datalist\">\n\t\t<option value=\"option\"></option>\n\t</datalist>\n</form>\n<div id=\"moretests\">\n\t<form>\n\t\t<div id=\"checkedtest\" style=\"display:none;\">\n\t\t\t<input type=\"radio\" name=\"checkedtestradios\" checked=\"checked\"/>\n\t\t\t<input type=\"radio\" name=\"checkedtestradios\" value=\"on\"/>\n\t\t\t<input type=\"checkbox\" name=\"checkedtestcheckboxes\" checked=\"checked\"/>\n\t\t\t<input type=\"checkbox\" name=\"checkedtestcheckboxes\" />\n\t\t</div>\n\t</form>\n\t<div id=\"nonnodes\"><span id=\"nonnodesElement\">hi</span> there <!-- mon ami --></div>\n\t<div id=\"t2037\">\n\t\t<div><div class=\"hidden\">hidden</div></div>\n\t</div>\n\t<div id=\"t6652\">\n\t\t<div></div>\n\t</div>\n\t<div id=\"no-clone-exception\"><object><embed></embed></object></div>\n</div>\n\n<div id=\"tabindex-tests\">\n\t<ol id=\"listWithTabIndex\" tabindex=\"5\">\n\t\t<li id=\"foodWithNegativeTabIndex\" tabindex=\"-1\">Rice</li>\n\t\t<li id=\"foodNoTabIndex\">Beans</li>\n\t\t<li>Blinis</li>\n\t\t<li>Tofu</li>\n\t</ol>\n\n\t<div id=\"divWithNoTabIndex\">I'm hungry. I should...</div>\n\t<span>...</span><a href=\"#\" id=\"linkWithNoTabIndex\">Eat lots of food</a><span>...</span> |\n\t<span>...</span><a href=\"#\" id=\"linkWithTabIndex\" tabindex=\"2\">Eat a little food</a><span>...</span> |\n\t<span>...</span><a href=\"#\" id=\"linkWithNegativeTabIndex\" tabindex=\"-1\">Eat no food</a><span>...</span>\n\t<span>...</span><a id=\"linkWithNoHrefWithNoTabIndex\">Eat a burger</a><span>...</span>\n\t<span>...</span><a id=\"linkWithNoHrefWithTabIndex\" tabindex=\"1\">Eat some funyuns</a><span>...</span>\n\t<span>...</span><a id=\"linkWithNoHrefWithNegativeTabIndex\" tabindex=\"-1\">Eat some funyuns</a><span>...</span>\n\t<input id=\"inputWithoutTabIndex\"/>\n\t<button id=\"buttonWithoutTabIndex\"></button>\n\t<textarea id=\"textareaWithoutTabIndex\"></textarea>\n\t<menu type=\"popup\">\n\t\t<menuitem id=\"menuitemWithoutTabIndex\" command=\"submitbutton\" default/>\n\t</menu>\n</div>\n\n<div id=\"liveHandlerOrder\">\n\t<span id=\"liveSpan1\"><a href=\"#\" id=\"liveLink1\"></a></span>\n\t<span id=\"liveSpan2\"><a href=\"#\" id=\"liveLink2\"></a></span>\n</div>\n\n<div id=\"siblingTest\">\n\t<em id=\"siblingfirst\">1</em>\n\t<em id=\"siblingnext\">2</em>\n\t<em id=\"siblingthird\">\n\t\t<em id=\"siblingchild\">\n\t\t\t<em id=\"siblinggrandchild\">\n\t\t\t\t<em id=\"siblinggreatgrandchild\"></em>\n\t\t\t</em>\n\t\t</em>\n\t</em>\n\t<span id=\"siblingspan\"></span>\n</div>\n<div id=\"fx-test-group\" style=\"position: absolute; width: 1px; height: 1px; overflow: hidden;\">\n\t<div id=\"fx-queue\" name=\"test\">\n\t\t<div id=\"fadein\" class='chain-test' name='div'>fadeIn<div>fadeIn</div></div>\n\t\t<div id=\"fadeout\" class='chain-test chain-test-out'>fadeOut<div>fadeOut</div></div>\n\n\t\t<div id=\"show\" class='chain-test'>show<div>show</div></div>\n\t\t<div id=\"hide\" class='chain-test chain-test-out'>hide<div>hide</div></div>\n\t\t<div id=\"easehide\" class='chain-test chain-test-out'>hide<div>hide</div></div>\n\n\t\t<div id=\"togglein\" class='chain-test'>togglein<div>togglein</div></div>\n\t\t<div id=\"toggleout\" class='chain-test chain-test-out'>toggleout<div>toggleout</div></div>\n\t\t<div id=\"easetoggleout\" class='chain-test chain-test-out'>toggleout<div>toggleout</div></div>\n\n\t\t<div id=\"slideup\" class='chain-test'>slideUp<div>slideUp</div></div>\n\t\t<div id=\"slidedown\" class='chain-test chain-test-out'>slideDown<div>slideDown</div></div>\n\t\t<div id=\"easeslideup\" class='chain-test'>slideUp<div>slideUp</div></div>\n\n\t\t<div id=\"slidetogglein\" class='chain-test'>slideToggleIn<div>slideToggleIn</div></div>\n\t\t<div id=\"slidetoggleout\" class='chain-test chain-test-out'>slideToggleOut<div>slideToggleOut</div></div>\n\n\t\t<div id=\"fadetogglein\" class='chain-test'>fadeToggleIn<div>fadeToggleIn</div></div>\n\t\t<div id=\"fadetoggleout\" class='chain-test chain-test-out'>fadeToggleOut<div>fadeToggleOut</div></div>\n\n\t\t<div id=\"fadeto\" class='chain-test'>fadeTo<div>fadeTo</div></div>\n\t</div>\n\n\t<div id=\"fx-tests\"></div>\n\t<span id=\"display\"></span>\n</div>\n";
+// Compat with QUnit 1.x:
+document.getElementById( "qunit-fixture" ).innerHTML = QUnit.config.fixture;
diff --git a/test/data/script.php b/test/data/script.php
deleted file mode 100644
index fb7110491..000000000
--- a/test/data/script.php
+++ /dev/null
@@ -1,11 +0,0 @@
-<?php
-error_reporting(0);
-if ( $_REQUEST['header'] ) {
- if ( $_REQUEST['header'] == "ecma" ) {
- header("Content-type: application/ecmascript");
- } else {
- header("Content-type: text/javascript");
- }
-}
-?>
-ok( true, "Script executed correctly." );
diff --git a/test/data/statusText.php b/test/data/statusText.php
deleted file mode 100644
index daf58ce3f..000000000
--- a/test/data/statusText.php
+++ /dev/null
@@ -1,5 +0,0 @@
-<?php
-
-header( "HTTP/1.0 $_GET[status] $_GET[text]" );
-
-?> \ No newline at end of file
diff --git a/test/data/support/csp-clean.php b/test/data/support/csp-clean.php
deleted file mode 100644
index e16d047a3..000000000
--- a/test/data/support/csp-clean.php
+++ /dev/null
@@ -1,3 +0,0 @@
-<?php
- file_put_contents("csp.log", "", LOCK_EX);
-?>
diff --git a/test/data/support/csp-log.php b/test/data/support/csp-log.php
deleted file mode 100644
index efbb9d7bc..000000000
--- a/test/data/support/csp-log.php
+++ /dev/null
@@ -1,3 +0,0 @@
-<?php
- file_put_contents("csp.log", "error", LOCK_EX);
-?>
diff --git a/test/data/support/csp.php b/test/data/support/csp.php
deleted file mode 100644
index 446000239..000000000
--- a/test/data/support/csp.php
+++ /dev/null
@@ -1,19 +0,0 @@
-<?php
- # This test page checks CSP only for browsers with "Content-Security-Policy" header support
- # i.e. no old WebKit or old Firefox
- header("Content-Security-Policy: default-src 'self'; report-uri csp-log.php");
-?>
-<!DOCTYPE html>
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>CSP Test Page</title>
- <script src="../../jquery.js"></script>
- <script src="../iframeTest.js"></script>
- <script src="csp.js"></script>
- <script src="getComputedSupport.js"></script>
-</head>
-<body>
- <p>CSP Test Page</p>
-</body>
-</html>
diff --git a/test/data/test.html b/test/data/test.include.html
index f5bc2199f..73299db07 100644
--- a/test/data/test.html
+++ b/test/data/test.include.html
@@ -1,7 +1,7 @@
html text<br/>
<script type="text/javascript">/* <![CDATA[ */
testFoo = "foo"; jQuery('#foo').html('foo');
-ok( true, "test.html executed" );
+ok( true, "test.include.html executed" );
/* ]]> */</script>
-<script src="data/testbar.php"></script>
+<script src="{{baseURL}}mock.php?action=testbar"></script>
blabla
diff --git a/test/data/test.php b/test/data/test.php
deleted file mode 100644
index d93dafad8..000000000
--- a/test/data/test.php
+++ /dev/null
@@ -1,7 +0,0 @@
-html text<br/>
-<script type="text/javascript">/* <![CDATA[ */
-testFoo = "foo"; jQuery('#foo').html('foo');
-ok( true, "test.php executed" );
-/* ]]> */</script>
-<script src="data/testbar.php?<?php srand(); echo time() . '' . rand(); ?>"></script>
-blabla
diff --git a/test/data/testbar.php b/test/data/testbar.php
deleted file mode 100644
index 21aa6882b..000000000
--- a/test/data/testbar.php
+++ /dev/null
@@ -1,3 +0,0 @@
-this.testBar = "bar";
-jQuery("#ap").html("bar");
-ok( true, "testbar.php executed");
diff --git a/test/data/testinit.js b/test/data/testinit.js
index 1aa9a65da..d6c0236e6 100644
--- a/test/data/testinit.js
+++ b/test/data/testinit.js
@@ -1,6 +1,11 @@
/* eslint no-multi-str: "off" */
-var baseURL = "",
+// baseURL is intentionally set to "data/" instead of "".
+// This is not just for convenience (since most files are in data/)
+// but also to ensure that urls without prefix fail.
+// Otherwise it's easy to write tests that pass on test/index.html
+// but fail in Karma runner (where the baseURL is different).
+var baseURL = "data/",
supportjQuery = this.jQuery,
// see RFC 2606
@@ -148,11 +153,13 @@ window.fireNative = document.createEvent ?
/**
* Add random number to url to stop caching
*
- * @example url("data/test.html")
- * @result "data/test.html?10538358428943"
+ * Also prefixes with baseURL automatically.
*
- * @example url("data/test.php?foo=bar")
- * @result "data/test.php?foo=bar&10538358345554"
+ * @example url("index.html")
+ * @result "data/index.html?10538358428943"
+ *
+ * @example url("mock.php?foo=bar")
+ * @result "data/mock.php?foo=bar&10538358345554"
*/
function url( value ) {
return baseURL + value + ( /\?/.test( value ) ? "&" : "?" ) +
@@ -239,7 +246,7 @@ this.testIframe = function( title, fileName, func, wrapper ) {
var done = assert.async(),
$iframe = supportjQuery( "<iframe/>" )
.css( { position: "absolute", top: "0", left: "-600px", width: "500px" } )
- .attr( { id: "qunit-fixture-iframe", src: url( "./data/" + fileName ) } );
+ .attr( { id: "qunit-fixture-iframe", src: url( fileName ) } );
// Test iframes are expected to invoke this via startIframeTest (cf. iframeTest.js)
window.iframeCallback = function() {
@@ -264,14 +271,20 @@ this.testIframe = function( title, fileName, func, wrapper ) {
};
this.iframeCallback = undefined;
-// Tests are always loaded async
-QUnit.config.autostart = false;
-this.loadTests = function() {
+if ( window.__karma__ ) {
+ // In Karma, files are served from /base
+ baseURL = "base/test/data/";
+} else {
+ // Tests are always loaded async
+ // except when running tests in Karma (See Gruntfile)
+ QUnit.config.autostart = false;
+}
- // Leverage QUnit URL parsing to detect testSwarm environment and "basic" testing mode
- QUnit.isSwarm = ( QUnit.urlParams.swarmURL + "" ).indexOf( "http" ) === 0;
- QUnit.basicTests = ( QUnit.urlParams.module + "" ) === "basic";
+// Leverage QUnit URL parsing to detect testSwarm environment and "basic" testing mode
+QUnit.isSwarm = ( QUnit.urlParams.swarmURL + "" ).indexOf( "http" ) === 0;
+QUnit.basicTests = ( QUnit.urlParams.module + "" ) === "basic";
+this.loadTests = function() {
// Get testSubproject from testrunner first
require( [ "data/testrunner.js" ], function() {
var i = 0,
diff --git a/test/data/text.php b/test/data/text.txt
index b9df4cf3b..b9df4cf3b 100644
--- a/test/data/text.php
+++ b/test/data/text.txt
diff --git a/test/data/with_fries_over_jsonp.php b/test/data/with_fries_over_jsonp.php
deleted file mode 100644
index 456aeb3bd..000000000
--- a/test/data/with_fries_over_jsonp.php
+++ /dev/null
@@ -1,7 +0,0 @@
-<?php
-error_reporting(0);
-$callback = $_REQUEST['callback'];
-$json = $_REQUEST['json'];
-$text = json_encode(file_get_contents(dirname(__FILE__)."/with_fries.xml"));
-echo "$callback($text)";
-?>
diff --git a/test/index.html b/test/index.html
index bf117b858..ce5892859 100644
--- a/test/index.html
+++ b/test/index.html
@@ -42,250 +42,7 @@
<!-- Test HTML -->
<!-- this iframe is outside the #qunit-fixture so it won't waste time by constantly reloading; the tests are "safe" and clean up after themselves -->
<iframe id="loadediframe" name="loadediframe" style="display:none;" src="data/iframe.html"></iframe>
- <dl id="dl" style="position:absolute;top:-32767px;left:-32767px;width:1px;">
- <div id="qunit-fixture">
- <p id="firstp">See <a id="simon1" href="http://simon.incutio.com/archive/2003/03/25/#getElementsBySelector" rel="bookmark">this blog entry</a> for more information.</p>
- <p id="ap">
- Here are some links in a normal paragraph: <a id="google" href="http://www.google.com/" title="Google!">Google</a>,
- <a id="groups" href="http://groups.google.com/" class="GROUPS">Google Groups (Link)</a>.
- This link has <code><a href="http://smin" id="anchor1">class="blog"</a></code>:
- <a href="http://diveintomark.org/" class="blog" hreflang="en" id="mark">diveintomark</a>
-
- </p>
- <div id="foo">
- <p id="sndp">Everything inside the red border is inside a div with <code>id="foo"</code>.</p>
- <p lang="en" id="en">This is a normal link: <a id="yahoo" href="http://www.yahoo.com/" class="blogTest">Yahoo</a></p>
- <p id="sap">This link has <code><a href="#2" id="anchor2">class="blog"</a></code>: <a href="http://simon.incutio.com/" class="blog link" id="simon">Simon Willison's Weblog</a></p>
-
- </div>
- <div id="nothiddendiv" style="height:1px;background:white;" class="nothiddendiv">
- <div id="nothiddendivchild"></div>
- </div>
- <span id="name+value"></span>
- <p id="first">Try them out:</p>
- <ul id="firstUL"></ul>
- <ol id="empty"></ol>
- <form id="form" action="formaction">
- <label for="action" id="label-for">Action:</label>
- <input type="text" name="action" value="Test" id="text1" maxlength="30"/>
- <input type="text" name="text2" value="Test" id="text2" disabled="disabled"/>
- <input type="radio" name="radio1" id="radio1" value="on"/>
-
- <input type="radio" name="radio2" id="radio2" checked="checked"/>
- <input type="checkbox" name="check" id="check1" checked="checked"/>
- <input type="checkbox" id="check2" value="on"/>
-
- <input type="hidden" name="hidden" id="hidden1"/>
- <input type="text" style="display:none;" name="foo[bar]" id="hidden2"/>
-
- <input type="text" id="name" name="name" value="name" />
- <input type="search" id="search" name="search" value="search" />
-
- <button id="button" name="button" type="button">Button</button>
-
- <textarea id="area1" maxlength="30">foobar</textarea>
-
- <select name="select1" id="select1">
- <option id="option1a" class="emptyopt" value="">Nothing</option>
- <option id="option1b" value="1">1</option>
- <option id="option1c" value="2">2</option>
- <option id="option1d" value="3">3</option>
- </select>
- <select name="select2" id="select2">
- <option id="option2a" class="emptyopt" value="">Nothing</option>
- <option id="option2b" value="1">1</option>
- <option id="option2c" value="2">2</option>
- <option id="option2d" selected="selected" value="3">3</option>
- </select>
- <select name="select3" id="select3" multiple="multiple">
- <option id="option3a" class="emptyopt" value="">Nothing</option>
- <option id="option3b" selected="selected" value="1">1</option>
- <option id="option3c" selected="selected" value="2">2</option>
- <option id="option3d" value="3">3</option>
- <option id="option3e">no value</option>
- </select>
- <select name="select4" id="select4" multiple="multiple">
- <optgroup disabled="disabled">
- <option id="option4a" class="emptyopt" value="">Nothing</option>
- <option id="option4b" disabled="disabled" selected="selected" value="1">1</option>
- <option id="option4c" selected="selected" value="2">2</option>
- </optgroup>
- <option selected="selected" disabled="disabled" id="option4d" value="3">3</option>
- <option id="option4e">no value</option>
- </select>
- <select name="select5" id="select5">
- <option id="option5a" value="3">1</option>
- <option id="option5b" value="2">2</option>
- <option id="option5c" value="1" data-attr="">3</option>
- </select>
-
- <object id="object1" codebase="stupid">
- <param name="p1" value="x1" />
- <param name="p2" value="x2" />
- </object>
-
- <span id="台北Táiběi"></span>
- <span id="台北" lang="中文"></span>
- <span id="utf8class1" class="台北Táiběi 台北"></span>
- <span id="utf8class2" class="台北"></span>
- <span id="foo:bar" class="foo:bar"></span>
- <span id="test.foo[5]bar" class="test.foo[5]bar"></span>
-
- <foo_bar id="foobar">test element</foo_bar>
- </form>
- <b id="floatTest">Float test.</b>
- <iframe id="iframe" name="iframe"></iframe>
- <form id="lengthtest">
- <input type="text" id="length" name="test"/>
- <input type="text" id="idTest" name="id"/>
- </form>
- <table id="table"></table>
-
- <form id="name-tests">
- <!-- Inputs with a grouped name attribute. -->
- <input name="types[]" id="types_all" type="checkbox" value="all" />
- <input name="types[]" id="types_anime" type="checkbox" value="anime" />
- <input name="types[]" id="types_movie" type="checkbox" value="movie" />
- </form>
-
- <form id="testForm" action="#" method="get">
- <textarea name="T3" rows="2" cols="15">?
-Z</textarea>
- <input type="hidden" name="H1" value="x" />
- <input type="hidden" name="H2" />
- <input name="PWD" type="password" value="" />
- <input name="T1" type="text" />
- <input name="T2" type="text" value="YES" readonly="readonly" />
- <input type="checkbox" name="C1" value="1" />
- <input type="checkbox" name="C2" />
- <input type="radio" name="R1" value="1" />
- <input type="radio" name="R1" value="2" />
- <input type="text" name="My Name" value="me" />
- <input type="reset" name="reset" value="NO" />
- <select name="S1">
- <option value="abc">ABC</option>
- <option value="abc">ABC</option>
- <option value="abc">ABC</option>
- </select>
- <select name="S2" multiple="multiple" size="3">
- <option value="abc">ABC</option>
- <option value="abc">ABC</option>
- <option value="abc">ABC</option>
- </select>
- <select name="S3">
- <option selected="selected">YES</option>
- </select>
- <select name="S4">
- <option value="" selected="selected">NO</option>
- </select>
- <input type="submit" name="sub1" value="NO" />
- <input type="submit" name="sub2" value="NO" />
- <input type="image" name="sub3" value="NO" />
- <button name="sub4" type="submit" value="NO">NO</button>
- <input name="D1" type="text" value="NO" disabled="disabled" />
- <input type="checkbox" checked="checked" disabled="disabled" name="D2" value="NO" />
- <input type="radio" name="D3" value="NO" checked="checked" disabled="disabled" />
- <select name="D4" disabled="disabled">
- <option selected="selected" value="NO">NO</option>
- </select>
- <input id="list-test" type="text" />
- <datalist id="datalist">
- <option value="option"></option>
- </datalist>
- </form>
- <div id="moretests">
- <form>
- <div id="checkedtest" style="display:none;">
- <input type="radio" name="checkedtestradios" checked="checked"/>
- <input type="radio" name="checkedtestradios" value="on"/>
- <input type="checkbox" name="checkedtestcheckboxes" checked="checked"/>
- <input type="checkbox" name="checkedtestcheckboxes" />
- </div>
- </form>
- <div id="nonnodes"><span id="nonnodesElement">hi</span> there <!-- mon ami --></div>
- <div id="t2037">
- <div><div class="hidden">hidden</div></div>
- </div>
- <div id="t6652">
- <div></div>
- </div>
- <div id="no-clone-exception"><object><embed></embed></object></div>
- </div>
-
- <div id="tabindex-tests">
- <ol id="listWithTabIndex" tabindex="5">
- <li id="foodWithNegativeTabIndex" tabindex="-1">Rice</li>
- <li id="foodNoTabIndex">Beans</li>
- <li>Blinis</li>
- <li>Tofu</li>
- </ol>
-
- <div id="divWithNoTabIndex">I'm hungry. I should...</div>
- <span>...</span><a href="#" id="linkWithNoTabIndex">Eat lots of food</a><span>...</span> |
- <span>...</span><a href="#" id="linkWithTabIndex" tabindex="2">Eat a little food</a><span>...</span> |
- <span>...</span><a href="#" id="linkWithNegativeTabIndex" tabindex="-1">Eat no food</a><span>...</span>
- <span>...</span><a id="linkWithNoHrefWithNoTabIndex">Eat a burger</a><span>...</span>
- <span>...</span><a id="linkWithNoHrefWithTabIndex" tabindex="1">Eat some funyuns</a><span>...</span>
- <span>...</span><a id="linkWithNoHrefWithNegativeTabIndex" tabindex="-1">Eat some funyuns</a><span>...</span>
- <input id="inputWithoutTabIndex"/>
- <button id="buttonWithoutTabIndex"></button>
- <textarea id="textareaWithoutTabIndex"></textarea>
- <menu type="popup">
- <menuitem id="menuitemWithoutTabIndex" command="submitbutton" default/>
- </menu>
- </div>
-
- <div id="liveHandlerOrder">
- <span id="liveSpan1"><a href="#" id="liveLink1"></a></span>
- <span id="liveSpan2"><a href="#" id="liveLink2"></a></span>
- </div>
-
- <div id="siblingTest">
- <em id="siblingfirst">1</em>
- <em id="siblingnext">2</em>
- <em id="siblingthird">
- <em id="siblingchild">
- <em id="siblinggrandchild">
- <em id="siblinggreatgrandchild"></em>
- </em>
- </em>
- </em>
- <span id="siblingspan"></span>
- </div>
- <div id="fx-test-group" style="position: absolute; width: 1px; height: 1px; overflow: hidden;">
- <div id="fx-queue" name="test">
- <div id="fadein" class='chain-test' name='div'>fadeIn<div>fadeIn</div></div>
- <div id="fadeout" class='chain-test chain-test-out'>fadeOut<div>fadeOut</div></div>
-
- <div id="show" class='chain-test'>show<div>show</div></div>
- <div id="hide" class='chain-test chain-test-out'>hide<div>hide</div></div>
- <div id="easehide" class='chain-test chain-test-out'>hide<div>hide</div></div>
-
- <div id="togglein" class='chain-test'>togglein<div>togglein</div></div>
- <div id="toggleout" class='chain-test chain-test-out'>toggleout<div>toggleout</div></div>
- <div id="easetoggleout" class='chain-test chain-test-out'>toggleout<div>toggleout</div></div>
-
- <div id="slideup" class='chain-test'>slideUp<div>slideUp</div></div>
- <div id="slidedown" class='chain-test chain-test-out'>slideDown<div>slideDown</div></div>
- <div id="easeslideup" class='chain-test'>slideUp<div>slideUp</div></div>
-
- <div id="slidetogglein" class='chain-test'>slideToggleIn<div>slideToggleIn</div></div>
- <div id="slidetoggleout" class='chain-test chain-test-out'>slideToggleOut<div>slideToggleOut</div></div>
-
- <div id="fadetogglein" class='chain-test'>fadeToggleIn<div>fadeToggleIn</div></div>
- <div id="fadetoggleout" class='chain-test chain-test-out'>fadeToggleOut<div>fadeToggleOut</div></div>
-
- <div id="fadeto" class='chain-test'>fadeTo<div>fadeTo</div></div>
- </div>
-
- <div id="fx-tests"></div>
- <span id="display"></span>
- </div>
- </div>
- </dl>
- <map name="imgmap" id="imgmap">
- <area shape="rect" coords="0,0,200,50">
- </map>
-
+ <div id="qunit-fixture"></div>
+ <script src="data/qunit-fixture.js"></script>
</body>
</html>
diff --git a/test/karma.context.html b/test/karma.context.html
new file mode 100644
index 000000000..e4f8a4f88
--- /dev/null
+++ b/test/karma.context.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html lang="en" id="html">
+<head>
+ <meta charset="utf-8">
+ <title>CONTEXT</title>
+ <!-- Karma serves this page from /context.html. Other files are served from /base -->
+ <link rel="stylesheet" href="/base/test/data/testsuite.css" />
+</head>
+<body id="body">
+ <div id="qunit"></div>
+
+ <!-- Start: jQuery Test HTML -->
+ <!-- this iframe is outside the #qunit-fixture so it won't waste time by constantly reloading; the tests are "safe" and clean up after themselves -->
+ <iframe id="loadediframe" name="loadediframe" style="display:none;" src="/base/test/data/iframe.html"></iframe>
+ <div id="qunit-fixture"></div>
+ <!-- End: jQuery Test HTML -->
+
+ <!-- Start: Karma boilerplate -->
+ <script src="/context.js"></script>
+ <script>
+ %CLIENT_CONFIG%
+ window.__karma__.setupContext(window);
+
+ %MAPPINGS%
+ </script>
+ %SCRIPTS%
+ <!-- End: Karma boilerplate -->
+
+ <script src="/base/test/data/qunit-fixture.js"></script>
+ <script>
+ // Workaround: Remove call to window.__karma__.loaded()
+ // in favour of calling window.__karma__.start() at window.onload
+ // because tests such as unit/ready.js should run after document ready
+ window.addEventListener('load', function() {
+ window.__karma__.start();
+
+ // Workaround: https://github.com/karma-runner/karma-qunit/issues/92
+ QUnit.testStart(function () {
+ // Restore content
+ document.getElementById("qunit-fixture").innerHTML = QUnit.config.fixture;
+ });
+ });
+ </script>
+</body>
+</html>
diff --git a/test/karma.debug.html b/test/karma.debug.html
new file mode 100644
index 000000000..950064db7
--- /dev/null
+++ b/test/karma.debug.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html lang="en" id="html">
+<head>
+%X_UA_COMPATIBLE%
+ <title>DEBUG</title>
+ <meta charset="utf-8">
+ <!-- Karma serves this page from /context.html. Other files are served from /base -->
+ <link rel="stylesheet" href="/base/external/qunit/qunit.css" />
+ <link rel="stylesheet" href="/base/test/data/testsuite.css" />
+</head>
+<body id="body">
+ <div id="qunit"></div>
+
+ <!-- Start: jQuery Test HTML -->
+ <!-- this iframe is outside the #qunit-fixture so it won't waste time by constantly reloading; the tests are "safe" and clean up after themselves -->
+ <iframe id="loadediframe" name="loadediframe" style="display:none;" src="/base/test/data/iframe.html"></iframe>
+ <div id="qunit-fixture"></div>
+ <!-- End: jQuery Test HTML -->
+
+ <!-- Start: Karma boilerplate -->
+ <script src="/context.js"></script>
+ <script src="/debug.js"></script>
+ <script>
+ %CLIENT_CONFIG%
+
+ %MAPPINGS%
+ </script>
+ %SCRIPTS%
+ <!-- End: Karma boilerplate -->
+
+ <script src="/base/test/data/qunit-fixture.js"></script>
+ <script>
+ // Workaround: Remove call to window.__karma__.loaded()
+ // in favour of calling window.__karma__.start() at window.onload
+ // because tests such as unit/ready.js should run after document ready
+ window.addEventListener('load', function() {
+ window.__karma__.start();
+
+ // Workaround: https://github.com/karma-runner/karma-qunit/issues/92
+ QUnit.testStart(function () {
+ // Restore content
+ document.getElementById("qunit-fixture").innerHTML = QUnit.config.fixture;
+ });
+ });
+ </script>
+</body>
+</html>
diff --git a/test/middleware-mockserver.js b/test/middleware-mockserver.js
new file mode 100644
index 000000000..35623761d
--- /dev/null
+++ b/test/middleware-mockserver.js
@@ -0,0 +1,284 @@
+/* eslint-env node */
+var url = require( "url" );
+var fs = require( "fs" );
+var getRawBody = require( "raw-body" );
+
+var cspLog = "";
+/**
+ * Keep in sync with /test/mock.php
+ */
+var mocks = {
+ contentType: function( req, resp ) {
+ resp.writeHead( 200, {
+ "content-type": req.query.contentType
+ } );
+ resp.end( req.query.response );
+ },
+ wait: function( req, resp ) {
+ var wait = Number( req.query.wait ) * 1000;
+ setTimeout( function() {
+ if ( req.query.script ) {
+ resp.writeHead( 200, { "content-type": "text/javascript" } );
+ } else {
+ resp.writeHead( 200, { "content-type": "text/html" } );
+ resp.end( "ERROR <script>ok( true, \"mock executed\" );</script>" );
+ }
+ }, wait );
+ },
+ name: function( req, resp, next ) {
+ resp.writeHead( 200 );
+ if ( req.query.name === "foo" ) {
+ resp.end( "bar" );
+ return;
+ }
+ getBody( req ).then( function( body ) {
+ if ( body === "name=peter" ) {
+ resp.end( "pan" );
+ } else {
+ resp.end( "ERROR" );
+ }
+ }, next );
+ },
+ xml: function( req, resp, next ) {
+ var content = "<math><calculation>5-2</calculation><result>3</result></math>";
+ resp.writeHead( 200, { "content-type": "text/xml" } );
+
+ if ( req.query.cal === "5-2" ) {
+ resp.end( content );
+ return;
+ }
+ getBody( req ).then( function( body ) {
+ if ( body === "cal=5-2" ) {
+ resp.end( content );
+ } else {
+ resp.end( "<error>ERROR</error>" );
+ }
+ }, next );
+ },
+ atom: function( req, resp, next ) {
+ resp.writeHead( 200, { "content-type": "atom+xml" } );
+ resp.end( "<root><element /></root>" );
+ },
+ script: function( req, resp ) {
+ if ( req.query.header === "ecma" ) {
+ resp.writeHead( 200, { "content-type": "application/ecmascript" } );
+ } else if ( req.query.header ) {
+ resp.writeHead( 200, { "content-type": "text/javascript" } );
+ } else {
+ resp.writeHead( 200, { "content-type": "text/html" } );
+ }
+ resp.end( "ok( true, \"mock executed\" );" );
+ },
+ testbar: function( req, resp ) {
+ resp.writeHead( 200 );
+ resp.end(
+ "this.testBar = 'bar'; " +
+ "jQuery('#ap').html('bar'); " +
+ "ok( true, 'mock executed');"
+ );
+ },
+ json: function( req, resp ) {
+ if ( req.query.header ) {
+ resp.writeHead( 200, { "content-type": "application/json" } );
+ }
+ if ( req.query.array ) {
+ resp.end( JSON.stringify(
+ [ { name: "John", age: 21 }, { name: "Peter", age: 25 } ]
+ ) );
+ } else {
+ resp.end( JSON.stringify(
+ { data: { lang: "en", length: 25 } }
+ ) );
+ }
+ },
+ jsonp: function( req, resp, next ) {
+ var callback;
+ if ( req.query.callback ) {
+ callback = Promise.resolve( req.query.callback );
+ } else if ( req.method === "GET" ) {
+ callback = Promise.resolve( req.url.match( /^.+\/([^\/?.]+)\?.+$/ )[ 1 ] );
+ } else {
+ callback = getBody( req ).then( function( body ) {
+ return body.trim().replace( "callback=", "" );
+ } );
+ }
+ var json = req.query.array ?
+ JSON.stringify(
+ [ { name: "John", age: 21 }, { name: "Peter", age: 25 } ]
+ ) :
+ JSON.stringify(
+ { data: { lang: "en", length: 25 } }
+ );
+ callback.then( function( cb ) {
+ resp.end( cb + "(" + json + ")" );
+ }, next );
+ },
+ xmlOverJsonp: function( req, resp ) {
+ var callback = req.query.callback;
+ var body = fs.readFileSync( __dirname + "/data/with_fries.xml" ).toString();
+ resp.writeHead( 200 );
+ resp.end( callback + "(" + JSON.stringify( body ) + ")\n" );
+ },
+ error: function( req, resp ) {
+ if ( req.query.json ) {
+ resp.writeHead( 400, { "content-type": "application/json" } );
+ resp.end( "{ \"code\": 40, \"message\": \"Bad Request\" }" );
+ } else {
+ resp.writeHead( 400 );
+ resp.end( "plain text message" );
+ }
+ },
+ headers: function( req, resp ) {
+ resp.writeHead( 200, {
+ "Sample-Header": "Hello World",
+ "Empty-Header": "",
+ "Sample-Header2": "Hello World 2"
+ } );
+ req.query.keys.split( "|" ).forEach( function( key ) {
+ if ( req.headers[ key.toLowerCase() ] ) {
+ resp.write( key + ": " + req.headers[ key.toLowerCase() ] + "\n" );
+ }
+ } );
+ resp.end();
+ },
+ echoData: function( req, resp, next ) {
+ getBody( req ).then( function( body ) {
+ resp.end( body );
+ }, next );
+ },
+ echoQuery: function( req, resp ) {
+ resp.end( req.parsed.search.slice( 1 ) );
+ },
+ echoMethod: function( req, resp ) {
+ resp.end( req.method );
+ },
+ echoHtml: function( req, resp, next ) {
+ resp.writeHead( 200, { "Content-Type": "text/html" } );
+ resp.write( "<div id='method'>" + req.method + "</div>" );
+ resp.write( "<div id='query'>" + req.parsed.search.slice( 1 ) + "</div>" );
+ getBody( req ).then( function( body ) {
+ resp.write( "<div id='data'>" + body + "</div>" );
+ resp.end( body );
+ }, next );
+ },
+ etag: function( req, resp ) {
+ var hash = Number( req.query.ts ).toString( 36 );
+ var etag = "W/\"" + hash + "\"";
+ if ( req.headers[ "if-none-match" ] === etag ) {
+ resp.writeHead( 304 );
+ resp.end();
+ return;
+ }
+ resp.writeHead( 200, {
+ "Etag": etag
+ } );
+ resp.end();
+ },
+ ims: function( req, resp, next ) {
+ var ts = req.query.ts;
+ if ( req.headers[ "if-modified-since" ] === ts ) {
+ resp.writeHead( 304 );
+ resp.end();
+ return;
+ }
+ resp.writeHead( 200, {
+ "Last-Modified": ts
+ } );
+ resp.end();
+ },
+ status: function( req, resp, next ) {
+ resp.writeHead( Number( req.query.code ) );
+ resp.end();
+ },
+ testHTML: function( req, resp ) {
+ resp.writeHead( 200, { "Content-Type": "text/html" } );
+ var body = fs.readFileSync( __dirname + "/data/test.include.html" ).toString();
+ body = body.replace( /{{baseURL}}/g, req.query.baseURL );
+ resp.end( body );
+ },
+ cspFrame: function( req, resp ) {
+ resp.writeHead( 200, {
+ "Content-Type": "text/html",
+ "Content-Security-Policy": "default-src 'self'; report-uri /base/test/data/mock.php?action=cspLog"
+ } );
+ var body = fs.readFileSync( __dirname + "/data/csp.include.html" ).toString();
+ resp.end( body );
+ },
+ cspLog: function( req, resp ) {
+ cspLog = "error";
+ resp.writeHead( 200 );
+ resp.end();
+ },
+ cspClean: function( req, resp ) {
+ cspLog = "";
+ resp.writeHead( 200 );
+ resp.end();
+ }
+};
+var handlers = {
+ "test/data/mock.php": function( req, resp, next ) {
+ if ( !mocks[ req.query.action ] ) {
+ resp.writeHead( 400 );
+ resp.end( "Invalid action query.\n" );
+ console.log( "Invalid action query:", req.method, req.url );
+ return;
+ }
+ mocks[ req.query.action ]( req, resp, next );
+ },
+ "test/data/support/csp.log": function( req, resp ) {
+ resp.writeHead( 200 );
+ resp.end( cspLog );
+ },
+ "test/data/404.txt": function( req, resp ) {
+ resp.writeHead( 404 );
+ resp.end( "" );
+ }
+};
+
+/**
+ * Connect-compatible middleware factory for mocking server responses.
+ * Used by Ajax unit tests when run via Karma.
+ *
+ * Despite Karma using Express, it uses Connect to deal with custom middleware,
+ * which passes the raw Node Request and Response objects instead of the
+ * Express versions of these (e.g. no req.path, req.query, resp.set).
+ */
+function MockserverMiddlewareFactory() {
+ /**
+ * @param {http.IncomingMessage} req
+ * @param {http.ServerResponse} resp
+ * @param {Function} next Continue request handling
+ */
+ return function( req, resp, next ) {
+ var method = req.method,
+ parsed = url.parse( req.url, /* parseQuery */ true ),
+ path = parsed.pathname.replace( /^\/base\//, "" ),
+ query = parsed.query,
+ subReq = Object.assign( Object.create( req ), {
+ query: query,
+ parsed: parsed
+ } );
+
+ if ( /^test\/data\/mock.php\//.test( path ) ) {
+ // Support REST-like Apache PathInfo
+ path = "test\/data\/mock.php";
+ }
+
+ if ( !handlers[ path ] ) {
+ next();
+ return;
+ }
+
+ handlers[ path ]( subReq, resp, next );
+ };
+}
+
+function getBody( req ) {
+ return req.method !== "POST" ?
+ Promise.resolve( "" ) :
+ getRawBody( req, {
+ encoding: true
+ } );
+}
+
+module.exports = MockserverMiddlewareFactory;
diff --git a/test/unit/ajax.js b/test/unit/ajax.js
index 4dc7b9d3a..a8fd3a075 100644
--- a/test/unit/ajax.js
+++ b/test/unit/ajax.js
@@ -40,7 +40,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - success callbacks", 8, function( assert ) {
return {
setup: addGlobalEvents( "ajaxStart ajaxStop ajaxSend ajaxComplete ajaxSuccess", assert ),
- url: url( "data/name.html" ),
+ url: url( "name.html" ),
beforeSend: function() {
assert.ok( true, "beforeSend" );
},
@@ -57,7 +57,7 @@ QUnit.module( "ajax", {
return {
setup: addGlobalEvents( "ajaxStart ajaxStop ajaxSend ajaxComplete ajaxSuccess", assert ),
create: function( options ) {
- return jQuery.ajax( url( "data/name.html" ), options );
+ return jQuery.ajax( url( "name.html" ), options );
},
beforeSend: function() {
assert.ok( true, "beforeSend" );
@@ -77,7 +77,7 @@ QUnit.module( "ajax", {
create: function( options ) {
options.crossDomain = true;
options.dataType = "script";
- return jQuery.ajax( url( "data/script.php?header=ecma" ), options );
+ return jQuery.ajax( url( "mock.php?action=script&header=ecma" ), options );
},
success: function() {
assert.ok( true, "success" );
@@ -93,7 +93,7 @@ QUnit.module( "ajax", {
return {
create: function( options ) {
options.crossDomain = true;
- return jQuery.ajax( url( "data/script.php" ), options );
+ return jQuery.ajax( url( "mock.php?action=script" ), options );
},
success: function() {
assert.ok( true, "success" );
@@ -112,7 +112,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - success callbacks (late binding)", 8, function( assert ) {
return {
setup: addGlobalEvents( "ajaxStart ajaxStop ajaxSend ajaxComplete ajaxSuccess", assert ),
- url: url( "data/name.html" ),
+ url: url( "name.html" ),
beforeSend: function() {
assert.ok( true, "beforeSend" );
},
@@ -132,7 +132,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - success callbacks (oncomplete binding)", 8, function( assert ) {
return {
setup: addGlobalEvents( "ajaxStart ajaxStop ajaxSend ajaxComplete ajaxSuccess", assert ),
- url: url( "data/name.html" ),
+ url: url( "name.html" ),
beforeSend: function() {
assert.ok( true, "beforeSend" );
},
@@ -152,7 +152,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - error callbacks", 8, function( assert ) {
return {
setup: addGlobalEvents( "ajaxStart ajaxStop ajaxSend ajaxComplete ajaxError", assert ),
- url: url( "data/name.php?wait=5" ),
+ url: url( "mock.php?action=wait&wait=5" ),
beforeSend: function() {
assert.ok( true, "beforeSend" );
},
@@ -170,7 +170,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - textStatus and errorThrown values", 4, function( assert ) {
return [ {
- url: url( "data/name.php?wait=5" ),
+ url: url( "mock.php?action=wait&wait=5" ),
error: function( _, textStatus, errorThrown ) {
assert.strictEqual( textStatus, "abort", "textStatus is 'abort' for abort" );
assert.strictEqual( errorThrown, "abort", "errorThrown is 'abort' for abort" );
@@ -180,7 +180,7 @@ QUnit.module( "ajax", {
}
},
{
- url: url( "data/name.php?wait=5" ),
+ url: url( "mock.php?action=wait&wait=5" ),
error: function( _, textStatus, errorThrown ) {
assert.strictEqual( textStatus, "mystatus", "textStatus is 'mystatus' for abort('mystatus')" );
assert.strictEqual( errorThrown, "mystatus", "errorThrown is 'mystatus' for abort('mystatus')" );
@@ -193,7 +193,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - responseText on error", 1, function( assert ) {
return {
- url: url( "data/errorWithText.php" ),
+ url: url( "mock.php?action=error" ),
error: function( xhr ) {
assert.strictEqual( xhr.responseText, "plain text message", "Test jqXHR.responseText is filled for HTTP errors" );
}
@@ -204,7 +204,7 @@ QUnit.module( "ajax", {
var previousUrl,
firstTime = true;
jQuery.ajax( {
- url: url( "data/errorWithText.php" ),
+ url: url( "mock.php?action=error" ),
error: function() {
if ( firstTime ) {
firstTime = false;
@@ -212,10 +212,7 @@ QUnit.module( "ajax", {
} else {
assert.ok( true, "Test retrying with jQuery.ajax(this) works" );
jQuery.ajax( {
- url: url( "data/errorWithText.php" ),
- data: {
- "x": 1
- },
+ url: url( "mock.php?action=error&x=2" ),
beforeSend: function() {
if ( !previousUrl ) {
previousUrl = this.url;
@@ -241,7 +238,7 @@ QUnit.module( "ajax", {
xhr.setRequestHeader( "ajax-send", "test" );
} );
},
- url: url( "data/headers.php?keys=siMPle_SometHing-elsE_OthEr_Nullable_undefined_Empty_ajax-send" ),
+ url: url( "mock.php?action=headers&keys=siMPle|SometHing-elsE|OthEr|Nullable|undefined|Empty|ajax-send" ),
headers: {
"siMPle": "value",
"SometHing-elsE": "other value",
@@ -281,7 +278,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - Accept header", 1, function( assert ) {
return {
- url: url( "data/headers.php?keys=accept" ),
+ url: url( "mock.php?action=headers&keys=accept" ),
headers: {
Accept: "very wrong accept value"
},
@@ -297,14 +294,14 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - contentType", 2, function( assert ) {
return [
{
- url: url( "data/headers.php?keys=content-type" ),
+ url: url( "mock.php?action=headers&keys=content-type" ),
contentType: "test",
success: function( data ) {
assert.strictEqual( data, "content-type: test\n", "Test content-type is sent when options.contentType is set" );
}
},
{
- url: url( "data/headers.php?keys=content-type" ),
+ url: url( "mock.php?action=headers&keys=content-type" ),
contentType: false,
success: function( data ) {
@@ -330,34 +327,34 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - hash", 4, function( assert ) {
return [
{
- url: "data/name.html#foo",
+ url: baseURL + "name.html#foo",
beforeSend: function( xhr, settings ) {
- assert.equal( settings.url, "data/name.html#foo", "Make sure that the URL has its hash." );
+ assert.equal( settings.url, baseURL + "name.html#foo", "Make sure that the URL has its hash." );
return false;
},
error: true
},
{
- url: "data/name.html?abc#foo",
+ url: baseURL + "name.html?abc#foo",
beforeSend: function( xhr, settings ) {
- assert.equal( settings.url, "data/name.html?abc#foo", "Make sure that the URL has its hash." );
+ assert.equal( settings.url, baseURL + "name.html?abc#foo", "Make sure that the URL has its hash." );
return false;
},
error: true
},
{
- url: "data/name.html?abc#foo",
+ url: baseURL + "name.html?abc#foo",
data: {
"test": 123
},
beforeSend: function( xhr, settings ) {
- assert.equal( settings.url, "data/name.html?abc&test=123#foo", "Make sure that the URL has its hash." );
+ assert.equal( settings.url, baseURL + "name.html?abc&test=123#foo", "Make sure that the URL has its hash." );
return false;
},
error: true
},
{
- url: "data/name.html?abc#brownies",
+ url: baseURL + "name.html?abc#brownies",
data: {
"devo": "hat"
},
@@ -365,7 +362,7 @@ QUnit.module( "ajax", {
beforeSend: function( xhr, settings ) {
// Remove the random number, but ensure the cache-buster param is there
var url = settings.url.replace( /\d+/, "" );
- assert.equal( url, "data/name.html?abc&devo=hat&_=#brownies", "Make sure that the URL has its hash." );
+ assert.equal( url, baseURL + "name.html?abc&devo=hat&_=#brownies", "Make sure that the URL has its hash." );
return false;
},
error: true
@@ -492,7 +489,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - abort", 9, function( assert ) {
return {
setup: addGlobalEvents( "ajaxStart ajaxStop ajaxSend ajaxError ajaxComplete", assert ),
- url: url( "data/name.php?wait=5" ),
+ url: url( "mock.php?action=wait&wait=5" ),
beforeSend: function() {
assert.ok( true, "beforeSend" );
},
@@ -510,7 +507,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - native abort", 2, function( assert ) {
return {
- url: url( "data/name.php?wait=1" ),
+ url: url( "mock.php?action=wait&wait=1" ),
xhr: function() {
var xhr = new window.XMLHttpRequest();
setTimeout( function() {
@@ -529,7 +526,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - native timeout", 2, function( assert ) {
return {
- url: url( "data/name.php?wait=1" ),
+ url: url( "mock.php?action=wait&wait=1" ),
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.timeout = 1;
@@ -566,13 +563,13 @@ QUnit.module( "ajax", {
.ajaxSuccess( event );
},
requests: [ {
- url: url( "data/name.html" ),
+ url: url( "name.html" ),
context: context,
beforeSend: callback( "beforeSend" ),
success: callback( "success" ),
complete: callback( "complete" )
}, {
- url: url( "data/404.html" ),
+ url: url( "404.txt" ),
context: context,
beforeSend: callback( "beforeSend" ),
error: callback( "error" ),
@@ -588,7 +585,7 @@ QUnit.module( "ajax", {
};
}
return {
- url: url( "data/404.html" ),
+ url: url( "404.txt" ),
beforeSend: nocallback( "beforeSend" ),
error: nocallback( "error" ),
complete: nocallback( "complete" )
@@ -598,7 +595,7 @@ QUnit.module( "ajax", {
ajaxTest( "#15118 - jQuery.ajax() - function without jQuery.event", 1, function( assert ) {
var holder;
return {
- url: url( "data/json.php" ),
+ url: url( "mock.php?action=json" ),
setup: function() {
holder = jQuery.event;
delete jQuery.event;
@@ -622,7 +619,7 @@ QUnit.module( "ajax", {
assert.equal( jqXHR.statusText, "abort", "jqXHR.statusText equals abort on global ajaxComplete and ajaxError events" );
} );
},
- url: url( "data/name.html" ),
+ url: url( "name.html" ),
error: true,
complete: function() {
assert.ok( true, "complete" );
@@ -632,7 +629,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - context modification", 1, function( assert ) {
return {
- url: url( "data/name.html" ),
+ url: url( "name.html" ),
context: {},
beforeSend: function() {
this.test = "foo";
@@ -654,12 +651,12 @@ QUnit.module( "ajax", {
assert.strictEqual( jQuery.ajaxSettings.context, obj, "Make sure the context is properly set in ajaxSettings." );
},
requests: [ {
- url: url( "data/name.html" ),
+ url: url( "name.html" ),
success: function() {
assert.strictEqual( this, obj, "Make sure the original object is maintained." );
}
}, {
- url: url( "data/name.html" ),
+ url: url( "name.html" ),
context: {},
success: function() {
assert.ok( this !== obj, "Make sure overriding context is possible." );
@@ -672,7 +669,7 @@ QUnit.module( "ajax", {
return {
setup: addGlobalEvents( "", assert ),
global: false,
- url: url( "data/name.html" ),
+ url: url( "name.html" ),
beforeSend: function() {
assert.ok( true, "beforeSend" );
},
@@ -687,7 +684,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - xml: non-namespace elements inside namespaced elements", 3, function( assert ) {
return {
- url: url( "data/with_fries.xml" ),
+ url: url( "with_fries.xml" ),
dataType: "xml",
success: function( resp ) {
assert.equal( jQuery( "properties", resp ).length, 1, "properties in responseXML" );
@@ -699,7 +696,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - xml: non-namespace elements inside namespaced elements (over JSONP)", 3, function( assert ) {
return {
- url: url( "data/with_fries_over_jsonp.php" ),
+ url: url( "mock.php?action=xmlOverJsonp" ),
dataType: "jsonp xml",
success: function( resp ) {
assert.equal( jQuery( "properties", resp ).length, 1, "properties in responseXML" );
@@ -712,14 +709,14 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - HEAD requests", 2, function( assert ) {
return [
{
- url: url( "data/name.html" ),
+ url: url( "name.html" ),
type: "HEAD",
success: function( data, status, xhr ) {
assert.ok( /Date/i.test( xhr.getAllResponseHeaders() ), "No Date in HEAD response" );
}
},
{
- url: url( "data/name.html" ),
+ url: url( "name.html" ),
data: {
"whip_it": "good"
},
@@ -733,7 +730,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - beforeSend", 1, function( assert ) {
return {
- url: url( "data/name.html" ),
+ url: url( "name.html" ),
beforeSend: function() {
this.check = true;
},
@@ -747,7 +744,7 @@ QUnit.module( "ajax", {
return {
create: function() {
return jQuery.ajax( {
- url: url( "data/name.html" ),
+ url: url( "name.html" ),
beforeSend: function( xhr ) {
assert.ok( true, "beforeSend got called, canceling" );
xhr.abort();
@@ -776,7 +773,7 @@ QUnit.module( "ajax", {
Globals.register( "testBar" );
},
dataType: "html",
- url: url( "data/test.html" ),
+ url: url( "mock.php?action=testHTML&baseURL=" + baseURL ),
success: function( data ) {
assert.ok( data.match( /^html text/ ), "Check content for datatype html" );
jQuery( "#ap" ).html( data );
@@ -788,7 +785,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - synchronous request", 1, function( assert ) {
return {
- url: url( "data/json_obj.js" ),
+ url: url( "json_obj.js" ),
dataType: "text",
async: false,
success: true,
@@ -800,7 +797,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - synchronous request with callbacks", 2, function( assert ) {
return {
- url: url( "data/json_obj.js" ),
+ url: url( "json_obj.js" ),
async: false,
dataType: "text",
success: true,
@@ -816,7 +813,7 @@ QUnit.module( "ajax", {
} );
QUnit.asyncTest( "jQuery.ajax(), jQuery.get[Script|JSON](), jQuery.post(), pass-through request object", 8, function( assert ) {
- var target = "data/name.html",
+ var target = "name.html",
successCount = 0,
errorCount = 0,
errorEx = "",
@@ -837,8 +834,8 @@ QUnit.module( "ajax", {
assert.ok( jQuery.get( url( target ), success ), "get" );
assert.ok( jQuery.post( url( target ), success ), "post" );
- assert.ok( jQuery.getScript( url( "data/testbar.php" ), success ), "script" );
- assert.ok( jQuery.getJSON( url( "data/json_obj.js" ), success ), "json" );
+ assert.ok( jQuery.getScript( url( "mock.php?action=testbar" ), success ), "script" );
+ assert.ok( jQuery.getJSON( url( "json_obj.js" ), success ), "json" );
assert.ok( jQuery.ajax( {
url: url( target ),
success: success
@@ -847,7 +844,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - cache", 28, function( assert ) {
var re = /_=(.*?)(&|$)/g,
- rootUrl = "data/text.php";
+ rootUrl = baseURL + "text.txt";
function request( url, title ) {
return {
@@ -908,7 +905,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - JSONP - Query String (?n)" + label, 4, function( assert ) {
return [
{
- url: "data/jsonp.php?callback=?",
+ url: baseURL + "mock.php?action=jsonp&callback=?",
dataType: "jsonp",
crossDomain: crossDomain,
success: function( data ) {
@@ -916,7 +913,7 @@ QUnit.module( "ajax", {
}
},
{
- url: "data/jsonp.php?callback=??",
+ url: baseURL + "mock.php?action=jsonp&callback=??",
dataType: "jsonp",
crossDomain: crossDomain,
success: function( data ) {
@@ -924,7 +921,7 @@ QUnit.module( "ajax", {
}
},
{
- url: "data/jsonp.php/??",
+ url: baseURL + "mock.php/???action=jsonp",
dataType: "jsonp",
crossDomain: crossDomain,
success: function( data ) {
@@ -932,7 +929,7 @@ QUnit.module( "ajax", {
}
},
{
- url: "data/jsonp.php/???json=1",
+ url: baseURL + "mock.php/???action=jsonp&array=1",
dataType: "jsonp",
crossDomain: crossDomain,
success: function( data ) {
@@ -953,7 +950,7 @@ QUnit.module( "ajax", {
};
},
requests: [ {
- url: "data/jsonp.php",
+ url: baseURL + "mock.php?action=jsonp",
dataType: "jsonp",
crossDomain: crossDomain,
jsonp: "callback",
@@ -961,7 +958,7 @@ QUnit.module( "ajax", {
assert.ok( data[ "data" ], "JSON results returned (GET, data obj callback)" );
}
}, {
- url: "data/jsonp.php",
+ url: baseURL + "mock.php?action=jsonp",
dataType: "jsonp",
crossDomain: crossDomain,
jsonpCallback: "jsonpResults",
@@ -974,7 +971,7 @@ QUnit.module( "ajax", {
assert.ok( data.data, "JSON results returned (GET, custom callback name)" );
}
}, {
- url: "data/jsonp.php",
+ url: baseURL + "mock.php?action=jsonp",
dataType: "jsonp",
crossDomain: crossDomain,
jsonpCallback: "functionToCleanUp",
@@ -983,7 +980,7 @@ QUnit.module( "ajax", {
assert.strictEqual( window[ "functionToCleanUp" ], true, "Callback was removed (GET, custom callback name to be cleaned up)" );
var xhr;
jQuery.ajax( {
- url: "data/jsonp.php",
+ url: baseURL + "mock.php?action=jsonp",
dataType: "jsonp",
crossDomain: crossDomain,
jsonpCallback: "functionToCleanUp",
@@ -998,13 +995,13 @@ QUnit.module( "ajax", {
} );
}
}, {
- url: "data/jsonp.php?callback=XXX",
+ url: baseURL + "mock.php?action=jsonp&callback=XXX",
dataType: "jsonp",
jsonp: false,
jsonpCallback: "XXX",
crossDomain: crossDomain,
beforeSend: function() {
- assert.ok( /^data\/jsonp.php\?callback=XXX&_=\d+$/.test( this.url ), "The URL wasn't messed with (GET, custom callback name with no url manipulation)" );
+ assert.ok( /action=jsonp&callback=XXX&_=\d+$/.test( this.url ), "The URL wasn't messed with (GET, custom callback name with no url manipulation)" );
},
success: function( data ) {
assert.ok( data[ "data" ], "JSON results returned (GET, custom callback name with no url manipulation)" );
@@ -1016,7 +1013,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - JSONP - Callback in data" + label, 2, function( assert ) {
return [
{
- url: "data/jsonp.php",
+ url: baseURL + "mock.php?action=jsonp",
dataType: "jsonp",
crossDomain: crossDomain,
data: "callback=?",
@@ -1025,7 +1022,7 @@ QUnit.module( "ajax", {
}
},
{
- url: "data/jsonp.php",
+ url: baseURL + "mock.php?action=jsonp",
dataType: "jsonp",
crossDomain: crossDomain,
data: "callback=??",
@@ -1040,7 +1037,7 @@ QUnit.module( "ajax", {
return [
{
type: "POST",
- url: "data/jsonp.php",
+ url: baseURL + "mock.php?action=jsonp",
dataType: "jsonp",
crossDomain: crossDomain,
success: function( data ) {
@@ -1049,7 +1046,7 @@ QUnit.module( "ajax", {
},
{
type: "POST",
- url: "data/jsonp.php",
+ url: baseURL + "mock.php?action=jsonp",
data: "callback=?",
dataType: "jsonp",
crossDomain: crossDomain,
@@ -1059,7 +1056,7 @@ QUnit.module( "ajax", {
},
{
type: "POST",
- url: "data/jsonp.php",
+ url: baseURL + "mock.php?action=jsonp",
jsonp: "callback",
dataType: "jsonp",
crossDomain: crossDomain,
@@ -1073,7 +1070,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - JSONP" + label, 3, function( assert ) {
return [
{
- url: "data/jsonp.php",
+ url: baseURL + "mock.php?action=jsonp",
dataType: "jsonp",
crossDomain: crossDomain,
success: function( data ) {
@@ -1094,7 +1091,7 @@ QUnit.module( "ajax", {
promise.abort = request.abort;
return promise;
},
- url: "data/jsonp.php",
+ url: baseURL + "mock.php?action=jsonp",
dataType: "jsonp",
crossDomain: crossDomain,
success: true
@@ -1109,7 +1106,7 @@ QUnit.module( "ajax", {
setup: function() {
Globals.register( "testBar" );
},
- url: window.location.href.replace( /[^\/]*$/, "" ) + "data/testbar.php",
+ url: window.location.href.replace( /[^\/]*$/, "" ) + baseURL + "mock.php?action=testbar",
dataType: "script",
success: function() {
assert.strictEqual( window[ "testBar" ], "bar", "Script results returned (GET, no callback)" );
@@ -1122,7 +1119,7 @@ QUnit.module( "ajax", {
setup: function() {
Globals.register( "testBar" );
},
- url: window.location.href.replace( /[^\/]*$/, "" ) + "data/testbar.php",
+ url: window.location.href.replace( /[^\/]*$/, "" ) + baseURL + "mock.php?action=testbar",
type: "POST",
dataType: "script",
success: function( data, status ) {
@@ -1137,7 +1134,7 @@ QUnit.module( "ajax", {
setup: function() {
Globals.register( "testBar" );
},
- url: window.location.href.replace( /[^\/]*$/, "" ).replace( /^.*?\/\//, "//" ) + "data/testbar.php",
+ url: window.location.href.replace( /[^\/]*$/, "" ).replace( /^.*?\/\//, "//" ) + baseURL + "mock.php?action=testbar",
dataType: "script",
success: function() {
assert.strictEqual( window[ "testBar" ], "bar", "Script results returned (GET, no callback)" );
@@ -1147,7 +1144,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - malformed JSON", 2, function( assert ) {
return {
- url: "data/badjson.js",
+ url: baseURL + "badjson.js",
dataType: "json",
error: function( xhr, msg, detailedMsg ) {
assert.strictEqual( msg, "parsererror", "A parse error occurred." );
@@ -1159,14 +1156,14 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - script by content-type", 2, function() {
return [
{
- url: "data/script.php",
+ url: baseURL + "mock.php?action=script",
data: {
"header": "script"
},
success: true
},
{
- url: "data/script.php",
+ url: baseURL + "mock.php?action=script",
data: {
"header": "ecma"
},
@@ -1177,10 +1174,10 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - JSON by content-type", 5, function( assert ) {
return {
- url: "data/json.php",
+ url: baseURL + "mock.php?action=json",
data: {
"header": "json",
- "json": "array"
+ "array": "1"
},
success: function( json ) {
assert.ok( json.length >= 2, "Check length" );
@@ -1194,10 +1191,10 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - JSON by content-type disabled with options", 6, function( assert ) {
return {
- url: url( "data/json.php" ),
+ url: url( "mock.php?action=json" ),
data: {
"header": "json",
- "json": "array"
+ "array": "1"
},
contents: {
"json": false
@@ -1217,7 +1214,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - simple get", 1, function( assert ) {
return {
type: "GET",
- url: url( "data/name.php?name=foo" ),
+ url: url( "mock.php?action=name&name=foo" ),
success: function( msg ) {
assert.strictEqual( msg, "bar", "Check for GET" );
}
@@ -1227,7 +1224,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - simple post", 1, function( assert ) {
return {
type: "POST",
- url: url( "data/name.php" ),
+ url: url( "mock.php?action=name" ),
data: "name=peter",
success: function( msg ) {
assert.strictEqual( msg, "pan", "Check for POST" );
@@ -1237,7 +1234,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - data option - empty bodies for non-GET requests", 1, function( assert ) {
return {
- url: "data/echoData.php",
+ url: baseURL + "mock.php?action=echoData",
data: undefined,
type: "post",
success: function( result ) {
@@ -1299,11 +1296,11 @@ QUnit.module( "ajax", {
function( label, cache ) {
jQuery.each(
{
- "If-Modified-Since": "if_modified_since.php",
- "Etag": "etag.php"
+ "If-Modified-Since": "mock.php?action=ims",
+ "Etag": "mock.php?action=etag"
},
function( type, url ) {
- url = "data/" + url + "?ts=" + ifModifiedNow++;
+ url = baseURL + url + "&ts=" + ifModifiedNow++;
QUnit.asyncTest( "jQuery.ajax() - " + type + " support" + label, 4, function( assert ) {
jQuery.ajax( {
url: url,
@@ -1355,7 +1352,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - atom+xml", 1, function( assert ) {
return {
- url: url( "data/atom+xml.php" ),
+ url: url( "mock.php?action=atom" ),
success: function() {
assert.ok( true, "success" );
}
@@ -1363,10 +1360,10 @@ QUnit.module( "ajax", {
} );
QUnit.asyncTest( "jQuery.ajax() - statusText", 3, function( assert ) {
- jQuery.ajax( url( "data/statusText.php?status=200&text=Hello" ) ).done( function( _, statusText, jqXHR ) {
+ jQuery.ajax( url( "mock.php?action=status&code=200&text=Hello" ) ).done( function( _, statusText, jqXHR ) {
assert.strictEqual( statusText, "success", "callback status text ok for success" );
assert.ok( jqXHR.statusText === "Hello" || jqXHR.statusText === "OK", "jqXHR status text ok for success (" + jqXHR.statusText + ")" );
- jQuery.ajax( url( "data/statusText.php?status=404&text=World" ) ).fail( function( jqXHR, statusText ) {
+ jQuery.ajax( url( "mock.php?action=status&code=404&text=World" ) ).fail( function( jqXHR, statusText ) {
assert.strictEqual( statusText, "error", "callback status text ok for error" );
QUnit.start();
} );
@@ -1398,11 +1395,10 @@ QUnit.module( "ajax", {
jQuery.each(
/* jQuery.each arguments start */
{
- "data/name.html": true,
- "data/someFileThatDoesNotExist.html": false
+ "name.html": true,
+ "404.txt": false
},
function( uri, isSuccess ) {
-
jQuery.ajax( url( uri ), {
statusCode: createStatusCodes( "in options", isSuccess ),
complete: countComplete
@@ -1478,7 +1474,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - transitive conversions", 8, function( assert ) {
return [
{
- url: url( "data/json.php" ),
+ url: url( "mock.php?action=json" ),
converters: {
"json myJson": function( data ) {
assert.ok( true, "converter called" );
@@ -1493,7 +1489,7 @@ QUnit.module( "ajax", {
}
},
{
- url: url( "data/json.php" ),
+ url: url( "mock.php?action=json" ),
converters: {
"json myJson": function( data ) {
assert.ok( true, "converter called (*)" );
@@ -1514,7 +1510,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - overrideMimeType", 2, function( assert ) {
return [
{
- url: url( "data/json.php" ),
+ url: url( "mock.php?action=json" ),
beforeSend: function( xhr ) {
xhr.overrideMimeType( "application/json" );
},
@@ -1523,7 +1519,7 @@ QUnit.module( "ajax", {
}
},
{
- url: url( "data/json.php" ),
+ url: url( "mock.php?action=json" ),
mimeType: "application/json",
success: function( json ) {
assert.ok( json.data, "Mimetype overridden using mimeType option" );
@@ -1534,7 +1530,7 @@ QUnit.module( "ajax", {
ajaxTest( "jQuery.ajax() - empty json gets to error callback instead of success callback.", 1, function( assert ) {
return {
- url: url( "data/echoData.php" ),
+ url: url( "mock.php?action=echoData" ),
error: function( _, __, error ) {
assert.equal( typeof error === "object", true, "Didn't get back error object for empty json response" );
},
@@ -1546,7 +1542,7 @@ QUnit.module( "ajax", {
return {
create: function() {
return jQuery.ajax( {
- url: url( "data/name.html" ),
+ url: url( "name.html" ),
beforeSend: function() {
assert.ok( true, "beforeSend got called, canceling" );
return false;
@@ -1570,14 +1566,14 @@ QUnit.module( "ajax", {
ajaxTest( "#2806 - jQuery.ajax() - data option - evaluate function values", 1, function( assert ) {
return {
- url: "data/echoQuery.php",
+ url: baseURL + "mock.php?action=echoQuery",
data: {
key: function() {
return "value";
}
},
success: function( result ) {
- assert.strictEqual( result, "key=value" );
+ assert.strictEqual( result, "action=echoQuery&key=value" );
}
};
} );
@@ -1602,7 +1598,7 @@ QUnit.module( "ajax", {
jQuery.each( [ " - Same Domain", " - Cross Domain" ], function( crossDomain, label ) {
ajaxTest( "#7578 - jQuery.ajax() - JSONP - default for cache option" + label, 1, function( assert ) {
return {
- url: "data/jsonp.php",
+ url: baseURL + "mock.php?action=jsonp",
dataType: "jsonp",
crossDomain: crossDomain,
beforeSend: function() {
@@ -1626,7 +1622,7 @@ QUnit.module( "ajax", {
},
{
create: function() {
- return jQuery.ajax( "data/name.html" );
+ return jQuery.ajax( baseURL + "name.html" );
},
done: function() {
assert.ok( true, "With only string URL argument" );
@@ -1634,7 +1630,7 @@ QUnit.module( "ajax", {
},
{
create: function() {
- return jQuery.ajax( "data/name.html", {} );
+ return jQuery.ajax( baseURL + "name.html", {} );
},
done: function() {
assert.ok( true, "With string URL param and map" );
@@ -1644,7 +1640,7 @@ QUnit.module( "ajax", {
create: function( options ) {
return jQuery.ajax( options );
},
- url: "data/name.html",
+ url: baseURL + "name.html",
success: function() {
assert.ok( true, "With only map" );
}
@@ -1655,7 +1651,7 @@ QUnit.module( "ajax", {
jQuery.each( [ " - Same Domain", " - Cross Domain" ], function( crossDomain, label ) {
ajaxTest( "#8205 - jQuery.ajax() - JSONP - re-use callbacks name" + label, 4, function( assert ) {
return {
- url: "data/jsonp.php",
+ url: baseURL + "mock.php?action=jsonp",
dataType: "jsonp",
crossDomain: crossDomain,
beforeSend: function( jqXHR, s ) {
@@ -1678,7 +1674,7 @@ QUnit.module( "ajax", {
);
jQuery.ajax( {
- url: "data/jsonp.php",
+ url: baseURL + "mock.php?action=jsonp",
dataType: "jsonp",
crossDomain: crossDomain,
beforeSend: function() {
@@ -1737,7 +1733,7 @@ QUnit.module( "ajax", {
ajaxTest( "#11151 - jQuery.ajax() - parse error body", 2, function( assert ) {
return {
- url: url( "data/errorWithJSON.php" ),
+ url: url( "mock.php?action=error&json=1" ),
dataFilter: function( string ) {
assert.ok( false, "dataFilter called" );
return string;
@@ -1751,7 +1747,7 @@ QUnit.module( "ajax", {
ajaxTest( "#11426 - jQuery.ajax() - loading binary data shouldn't throw an exception in IE", 1, function( assert ) {
return {
- url: url( "data/1x1.jpg" ),
+ url: url( "1x1.jpg" ),
success: function( data ) {
assert.ok( data === undefined || /JFIF/.test( data ), "success callback reached" );
}
@@ -1772,7 +1768,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
ajaxTest( "gh-2498 - jQuery.ajax() - binary data shouldn't throw an exception", 2, function( assert ) {
return {
- url: url( "data/1x1.jpg" ),
+ url: url( "1x1.jpg" ),
dataType: "arraybuffer",
success: function( data, s, jqxhr ) {
assert.ok( data instanceof window.ArrayBuffer, "correct data type" );
@@ -1790,7 +1786,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
QUnit.start();
};
jQuery.ajax( {
- url: "data/badjson.js",
+ url: baseURL + "badjson.js",
dataType: "script",
throws: true
} );
@@ -1799,7 +1795,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
jQuery.each( [ "method", "type" ], function( _, globalOption ) {
function request( assert, option ) {
var options = {
- url: url( "data/echoData.php" ),
+ url: url( "mock.php?action=echoData" ),
data: "hello",
success: function( msg ) {
assert.strictEqual( msg, "hello", "Check for POST (no override)" );
@@ -1836,7 +1832,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
ajaxTest( "#13276 - jQuery.ajax() - compatibility between XML documents from ajax requests and parsed string", 1, function( assert ) {
return {
- url: "data/dashboard.xml",
+ url: baseURL + "dashboard.xml",
dataType: "xml",
success: function( ajaxXML ) {
var parsedXML = jQuery( jQuery.parseXML( "<tab title=\"Added\">blibli</tab>" ) ).find( "tab" );
@@ -1854,7 +1850,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
ajaxTest( "#13292 - jQuery.ajax() - converter is bypassed for 204 requests", 3, function( assert ) {
return {
- url: "data/nocontent.php",
+ url: baseURL + "mock.php?action=status&code=204&text=No+Content",
dataType: "testing",
converters: {
"* testing": function() {
@@ -1876,7 +1872,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
ajaxTest( "#13388 - jQuery.ajax() - responseXML", 3, function( assert ) {
return {
- url: url( "data/with_fries.xml" ),
+ url: url( "with_fries.xml" ),
dataType: "xml",
success: function( resp, _, jqXHR ) {
assert.notStrictEqual( resp, undefined, "XML document exists" );
@@ -1888,7 +1884,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
ajaxTest( "#13922 - jQuery.ajax() - converter is bypassed for HEAD requests", 3, function( assert ) {
return {
- url: "data/json.php",
+ url: baseURL + "mock.php?action=json",
method: "HEAD",
data: {
header: "yes"
@@ -1922,7 +1918,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
ajaxTest( "#14683 - jQuery.ajax() - Exceptions thrown synchronously by xhr.send should be caught", 4, function( assert ) {
return [ {
- url: "data/params_html.php",
+ url: baseURL + "mock.php?action=echoData",
method: "POST",
data: {
toString: function() {
@@ -1951,9 +1947,9 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
ajaxTest( "gh-2587 - when content-type not xml, but looks like one", 1, function( assert ) {
return {
- url: url( "data/ajax/content-type.php" ),
+ url: url( "mock.php?action=contentType" ),
data: {
- "content-type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"response": "<test/>"
},
success: function( result ) {
@@ -1968,9 +1964,9 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
ajaxTest( "gh-2587 - when content-type not xml, but looks like one", 1, function( assert ) {
return {
- url: url( "data/ajax/content-type.php" ),
+ url: url( "mock.php?action=contentType" ),
data: {
- "content-type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ contentType: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"response": "<test/>"
},
success: function( result ) {
@@ -1985,9 +1981,9 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
ajaxTest( "gh-2587 - when content-type not json, but looks like one", 1, function( assert ) {
return {
- url: url( "data/ajax/content-type.php" ),
+ url: url( "mock.php?action=contentType" ),
data: {
- "content-type": "test/jsontest",
+ contentType: "test/jsontest",
"response": JSON.stringify( { test: "test" } )
},
success: function( result ) {
@@ -2002,9 +1998,9 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
ajaxTest( "gh-2587 - when content-type not html, but looks like one", 1, function( assert ) {
return {
- url: url( "data/ajax/content-type.php" ),
+ url: url( "mock.php?action=contentType" ),
data: {
- "content-type": "test/htmltest",
+ contentType: "test/htmltest",
"response": "<p>test</p>"
},
success: function( result ) {
@@ -2019,9 +2015,9 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
ajaxTest( "gh-2587 - when content-type not javascript, but looks like one", 1, function( assert ) {
return {
- url: url( "data/ajax/content-type.php" ),
+ url: url( "mock.php?action=contentType" ),
data: {
- "content-type": "test/testjavascript",
+ contentType: "test/testjavascript",
"response": "alert(1)"
},
success: function( result ) {
@@ -2036,9 +2032,9 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
ajaxTest( "gh-2587 - when content-type not ecmascript, but looks like one", 1, function( assert ) {
return {
- url: url( "data/ajax/content-type.php" ),
+ url: url( "mock.php?action=contentType" ),
data: {
- "content-type": "test/testjavascript",
+ contentType: "test/testjavascript",
"response": "alert(1)"
},
success: function( result ) {
@@ -2079,7 +2075,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
QUnit.asyncTest( "jQuery.ajaxSetup()", 1, function( assert ) {
jQuery.ajaxSetup( {
- url: url( "data/name.php?name=foo" ),
+ url: url( "mock.php?action=name&name=foo" ),
success: function( msg ) {
assert.strictEqual( msg, "bar", "Check for GET" );
QUnit.start();
@@ -2110,7 +2106,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
jQuery.ajax( {
type: "GET",
- url: url( "data/name.php?wait=5" ),
+ url: url( "mock.php?action=wait&wait=5" ),
error: pass,
success: fail
} );
@@ -2123,7 +2119,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
jQuery.ajax( {
type: "GET",
timeout: 15000,
- url: url( "data/name.php?wait=1" ),
+ url: url( "mock.php?action=wait&wait=1" ),
error: function() {
assert.ok( false, "Check for local timeout failed" );
QUnit.start();
@@ -2148,7 +2144,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
assert.ok( false, "Global event triggered" );
} );
- jQuery( "#qunit-fixture" ).append( "<script src='data/ajax/evalScript.php'></script>" );
+ jQuery( "#qunit-fixture" ).append( "<script src='" + baseURL + "mock.php?action=script'></script>" );
jQuery( document ).off( "ajaxStart ajaxStop" );
} );
@@ -2162,7 +2158,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
type: "POST"
} );
- jQuery( "#qunit-fixture" ).load( "data/ajax/method.php", function( method ) {
+ jQuery( "#qunit-fixture" ).load( baseURL + "mock.php?action=echoMethod", function( method ) {
assert.equal( method, "GET" );
done();
} );
@@ -2178,7 +2174,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
ps.appendTo( "#qunit-fixture" );
- ps.load( "data/ajax/method.php", function() {
+ ps.load( baseURL + "mock.php?action=echoMethod", function() {
assert.strictEqual( this, ps[ i++ ] );
if ( i === 2 ) {
@@ -2191,14 +2187,14 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
QUnit.test(
"#11402 - jQuery.domManip() - script in comments are properly evaluated", 2,
function( assert ) {
- jQuery( "#qunit-fixture" ).load( "data/cleanScript.html", assert.async() );
+ jQuery( "#qunit-fixture" ).load( baseURL + "cleanScript.html", assert.async() );
}
);
//----------- jQuery.get()
QUnit.asyncTest( "jQuery.get( String, Hash, Function ) - parse xml and use text() on nodes", 2, function( assert ) {
- jQuery.get( url( "data/dashboard.xml" ), function( xml ) {
+ jQuery.get( url( "dashboard.xml" ), function( xml ) {
var content = [];
jQuery( "tab", xml ).each( function() {
content.push( jQuery( this ).text() );
@@ -2213,7 +2209,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
jQuery.ajaxSetup( {
data: "helloworld"
} );
- jQuery.get( url( "data/echoQuery.php" ), function( data ) {
+ jQuery.get( url( "mock.php?action=echoQuery" ), function( data ) {
assert.ok( /helloworld$/.test( data ), "Data from ajaxSettings was used" );
QUnit.start();
} );
@@ -2223,9 +2219,9 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
QUnit.asyncTest( "jQuery.getJSON( String, Hash, Function ) - JSON array", 5, function( assert ) {
jQuery.getJSON(
- url( "data/json.php" ),
+ url( "mock.php?action=json" ),
{
- "json": "array"
+ "array": "1"
},
function( json ) {
assert.ok( json.length >= 2, "Check length" );
@@ -2239,7 +2235,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
} );
QUnit.asyncTest( "jQuery.getJSON( String, Function ) - JSON object", 2, function( assert ) {
- jQuery.getJSON( url( "data/json.php" ), function( json ) {
+ jQuery.getJSON( url( "mock.php?action=json" ), function( json ) {
if ( json && json[ "data" ] ) {
assert.strictEqual( json[ "data" ][ "lang" ], "en", "Check JSON: lang" );
assert.strictEqual( json[ "data" ].length, 25, "Check JSON: length" );
@@ -2249,7 +2245,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
} );
QUnit.asyncTest( "jQuery.getJSON( String, Function ) - JSON object with absolute url to local content", 2, function( assert ) {
- jQuery.getJSON( url( window.location.href.replace( /[^\/]*$/, "" ) + "data/json.php" ), function( json ) {
+ jQuery.getJSON( window.location.href.replace( /[^\/]*$/, "" ) + url( "mock.php?action=json" ), function( json ) {
assert.strictEqual( json.data.lang, "en", "Check JSON: lang" );
assert.strictEqual( json.data.length, 25, "Check JSON: length" );
QUnit.start();
@@ -2263,7 +2259,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
var done = assert.async();
Globals.register( "testBar" );
- jQuery.getScript( url( "data/testbar.php" ), function() {
+ jQuery.getScript( url( "mock.php?action=testbar" ), function() {
assert.strictEqual( window[ "testBar" ], "bar", "Check if script was evaluated" );
done();
} );
@@ -2272,14 +2268,14 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
QUnit.test( "jQuery.getScript( String, Function ) - no callback", 1, function( assert ) {
Globals.register( "testBar" );
- jQuery.getScript( url( "data/testbar.php" ) ).done( assert.async() );
+ jQuery.getScript( url( "mock.php?action=testbar" ) ).done( assert.async() );
} );
QUnit.test( "#8082 - jQuery.getScript( String, Function ) - source as responseText", 2, function( assert ) {
var done = assert.async();
Globals.register( "testBar" );
- jQuery.getScript( url( "data/testbar.php" ), function( data, _, jqXHR ) {
+ jQuery.getScript( url( "mock.php?action=testbar" ), function( data, _, jqXHR ) {
assert.strictEqual( data, jqXHR.responseText, "Same-domain script requests returns the source of the script" );
done();
} );
@@ -2294,7 +2290,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
assert.strictEqual( this.type, "GET", "no data means GET request" );
}
} );
- jQuery( "#first" ).load( "data/name.html", assert.async() );
+ jQuery( "#first" ).load( baseURL + "name.html", assert.async() );
} );
QUnit.test( "jQuery.fn.load() - 404 error callbacks", function( assert ) {
@@ -2303,7 +2299,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
addGlobalEvents( "ajaxStart ajaxStop ajaxSend ajaxComplete ajaxError", assert )();
jQuery( document ).ajaxStop( done );
- jQuery( "<div/>" ).load( "data/404.html", function() {
+ jQuery( "<div/>" ).load( baseURL + "404.txt", function() {
assert.ok( true, "complete" );
} );
} );
@@ -2315,7 +2311,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
assert.strictEqual( this.type, "GET", "no data means GET request" );
}
} );
- jQuery( "#first" ).load( "data/name.html", null, assert.async() );
+ jQuery( "#first" ).load( baseURL + "name.html", null, assert.async() );
} );
// check if load can be called with url and undefined data
@@ -2325,12 +2321,12 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
assert.strictEqual( this.type, "GET", "no data means GET request" );
}
} );
- jQuery( "#first" ).load( "data/name.html", undefined, assert.async() );
+ jQuery( "#first" ).load( baseURL + "name.html", undefined, assert.async() );
} );
// check if load can be called with only url
QUnit.asyncTest( "jQuery.fn.load( URL_SELECTOR )", 1, function( assert ) {
- jQuery( "#first" ).load( "data/test3.html div.user", function() {
+ jQuery( "#first" ).load( baseURL + "test3.html div.user", function() {
assert.strictEqual( jQuery( this ).children( "div" ).length, 2, "Verify that specific elements were injected" );
QUnit.start();
} );
@@ -2338,7 +2334,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
// Selector should be trimmed to avoid leading spaces (#14773)
QUnit.asyncTest( "jQuery.fn.load( URL_SELECTOR with spaces )", 1, function( assert ) {
- jQuery( "#first" ).load( "data/test3.html #superuser ", function() {
+ jQuery( "#first" ).load( baseURL + "test3.html #superuser ", function() {
assert.strictEqual( jQuery( this ).children( "div" ).length, 1, "Verify that specific elements were injected" );
QUnit.start();
} );
@@ -2349,14 +2345,14 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
QUnit.test( "jQuery.fn.load( URL_SELECTOR with non-HTML whitespace(#3003) )", function( assert ) {
assert.expect( 1 );
var done = assert.async();
- jQuery( "#first" ).load( "data/test3.html #whitespace\\\\xA0 ", function() {
+ jQuery( "#first" ).load( baseURL + "test3.html #whitespace\\\\xA0 ", function() {
assert.strictEqual( jQuery( this ).children( "div" ).length, 1, "Verify that specific elements were injected" );
done();
} );
} );
QUnit.asyncTest( "jQuery.fn.load( String, Function ) - simple: inject text into DOM", 2, function( assert ) {
- jQuery( "#first" ).load( url( "data/name.html" ), function() {
+ jQuery( "#first" ).load( url( "name.html" ), function() {
assert.ok( /^ERROR/.test( jQuery( "#first" ).text() ), "Check if content was injected into the DOM" );
QUnit.start();
} );
@@ -2372,7 +2368,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
Globals.register( "testFoo" );
Globals.register( "testBar" );
- jQuery( "#first" ).load( url( "data/test.html" ), function() {
+ jQuery( "#first" ).load( url( "mock.php?action=testHTML&baseURL=" + baseURL ), function() {
assert.ok( jQuery( "#first" ).html().match( /^html text/ ), "Check content after loading html" );
assert.strictEqual( jQuery( "#foo" ).html(), "foo", "Check if script evaluation has modified DOM" );
assert.strictEqual( window[ "testFoo" ], "foo", "Check if script was evaluated after load" );
@@ -2383,7 +2379,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
QUnit.asyncTest( "jQuery.fn.load( String, Function ) - check file with only a script tag", 3, function( assert ) {
Globals.register( "testFoo" );
- jQuery( "#first" ).load( url( "data/test2.html" ), function() {
+ jQuery( "#first" ).load( url( "test2.html" ), function() {
assert.strictEqual( jQuery( "#foo" ).html(), "foo", "Check if script evaluation has modified DOM" );
assert.strictEqual( window[ "testFoo" ], "foo", "Check if script was evaluated after load" );
QUnit.start();
@@ -2396,7 +2392,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
return "Hello World";
}
} );
- jQuery( "<div/>" ).load( url( "data/name.html" ), function( responseText ) {
+ jQuery( "<div/>" ).load( url( "name.html" ), function( responseText ) {
assert.strictEqual( jQuery( this ).html(), "Hello World", "Test div was filled with filtered data" );
assert.strictEqual( responseText, "Hello World", "Test callback receives filtered data" );
QUnit.start();
@@ -2404,13 +2400,12 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
} );
QUnit.asyncTest( "jQuery.fn.load( String, Object, Function )", 2, function( assert ) {
- jQuery( "<div />" ).load( url( "data/params_html.php" ), {
- "foo": 3,
+ jQuery( "<div />" ).load( url( "mock.php?action=echoHtml" ), {
"bar": "ok"
}, function() {
- var $post = jQuery( this ).find( "#post" );
- assert.strictEqual( $post.find( "#foo" ).text(), "3", "Check if a hash of data is passed correctly" );
- assert.strictEqual( $post.find( "#bar" ).text(), "ok", "Check if a hash of data is passed correctly" );
+ var $node = jQuery( this );
+ assert.strictEqual( $node.find( "#method" ).text(), "POST", "Check method" );
+ assert.strictEqual( $node.find( "#data" ).text(), "bar=ok", "Check if data is passed correctly" );
QUnit.start();
} );
} );
@@ -2418,10 +2413,10 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
QUnit.test( "jQuery.fn.load( String, String, Function )", 2, function( assert ) {
var done = assert.async();
- jQuery( "<div />" ).load( url( "data/params_html.php" ), "foo=3&bar=ok", function() {
- var $get = jQuery( this ).find( "#get" );
- assert.strictEqual( $get.find( "#foo" ).text(), "3", "Check if a string of data is passed correctly" );
- assert.strictEqual( $get.find( "#bar" ).text(), "ok", "Check if a of data is passed correctly" );
+ jQuery( "<div />" ).load( url( "mock.php?action=echoHtml" ), "foo=3&bar=ok", function() {
+ var $node = jQuery( this );
+ assert.strictEqual( $node.find( "#method" ).text(), "GET", "Check method" );
+ assert.ok( $node.find( "#query" ).text().match( /foo=3&bar=ok/ ), "Check if a string of data is passed correctly" );
done();
} );
} );
@@ -2444,11 +2439,11 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
jQuery.map( [
{
type: "success",
- url: "data/echoQuery.php?arg=pop"
+ url: baseURL + "mock.php?action=echoQuery&arg=pop"
},
{
type: "error",
- url: "data/404.php"
+ url: baseURL + "404.txt"
}
],
function( options ) {
@@ -2477,7 +2472,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
jQuery( document ).off( "ajaxComplete" );
done();
} );
- jQuery( "#first" ).load( "data/test3.html" );
+ jQuery( "#first" ).load( baseURL + "test3.html" );
} );
QUnit.test( "#10524 - jQuery.fn.load() - data specified in ajaxSettings is merged in", 1, function( assert ) {
@@ -2491,7 +2486,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
"foo": "bar"
}
} );
- jQuery( "#foo" ).load( "data/echoQuery.php", data );
+ jQuery( "#foo" ).load( baseURL + "mock.php?action=echoQuery", data );
jQuery( document ).ajaxComplete( function( event, jqXHR, options ) {
assert.ok( ~options.data.indexOf( "foo=bar" ), "Data from ajaxSettings was used" );
done();
@@ -2505,10 +2500,9 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
jQuery.when(
jQuery.post(
- url( "data/name.php" ),
+ url( "mock.php?action=xml" ),
{
- xml: "5-2",
- length: 3
+ cal: "5-2"
},
function( xml ) {
jQuery( "math", xml ).each( function() {
@@ -2518,7 +2512,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
}
),
jQuery.ajax( {
- url: url( "data/echoData.php" ),
+ url: url( "mock.php?action=echoData" ),
type: "POST",
data: {
"test": {
@@ -2530,9 +2524,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
assert.strictEqual( data, "test%5Blength%5D=7&test%5Bfoo%5D=bar", "Check if a sub-object with a length param is serialized correctly" );
}
} )
- ).always( function() {
- done();
- } );
+ ).always( done );
} );
QUnit.test( "jQuery.post( String, Hash, Function ) - simple with xml", 4, function( assert ) {
@@ -2540,9 +2532,9 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
jQuery.when(
jQuery.post(
- url( "data/name.php" ),
+ url( "mock.php?action=xml" ),
{
- "xml": "5-2"
+ cal: "5-2"
},
function( xml ) {
jQuery( "math", xml ).each( function() {
@@ -2551,7 +2543,7 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
} );
}
),
- jQuery.post( url( "data/name.php?xml=5-2" ), {}, function( xml ) {
+ jQuery.post( url( "mock.php?action=xml&cal=5-2" ), {}, function( xml ) {
jQuery( "math", xml ).each( function() {
assert.strictEqual( jQuery( "calculation", this ).text(), "5-2", "Check for XML" );
assert.strictEqual( jQuery( "result", this ).text(), "3", "Check for XML" );
@@ -2568,9 +2560,9 @@ if ( typeof window.ArrayBuffer === "undefined" || typeof new XMLHttpRequest().re
jQuery.when.apply( jQuery,
jQuery.map( [ "get", "post" ], function( method ) {
return jQuery[ method ]( {
- url: url( "data/name.php" ),
+ url: url( "mock.php?action=xml" ),
data: {
- "xml": "5-2"
+ cal: "5-2"
},
success: function( xml ) {
jQuery( "math", xml ).each( function() {
diff --git a/test/unit/attributes.js b/test/unit/attributes.js
index 1284ffd18..3ab023eaf 100644
--- a/test/unit/attributes.js
+++ b/test/unit/attributes.js
@@ -127,7 +127,7 @@ QUnit.test( "attr(String)", function( assert ) {
assert.equal( jQuery( option ).prop( "selected" ), true, "Make sure that a single option is selected, even when in an optgroup." );
- $img = jQuery( "<img style='display:none' width='215' height='53' src='data/1x1.jpg'/>" ).appendTo( "body" );
+ $img = jQuery( "<img style='display:none' width='215' height='53' src='" + baseURL + "1x1.jpg'/>" ).appendTo( "body" );
assert.equal( $img.attr( "width" ), "215", "Retrieve width attribute on an element with display:none." );
assert.equal( $img.attr( "height" ), "53", "Retrieve height attribute on an element with display:none." );
@@ -780,7 +780,7 @@ QUnit.test( "prop('tabindex')", function( assert ) {
QUnit.test( "image.prop( 'tabIndex' )", function( assert ) {
assert.expect( 1 );
- var image = jQuery( "<img src='data/1x1.jpg' />" )
+ var image = jQuery( "<img src='" + baseURL + "1x1.jpg' />" )
.appendTo( "#qunit-fixture" );
assert.equal( image.prop( "tabIndex" ), -1, "tabIndex on image" );
} );
diff --git a/test/unit/basic.js b/test/unit/basic.js
index 15bca8ff6..b46a04c28 100644
--- a/test/unit/basic.js
+++ b/test/unit/basic.js
@@ -8,7 +8,7 @@ QUnit.test( "ajax", function( assert ) {
jQuery.ajax( {
type: "GET",
- url: url( "data/name.php?name=foo" ),
+ url: url( "mock.php?action=name&name=foo" ),
success: function( msg ) {
assert.strictEqual( msg, "bar", "Check for GET" );
done.pop()();
@@ -17,7 +17,7 @@ QUnit.test( "ajax", function( assert ) {
jQuery.ajax( {
type: "POST",
- url: url( "data/name.php" ),
+ url: url( "mock.php?action=name" ),
data: "name=peter",
success: function( msg ) {
assert.strictEqual( msg, "pan", "Check for POST" );
@@ -25,7 +25,7 @@ QUnit.test( "ajax", function( assert ) {
}
} );
- jQuery( "#first" ).load( url( "data/name.html" ), function() {
+ jQuery( "#first" ).load( url( "name.html" ), function() {
assert.ok( /^ERROR/.test( jQuery( "#first" ).text() ),
"Check if content was injected into the DOM" );
done.pop()();
diff --git a/test/unit/core.js b/test/unit/core.js
index 322b21dc6..3229f78d5 100644
--- a/test/unit/core.js
+++ b/test/unit/core.js
@@ -188,7 +188,7 @@ QUnit.test( "globalEval execution after script injection (#7862)", function( ass
var now,
script = document.createElement( "script" );
- script.src = "data/longLoadScript.php?sleep=2";
+ script.src = baseURL + "mock.php?action=wait&wait=2&script=1";
now = jQuery.now();
document.body.appendChild( script );
@@ -1627,10 +1627,10 @@ QUnit.test( "jQuery.parseHTML", function( assert ) {
QUnit.test( "jQuery.parseHTML(<a href>) - gh-2965", function( assert ) {
assert.expect( 1 );
- var html = "<a href='test.html'></a>",
+ var html = "<a href='example.html'></a>",
href = jQuery.parseHTML( html )[ 0 ].href;
- assert.ok( /\/test\.html$/.test( href ), "href is not lost after parsing anchor" );
+ assert.ok( /\/example\.html$/.test( href ), "href is not lost after parsing anchor" );
} );
if ( jQuery.support.createHTMLDocument ) {
diff --git a/test/unit/css.js b/test/unit/css.js
index 2ca72c1aa..20f8195aa 100644
--- a/test/unit/css.js
+++ b/test/unit/css.js
@@ -1066,7 +1066,7 @@ QUnit.test( "can't get css for disconnected in IE<9, see #10254 and #8388", func
assert.expect( 2 );
var span, div;
- span = jQuery( "<span/>" ).css( "background-image", "url(data/1x1.jpg)" );
+ span = jQuery( "<span/>" ).css( "background-image", "url(" + baseURL + "1x1.jpg)" );
assert.notEqual( span.css( "background-image" ), null, "can't get background-image in IE<9, see #10254" );
div = jQuery( "<div/>" ).css( "top", 10 );
@@ -1374,7 +1374,6 @@ QUnit.test(
"Clearing a Cloned Element's Style Shouldn't Clear the Original Element's Style (#8908)",
24,
function( assert ) {
- var baseUrl = document.location.href.replace( /([^\/]*)$/, "" );
var done = assert.async();
var styles = [ {
name: "backgroundAttachment",
@@ -1388,7 +1387,7 @@ QUnit.test(
// Firefox returns auto's value
name: "backgroundImage",
- value: [ "url('test.png')", "url(" + baseUrl + "test.png)", "url(\"" + baseUrl + "test.png\")" ],
+ value: [ "url('test.png')", "url(" + baseURL + "test.png)", "url(\"" + baseURL + "test.png\")" ],
expected: [ "none", "url(\"http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif\")" ]
}, {
name: "backgroundPosition",
diff --git a/test/unit/data.js b/test/unit/data.js
index 0eb1d5149..248878eda 100644
--- a/test/unit/data.js
+++ b/test/unit/data.js
@@ -777,7 +777,7 @@ QUnit.test( ".removeData should not throw exceptions. (#10080)", function( asser
} );
// change the url to trigger unload
- frame.attr( "src", "data/iframe.html?param=true" );
+ frame.attr( "src", baseURL + "iframe.html?param=true" );
} );
QUnit.test( ".data only checks element attributes once. #8909", function( assert ) {
diff --git a/test/unit/effects.js b/test/unit/effects.js
index ec1669f54..c5f8d53c3 100644
--- a/test/unit/effects.js
+++ b/test/unit/effects.js
@@ -33,7 +33,7 @@ QUnit.module( "effects", {
QUnit[ jQuery.find.compile ? "test" : "skip" ]( "sanity check", function( assert ) {
assert.expect( 1 );
- assert.equal( jQuery( "#dl:visible, #qunit-fixture:visible, #foo:visible" ).length, 3, "QUnit state is correct for testing effects" );
+ assert.equal( jQuery( "#qunit-fixture:visible, #foo:visible" ).length, 2, "QUnit state is correct for testing effects" );
} );
QUnit.test( "show() basic", function( assert ) {
diff --git a/test/unit/event.js b/test/unit/event.js
index d7290a6a4..ccaf72514 100644
--- a/test/unit/event.js
+++ b/test/unit/event.js
@@ -1281,8 +1281,7 @@ QUnit.test( ".trigger() doesn't bubble load event (#10717)", function( assert )
assert.ok( false, "load fired on window" );
} );
- // It's not an image, but as long as it fires load...
- jQuery( "<img src='index.html' />" )
+ jQuery( "<img src='" + baseURL + "1x1.jpg' />" )
.appendTo( "body" )
.on( "load", function() {
assert.ok( true, "load fired on img" );
@@ -1443,7 +1442,7 @@ QUnit.test( "Submit event can be stopped (#11049)", function( assert ) {
// handler making it impossible to feature-detect the support.
QUnit[ /(ipad|iphone|ipod)/i.test( navigator.userAgent ) ? "skip" : "test" ](
"on(beforeunload)", 1, function( assert ) {
- var iframe = jQuery( jQuery.parseHTML( "<iframe src='data/event/onbeforeunload.html'><iframe>" ) );
+ var iframe = jQuery( jQuery.parseHTML( "<iframe src='" + baseURL + "event/onbeforeunload.html'><iframe>" ) );
var done = assert.async();
window.onmessage = function( event ) {
diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js
index 4ad65ccb7..528a192ce 100644
--- a/test/unit/manipulation.js
+++ b/test/unit/manipulation.js
@@ -2377,7 +2377,7 @@ QUnit.asyncTest( "html() - script exceptions bubble (#11743)", 2, function( asse
assert.ok( true, "Exception thrown in remote script" );
};
- jQuery( "#qunit-fixture" ).html( "<script src='data/badcall.js'></script>" );
+ jQuery( "#qunit-fixture" ).html( "<script src='" + baseURL + "badcall.js'></script>" );
assert.ok( true, "Exception ignored" );
} else {
assert.ok( true, "No jQuery.ajax" );
@@ -2463,7 +2463,7 @@ QUnit.test( "script evaluation (#11795)", function( assert ) {
if ( jQuery.ajax ) {
Globals.register( "testBar" );
- jQuery( "#qunit-fixture" ).append( "<script src='" + url( "data/testbar.php" ) + "'/>" );
+ jQuery( "#qunit-fixture" ).append( "<script src='" + url( "mock.php?action=testbar" ) + "'/>" );
assert.strictEqual( window.testBar, "bar", "Global script evaluation" );
} else {
assert.ok( true, "No jQuery.ajax" );
diff --git a/test/unit/offset.js b/test/unit/offset.js
index 8e0cd7275..61f762eea 100644
--- a/test/unit/offset.js
+++ b/test/unit/offset.js
@@ -771,12 +771,12 @@ QUnit.test( "offsetParent", function( assert ) {
assert.equal( div[ 0 ], document.documentElement, "The html element is the offsetParent of the body." );
assert.equal( div[ 1 ], jQuery( "#nothiddendiv" )[ 0 ], "The div is the offsetParent." );
- area = jQuery( "#imgmap area" ).offsetParent();
- assert.equal( area[ 0 ], document.documentElement, "The html element is the offsetParent of the body." );
+ area = jQuery( "<map name=\"imgmap\"><area shape=\"rect\" coords=\"0,0,200,50\"></map>" ).appendTo( "body" ).find( "area" );
+ assert.equal( area.offsetParent()[ 0 ], document.documentElement, "The html element is the offsetParent of a map area." );
+ area.remove();
div = jQuery( "<div>" ).css( { "position": "absolute" } ).appendTo( "body" );
assert.equal( div.offsetParent()[ 0 ], document.documentElement, "Absolutely positioned div returns html as offset parent, see #12139" );
-
div.remove();
} );
diff --git a/test/unit/support.js b/test/unit/support.js
index 312173207..a42a129f1 100644
--- a/test/unit/support.js
+++ b/test/unit/support.js
@@ -39,7 +39,7 @@ if ( jQuery.css ) {
// i.e. no old WebKit or old Firefox
testIframe(
"Check CSP (https://developer.mozilla.org/en-US/docs/Security/CSP) restrictions",
- "support/csp.php",
+ "mock.php?action=cspFrame",
function( assert, jQuery, window, document, support ) {
var done = assert.async();
@@ -47,9 +47,9 @@ testIframe(
assert.deepEqual( jQuery.extend( {}, support ), computedSupport,
"No violations of CSP polices" );
- supportjQuery.get( "data/support/csp.log" ).done( function( data ) {
+ supportjQuery.get( baseURL + "support/csp.log" ).done( function( data ) {
assert.equal( data, "", "No log request should be sent" );
- supportjQuery.get( "data/support/csp-clean.php" ).done( done );
+ supportjQuery.get( baseURL + "mock.php?action=cspClean" ).done( done );
} );
}
);
diff --git a/test/unit/traversing.js b/test/unit/traversing.js
index 83c267a27..eeda204a5 100644
--- a/test/unit/traversing.js
+++ b/test/unit/traversing.js
@@ -608,7 +608,7 @@ QUnit.test( "parents([String])", function( assert ) {
assert.equal( jQuery( "#groups" ).parents( "p" )[ 0 ].id, "ap", "Filtered parents check" );
assert.equal( jQuery( "#groups" ).parents( "div" )[ 0 ].id, "qunit-fixture", "Filtered parents check2" );
assert.deepEqual( jQuery( "#groups" ).parents( "p, div" ).get(), q( "ap", "qunit-fixture" ), "Check for multiple filters" );
- assert.deepEqual( jQuery( "#en, #sndp" ).parents().get(), q( "foo", "qunit-fixture", "dl", "body", "html" ), "Check for unique results from parents" );
+ assert.deepEqual( jQuery( "#en, #sndp" ).parents().get(), q( "foo", "qunit-fixture", "body", "html" ), "Check for unique results from parents" );
} );
QUnit.test( "parentsUntil([String])", function( assert ) {
@@ -621,11 +621,11 @@ QUnit.test( "parentsUntil([String])", function( assert ) {
assert.deepEqual( jQuery( "#groups" ).parentsUntil( "#html" ).get(), parents.slice( 0, -1 ).get(), "Simple parentsUntil check" );
assert.equal( jQuery( "#groups" ).parentsUntil( "#ap" ).length, 0, "Simple parentsUntil check" );
assert.deepEqual( jQuery( "#nonnodes" ).contents().eq( 1 ).parentsUntil( "#html" ).eq( 0 ).get(), q( "nonnodes" ), "Text node parentsUntil check" );
- assert.deepEqual( jQuery( "#groups" ).parentsUntil( "#html, #body" ).get(), parents.slice( 0, 3 ).get(), "Less simple parentsUntil check" );
+ assert.deepEqual( jQuery( "#groups" ).parentsUntil( "#html, #body" ).get(), parents.slice( 0, 2 ).get(), "Less simple parentsUntil check" );
assert.deepEqual( jQuery( "#groups" ).parentsUntil( "#html", "div" ).get(), jQuery( "#qunit-fixture" ).get(), "Filtered parentsUntil check" );
- assert.deepEqual( jQuery( "#groups" ).parentsUntil( "#html", "p,div,dl" ).get(), parents.slice( 0, 3 ).get(), "Multiple-filtered parentsUntil check" );
+ assert.deepEqual( jQuery( "#groups" ).parentsUntil( "#html", "p,div" ).get(), parents.slice( 0, 2 ).get(), "Multiple-filtered parentsUntil check" );
assert.equal( jQuery( "#groups" ).parentsUntil( "#html", "span" ).length, 0, "Filtered parentsUntil check, no match" );
- assert.deepEqual( jQuery( "#groups, #ap" ).parentsUntil( "#html", "p,div,dl" ).get(), parents.slice( 0, 3 ).get(), "Multi-source, multiple-filtered parentsUntil check" );
+ assert.deepEqual( jQuery( "#groups, #ap" ).parentsUntil( "#html", "p,div" ).get(), parents.slice( 0, 2 ).get(), "Multi-source, multiple-filtered parentsUntil check" );
} );
QUnit.test( "next([String])", function( assert ) {
@@ -784,7 +784,7 @@ QUnit[ "content" in document.createElement( "template" ) ? "test" : "skip" ](
jQuery( "#qunit-fixture" ).append(
"<template id='template'>" +
" <script>testScript = 1;</script>" +
- " <img src='data/1x1.jpg' onload='testImgOnload = 1' >" +
+ " <img src='" + baseURL + "1x1.jpg' onload='testImgOnload = 1' >" +
"</template>"
);