Build: Bump the github-actions group with 2 updates
[jquery.git] / test / data / testinit.js
blob80c1911e45cca7c03c48efe93901b03062904746
1 /* eslint no-multi-str: "off" */
2 "use strict";
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
13         excludedFromSlim = [
14                 "ajax",
15                 "callbacks",
16                 "deferred",
17                 "effects",
18                 "queue"
19         ];
21 // see RFC 2606
22 this.externalHost = "example.com";
23 this.hasPHP = true;
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";
31 /**
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">]
35  */
36 this.q = function() {
37         var r = [],
38                 i = 0;
40         for ( ; i < arguments.length; i++ ) {
41                 r.push( document.getElementById( arguments[ i ] ) );
42         }
43         return r;
46 /**
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"]);
53  */
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 + ")" );
60 /**
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"]);
67  */
68 QUnit.assert.t = function( message, selector, expectedIds ) {
69         match( message, selector, expectedIds, undefined, QUnit.assert );
72 /**
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"]);
79  */
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'?> \
86         <dashboard> \
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> \
92                                 </infowindowtab> \
93                         </location> \
94                 </locations> \
95         </dashboard>";
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'> \
105                 <soap:Body> \
106                         <jsconf xmlns='http://www.example.com/ns1'> \
107                                 <response xmlns:ab='http://www.example.com/ns2'> \
108                                         <meta> \
109                                                 <component id='seite1' class='component'> \
110                                                         <properties xmlns:cd='http://www.example.com/ns3'> \
111                                                                 <property name='prop1'> \
112                                                                         <thing /> \
113                                                                         <value>1</value> \
114                                                                 </property> \
115                                                                 <property name='prop2'> \
116                                                                         <thing att='something' /> \
117                                                                 </property> \
118                                                                 <foo_bar>foo</foo_bar> \
119                                                         </properties> \
120                                                 </component> \
121                                         </meta> \
122                                 </response> \
123                         </jsconf> \
124                 </soap:Body> \
125         </soap:Envelope>";
127         return jQuery.parseXML( string );
130 this.createXMLFragment = function() {
131         var frag,
132                 xml = document.implementation.createDocument( "", "", null );
134         if ( xml ) {
135                 frag = xml.createElement( "data" );
136         }
138         return frag;
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"
158  */
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 ) {
166         if ( !wrapper ) {
167                 wrapper = QUnit.test;
168         }
169         wrapper.call( QUnit, title, function( assert ) {
170                 assert.expect( expect );
171                 var requestOptions;
173                 if ( typeof options === "function" ) {
174                         options = options( assert );
175                 }
176                 options = options || [];
177                 requestOptions = options.requests || options.request || options;
178                 if ( !Array.isArray( requestOptions ) ) {
179                         requestOptions = [ requestOptions ];
180                 }
182                 var done = assert.async();
184                 if ( options.setup ) {
185                         options.setup();
186                 }
188                 var completed = false,
189                         remaining = requestOptions.length,
190                         complete = function() {
191                                 if ( !completed && --remaining === 0 ) {
192                                         completed = true;
193                                         delete ajaxTest.abort;
194                                         if ( options.teardown ) {
195                                                 options.teardown();
196                                         }
198                                         // Make sure all events will be called before done()
199                                         setTimeout( done );
200                                 }
201                         },
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 ) {
207                                                         if ( !completed ) {
208                                                                 if ( !handler ) {
209                                                                         assert.ok( false, "unexpected " + status );
210                                                                 } else if ( typeof handler === "function" ) {
211                                                                         handler.apply( this, arguments );
212                                                                 }
213                                                         }
214                                                 };
215                                         };
217                                 if ( options.afterSend ) {
218                                         options.afterSend( request, assert );
219                                 }
221                                 return request
222                                         .done( callIfDefined( "done", "success" ) )
223                                         .fail( callIfDefined( "fail", "error" ) )
224                                         .always( complete );
225                         } );
227                 ajaxTest.abort = function( reason ) {
228                         if ( !completed ) {
229                                 completed = true;
230                                 delete ajaxTest.abort;
231                                 assert.ok( false, "aborted " + reason );
232                                 jQuery.each( requests, function( _i, request ) {
233                                         request.abort();
234                                 } );
235                         }
236                 };
237         } );
240 this.testIframe = function( title, fileName, func, wrapper, iframeStyles ) {
241         if ( !wrapper ) {
242                 wrapper = QUnit.test;
243         }
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 );
253                 }
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() {
262                                 var result;
264                                 this.iframeCallback = undefined;
266                                 result = func.apply( this, args );
268                                 function finish() {
269                                         func = function() {};
270                                         $iframe.remove();
271                                         done();
272                                 }
274                                 // Wait for promises returned by `func`.
275                                 if ( result && result.then ) {
276                                         result.then( finish );
277                                 } else {
278                                         finish();
279                                 }
280                         } );
281                 };
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 );
286         } );
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";
295 // Support: IE 11+
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;
316         }
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"
324                 .split( " " )[ 1 ];
326         if ( !excludedModulesPart ) {
328                 // No build part => the full build where everything is included.
329                 return true;
330         }
332         excludedModules = excludedModulesPart
334                 // Turn to an array.
335                 // Example: [ "-deprecated", "-deprecated/ajax-event-alias", "-deprecated/event" ]
336                 .split( "," )
338                 // Remove the leading "-".
339                 // Example: [ "deprecated", "deprecated/ajax-event-alias", "deprecated/event" ]
340                 .map( function( moduleName ) {
341                         return moduleName.slice( 1 );
342                 } )
344                 // Filter out deep names - ones that contain a slash.
345                 // Example: [ "deprecated" ]
346                 .filter( function( moduleName ) {
347                         return moduleName.indexOf( "/" ) === -1;
348                 } );
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;
360         if ( jsdom ) {
362                 // JSDOM doesn't implement scrollTo
363                 QUnit.config.scrolltop = false;
364         }
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>" );
369         } else {
370                 QUnit.module( "ready", function() {
371                         QUnit.skip( "jQuery ready tests skipped in async mode", function() {} );
372                 } );
373         }
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" );
389                 var i = 0,
390                         tests = [
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.
395                                 "unit/basic.js",
397                                 "unit/core.js",
398                                 "unit/callbacks.js",
399                                 "unit/deferred.js",
400                                 "unit/deprecated.js",
401                                 "unit/support.js",
402                                 "unit/data.js",
403                                 "unit/queue.js",
404                                 "unit/attributes.js",
405                                 "unit/event.js",
406                                 "unit/selector.js",
407                                 "unit/traversing.js",
408                                 "unit/manipulation.js",
409                                 "unit/wrap.js",
410                                 "unit/css.js",
411                                 "unit/serialize.js",
412                                 "unit/ajax.js",
413                                 "unit/effects.js",
414                                 "unit/offset.js",
415                                 "unit/dimensions.js",
416                                 "unit/animation.js",
417                                 "unit/tween.js"
418                         ];
420                 // Ensure load order (to preserve test numbers)
421                 ( function loadDep() {
422                         var dep = tests[ i++ ];
424                         if ( dep ) {
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
429                                 // impaired clients.
430                                 } else {
431                                         QUnit.module( dep.replace( /^.*\/|\.js$/g, "" ) );
432                                         loadDep();
433                                 }
435                         } else {
437                                 /**
438                                  * Run in noConflict mode
439                                  */
440                                 jQuery.noConflict();
442                                 QUnit.start();
443                         }
444                 } )();
445         } );