1 /* eslint no-multi-str: "off" */
4 var parentUrl = window.location.protocol + "//" + window.location.host,
6 // baseURL is intentionally set to "data/" instead of "".
7 // This is not just for convenience (since most files are in data/)
8 // but also to ensure that urls without prefix fail.
9 baseURL = parentUrl + "/test/data/",
10 supportjQuery = this.jQuery,
12 // NOTE: keep it in sync with build/tasks/lib/slim-exclude.js
22 this.externalHost = "example.com";
24 this.isLocal = window.location.protocol === "file:";
26 // Setup global variables before loading jQuery for testing .noConflict()
27 supportjQuery.noConflict( true );
28 window.originaljQuery = this.jQuery = undefined;
29 window.original$ = this.$ = "replaced";
32 * Returns an array of elements with the given IDs
33 * @example q( "main", "foo", "bar" )
34 * @result [<div id="main">, <span id="foo">, <input id="bar">]
40 for ( ; i < arguments.length; i++ ) {
41 r.push( document.getElementById( arguments[ i ] ) );
47 * Asserts that a select matches the given IDs
48 * @param {String} message - Assertion name
49 * @param {String} selector - jQuery selector
50 * @param {String} expectedIds - Array of ids to construct what is expected
51 * @param {(String|Node)=document} context - Selector context
52 * @example match("Check for something", "p", ["foo", "bar"]);
54 function match( message, selector, expectedIds, context, assert ) {
55 var elems = jQuery( selector, context ).get();
57 assert.deepEqual( elems, q.apply( q, expectedIds ), message + " (" + selector + ")" );
61 * Asserts that a select matches the given IDs.
62 * The select is not bound by a context.
63 * @param {String} message - Assertion name
64 * @param {String} selector - jQuery selector
65 * @param {String} expectedIds - Array of ids to construct what is expected
66 * @example t("Check for something", "p", ["foo", "bar"]);
68 QUnit.assert.t = function( message, selector, expectedIds ) {
69 match( message, selector, expectedIds, undefined, QUnit.assert );
73 * Asserts that a select matches the given IDs.
74 * The select is performed within the `#qunit-fixture` context.
75 * @param {String} message - Assertion name
76 * @param {String} selector - jQuery selector
77 * @param {String} expectedIds - Array of ids to construct what is expected
78 * @example selectInFixture("Check for something", "p", ["foo", "bar"]);
80 QUnit.assert.selectInFixture = function( message, selector, expectedIds ) {
81 match( message, selector, expectedIds, "#qunit-fixture", QUnit.assert );
84 this.createDashboardXML = function() {
85 var string = "<?xml version='1.0' encoding='UTF-8'?> \
87 <locations class='foo'> \
88 <location for='bar' checked='different'> \
89 <infowindowtab normal='ab' mixedCase='yes'> \
90 <tab title='Location'><![CDATA[blabla]]></tab> \
91 <tab title='Users'><![CDATA[blublu]]></tab> \
97 return jQuery.parseXML( string );
100 this.createWithFriesXML = function() {
101 var string = "<?xml version='1.0' encoding='UTF-8'?> \
102 <soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' \
103 xmlns:xsd='http://www.w3.org/2001/XMLSchema' \
104 xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> \
106 <jsconf xmlns='http://www.example.com/ns1'> \
107 <response xmlns:ab='http://www.example.com/ns2'> \
109 <component id='seite1' class='component'> \
110 <properties xmlns:cd='http://www.example.com/ns3'> \
111 <property name='prop1'> \
115 <property name='prop2'> \
116 <thing att='something' /> \
118 <foo_bar>foo</foo_bar> \
127 return jQuery.parseXML( string );
130 this.createXMLFragment = function() {
132 xml = document.implementation.createDocument( "", "", null );
135 frag = xml.createElement( "data" );
141 window.fireNative = function( node, type ) {
142 var event = document.createEvent( "HTMLEvents" );
144 event.initEvent( type, true, true );
145 node.dispatchEvent( event );
149 * Add random number to url to stop caching
151 * Also prefixes with baseURL automatically.
153 * @example url("index.html")
154 * @result "data/index.html?10538358428943"
156 * @example url("mock.php?foo=bar")
157 * @result "data/mock.php?foo=bar&10538358345554"
159 function url( value ) {
160 return baseURL + value + ( /\?/.test( value ) ? "&" : "?" ) +
161 new Date().getTime() + "" + parseInt( Math.random() * 100000, 10 );
164 // Ajax testing helper
165 this.ajaxTest = function( title, expect, options, wrapper ) {
167 wrapper = QUnit.test;
169 wrapper.call( QUnit, title, function( assert ) {
170 assert.expect( expect );
173 if ( typeof options === "function" ) {
174 options = options( assert );
176 options = options || [];
177 requestOptions = options.requests || options.request || options;
178 if ( !Array.isArray( requestOptions ) ) {
179 requestOptions = [ requestOptions ];
182 var done = assert.async();
184 if ( options.setup ) {
188 var completed = false,
189 remaining = requestOptions.length,
190 complete = function() {
191 if ( !completed && --remaining === 0 ) {
193 delete ajaxTest.abort;
194 if ( options.teardown ) {
198 // Make sure all events will be called before done()
202 requests = jQuery.map( requestOptions, function( options ) {
203 var request = ( options.create || jQuery.ajax )( options ),
204 callIfDefined = function( deferType, optionType ) {
205 var handler = options[ deferType ] || !!options[ optionType ];
206 return function( _, status ) {
209 assert.ok( false, "unexpected " + status );
210 } else if ( typeof handler === "function" ) {
211 handler.apply( this, arguments );
217 if ( options.afterSend ) {
218 options.afterSend( request, assert );
222 .done( callIfDefined( "done", "success" ) )
223 .fail( callIfDefined( "fail", "error" ) )
227 ajaxTest.abort = function( reason ) {
230 delete ajaxTest.abort;
231 assert.ok( false, "aborted " + reason );
232 jQuery.each( requests, function( _i, request ) {
240 this.testIframe = function( title, fileName, func, wrapper, iframeStyles ) {
242 wrapper = QUnit.test;
244 wrapper.call( QUnit, title, function( assert ) {
245 var done = assert.async(),
246 $iframe = supportjQuery( "<iframe></iframe>" )
247 .css( { position: "absolute", top: "0", left: "-600px", width: "500px" } )
248 .attr( { id: "qunit-fixture-iframe", src: url( fileName ) } );
250 // Add other iframe styles
251 if ( iframeStyles ) {
252 $iframe.css( iframeStyles );
255 // Test iframes are expected to invoke this via startIframeTest (cf. iframeTest.js)
256 window.iframeCallback = function() {
257 var args = Array.prototype.slice.call( arguments );
259 args.unshift( assert );
261 setTimeout( function() {
264 this.iframeCallback = undefined;
266 result = func.apply( this, args );
269 func = function() {};
274 // Wait for promises returned by `func`.
275 if ( result && result.then ) {
276 result.then( finish );
283 // Attach iframe to the body for visibility-dependent code
284 // It will be removed by either the above code, or the testDone callback in testrunner.js
285 $iframe.prependTo( document.body );
288 this.iframeCallback = undefined;
290 QUnit.config.autostart = false;
292 // Leverage QUnit URL parsing to detect "basic" testing mode
293 QUnit.basicTests = ( QUnit.urlParams.module + "" ) === "basic";
296 // A variable to make it easier to skip specific tests in IE, mostly
297 // testing integrations with newer Web features not supported by it.
298 QUnit.isIE = !!window.document.documentMode;
299 QUnit.testUnlessIE = QUnit.isIE ? QUnit.skip : QUnit.test;
301 // Returns whether a particular module like "ajax" or "deprecated"
302 // is included in the current jQuery build; it handles the slim build
303 // as well. The util was created so that we don't treat presence of
304 // particular APIs to decide whether to run a test as then if we
305 // accidentally remove an API, the tests would still not fail.
306 this.includesModule = function( moduleName ) {
308 var excludedModulesPart, excludedModules;
310 // A short-cut for the slim build, e.g. "4.0.0-pre+slim"
311 if ( jQuery.fn.jquery.indexOf( "+slim" ) > -1 ) {
313 // The module is included if it does NOT exist on the list
314 // of modules excluded in the slim build
315 return excludedFromSlim.indexOf( moduleName ) === -1;
318 // example version for `npm run build -- -e deprecated`:
319 // "v4.0.0-pre+14dc9347 -deprecated,-deprecated/ajax-event-alias,-deprecated/event"
320 excludedModulesPart = jQuery.fn.jquery
322 // Take the flags out of the version string.
323 // Example: "-deprecated,-deprecated/ajax-event-alias,-deprecated/event"
326 if ( !excludedModulesPart ) {
328 // No build part => the full build where everything is included.
332 excludedModules = excludedModulesPart
335 // Example: [ "-deprecated", "-deprecated/ajax-event-alias", "-deprecated/event" ]
338 // Remove the leading "-".
339 // Example: [ "deprecated", "deprecated/ajax-event-alias", "deprecated/event" ]
340 .map( function( moduleName ) {
341 return moduleName.slice( 1 );
344 // Filter out deep names - ones that contain a slash.
345 // Example: [ "deprecated" ]
346 .filter( function( moduleName ) {
347 return moduleName.indexOf( "/" ) === -1;
350 return excludedModules.indexOf( moduleName ) === -1;
353 this.loadTests = function() {
355 // QUnit.config is populated from QUnit.urlParams but only at the beginning
356 // of the test run. We need to read both.
357 var esmodules = QUnit.config.esmodules || QUnit.urlParams.esmodules;
358 var jsdom = QUnit.config.jsdom || QUnit.urlParams.jsdom;
362 // JSDOM doesn't implement scrollTo
363 QUnit.config.scrolltop = false;
366 // Directly load tests that need evaluation before DOMContentLoaded.
367 if ( !jsdom && ( !esmodules || document.readyState === "loading" ) ) {
368 document.write( "<script src='" + parentUrl + "/test/unit/ready.js'><\x2Fscript>" );
370 QUnit.module( "ready", function() {
371 QUnit.skip( "jQuery ready tests skipped in async mode", function() {} );
375 // Get testSubproject from testrunner first
376 require( [ parentUrl + "/test/data/testrunner.js" ], function() {
378 // Says whether jQuery positional selector extensions are supported.
379 // A full selector engine is required to support them as they need to
380 // be evaluated left-to-right. Remove that property when support for
381 // positional selectors is dropped.
382 QUnit.jQuerySelectorsPos = includesModule( "selector" );
384 // Says whether jQuery selector extensions are supported. Change that
385 // to `false` if your custom jQuery versions relies more on native qSA.
386 // This doesn't include support for positional selectors (see above).
387 QUnit.jQuerySelectors = includesModule( "selector" );
392 // A special module with basic tests, meant for not fully
393 // supported environments like jsdom. We run it everywhere,
394 // though, to make sure tests are not broken.
400 "unit/deprecated.js",
404 "unit/attributes.js",
407 "unit/traversing.js",
408 "unit/manipulation.js",
415 "unit/dimensions.js",
420 // Ensure load order (to preserve test numbers)
421 ( function loadDep() {
422 var dep = tests[ i++ ];
425 if ( !QUnit.basicTests || i === 1 ) {
426 require( [ parentUrl + "/test/" + dep ], loadDep );
428 // When running basic tests, replace other modules with dummies to avoid overloading
431 QUnit.module( dep.replace( /^.*\/|\.js$/g, "" ) );
438 * Run in noConflict mode