diff --git a/bower.json b/bower.json
index 8d0dfdd14..bff22caf8 100644
--- a/bower.json
+++ b/bower.json
@@ -17,7 +17,7 @@
},
"devDependencies": {
"requirejs": "2.1.10",
- "qunit": "1.12.0",
+ "qunit": "1.14.0",
"sinon": "1.8.1"
},
"keywords": [
diff --git a/test/.jshintrc b/test/.jshintrc
index 0599c8f39..563b299e7 100644
--- a/test/.jshintrc
+++ b/test/.jshintrc
@@ -35,7 +35,7 @@
"start": false,
"stop": false,
"expect": false,
- "raises": false,
+ "throws": false,
"ajaxTest": false,
"testIframe": false,
"testIframeWithCallback": false,
diff --git a/test/libs/qunit/qunit.css b/test/libs/qunit/qunit.css
index 7ba3f9a30..93026e3ba 100644
--- a/test/libs/qunit/qunit.css
+++ b/test/libs/qunit/qunit.css
@@ -1,11 +1,12 @@
-/**
- * QUnit v1.12.0 - A JavaScript Unit Testing Framework
+/*!
+ * QUnit 1.14.0
+ * http://qunitjs.com/
*
- * http://qunitjs.com
- *
- * Copyright 2012 jQuery Foundation and other contributors
- * Released under the MIT license.
+ * Copyright 2013 jQuery Foundation and other contributors
+ * Released under the MIT license
* http://jquery.org/license
+ *
+ * Date: 2014-01-31T16:40Z
*/
/** Font Family and Sizes */
@@ -31,32 +32,29 @@
#qunit-header {
padding: 0.5em 0 0.5em 1em;
- color: #8699a4;
- background-color: #0d3349;
+ color: #8699A4;
+ background-color: #0D3349;
font-size: 1.5em;
line-height: 1em;
- font-weight: normal;
+ font-weight: 400;
border-radius: 5px 5px 0 0;
- -moz-border-radius: 5px 5px 0 0;
- -webkit-border-top-right-radius: 5px;
- -webkit-border-top-left-radius: 5px;
}
#qunit-header a {
text-decoration: none;
- color: #c2ccd1;
+ color: #C2CCD1;
}
#qunit-header a:hover,
#qunit-header a:focus {
- color: #fff;
+ color: #FFF;
}
#qunit-testrunner-toolbar label {
display: inline-block;
- padding: 0 .5em 0 .1em;
+ padding: 0 0.5em 0 0.1em;
}
#qunit-banner {
@@ -66,14 +64,14 @@
#qunit-testrunner-toolbar {
padding: 0.5em 0 0.5em 2em;
color: #5E740B;
- background-color: #eee;
+ background-color: #EEE;
overflow: hidden;
}
#qunit-userAgent {
padding: 0.5em 0 0.5em 2.5em;
- background-color: #2b81af;
- color: #fff;
+ background-color: #2B81AF;
+ color: #FFF;
text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
}
@@ -89,7 +87,7 @@
#qunit-tests li {
padding: 0.4em 0.5em 0.4em 2.5em;
- border-bottom: 1px solid #fff;
+ border-bottom: 1px solid #FFF;
list-style-position: inside;
}
@@ -103,7 +101,7 @@
#qunit-tests li a {
padding: 0.5em;
- color: #c2ccd1;
+ color: #C2CCD1;
text-decoration: none;
}
#qunit-tests li a:hover,
@@ -120,11 +118,9 @@
margin-top: 0.5em;
padding: 0.5em;
- background-color: #fff;
+ background-color: #FFF;
border-radius: 5px;
- -moz-border-radius: 5px;
- -webkit-border-radius: 5px;
}
.qunit-collapsed {
@@ -133,13 +129,13 @@
#qunit-tests table {
border-collapse: collapse;
- margin-top: .2em;
+ margin-top: 0.2em;
}
#qunit-tests th {
text-align: right;
vertical-align: top;
- padding: 0 .5em 0 0;
+ padding: 0 0.5em 0 0;
}
#qunit-tests td {
@@ -153,26 +149,26 @@
}
#qunit-tests del {
- background-color: #e0f2be;
- color: #374e0c;
+ background-color: #E0F2BE;
+ color: #374E0C;
text-decoration: none;
}
#qunit-tests ins {
- background-color: #ffcaca;
+ background-color: #FFCACA;
color: #500;
text-decoration: none;
}
/*** Test Counts */
-#qunit-tests b.counts { color: black; }
+#qunit-tests b.counts { color: #000; }
#qunit-tests b.passed { color: #5E740B; }
#qunit-tests b.failed { color: #710909; }
#qunit-tests li li {
padding: 5px;
- background-color: #fff;
+ background-color: #FFF;
border-bottom: none;
list-style-position: inside;
}
@@ -180,8 +176,8 @@
/*** Passing Styles */
#qunit-tests li li.pass {
- color: #3c510c;
- background-color: #fff;
+ color: #3C510C;
+ background-color: #FFF;
border-left: 10px solid #C6E746;
}
@@ -189,7 +185,7 @@
#qunit-tests .pass .test-name { color: #366097; }
#qunit-tests .pass .test-actual,
-#qunit-tests .pass .test-expected { color: #999999; }
+#qunit-tests .pass .test-expected { color: #999; }
#qunit-banner.qunit-pass { background-color: #C6E746; }
@@ -197,24 +193,21 @@
#qunit-tests li li.fail {
color: #710909;
- background-color: #fff;
+ background-color: #FFF;
border-left: 10px solid #EE5757;
white-space: pre;
}
#qunit-tests > li:last-child {
border-radius: 0 0 5px 5px;
- -moz-border-radius: 0 0 5px 5px;
- -webkit-border-bottom-right-radius: 5px;
- -webkit-border-bottom-left-radius: 5px;
}
-#qunit-tests .fail { color: #000000; background-color: #EE5757; }
+#qunit-tests .fail { color: #000; background-color: #EE5757; }
#qunit-tests .fail .test-name,
-#qunit-tests .fail .module-name { color: #000000; }
+#qunit-tests .fail .module-name { color: #000; }
#qunit-tests .fail .test-actual { color: #EE5757; }
-#qunit-tests .fail .test-expected { color: green; }
+#qunit-tests .fail .test-expected { color: #008000; }
#qunit-banner.qunit-fail { background-color: #EE5757; }
@@ -224,13 +217,13 @@
#qunit-testresult {
padding: 0.5em 0.5em 0.5em 2.5em;
- color: #2b81af;
+ color: #2B81AF;
background-color: #D2E0E6;
- border-bottom: 1px solid white;
+ border-bottom: 1px solid #FFF;
}
#qunit-testresult .module-name {
- font-weight: bold;
+ font-weight: 700;
}
/** Fixture */
diff --git a/test/libs/qunit/qunit.js b/test/libs/qunit/qunit.js
index 84c73907d..0e279fde1 100644
--- a/test/libs/qunit/qunit.js
+++ b/test/libs/qunit/qunit.js
@@ -1,11 +1,12 @@
-/**
- * QUnit v1.12.0 - A JavaScript Unit Testing Framework
- *
- * http://qunitjs.com
+/*!
+ * QUnit 1.14.0
+ * http://qunitjs.com/
*
* Copyright 2013 jQuery Foundation and other contributors
- * Released under the MIT license.
- * https://jquery.org/license/
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2014-01-31T16:40Z
*/
(function( window ) {
@@ -21,7 +22,9 @@ var QUnit,
// Keep a local reference to Date (GH-283)
Date = window.Date,
setTimeout = window.setTimeout,
+ clearTimeout = window.clearTimeout,
defined = {
+ document: typeof window.document !== "undefined",
setTimeout: typeof window.setTimeout !== "undefined",
sessionStorage: (function() {
var x = "qunit-test-string";
@@ -84,6 +87,1103 @@ var QUnit,
return vals;
};
+
+// Root QUnit object.
+// `QUnit` initialized at top of scope
+QUnit = {
+
+ // call on start of module test to prepend name to all tests
+ module: function( name, testEnvironment ) {
+ config.currentModule = name;
+ config.currentModuleTestEnvironment = testEnvironment;
+ config.modules[name] = true;
+ },
+
+ asyncTest: function( testName, expected, callback ) {
+ if ( arguments.length === 2 ) {
+ callback = expected;
+ expected = null;
+ }
+
+ QUnit.test( testName, expected, callback, true );
+ },
+
+ test: function( testName, expected, callback, async ) {
+ var test,
+ nameHtml = "" + escapeText( testName ) + "";
+
+ if ( arguments.length === 2 ) {
+ callback = expected;
+ expected = null;
+ }
+
+ if ( config.currentModule ) {
+ nameHtml = "" + escapeText( config.currentModule ) + ": " + nameHtml;
+ }
+
+ test = new Test({
+ nameHtml: nameHtml,
+ testName: testName,
+ expected: expected,
+ async: async,
+ callback: callback,
+ module: config.currentModule,
+ moduleTestEnvironment: config.currentModuleTestEnvironment,
+ stack: sourceFromStacktrace( 2 )
+ });
+
+ if ( !validTest( test ) ) {
+ return;
+ }
+
+ test.queue();
+ },
+
+ // Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through.
+ expect: function( asserts ) {
+ if (arguments.length === 1) {
+ config.current.expected = asserts;
+ } else {
+ return config.current.expected;
+ }
+ },
+
+ start: function( count ) {
+ // QUnit hasn't been initialized yet.
+ // Note: RequireJS (et al) may delay onLoad
+ if ( config.semaphore === undefined ) {
+ QUnit.begin(function() {
+ // This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first
+ setTimeout(function() {
+ QUnit.start( count );
+ });
+ });
+ return;
+ }
+
+ config.semaphore -= count || 1;
+ // don't start until equal number of stop-calls
+ if ( config.semaphore > 0 ) {
+ return;
+ }
+ // ignore if start is called more often then stop
+ if ( config.semaphore < 0 ) {
+ config.semaphore = 0;
+ QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) );
+ return;
+ }
+ // A slight delay, to avoid any current callbacks
+ if ( defined.setTimeout ) {
+ setTimeout(function() {
+ if ( config.semaphore > 0 ) {
+ return;
+ }
+ if ( config.timeout ) {
+ clearTimeout( config.timeout );
+ }
+
+ config.blocking = false;
+ process( true );
+ }, 13);
+ } else {
+ config.blocking = false;
+ process( true );
+ }
+ },
+
+ stop: function( count ) {
+ config.semaphore += count || 1;
+ config.blocking = true;
+
+ if ( config.testTimeout && defined.setTimeout ) {
+ clearTimeout( config.timeout );
+ config.timeout = setTimeout(function() {
+ QUnit.ok( false, "Test timed out" );
+ config.semaphore = 1;
+ QUnit.start();
+ }, config.testTimeout );
+ }
+ }
+};
+
+// We use the prototype to distinguish between properties that should
+// be exposed as globals (and in exports) and those that shouldn't
+(function() {
+ function F() {}
+ F.prototype = QUnit;
+ QUnit = new F();
+ // Make F QUnit's constructor so that we can add to the prototype later
+ QUnit.constructor = F;
+}());
+
+/**
+ * Config object: Maintain internal state
+ * Later exposed as QUnit.config
+ * `config` initialized at top of scope
+ */
+config = {
+ // The queue of tests to run
+ queue: [],
+
+ // block until document ready
+ blocking: true,
+
+ // when enabled, show only failing tests
+ // gets persisted through sessionStorage and can be changed in UI via checkbox
+ hidepassed: false,
+
+ // 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
+ altertitle: true,
+
+ // by default, scroll to top of the page when suite is done
+ scrolltop: true,
+
+ // 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: "noglobals",
+ label: "Check for Globals",
+ tooltip: "Enabling this will test if any test introduces new properties on the `window` object. 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."
+ }
+ ],
+
+ // Set of all modules.
+ modules: {},
+
+ // logging callback queues
+ begin: [],
+ done: [],
+ log: [],
+ testStart: [],
+ testDone: [],
+ moduleStart: [],
+ moduleDone: []
+};
+
+// Initialize more QUnit.config and QUnit.urlParams
+(function() {
+ var i, current,
+ location = window.location || { search: "", protocol: "file:" },
+ params = location.search.slice( 1 ).split( "&" ),
+ length = params.length,
+ urlParams = {};
+
+ 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 ];
+ }
+ }
+ }
+
+ QUnit.urlParams = urlParams;
+
+ // String search anywhere in moduleName+testName
+ config.filter = urlParams.filter;
+
+ // Exact match of the module name
+ config.module = urlParams.module;
+
+ config.testNumber = [];
+ if ( urlParams.testNumber ) {
+
+ // Ensure that urlParams.testNumber is an array
+ urlParams.testNumber = [].concat( urlParams.testNumber );
+ for ( i = 0; i < urlParams.testNumber.length; i++ ) {
+ current = urlParams.testNumber[ i ];
+ config.testNumber.push( parseInt( current, 10 ) );
+ }
+ }
+
+ // Figure out if we're running the tests from a server or not
+ QUnit.isLocal = location.protocol === "file:";
+}());
+
+extend( QUnit, {
+
+ config: config,
+
+ // Initialize the configuration options
+ init: function() {
+ extend( config, {
+ stats: { all: 0, bad: 0 },
+ moduleStats: { all: 0, bad: 0 },
+ started: +new Date(),
+ updateRate: 1000,
+ blocking: false,
+ autostart: true,
+ autorun: false,
+ filter: "",
+ queue: [],
+ semaphore: 1
+ });
+
+ var tests, banner, result,
+ qunit = id( "qunit" );
+
+ if ( qunit ) {
+ qunit.innerHTML =
+ "
" +
+ "" +
+ "" +
+ "" +
+ "
";
+ }
+
+ 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...
";
+ }
+ },
+
+ // Resets the test setup. Useful for tests that modify the DOM.
+ /*
+ DEPRECATED: Use multiple tests instead of resetting inside a test.
+ Use testStart or testDone for custom cleanup.
+ This method will throw an error in 2.0, and will be removed in 2.1
+ */
+ reset: function() {
+ var fixture = id( "qunit-fixture" );
+ if ( fixture ) {
+ fixture.innerHTML = config.fixture;
+ }
+ },
+
+ // Safe object type checking
+ is: function( type, obj ) {
+ return QUnit.objectType( obj ) === type;
+ },
+
+ objectType: function( obj ) {
+ if ( typeof obj === "undefined" ) {
+ return "undefined";
+ }
+
+ // Consider: typeof null === object
+ if ( obj === null ) {
+ return "null";
+ }
+
+ var match = toString.call( obj ).match(/^\[object\s(.*)\]$/),
+ type = match && match[1] || "";
+
+ switch ( type ) {
+ case "Number":
+ if ( isNaN(obj) ) {
+ return "nan";
+ }
+ return "number";
+ case "String":
+ case "Boolean":
+ case "Array":
+ case "Date":
+ case "RegExp":
+ case "Function":
+ return type.toLowerCase();
+ }
+ if ( typeof obj === "object" ) {
+ return "object";
+ }
+ return undefined;
+ },
+
+ push: function( result, actual, expected, message ) {
+ if ( !config.current ) {
+ throw new Error( "assertion outside test context, was " + sourceFromStacktrace() );
+ }
+
+ var output, source,
+ details = {
+ module: config.current.module,
+ name: config.current.testName,
+ result: result,
+ message: message,
+ actual: actual,
+ expected: expected
+ };
+
+ message = escapeText( message ) || ( result ? "okay" : "failed" );
+ message = "" + message + "";
+ output = message;
+
+ if ( !result ) {
+ expected = escapeText( QUnit.jsDump.parse(expected) );
+ actual = escapeText( QUnit.jsDump.parse(actual) );
+ output += "Expected: | " + expected + " |
";
+
+ if ( actual !== expected ) {
+ output += "Result: | " + actual + " |
";
+ output += "Diff: | " + QUnit.diff( expected, actual ) + " |
";
+ }
+
+ source = sourceFromStacktrace();
+
+ if ( source ) {
+ details.source = source;
+ output += "Source: | " + escapeText( source ) + " |
";
+ }
+
+ output += "
";
+ }
+
+ runLoggingCallbacks( "log", QUnit, details );
+
+ config.current.assertions.push({
+ result: !!result,
+ message: output
+ });
+ },
+
+ pushFailure: function( message, source, actual ) {
+ if ( !config.current ) {
+ throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) );
+ }
+
+ var output,
+ details = {
+ module: config.current.module,
+ name: config.current.testName,
+ result: false,
+ message: message
+ };
+
+ message = escapeText( message ) || "error";
+ message = "" + message + "";
+ output = message;
+
+ output += "";
+
+ if ( actual ) {
+ output += "Result: | " + escapeText( actual ) + " |
";
+ }
+
+ if ( source ) {
+ details.source = source;
+ output += "Source: | " + escapeText( source ) + " |
";
+ }
+
+ output += "
";
+
+ runLoggingCallbacks( "log", QUnit, details );
+
+ config.current.assertions.push({
+ result: false,
+ message: output
+ });
+ },
+
+ url: function( params ) {
+ params = extend( extend( {}, QUnit.urlParams ), params );
+ var key,
+ querystring = "?";
+
+ for ( key in params ) {
+ if ( hasOwn.call( params, key ) ) {
+ querystring += encodeURIComponent( key ) + "=" +
+ encodeURIComponent( params[ key ] ) + "&";
+ }
+ }
+ return window.location.protocol + "//" + window.location.host +
+ window.location.pathname + querystring.slice( 0, -1 );
+ },
+
+ extend: extend,
+ id: id,
+ addEvent: addEvent,
+ addClass: addClass,
+ hasClass: hasClass,
+ removeClass: removeClass
+ // load, equiv, jsDump, diff: Attached later
+});
+
+/**
+ * @deprecated: Created for backwards compatibility with test runner that set the hook function
+ * into QUnit.{hook}, instead of invoking it and passing the hook function.
+ * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here.
+ * Doing this allows us to tell if the following methods have been overwritten on the actual
+ * QUnit object.
+ */
+extend( QUnit.constructor.prototype, {
+
+ // Logging callbacks; all receive a single argument with the listed properties
+ // run test/logs.html for any related changes
+ begin: registerLoggingCallback( "begin" ),
+
+ // done: { failed, passed, total, runtime }
+ done: registerLoggingCallback( "done" ),
+
+ // log: { result, actual, expected, message }
+ log: registerLoggingCallback( "log" ),
+
+ // testStart: { name }
+ testStart: registerLoggingCallback( "testStart" ),
+
+ // testDone: { name, failed, passed, total, runtime }
+ testDone: registerLoggingCallback( "testDone" ),
+
+ // moduleStart: { name }
+ moduleStart: registerLoggingCallback( "moduleStart" ),
+
+ // moduleDone: { name, failed, passed, total }
+ moduleDone: registerLoggingCallback( "moduleDone" )
+});
+
+if ( !defined.document || document.readyState === "complete" ) {
+ config.autorun = true;
+}
+
+QUnit.load = function() {
+ runLoggingCallbacks( "begin", QUnit, {} );
+
+ // Initialize the config, saving the execution queue
+ var banner, filter, i, j, label, len, main, ol, toolbar, val, selection,
+ urlConfigContainer, moduleFilter, userAgent,
+ numModules = 0,
+ moduleNames = [],
+ moduleFilterHtml = "",
+ urlConfigHtml = "",
+ oldconfig = extend( {}, config );
+
+ QUnit.init();
+ extend(config, oldconfig);
+
+ config.blocking = false;
+
+ len = config.urlConfig.length;
+
+ for ( i = 0; i < len; i++ ) {
+ val = config.urlConfig[i];
+ if ( typeof val === "string" ) {
+ val = {
+ id: val,
+ label: val
+ };
+ }
+ config[ val.id ] = QUnit.urlParams[ val.id ];
+ if ( !val.value || typeof val.value === "string" ) {
+ urlConfigHtml += "";
+ } else {
+ urlConfigHtml += "";
+ }
+ }
+ for ( i in config.modules ) {
+ if ( config.modules.hasOwnProperty( i ) ) {
+ moduleNames.push(i);
+ }
+ }
+ numModules = moduleNames.length;
+ moduleNames.sort( function( a, b ) {
+ return a.localeCompare( b );
+ });
+ moduleFilterHtml += "";
+
+ // `userAgent` initialized at top of scope
+ userAgent = id( "qunit-userAgent" );
+ if ( userAgent ) {
+ userAgent.innerHTML = navigator.userAgent;
+ }
+
+ // `banner` initialized at top of scope
+ banner = id( "qunit-header" );
+ if ( banner ) {
+ banner.innerHTML = "" + banner.innerHTML + " ";
+ }
+
+ // `toolbar` initialized at top of scope
+ toolbar = id( "qunit-testrunner-toolbar" );
+ if ( toolbar ) {
+ // `filter` initialized at top of scope
+ filter = document.createElement( "input" );
+ filter.type = "checkbox";
+ filter.id = "qunit-filter-pass";
+
+ addEvent( filter, "click", function() {
+ var tmp,
+ ol = id( "qunit-tests" );
+
+ if ( filter.checked ) {
+ ol.className = ol.className + " hidepass";
+ } else {
+ tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " ";
+ ol.className = tmp.replace( / hidepass /, " " );
+ }
+ if ( defined.sessionStorage ) {
+ if (filter.checked) {
+ sessionStorage.setItem( "qunit-filter-passed-tests", "true" );
+ } else {
+ sessionStorage.removeItem( "qunit-filter-passed-tests" );
+ }
+ }
+ });
+
+ if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) {
+ filter.checked = true;
+ // `ol` initialized at top of scope
+ ol = id( "qunit-tests" );
+ ol.className = ol.className + " hidepass";
+ }
+ toolbar.appendChild( filter );
+
+ // `label` initialized at top of scope
+ label = document.createElement( "label" );
+ label.setAttribute( "for", "qunit-filter-pass" );
+ label.setAttribute( "title", "Only show tests and assertions that fail. Stored in sessionStorage." );
+ label.innerHTML = "Hide passed tests";
+ toolbar.appendChild( label );
+
+ urlConfigContainer = document.createElement("span");
+ urlConfigContainer.innerHTML = urlConfigHtml;
+ // For oldIE support:
+ // * Add handlers to the individual elements instead of the container
+ // * Use "click" instead of "change" for checkboxes
+ // * Fallback from event.target to event.srcElement
+ addEvents( urlConfigContainer.getElementsByTagName("input"), "click", function( event ) {
+ var params = {},
+ target = event.target || event.srcElement;
+ params[ target.name ] = target.checked ?
+ target.defaultValue || true :
+ undefined;
+ window.location = QUnit.url( params );
+ });
+ addEvents( urlConfigContainer.getElementsByTagName("select"), "change", function( event ) {
+ var params = {},
+ target = event.target || event.srcElement;
+ params[ target.name ] = target.options[ target.selectedIndex ].value || undefined;
+ window.location = QUnit.url( params );
+ });
+ toolbar.appendChild( urlConfigContainer );
+
+ if (numModules > 1) {
+ moduleFilter = document.createElement( "span" );
+ moduleFilter.setAttribute( "id", "qunit-modulefilter-container" );
+ moduleFilter.innerHTML = moduleFilterHtml;
+ addEvent( moduleFilter.lastChild, "change", function() {
+ var selectBox = moduleFilter.getElementsByTagName("select")[0],
+ selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
+
+ window.location = QUnit.url({
+ module: ( selectedModule === "" ) ? undefined : selectedModule,
+ // Remove any existing filters
+ filter: undefined,
+ testNumber: undefined
+ });
+ });
+ toolbar.appendChild(moduleFilter);
+ }
+ }
+
+ // `main` initialized at top of scope
+ main = id( "qunit-fixture" );
+ if ( main ) {
+ config.fixture = main.innerHTML;
+ }
+
+ if ( config.autostart ) {
+ QUnit.start();
+ }
+};
+
+if ( defined.document ) {
+ addEvent( window, "load", QUnit.load );
+}
+
+// `onErrorFnPrev` initialized at top of scope
+// Preserve other handlers
+onErrorFnPrev = window.onerror;
+
+// Cover uncaught exceptions
+// Returning true will suppress the default browser handler,
+// returning false will let it run.
+window.onerror = function ( error, filePath, linerNr ) {
+ var ret = false;
+ if ( onErrorFnPrev ) {
+ ret = onErrorFnPrev( error, filePath, linerNr );
+ }
+
+ // Treat return value as window.onerror itself does,
+ // Only do our handling if not suppressed.
+ if ( ret !== true ) {
+ if ( QUnit.config.current ) {
+ if ( QUnit.config.current.ignoreGlobalErrors ) {
+ return true;
+ }
+ QUnit.pushFailure( error, filePath + ":" + linerNr );
+ } else {
+ QUnit.test( "global failure", extend( function() {
+ QUnit.pushFailure( error, filePath + ":" + linerNr );
+ }, { validTest: validTest } ) );
+ }
+ return false;
+ }
+
+ return ret;
+};
+
+function done() {
+ config.autorun = true;
+
+ // Log the last module results
+ if ( config.previousModule ) {
+ runLoggingCallbacks( "moduleDone", QUnit, {
+ name: config.previousModule,
+ failed: config.moduleStats.bad,
+ passed: config.moduleStats.all - config.moduleStats.bad,
+ total: config.moduleStats.all
+ });
+ }
+ delete config.previousModule;
+
+ var i, key,
+ banner = id( "qunit-banner" ),
+ tests = id( "qunit-tests" ),
+ runtime = +new Date() - config.started,
+ passed = config.stats.all - config.stats.bad,
+ html = [
+ "Tests completed in ",
+ runtime,
+ " milliseconds.
",
+ "",
+ passed,
+ " assertions of ",
+ config.stats.all,
+ " passed, ",
+ config.stats.bad,
+ " failed."
+ ].join( "" );
+
+ if ( banner ) {
+ banner.className = ( config.stats.bad ? "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 = [
+ ( config.stats.bad ? "\u2716" : "\u2714" ),
+ document.title.replace( /^[\u2714\u2716] /i, "" )
+ ].join( " " );
+ }
+
+ // clear own sessionStorage items if all tests passed
+ if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) {
+ // `key` & `i` initialized at top of scope
+ 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);
+ }
+
+ runLoggingCallbacks( "done", QUnit, {
+ failed: config.stats.bad,
+ passed: passed,
+ total: config.stats.all,
+ runtime: runtime
+ });
+}
+
+/** @return Boolean: true if this test should be ran */
+function validTest( test ) {
+ var include,
+ filter = config.filter && config.filter.toLowerCase(),
+ module = config.module && config.module.toLowerCase(),
+ fullName = ( test.module + ": " + test.testName ).toLowerCase();
+
+ // Internally-generated tests are always valid
+ if ( test.callback && test.callback.validTest === validTest ) {
+ delete test.callback.validTest;
+ return true;
+ }
+
+ if ( config.testNumber.length > 0 ) {
+ if ( inArray( test.testNumber, config.testNumber ) < 0 ) {
+ return false;
+ }
+ }
+
+ if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) {
+ return false;
+ }
+
+ if ( !filter ) {
+ return true;
+ }
+
+ include = filter.charAt( 0 ) !== "!";
+ if ( !include ) {
+ filter = filter.slice( 1 );
+ }
+
+ // If the filter matches, we need to honour include
+ if ( fullName.indexOf( filter ) !== -1 ) {
+ return include;
+ }
+
+ // Otherwise, do the opposite
+ return !include;
+}
+
+// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions)
+// Later Safari and IE10 are supposed to support error.stack as well
+// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
+function extractStacktrace( e, offset ) {
+ offset = offset === undefined ? 3 : offset;
+
+ var stack, include, i;
+
+ if ( e.stacktrace ) {
+ // Opera
+ return e.stacktrace.split( "\n" )[ offset + 3 ];
+ } else if ( e.stack ) {
+ // Firefox, Chrome
+ stack = e.stack.split( "\n" );
+ if (/^error$/i.test( stack[0] ) ) {
+ stack.shift();
+ }
+ if ( fileName ) {
+ include = [];
+ for ( i = offset; i < stack.length; i++ ) {
+ if ( stack[ i ].indexOf( fileName ) !== -1 ) {
+ break;
+ }
+ include.push( stack[ i ] );
+ }
+ if ( include.length ) {
+ return include.join( "\n" );
+ }
+ }
+ return stack[ offset ];
+ } else if ( e.sourceURL ) {
+ // Safari, PhantomJS
+ // hopefully one day Safari provides actual stacktraces
+ // exclude useless self-reference for generated Error objects
+ if ( /qunit.js$/.test( e.sourceURL ) ) {
+ return;
+ }
+ // for actual exceptions, this is useful
+ return e.sourceURL + ":" + e.line;
+ }
+}
+function sourceFromStacktrace( offset ) {
+ try {
+ throw new Error();
+ } catch ( e ) {
+ return extractStacktrace( e, offset );
+ }
+}
+
+/**
+ * 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 "'";
+ case "\"":
+ return """;
+ case "<":
+ return "<";
+ case ">":
+ return ">";
+ case "&":
+ return "&";
+ }
+ });
+}
+
+function synchronize( callback, last ) {
+ config.queue.push( callback );
+
+ if ( config.autorun && !config.blocking ) {
+ process( last );
+ }
+}
+
+function process( last ) {
+ function next() {
+ process( last );
+ }
+ var start = new Date().getTime();
+ config.depth = config.depth ? config.depth + 1 : 1;
+
+ while ( config.queue.length && !config.blocking ) {
+ if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {
+ config.queue.shift()();
+ } else {
+ setTimeout( next, 13 );
+ break;
+ }
+ }
+ config.depth--;
+ if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
+ done();
+ }
+}
+
+function saveGlobal() {
+ config.pollution = [];
+
+ if ( config.noglobals ) {
+ for ( var key in window ) {
+ if ( hasOwn.call( window, key ) ) {
+ // in Opera sometimes DOM element ids show up here, ignore them
+ if ( /^qunit-test-output/.test( key ) ) {
+ continue;
+ }
+ config.pollution.push( key );
+ }
+ }
+ }
+}
+
+function checkPollution() {
+ var newGlobals,
+ deletedGlobals,
+ old = config.pollution;
+
+ saveGlobal();
+
+ newGlobals = diff( config.pollution, old );
+ if ( newGlobals.length > 0 ) {
+ QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") );
+ }
+
+ deletedGlobals = diff( old, config.pollution );
+ if ( deletedGlobals.length > 0 ) {
+ QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") );
+ }
+}
+
+// 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();
+
+ for ( i = 0; i < result.length; i++ ) {
+ for ( j = 0; j < b.length; j++ ) {
+ if ( result[i] === b[j] ) {
+ result.splice( i, 1 );
+ i--;
+ break;
+ }
+ }
+ }
+ return result;
+}
+
+function extend( a, b ) {
+ for ( var prop in b ) {
+ if ( hasOwn.call( b, prop ) ) {
+ // Avoid "Member not found" error in IE8 caused by messing with window.constructor
+ if ( !( prop === "constructor" && a === window ) ) {
+ if ( b[ prop ] === undefined ) {
+ delete a[ prop ];
+ } else {
+ a[ prop ] = b[ prop ];
+ }
+ }
+ }
+ }
+
+ return a;
+}
+
+/**
+ * @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, fn );
+ } else {
+
+ // Caller must ensure support for event listeners is present
+ throw new Error( "addEvent() was called in a context without event listener support" );
+ }
+}
+
+/**
+ * @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 + " ") > -1;
+}
+
+function addClass( elem, name ) {
+ if ( !hasClass( elem, name ) ) {
+ elem.className += (elem.className ? " " : "") + name;
+ }
+}
+
+function removeClass( elem, name ) {
+ var set = " " + elem.className + " ";
+ // Class name may appear multiple times
+ while ( set.indexOf(" " + name + " ") > -1 ) {
+ set = set.replace(" " + name + " " , " ");
+ }
+ // If possible, trim it for prettiness, but not necessarily
+ 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 registerLoggingCallback( key ) {
+ return function( callback ) {
+ config[key].push( callback );
+ };
+}
+
+// Supports deprecated method of completely overwriting logging callbacks
+function runLoggingCallbacks( key, scope, args ) {
+ var i, callbacks;
+ if ( QUnit.hasOwnProperty( key ) ) {
+ QUnit[ key ].call(scope, args );
+ } else {
+ callbacks = config[ key ];
+ for ( i = 0; i < callbacks.length; i++ ) {
+ callbacks[ i ].call( scope, args );
+ }
+ }
+}
+
+// from jquery.js
+function inArray( elem, array ) {
+ if ( array.indexOf ) {
+ return array.indexOf( elem );
+ }
+
+ for ( var i = 0, length = array.length; i < length; i++ ) {
+ if ( array[ i ] === elem ) {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
function Test( settings ) {
extend( this, settings );
this.assertions = [];
@@ -337,6 +1437,8 @@ Test.prototype = {
failed: bad,
passed: this.assertions.length - bad,
total: this.assertions.length,
+ runtime: this.runtime,
+ // DEPRECATED: this property will be removed in 2.0.0, use runtime instead
duration: this.runtime
});
@@ -381,132 +1483,12 @@ Test.prototype = {
}
};
-// Root QUnit object.
-// `QUnit` initialized at top of scope
-QUnit = {
-
- // call on start of module test to prepend name to all tests
- module: function( name, testEnvironment ) {
- config.currentModule = name;
- config.currentModuleTestEnvironment = testEnvironment;
- config.modules[name] = true;
- },
-
- asyncTest: function( testName, expected, callback ) {
- if ( arguments.length === 2 ) {
- callback = expected;
- expected = null;
- }
-
- QUnit.test( testName, expected, callback, true );
- },
-
- test: function( testName, expected, callback, async ) {
- var test,
- nameHtml = "" + escapeText( testName ) + "";
-
- if ( arguments.length === 2 ) {
- callback = expected;
- expected = null;
- }
-
- if ( config.currentModule ) {
- nameHtml = "" + escapeText( config.currentModule ) + ": " + nameHtml;
- }
-
- test = new Test({
- nameHtml: nameHtml,
- testName: testName,
- expected: expected,
- async: async,
- callback: callback,
- module: config.currentModule,
- moduleTestEnvironment: config.currentModuleTestEnvironment,
- stack: sourceFromStacktrace( 2 )
- });
-
- if ( !validTest( test ) ) {
- return;
- }
-
- test.queue();
- },
-
- // Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through.
- expect: function( asserts ) {
- if (arguments.length === 1) {
- config.current.expected = asserts;
- } else {
- return config.current.expected;
- }
- },
-
- start: function( count ) {
- // QUnit hasn't been initialized yet.
- // Note: RequireJS (et al) may delay onLoad
- if ( config.semaphore === undefined ) {
- QUnit.begin(function() {
- // This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first
- setTimeout(function() {
- QUnit.start( count );
- });
- });
- return;
- }
-
- config.semaphore -= count || 1;
- // don't start until equal number of stop-calls
- if ( config.semaphore > 0 ) {
- return;
- }
- // ignore if start is called more often then stop
- if ( config.semaphore < 0 ) {
- config.semaphore = 0;
- QUnit.pushFailure( "Called start() while already started (QUnit.config.semaphore was 0 already)", null, sourceFromStacktrace(2) );
- return;
- }
- // A slight delay, to avoid any current callbacks
- if ( defined.setTimeout ) {
- setTimeout(function() {
- if ( config.semaphore > 0 ) {
- return;
- }
- if ( config.timeout ) {
- clearTimeout( config.timeout );
- }
-
- config.blocking = false;
- process( true );
- }, 13);
- } else {
- config.blocking = false;
- process( true );
- }
- },
-
- stop: function( count ) {
- config.semaphore += count || 1;
- config.blocking = true;
-
- if ( config.testTimeout && defined.setTimeout ) {
- clearTimeout( config.timeout );
- config.timeout = setTimeout(function() {
- QUnit.ok( false, "Test timed out" );
- config.semaphore = 1;
- QUnit.start();
- }, config.testTimeout );
- }
- }
-};
-
// `assert` initialized at top of scope
// Assert helpers
// All of these must either call QUnit.push() or manually do:
// - runLoggingCallbacks( "log", .. );
// - config.current.assertions.push({ .. });
-// We attach it to the QUnit object *after* we expose the public API,
-// otherwise `assert` will become a global variable in browsers (#341).
-assert = {
+assert = QUnit.assert = {
/**
* Asserts rough true-ish result.
* @name ok
@@ -518,7 +1500,7 @@ assert = {
throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) );
}
result = !!result;
- msg = msg || (result ? "okay" : "failed" );
+ msg = msg || ( result ? "okay" : "failed" );
var source,
details = {
@@ -534,7 +1516,9 @@ assert = {
source = sourceFromStacktrace( 2 );
if ( source ) {
details.source = source;
- msg += "Source: | " + escapeText( source ) + " |
---|
";
+ msg += "Source: | " +
+ escapeText( source ) +
+ " |
---|
";
}
}
runLoggingCallbacks( "log", QUnit, details );
@@ -623,7 +1607,7 @@ assert = {
ok = false;
// 'expected' is optional
- if ( typeof expected === "string" ) {
+ if ( !message && typeof expected === "string" ) {
message = expected;
expected = null;
}
@@ -637,16 +1621,30 @@ assert = {
config.current.ignoreGlobalErrors = false;
if ( actual ) {
+
// we don't want to validate thrown error
if ( !expected ) {
ok = true;
expectedOutput = null;
+
+ // expected is an Error object
+ } else if ( expected instanceof Error ) {
+ ok = actual instanceof Error &&
+ actual.name === expected.name &&
+ actual.message === expected.message;
+
// expected is a regexp
} else if ( QUnit.objectType( expected ) === "regexp" ) {
ok = expected.test( errorString( actual ) );
+
+ // expected is a string
+ } else if ( QUnit.objectType( expected ) === "string" ) {
+ ok = expected === errorString( actual );
+
// expected is a constructor
} else if ( actual instanceof expected ) {
ok = true;
+
// expected is a validation function which returns true is validation passed
} else if ( expected.call( {}, actual ) === true ) {
expectedOutput = null;
@@ -664,943 +1662,27 @@ assert = {
* @deprecated since 1.8.0
* Kept assertion helpers in root for backwards compatibility.
*/
-extend( QUnit, assert );
+extend( QUnit.constructor.prototype, assert );
/**
* @deprecated since 1.9.0
- * Kept root "raises()" for backwards compatibility.
- * (Note that we don't introduce assert.raises).
+ * Kept to avoid TypeErrors for undefined methods.
*/
-QUnit.raises = assert[ "throws" ];
+QUnit.constructor.prototype.raises = function() {
+ QUnit.push( false, false, false, "QUnit.raises has been deprecated since 2012 (fad3c1ea), use QUnit.throws instead" );
+};
/**
* @deprecated since 1.0.0, replaced with error pushes since 1.3.0
* Kept to avoid TypeErrors for undefined methods.
*/
-QUnit.equals = function() {
+QUnit.constructor.prototype.equals = function() {
QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" );
};
-QUnit.same = function() {
+QUnit.constructor.prototype.same = function() {
QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" );
};
-// We want access to the constructor's prototype
-(function() {
- function F() {}
- F.prototype = QUnit;
- QUnit = new F();
- // Make F QUnit's constructor so that we can add to the prototype later
- QUnit.constructor = F;
-}());
-
-/**
- * Config object: Maintain internal state
- * Later exposed as QUnit.config
- * `config` initialized at top of scope
- */
-config = {
- // The queue of tests to run
- queue: [],
-
- // block until document ready
- blocking: true,
-
- // when enabled, show only failing tests
- // gets persisted through sessionStorage and can be changed in UI via checkbox
- hidepassed: false,
-
- // 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
- altertitle: true,
-
- // 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: "noglobals",
- label: "Check for Globals",
- tooltip: "Enabling this will test if any test introduces new properties on the `window` object. 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."
- }
- ],
-
- // Set of all modules.
- modules: {},
-
- // logging callback queues
- begin: [],
- done: [],
- log: [],
- testStart: [],
- testDone: [],
- moduleStart: [],
- moduleDone: []
-};
-
-// Export global variables, unless an 'exports' object exists,
-// in that case we assume we're in CommonJS (dealt with on the bottom of the script)
-if ( typeof exports === "undefined" ) {
- extend( window, QUnit.constructor.prototype );
-
- // Expose QUnit object
- window.QUnit = QUnit;
-}
-
-// Initialize more QUnit.config and QUnit.urlParams
-(function() {
- var i,
- location = window.location || { search: "", protocol: "file:" },
- params = location.search.slice( 1 ).split( "&" ),
- length = params.length,
- urlParams = {},
- current;
-
- 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;
- urlParams[ current[ 0 ] ] = current[ 1 ];
- }
- }
-
- QUnit.urlParams = urlParams;
-
- // String search anywhere in moduleName+testName
- config.filter = urlParams.filter;
-
- // Exact match of the module name
- config.module = urlParams.module;
-
- config.testNumber = parseInt( urlParams.testNumber, 10 ) || null;
-
- // Figure out if we're running the tests from a server or not
- QUnit.isLocal = location.protocol === "file:";
-}());
-
-// Extend QUnit object,
-// these after set here because they should not be exposed as global functions
-extend( QUnit, {
- assert: assert,
-
- config: config,
-
- // Initialize the configuration options
- init: function() {
- extend( config, {
- stats: { all: 0, bad: 0 },
- moduleStats: { all: 0, bad: 0 },
- started: +new Date(),
- updateRate: 1000,
- blocking: false,
- autostart: true,
- autorun: false,
- filter: "",
- queue: [],
- semaphore: 1
- });
-
- var tests, banner, result,
- qunit = id( "qunit" );
-
- if ( qunit ) {
- qunit.innerHTML =
- "" +
- "" +
- "" +
- "" +
- "
";
- }
-
- 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...
";
- }
- },
-
- // Resets the test setup. Useful for tests that modify the DOM.
- /*
- DEPRECATED: Use multiple tests instead of resetting inside a test.
- Use testStart or testDone for custom cleanup.
- This method will throw an error in 2.0, and will be removed in 2.1
- */
- reset: function() {
- var fixture = id( "qunit-fixture" );
- if ( fixture ) {
- fixture.innerHTML = config.fixture;
- }
- },
-
- // Trigger an event on an element.
- // @example triggerEvent( document.body, "click" );
- triggerEvent: function( elem, type, event ) {
- if ( document.createEvent ) {
- event = document.createEvent( "MouseEvents" );
- event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
- 0, 0, 0, 0, 0, false, false, false, false, 0, null);
-
- elem.dispatchEvent( event );
- } else if ( elem.fireEvent ) {
- elem.fireEvent( "on" + type );
- }
- },
-
- // Safe object type checking
- is: function( type, obj ) {
- return QUnit.objectType( obj ) === type;
- },
-
- objectType: function( obj ) {
- if ( typeof obj === "undefined" ) {
- return "undefined";
- // consider: typeof null === object
- }
- if ( obj === null ) {
- return "null";
- }
-
- var match = toString.call( obj ).match(/^\[object\s(.*)\]$/),
- type = match && match[1] || "";
-
- switch ( type ) {
- case "Number":
- if ( isNaN(obj) ) {
- return "nan";
- }
- return "number";
- case "String":
- case "Boolean":
- case "Array":
- case "Date":
- case "RegExp":
- case "Function":
- return type.toLowerCase();
- }
- if ( typeof obj === "object" ) {
- return "object";
- }
- return undefined;
- },
-
- push: function( result, actual, expected, message ) {
- if ( !config.current ) {
- throw new Error( "assertion outside test context, was " + sourceFromStacktrace() );
- }
-
- var output, source,
- details = {
- module: config.current.module,
- name: config.current.testName,
- result: result,
- message: message,
- actual: actual,
- expected: expected
- };
-
- message = escapeText( message ) || ( result ? "okay" : "failed" );
- message = "" + message + "";
- output = message;
-
- if ( !result ) {
- expected = escapeText( QUnit.jsDump.parse(expected) );
- actual = escapeText( QUnit.jsDump.parse(actual) );
- output += "Expected: | " + expected + " |
";
-
- if ( actual !== expected ) {
- output += "Result: | " + actual + " |
";
- output += "Diff: | " + QUnit.diff( expected, actual ) + " |
";
- }
-
- source = sourceFromStacktrace();
-
- if ( source ) {
- details.source = source;
- output += "Source: | " + escapeText( source ) + " |
";
- }
-
- output += "
";
- }
-
- runLoggingCallbacks( "log", QUnit, details );
-
- config.current.assertions.push({
- result: !!result,
- message: output
- });
- },
-
- pushFailure: function( message, source, actual ) {
- if ( !config.current ) {
- throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) );
- }
-
- var output,
- details = {
- module: config.current.module,
- name: config.current.testName,
- result: false,
- message: message
- };
-
- message = escapeText( message ) || "error";
- message = "" + message + "";
- output = message;
-
- output += "";
-
- if ( actual ) {
- output += "Result: | " + escapeText( actual ) + " |
";
- }
-
- if ( source ) {
- details.source = source;
- output += "Source: | " + escapeText( source ) + " |
";
- }
-
- output += "
";
-
- runLoggingCallbacks( "log", QUnit, details );
-
- config.current.assertions.push({
- result: false,
- message: output
- });
- },
-
- url: function( params ) {
- params = extend( extend( {}, QUnit.urlParams ), params );
- var key,
- querystring = "?";
-
- for ( key in params ) {
- if ( hasOwn.call( params, key ) ) {
- querystring += encodeURIComponent( key ) + "=" +
- encodeURIComponent( params[ key ] ) + "&";
- }
- }
- return window.location.protocol + "//" + window.location.host +
- window.location.pathname + querystring.slice( 0, -1 );
- },
-
- extend: extend,
- id: id,
- addEvent: addEvent,
- addClass: addClass,
- hasClass: hasClass,
- removeClass: removeClass
- // load, equiv, jsDump, diff: Attached later
-});
-
-/**
- * @deprecated: Created for backwards compatibility with test runner that set the hook function
- * into QUnit.{hook}, instead of invoking it and passing the hook function.
- * QUnit.constructor is set to the empty F() above so that we can add to it's prototype here.
- * Doing this allows us to tell if the following methods have been overwritten on the actual
- * QUnit object.
- */
-extend( QUnit.constructor.prototype, {
-
- // Logging callbacks; all receive a single argument with the listed properties
- // run test/logs.html for any related changes
- begin: registerLoggingCallback( "begin" ),
-
- // done: { failed, passed, total, runtime }
- done: registerLoggingCallback( "done" ),
-
- // log: { result, actual, expected, message }
- log: registerLoggingCallback( "log" ),
-
- // testStart: { name }
- testStart: registerLoggingCallback( "testStart" ),
-
- // testDone: { name, failed, passed, total, duration }
- testDone: registerLoggingCallback( "testDone" ),
-
- // moduleStart: { name }
- moduleStart: registerLoggingCallback( "moduleStart" ),
-
- // moduleDone: { name, failed, passed, total }
- moduleDone: registerLoggingCallback( "moduleDone" )
-});
-
-if ( typeof document === "undefined" || document.readyState === "complete" ) {
- config.autorun = true;
-}
-
-QUnit.load = function() {
- runLoggingCallbacks( "begin", QUnit, {} );
-
- // Initialize the config, saving the execution queue
- var banner, filter, i, label, len, main, ol, toolbar, userAgent, val,
- urlConfigCheckboxesContainer, urlConfigCheckboxes, moduleFilter,
- numModules = 0,
- moduleNames = [],
- moduleFilterHtml = "",
- urlConfigHtml = "",
- oldconfig = extend( {}, config );
-
- QUnit.init();
- extend(config, oldconfig);
-
- config.blocking = false;
-
- len = config.urlConfig.length;
-
- for ( i = 0; i < len; i++ ) {
- val = config.urlConfig[i];
- if ( typeof val === "string" ) {
- val = {
- id: val,
- label: val,
- tooltip: "[no tooltip available]"
- };
- }
- config[ val.id ] = QUnit.urlParams[ val.id ];
- urlConfigHtml += "";
- }
- for ( i in config.modules ) {
- if ( config.modules.hasOwnProperty( i ) ) {
- moduleNames.push(i);
- }
- }
- numModules = moduleNames.length;
- moduleNames.sort( function( a, b ) {
- return a.localeCompare( b );
- });
- moduleFilterHtml += "";
-
- // `userAgent` initialized at top of scope
- userAgent = id( "qunit-userAgent" );
- if ( userAgent ) {
- userAgent.innerHTML = navigator.userAgent;
- }
-
- // `banner` initialized at top of scope
- banner = id( "qunit-header" );
- if ( banner ) {
- banner.innerHTML = "" + banner.innerHTML + " ";
- }
-
- // `toolbar` initialized at top of scope
- toolbar = id( "qunit-testrunner-toolbar" );
- if ( toolbar ) {
- // `filter` initialized at top of scope
- filter = document.createElement( "input" );
- filter.type = "checkbox";
- filter.id = "qunit-filter-pass";
-
- addEvent( filter, "click", function() {
- var tmp,
- ol = document.getElementById( "qunit-tests" );
-
- if ( filter.checked ) {
- ol.className = ol.className + " hidepass";
- } else {
- tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " ";
- ol.className = tmp.replace( / hidepass /, " " );
- }
- if ( defined.sessionStorage ) {
- if (filter.checked) {
- sessionStorage.setItem( "qunit-filter-passed-tests", "true" );
- } else {
- sessionStorage.removeItem( "qunit-filter-passed-tests" );
- }
- }
- });
-
- if ( config.hidepassed || defined.sessionStorage && sessionStorage.getItem( "qunit-filter-passed-tests" ) ) {
- filter.checked = true;
- // `ol` initialized at top of scope
- ol = document.getElementById( "qunit-tests" );
- ol.className = ol.className + " hidepass";
- }
- toolbar.appendChild( filter );
-
- // `label` initialized at top of scope
- label = document.createElement( "label" );
- label.setAttribute( "for", "qunit-filter-pass" );
- label.setAttribute( "title", "Only show tests and assertions that fail. Stored in sessionStorage." );
- label.innerHTML = "Hide passed tests";
- toolbar.appendChild( label );
-
- urlConfigCheckboxesContainer = document.createElement("span");
- urlConfigCheckboxesContainer.innerHTML = urlConfigHtml;
- urlConfigCheckboxes = urlConfigCheckboxesContainer.getElementsByTagName("input");
- // For oldIE support:
- // * Add handlers to the individual elements instead of the container
- // * Use "click" instead of "change"
- // * Fallback from event.target to event.srcElement
- addEvents( urlConfigCheckboxes, "click", function( event ) {
- var params = {},
- target = event.target || event.srcElement;
- params[ target.name ] = target.checked ? true : undefined;
- window.location = QUnit.url( params );
- });
- toolbar.appendChild( urlConfigCheckboxesContainer );
-
- if (numModules > 1) {
- moduleFilter = document.createElement( "span" );
- moduleFilter.setAttribute( "id", "qunit-modulefilter-container" );
- moduleFilter.innerHTML = moduleFilterHtml;
- addEvent( moduleFilter.lastChild, "change", function() {
- var selectBox = moduleFilter.getElementsByTagName("select")[0],
- selectedModule = decodeURIComponent(selectBox.options[selectBox.selectedIndex].value);
-
- window.location = QUnit.url({
- module: ( selectedModule === "" ) ? undefined : selectedModule,
- // Remove any existing filters
- filter: undefined,
- testNumber: undefined
- });
- });
- toolbar.appendChild(moduleFilter);
- }
- }
-
- // `main` initialized at top of scope
- main = id( "qunit-fixture" );
- if ( main ) {
- config.fixture = main.innerHTML;
- }
-
- if ( config.autostart ) {
- QUnit.start();
- }
-};
-
-addEvent( window, "load", QUnit.load );
-
-// `onErrorFnPrev` initialized at top of scope
-// Preserve other handlers
-onErrorFnPrev = window.onerror;
-
-// Cover uncaught exceptions
-// Returning true will suppress the default browser handler,
-// returning false will let it run.
-window.onerror = function ( error, filePath, linerNr ) {
- var ret = false;
- if ( onErrorFnPrev ) {
- ret = onErrorFnPrev( error, filePath, linerNr );
- }
-
- // Treat return value as window.onerror itself does,
- // Only do our handling if not suppressed.
- if ( ret !== true ) {
- if ( QUnit.config.current ) {
- if ( QUnit.config.current.ignoreGlobalErrors ) {
- return true;
- }
- QUnit.pushFailure( error, filePath + ":" + linerNr );
- } else {
- QUnit.test( "global failure", extend( function() {
- QUnit.pushFailure( error, filePath + ":" + linerNr );
- }, { validTest: validTest } ) );
- }
- return false;
- }
-
- return ret;
-};
-
-function done() {
- config.autorun = true;
-
- // Log the last module results
- if ( config.currentModule ) {
- runLoggingCallbacks( "moduleDone", QUnit, {
- name: config.currentModule,
- failed: config.moduleStats.bad,
- passed: config.moduleStats.all - config.moduleStats.bad,
- total: config.moduleStats.all
- });
- }
- delete config.previousModule;
-
- var i, key,
- banner = id( "qunit-banner" ),
- tests = id( "qunit-tests" ),
- runtime = +new Date() - config.started,
- passed = config.stats.all - config.stats.bad,
- html = [
- "Tests completed in ",
- runtime,
- " milliseconds.
",
- "",
- passed,
- " assertions of ",
- config.stats.all,
- " passed, ",
- config.stats.bad,
- " failed."
- ].join( "" );
-
- if ( banner ) {
- banner.className = ( config.stats.bad ? "qunit-fail" : "qunit-pass" );
- }
-
- if ( tests ) {
- id( "qunit-testresult" ).innerHTML = html;
- }
-
- if ( config.altertitle && typeof document !== "undefined" && 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 = [
- ( config.stats.bad ? "\u2716" : "\u2714" ),
- document.title.replace( /^[\u2714\u2716] /i, "" )
- ].join( " " );
- }
-
- // clear own sessionStorage items if all tests passed
- if ( config.reorder && defined.sessionStorage && config.stats.bad === 0 ) {
- // `key` & `i` initialized at top of scope
- 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 ( window.scrollTo ) {
- window.scrollTo(0, 0);
- }
-
- runLoggingCallbacks( "done", QUnit, {
- failed: config.stats.bad,
- passed: passed,
- total: config.stats.all,
- runtime: runtime
- });
-}
-
-/** @return Boolean: true if this test should be ran */
-function validTest( test ) {
- var include,
- filter = config.filter && config.filter.toLowerCase(),
- module = config.module && config.module.toLowerCase(),
- fullName = (test.module + ": " + test.testName).toLowerCase();
-
- // Internally-generated tests are always valid
- if ( test.callback && test.callback.validTest === validTest ) {
- delete test.callback.validTest;
- return true;
- }
-
- if ( config.testNumber ) {
- return test.testNumber === config.testNumber;
- }
-
- if ( module && ( !test.module || test.module.toLowerCase() !== module ) ) {
- return false;
- }
-
- if ( !filter ) {
- return true;
- }
-
- include = filter.charAt( 0 ) !== "!";
- if ( !include ) {
- filter = filter.slice( 1 );
- }
-
- // If the filter matches, we need to honour include
- if ( fullName.indexOf( filter ) !== -1 ) {
- return include;
- }
-
- // Otherwise, do the opposite
- return !include;
-}
-
-// so far supports only Firefox, Chrome and Opera (buggy), Safari (for real exceptions)
-// Later Safari and IE10 are supposed to support error.stack as well
-// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
-function extractStacktrace( e, offset ) {
- offset = offset === undefined ? 3 : offset;
-
- var stack, include, i;
-
- if ( e.stacktrace ) {
- // Opera
- return e.stacktrace.split( "\n" )[ offset + 3 ];
- } else if ( e.stack ) {
- // Firefox, Chrome
- stack = e.stack.split( "\n" );
- if (/^error$/i.test( stack[0] ) ) {
- stack.shift();
- }
- if ( fileName ) {
- include = [];
- for ( i = offset; i < stack.length; i++ ) {
- if ( stack[ i ].indexOf( fileName ) !== -1 ) {
- break;
- }
- include.push( stack[ i ] );
- }
- if ( include.length ) {
- return include.join( "\n" );
- }
- }
- return stack[ offset ];
- } else if ( e.sourceURL ) {
- // Safari, PhantomJS
- // hopefully one day Safari provides actual stacktraces
- // exclude useless self-reference for generated Error objects
- if ( /qunit.js$/.test( e.sourceURL ) ) {
- return;
- }
- // for actual exceptions, this is useful
- return e.sourceURL + ":" + e.line;
- }
-}
-function sourceFromStacktrace( offset ) {
- try {
- throw new Error();
- } catch ( e ) {
- return extractStacktrace( e, offset );
- }
-}
-
-/**
- * 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 "'";
- case "\"":
- return """;
- case "<":
- return "<";
- case ">":
- return ">";
- case "&":
- return "&";
- }
- });
-}
-
-function synchronize( callback, last ) {
- config.queue.push( callback );
-
- if ( config.autorun && !config.blocking ) {
- process( last );
- }
-}
-
-function process( last ) {
- function next() {
- process( last );
- }
- var start = new Date().getTime();
- config.depth = config.depth ? config.depth + 1 : 1;
-
- while ( config.queue.length && !config.blocking ) {
- if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {
- config.queue.shift()();
- } else {
- setTimeout( next, 13 );
- break;
- }
- }
- config.depth--;
- if ( last && !config.blocking && !config.queue.length && config.depth === 0 ) {
- done();
- }
-}
-
-function saveGlobal() {
- config.pollution = [];
-
- if ( config.noglobals ) {
- for ( var key in window ) {
- if ( hasOwn.call( window, key ) ) {
- // in Opera sometimes DOM element ids show up here, ignore them
- if ( /^qunit-test-output/.test( key ) ) {
- continue;
- }
- config.pollution.push( key );
- }
- }
- }
-}
-
-function checkPollution() {
- var newGlobals,
- deletedGlobals,
- old = config.pollution;
-
- saveGlobal();
-
- newGlobals = diff( config.pollution, old );
- if ( newGlobals.length > 0 ) {
- QUnit.pushFailure( "Introduced global variable(s): " + newGlobals.join(", ") );
- }
-
- deletedGlobals = diff( old, config.pollution );
- if ( deletedGlobals.length > 0 ) {
- QUnit.pushFailure( "Deleted global variable(s): " + deletedGlobals.join(", ") );
- }
-}
-
-// 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();
-
- for ( i = 0; i < result.length; i++ ) {
- for ( j = 0; j < b.length; j++ ) {
- if ( result[i] === b[j] ) {
- result.splice( i, 1 );
- i--;
- break;
- }
- }
- }
- return result;
-}
-
-function extend( a, b ) {
- for ( var prop in b ) {
- if ( hasOwn.call( b, prop ) ) {
- // Avoid "Member not found" error in IE8 caused by messing with window.constructor
- if ( !( prop === "constructor" && a === window ) ) {
- if ( b[ prop ] === undefined ) {
- delete a[ prop ];
- } else {
- a[ prop ] = b[ prop ];
- }
- }
- }
- }
-
- return a;
-}
-
-/**
- * @param {HTMLElement} elem
- * @param {string} type
- * @param {Function} fn
- */
-function addEvent( elem, type, fn ) {
- // Standards-based browsers
- if ( elem.addEventListener ) {
- elem.addEventListener( type, fn, false );
- // IE
- } else {
- elem.attachEvent( "on" + type, fn );
- }
-}
-
-/**
- * @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 + " ") > -1;
-}
-
-function addClass( elem, name ) {
- if ( !hasClass( elem, name ) ) {
- elem.className += (elem.className ? " " : "") + name;
- }
-}
-
-function removeClass( elem, name ) {
- var set = " " + elem.className + " ";
- // Class name may appear multiple times
- while ( set.indexOf(" " + name + " ") > -1 ) {
- set = set.replace(" " + name + " " , " ");
- }
- // If possible, trim it for prettiness, but not necessarily
- elem.className = typeof set.trim === "function" ? set.trim() : set.replace(/^\s+|\s+$/g, "");
-}
-
-function id( name ) {
- return !!( typeof document !== "undefined" && document && document.getElementById ) &&
- document.getElementById( name );
-}
-
-function registerLoggingCallback( key ) {
- return function( callback ) {
- config[key].push( callback );
- };
-}
-
-// Supports deprecated method of completely overwriting logging callbacks
-function runLoggingCallbacks( key, scope, args ) {
- var i, callbacks;
- if ( QUnit.hasOwnProperty( key ) ) {
- QUnit[ key ].call(scope, args );
- } else {
- callbacks = config[ key ];
- for ( i = 0; i < callbacks.length; i++ ) {
- callbacks[ i ].call( scope, args );
- }
- }
-}
-
// Test for equality any JavaScript type.
// Author: Philippe Rathé
QUnit.equiv = (function() {
@@ -2040,21 +2122,6 @@ QUnit.jsDump = (function() {
return jsDump;
}());
-// from jquery.js
-function inArray( elem, array ) {
- if ( array.indexOf ) {
- return array.indexOf( elem );
- }
-
- for ( var i = 0, length = array.length; i < length; i++ ) {
- if ( array[ i ] === elem ) {
- return i;
- }
- }
-
- return -1;
-}
-
/*
* Javascript Diff Algorithm
* By John Resig (http://ejohn.org/)
@@ -2203,10 +2270,19 @@ QUnit.diff = (function() {
};
}());
-// for CommonJS environments, export everything
-if ( typeof exports !== "undefined" ) {
- extend( exports, QUnit.constructor.prototype );
+// For browser, export only select globals
+if ( typeof window !== "undefined" ) {
+ extend( window, QUnit.constructor.prototype );
+ window.QUnit = QUnit;
}
-// get at whatever the global object is, like window in browsers
-}( (function() {return this;}.call()) ));
+// For CommonJS environments, export everything
+if ( typeof module !== "undefined" && module.exports ) {
+ module.exports = QUnit;
+}
+
+
+// Get a reference to the global object, like window in browsers
+}( (function() {
+ return this;
+})() ));
diff --git a/test/unit/core.js b/test/unit/core.js
index fa5ed93b9..d781d261a 100644
--- a/test/unit/core.js
+++ b/test/unit/core.js
@@ -1326,7 +1326,7 @@ test("jQuery.parseHTML", function() {
equal( jQuery.parseHTML(), null, "Nothing in, null out." );
equal( jQuery.parseHTML( null ), null, "Null in, null out." );
equal( jQuery.parseHTML( "" ), null, "Empty string in, null out." );
- raises(function() {
+ throws(function() {
jQuery.parseHTML( "", document.getElementById("form") );
}, "Passing an element as the context raises an exception (context should be a document)");
@@ -1387,34 +1387,34 @@ test("jQuery.parseJSON", function() {
deepEqual( jQuery.parseJSON("\n{\"test\":1}\t"), { "test": 1 },
"Leading and trailing whitespace are ignored" );
- raises(function() {
+ throws(function() {
jQuery.parseJSON();
}, null, "Undefined raises an error" );
- raises( function() {
+ throws(function() {
jQuery.parseJSON( "" );
}, null, "Empty string raises an error" );
- raises(function() {
+ throws(function() {
jQuery.parseJSON("''");
}, null, "Single-quoted string raises an error" );
/*
// Broken on IE8
- raises(function() {
+ throws(function() {
jQuery.parseJSON("\" \\a \"");
}, null, "Invalid string escape raises an error" );
// Broken on IE8, Safari 5.1 Windows
- raises(function() {
+ throws(function() {
jQuery.parseJSON("\"\t\"");
}, null, "Unescaped control character raises an error" );
// Broken on IE8
- raises(function() {
+ throws(function() {
jQuery.parseJSON(".123");
}, null, "Number with no integer component raises an error" );
*/
- raises(function() {
+ throws(function() {
var result = jQuery.parseJSON("0101");
// Support: IE9+
@@ -1423,22 +1423,22 @@ test("jQuery.parseJSON", function() {
throw new Error("close enough");
}
}, null, "Leading-zero number raises an error or is parsed as decimal" );
- raises(function() {
+ throws(function() {
jQuery.parseJSON("{a:1}");
}, null, "Unquoted property raises an error" );
- raises(function() {
+ throws(function() {
jQuery.parseJSON("{'a':1}");
}, null, "Single-quoted property raises an error" );
- raises(function() {
+ throws(function() {
jQuery.parseJSON("[,]");
}, null, "Array element elision raises an error" );
- raises(function() {
+ throws(function() {
jQuery.parseJSON("{},[]");
}, null, "Comma expression raises an error" );
- raises(function() {
+ throws(function() {
jQuery.parseJSON("[]\n,{}");
}, null, "Newline-containing comma expression raises an error" );
- raises(function() {
+ throws(function() {
jQuery.parseJSON("\"\"\n\"\"");
}, null, "Automatic semicolon insertion raises an error" );
diff --git a/test/unit/effects.js b/test/unit/effects.js
index 603041c4a..ba63a3b00 100644
--- a/test/unit/effects.js
+++ b/test/unit/effects.js
@@ -1319,7 +1319,7 @@ test( "callbacks that throw exceptions will be removed (#5684)", function() {
jQuery.fx.stop();
this.clock.tick( 1 );
- raises( jQuery.fx.tick, TestException, "Exception was thrown" );
+ throws( jQuery.fx.tick, TestException, "Exception was thrown" );
// the second call shouldn't
jQuery.fx.tick();
diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js
index f5fbeffa6..7485da459 100644
--- a/test/unit/manipulation.js
+++ b/test/unit/manipulation.js
@@ -2183,7 +2183,7 @@ test( "html() - script exceptions bubble (#11743)", function() {
expect( 3 );
- raises(function() {
+ throws(function() {
jQuery("#qunit-fixture").html("");
ok( false, "Exception ignored" );
}, "Exception bubbled from inline script" );