| /* eslint no-multi-str: "off" */ | |
| var FILEPATH = "/test/data/testinit.js", | |
| activeScript = [].slice.call( document.getElementsByTagName( "script" ), -1 )[ 0 ], | |
| parentUrl = activeScript && activeScript.src ? | |
| activeScript.src.replace( /[?#].*/, "" ) + FILEPATH.replace( /[^/]+/g, ".." ) + "/" : | |
| "../", | |
| // 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). | |
| baseURL = parentUrl + "test/data/", | |
| supportjQuery = this.jQuery, | |
| // see RFC 2606 | |
| externalHost = "example.com", | |
| // NOTE: keep it in sync with build/tasks/lib/slim-build-flags.js | |
| slimBuildFlags = [ | |
| "-ajax", | |
| "-effects" | |
| ]; | |
| this.hasPHP = true; | |
| this.isLocal = window.location.protocol === "file:"; | |
| // Setup global variables before loading jQuery for testing .noConflict() | |
| supportjQuery.noConflict( true ); | |
| window.originaljQuery = this.jQuery = undefined; | |
| window.original$ = this.$ = "replaced"; | |
| /** | |
| * Returns an array of elements with the given IDs | |
| * @example q( "main", "foo", "bar" ) | |
| * @result [<div id="main">, <span id="foo">, <input id="bar">] | |
| */ | |
| this.q = function() { | |
| var r = [], | |
| i = 0; | |
| for ( ; i < arguments.length; i++ ) { | |
| r.push( document.getElementById( arguments[ i ] ) ); | |
| } | |
| return r; | |
| }; | |
| /** | |
| * Asserts that a select matches the given IDs | |
| * @param {String} message - Assertion name | |
| * @param {String} selector - Sizzle selector | |
| * @param {String} expectedIds - Array of ids to construct what is expected | |
| * @param {(String|Node)=document} context - Selector context | |
| * @example match("Check for something", "p", ["foo", "bar"]); | |
| */ | |
| function match( message, selector, expectedIds, context, assert ) { | |
| var f = jQuery( selector, context ).get(), | |
| s = "", | |
| i = 0; | |
| for ( ; i < f.length; i++ ) { | |
| s += ( s && "," ) + "\"" + f[ i ].id + "\""; | |
| } | |
| assert.deepEqual( f, q.apply( q, expectedIds ), message + " (" + selector + ")" ); | |
| } | |
| /** | |
| * Asserts that a select matches the given IDs. | |
| * The select is not bound by a context. | |
| * @param {String} message - Assertion name | |
| * @param {String} selector - Sizzle selector | |
| * @param {String} expectedIds - Array of ids to construct what is expected | |
| * @example t("Check for something", "p", ["foo", "bar"]); | |
| */ | |
| QUnit.assert.t = function( message, selector, expectedIds ) { | |
| match( message, selector, expectedIds, undefined, QUnit.assert ); | |
| }; | |
| /** | |
| * Asserts that a select matches the given IDs. | |
| * The select is performed within the `#qunit-fixture` context. | |
| * @param {String} message - Assertion name | |
| * @param {String} selector - Sizzle selector | |
| * @param {String} expectedIds - Array of ids to construct what is expected | |
| * @example selectInFixture("Check for something", "p", ["foo", "bar"]); | |
| */ | |
| QUnit.assert.selectInFixture = function( message, selector, expectedIds ) { | |
| match( message, selector, expectedIds, "#qunit-fixture", QUnit.assert ); | |
| }; | |
| this.createDashboardXML = function() { | |
| var string = "<?xml version='1.0' encoding='UTF-8'?> \ | |
| <dashboard> \ | |
| <locations class='foo'> \ | |
| <location for='bar' checked='different'> \ | |
| <infowindowtab normal='ab' mixedCase='yes'> \ | |
| <tab title='Location'><![CDATA[blabla]]></tab> \ | |
| <tab title='Users'><![CDATA[blublu]]></tab> \ | |
| </infowindowtab> \ | |
| </location> \ | |
| </locations> \ | |
| </dashboard>"; | |
| return jQuery.parseXML( string ); | |
| }; | |
| this.createWithFriesXML = function() { | |
| var string = "<?xml version='1.0' encoding='UTF-8'?> \ | |
| <soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' \ | |
| xmlns:xsd='http://www.w3.org/2001/XMLSchema' \ | |
| xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'> \ | |
| <soap:Body> \ | |
| <jsconf xmlns='http://{{ externalHost }}/ns1'> \ | |
| <response xmlns:ab='http://{{ externalHost }}/ns2'> \ | |
| <meta> \ | |
| <component id='seite1' class='component'> \ | |
| <properties xmlns:cd='http://{{ externalHost }}/ns3'> \ | |
| <property name='prop1'> \ | |
| <thing /> \ | |
| <value>1</value> \ | |
| </property> \ | |
| <property name='prop2'> \ | |
| <thing att='something' /> \ | |
| </property> \ | |
| <foo_bar>foo</foo_bar> \ | |
| </properties> \ | |
| </component> \ | |
| </meta> \ | |
| </response> \ | |
| </jsconf> \ | |
| </soap:Body> \ | |
| </soap:Envelope>"; | |
| return jQuery.parseXML( string.replace( /\{\{\s*externalHost\s*\}\}/g, externalHost ) ); | |
| }; | |
| this.createXMLFragment = function() { | |
| var xml, frag; | |
| if ( window.ActiveXObject ) { | |
| xml = new window.ActiveXObject( "msxml2.domdocument" ); | |
| } else { | |
| xml = document.implementation.createDocument( "", "", null ); | |
| } | |
| if ( xml ) { | |
| frag = xml.createElement( "data" ); | |
| } | |
| return frag; | |
| }; | |
| window.fireNative = document.createEvent ? | |
| function( node, type ) { | |
| var event = document.createEvent( "HTMLEvents" ); | |
| event.initEvent( type, true, true ); | |
| node.dispatchEvent( event ); | |
| } : | |
| function( node, type ) { | |
| node.fireEvent( "on" + type, document.createEventObject() ); | |
| }; | |
| /** | |
| * Add random number to url to stop caching | |
| * | |
| * Also prefixes with baseURL automatically. | |
| * | |
| * @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 ) ? "&" : "?" ) + | |
| new Date().getTime() + "" + parseInt( Math.random() * 100000, 10 ); | |
| } | |
| // Ajax testing helper | |
| this.ajaxTest = function( title, expect, options ) { | |
| QUnit.test( title, function( assert ) { | |
| assert.expect( expect ); | |
| var requestOptions; | |
| if ( typeof options === "function" ) { | |
| options = options( assert ); | |
| } | |
| options = options || []; | |
| requestOptions = options.requests || options.request || options; | |
| if ( !Array.isArray( requestOptions ) ) { | |
| requestOptions = [ requestOptions ]; | |
| } | |
| var done = assert.async(); | |
| if ( options.setup ) { | |
| options.setup(); | |
| } | |
| var completed = false, | |
| remaining = requestOptions.length, | |
| complete = function() { | |
| if ( !completed && --remaining === 0 ) { | |
| completed = true; | |
| delete ajaxTest.abort; | |
| if ( options.teardown ) { | |
| options.teardown(); | |
| } | |
| // Make sure all events will be called before done() | |
| setTimeout( done ); | |
| } | |
| }, | |
| requests = jQuery.map( requestOptions, function( options ) { | |
| var request = ( options.create || jQuery.ajax )( options ), | |
| callIfDefined = function( deferType, optionType ) { | |
| var handler = options[ deferType ] || !!options[ optionType ]; | |
| return function( _, status ) { | |
| if ( !completed ) { | |
| if ( !handler ) { | |
| assert.ok( false, "unexpected " + status ); | |
| } else if ( typeof handler === "function" ) { | |
| handler.apply( this, arguments ); | |
| } | |
| } | |
| }; | |
| }; | |
| if ( options.afterSend ) { | |
| options.afterSend( request, assert ); | |
| } | |
| return request | |
| .done( callIfDefined( "done", "success" ) ) | |
| .fail( callIfDefined( "fail", "error" ) ) | |
| .always( complete ); | |
| } ); | |
| ajaxTest.abort = function( reason ) { | |
| if ( !completed ) { | |
| completed = true; | |
| delete ajaxTest.abort; | |
| assert.ok( false, "aborted " + reason ); | |
| jQuery.each( requests, function( i, request ) { | |
| request.abort(); | |
| } ); | |
| } | |
| }; | |
| } ); | |
| }; | |
| this.testIframe = function( title, fileName, func, wrapper ) { | |
| if ( !wrapper ) { | |
| wrapper = QUnit.test; | |
| } | |
| wrapper.call( QUnit, title, function( assert ) { | |
| var done = assert.async(), | |
| $iframe = supportjQuery( "<iframe></iframe>" ) | |
| .css( { position: "absolute", top: "0", left: "-600px", width: "500px" } ) | |
| .attr( { id: "qunit-fixture-iframe", src: url( fileName ) } ); | |
| // Test iframes are expected to invoke this via startIframeTest (cf. iframeTest.js) | |
| window.iframeCallback = function() { | |
| var args = Array.prototype.slice.call( arguments ); | |
| args.unshift( assert ); | |
| setTimeout( function() { | |
| var result; | |
| this.iframeCallback = undefined; | |
| result = func.apply( this, args ); | |
| function finish() { | |
| func = function() {}; | |
| $iframe.remove(); | |
| done(); | |
| } | |
| // Wait for promises returned by `func`. | |
| if ( result && result.then ) { | |
| result.then( finish ); | |
| } else { | |
| finish(); | |
| } | |
| } ); | |
| }; | |
| // Attach iframe to the body for visibility-dependent code | |
| // It will be removed by either the above code, or the testDone callback in testrunner.js | |
| $iframe.prependTo( document.body ); | |
| } ); | |
| }; | |
| this.iframeCallback = undefined; | |
| // Tests are always loaded async | |
| // except when running tests in Karma (See Gruntfile) | |
| if ( !window.__karma__ ) { | |
| 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"; | |
| // Async test for module script type support | |
| function moduleTypeSupported() { | |
| var script = document.createElement( "script" ); | |
| script.type = "module"; | |
| script.text = "QUnit.moduleTypeSupported = true"; | |
| document.head.appendChild( script ).parentNode.removeChild( script ); | |
| } | |
| moduleTypeSupported(); | |
| // Returns whether a particular module like "ajax" or "deprecated" | |
| // is included in the current jQuery build; it handles the slim build | |
| // as well. The util was created so that we don't treat presence of | |
| // particular APIs to decide whether to run a test as then if we | |
| // accidentally remove an API, the tests would still not fail. | |
| this.includesModule = function( moduleName ) { | |
| var excludedModulesPart, excludedModules; | |
| // A short-cut for the slim build, e.g. "4.0.0-pre slim" | |
| if ( jQuery.fn.jquery.indexOf( " slim" ) > -1 ) { | |
| // The module is included if it does NOT exist on the list | |
| // of modules excluded in the slim build | |
| return slimBuildFlags.indexOf( "-" + moduleName ) === -1; | |
| } | |
| // example version for `grunt custom:-deprecated`: | |
| // "4.0.0-pre -deprecated,-deprecated/ajax-event-alias,-deprecated/event" | |
| excludedModulesPart = jQuery.fn.jquery | |
| // Take the flags out of the version string. | |
| // Example: "-deprecated,-deprecated/ajax-event-alias,-deprecated/event" | |
| .split( " " )[ 1 ]; | |
| if ( !excludedModulesPart ) { | |
| // No build part => the full build where everything is included. | |
| return true; | |
| } | |
| excludedModules = excludedModulesPart | |
| // Turn to an array. | |
| // Example: [ "-deprecated", "-deprecated/ajax-event-alias", "-deprecated/event" ] | |
| .split( "," ) | |
| // Remove the leading "-". | |
| // Example: [ "deprecated", "deprecated/ajax-event-alias", "deprecated/event" ] | |
| .map( function( moduleName ) { | |
| return moduleName.slice( 1 ); | |
| } ) | |
| // Filter out deep names - ones that contain a slash. | |
| // Example: [ "deprecated" ] | |
| .filter( function( moduleName ) { | |
| return moduleName.indexOf( "/" ) === -1; | |
| } ); | |
| return excludedModules.indexOf( moduleName ) === -1; | |
| }; | |
| this.loadTests = function() { | |
| // QUnit.config is populated from QUnit.urlParams but only at the beginning | |
| // of the test run. We need to read both. | |
| var amd = QUnit.config.amd || QUnit.urlParams.amd; | |
| // Directly load tests that need evaluation before DOMContentLoaded. | |
| if ( !amd || document.readyState === "loading" ) { | |
| document.write( "<script src='" + parentUrl + "test/unit/ready.js'><\x2Fscript>" ); | |
| } else { | |
| QUnit.module( "ready", function() { | |
| QUnit.skip( "jQuery ready tests skipped in async mode", function() {} ); | |
| } ); | |
| } | |
| // Get testSubproject from testrunner first | |
| require( [ parentUrl + "test/data/testrunner.js" ], function() { | |
| var i = 0, | |
| tests = [ | |
| // A special module with basic tests, meant for | |
| // not fully supported environments like Android 2.3, | |
| // jsdom or PhantomJS. We run it everywhere, though, | |
| // to make sure tests are not broken. | |
| "unit/basic.js", | |
| "unit/core.js", | |
| "unit/callbacks.js", | |
| "unit/deferred.js", | |
| "unit/deprecated.js", | |
| "unit/support.js", | |
| "unit/data.js", | |
| "unit/queue.js", | |
| "unit/attributes.js", | |
| "unit/event.js", | |
| "unit/selector.js", | |
| "unit/traversing.js", | |
| "unit/manipulation.js", | |
| "unit/wrap.js", | |
| "unit/css.js", | |
| "unit/serialize.js", | |
| "unit/ajax.js", | |
| "unit/effects.js", | |
| "unit/offset.js", | |
| "unit/dimensions.js", | |
| "unit/animation.js", | |
| "unit/tween.js" | |
| ]; | |
| // Ensure load order (to preserve test numbers) | |
| ( function loadDep() { | |
| var dep = tests[ i++ ]; | |
| if ( dep ) { | |
| if ( !QUnit.basicTests || i === 1 ) { | |
| require( [ parentUrl + "test/" + dep ], loadDep ); | |
| // Support: Android 2.3 only | |
| // When running basic tests, replace other modules with dummies to avoid overloading | |
| // impaired clients. | |
| } else { | |
| QUnit.module( dep.replace( /^.*\/|\.js$/g, "" ) ); | |
| loadDep(); | |
| } | |
| } else { | |
| if ( window.__karma__ && window.__karma__.start ) { | |
| window.__karma__.start(); | |
| } else { | |
| QUnit.load(); | |
| } | |
| /** | |
| * Run in noConflict mode | |
| */ | |
| jQuery.noConflict(); | |
| // Load the TestSwarm listener if swarmURL is in the address. | |
| if ( QUnit.isSwarm ) { | |
| require( [ "https://swarm.jquery.org/js/inject.js?" + ( new Date() ).getTime() ], | |
| function() { | |
| QUnit.start(); | |
| } ); | |
| } else { | |
| QUnit.start(); | |
| } | |
| } | |
| } )(); | |
| } ); | |
| }; |