aboutsummaryrefslogtreecommitdiffstats
path: root/external
diff options
context:
space:
mode:
authorJörn Zaefferer <joern.zaefferer@gmail.com>2012-06-14 00:21:54 +0200
committerJörn Zaefferer <joern.zaefferer@gmail.com>2012-06-14 00:21:54 +0200
commit679f7f31721dc6004aadba10bf82e41dcd84a3ff (patch)
treec9b93598706d78714b38bb025954fe32b86ebb88 /external
parentca5d84258497ca3ca2f087fe32840a7839fc51df (diff)
downloadjquery-ui-679f7f31721dc6004aadba10bf82e41dcd84a3ff.tar.gz
jquery-ui-679f7f31721dc6004aadba10bf82e41dcd84a3ff.zip
Update QUnit to 1.8.0
Diffstat (limited to 'external')
-rw-r--r--external/qunit.css2
-rw-r--r--external/qunit.js342
2 files changed, 224 insertions, 120 deletions
diff --git a/external/qunit.css b/external/qunit.css
index 23235ec84..5684a4485 100644
--- a/external/qunit.css
+++ b/external/qunit.css
@@ -1,5 +1,5 @@
/**
- * QUnit v1.6.0 - A JavaScript Unit Testing Framework
+ * QUnit v1.8.0 - A JavaScript Unit Testing Framework
*
* http://docs.jquery.com/QUnit
*
diff --git a/external/qunit.js b/external/qunit.js
index 2c277fab5..c1570c252 100644
--- a/external/qunit.js
+++ b/external/qunit.js
@@ -1,5 +1,5 @@
/**
- * QUnit v1.6.0 - A JavaScript Unit Testing Framework
+ * QUnit v1.8.0 - A JavaScript Unit Testing Framework
*
* http://docs.jquery.com/QUnit
*
@@ -12,7 +12,9 @@
var QUnit,
config,
+ onErrorFnPrev,
testId = 0,
+ fileName = (sourceFromStacktrace( 0 ) || "" ).replace(/(:\d+)+\)?/, "").replace(/.+\//, ""),
toString = Object.prototype.toString,
hasOwn = Object.prototype.hasOwnProperty,
defined = {
@@ -29,26 +31,31 @@ var QUnit,
}())
};
-function Test( name, testName, expected, async, callback ) {
- this.name = name;
- this.testName = testName;
- this.expected = expected;
- this.async = async;
- this.callback = callback;
+function Test( settings ) {
+ extend( this, settings );
this.assertions = [];
+ this.testNumber = ++Test.count;
}
+Test.count = 0;
+
Test.prototype = {
init: function() {
- var b, li,
+ var a, b, li,
tests = id( "qunit-tests" );
if ( tests ) {
b = document.createElement( "strong" );
- b.innerHTML = "Running " + this.name;
+ b.innerHTML = this.name;
+
+ // `a` initialized at top of scope
+ a = document.createElement( "a" );
+ a.innerHTML = "Rerun";
+ a.href = QUnit.url({ testNumber: this.testNumber });
li = document.createElement( "li" );
li.appendChild( b );
+ li.appendChild( a );
li.className = "running";
li.id = this.id = "qunit-test-output" + testId++;
@@ -119,14 +126,14 @@ Test.prototype = {
}
if ( config.notrycatch ) {
- this.callback.call( this.testEnvironment );
+ this.callback.call( this.testEnvironment, QUnit.assert );
return;
}
try {
- this.callback.call( this.testEnvironment );
+ this.callback.call( this.testEnvironment, QUnit.assert );
} catch( e ) {
- QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + ": " + e.message, extractStacktrace( e, 1 ) );
+ QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + e.message, extractStacktrace( e, 0 ) );
// else next test will carry the responsibility
saveGlobal();
@@ -152,13 +159,16 @@ Test.prototype = {
},
finish: function() {
config.current = this;
- if ( this.expected != null && this.expected != this.assertions.length ) {
+ if ( config.requireExpects && this.expected == null ) {
+ QUnit.pushFailure( "Expected number of assertions to be defined, but expect() was not called.", this.stack );
+ } else if ( this.expected != null && this.expected != this.assertions.length ) {
QUnit.pushFailure( "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run", this.stack );
} else if ( this.expected == null && !this.assertions.length ) {
QUnit.pushFailure( "Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.", this.stack );
}
var assertion, a, b, i, li, ol,
+ test = this,
good = 0,
bad = 0,
tests = id( "qunit-tests" );
@@ -203,11 +213,6 @@ Test.prototype = {
b = document.createElement( "strong" );
b.innerHTML = this.name + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
- // `a` initialized at top of scope
- a = document.createElement( "a" );
- a.innerHTML = "Rerun";
- a.href = QUnit.url({ filter: getText([b]).replace( /\([^)]+\)$/, "" ).replace( /(^\s*|\s*$)/g, "" ) });
-
addEvent(b, "click", function() {
var next = b.nextSibling.nextSibling,
display = next.style.display;
@@ -220,9 +225,7 @@ Test.prototype = {
target = target.parentNode;
}
if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
- window.location = QUnit.url({
- filter: getText([target]).replace( /\([^)]+\)$/, "" ).replace( /(^\s*|\s*$)/g, "" )
- });
+ window.location = QUnit.url({ testNumber: test.testNumber });
}
});
@@ -230,8 +233,9 @@ Test.prototype = {
li = id( this.id );
li.className = bad ? "fail" : "pass";
li.removeChild( li.firstChild );
+ a = li.firstChild;
li.appendChild( b );
- li.appendChild( a );
+ li.appendChild ( a );
li.appendChild( ol );
} else {
@@ -253,6 +257,8 @@ Test.prototype = {
});
QUnit.reset();
+
+ config.current = undefined;
},
queue: function() {
@@ -291,6 +297,7 @@ Test.prototype = {
}
};
+// Root QUnit object.
// `QUnit` initialized at top of scope
QUnit = {
@@ -322,14 +329,21 @@ QUnit = {
name = "<span class='module-name'>" + config.currentModule + "</span>: " + name;
}
- if ( !validTest(config.currentModule + ": " + testName) ) {
+ test = new Test({
+ name: name,
+ testName: testName,
+ expected: expected,
+ async: async,
+ callback: callback,
+ module: config.currentModule,
+ moduleTestEnvironment: config.currentModuleTestEnviroment,
+ stack: sourceFromStacktrace( 2 )
+ });
+
+ if ( !validTest( test ) ) {
return;
}
- test = new Test( name, testName, expected, async, callback );
- test.module = config.currentModule;
- test.moduleTestEnvironment = config.currentModuleTestEnviroment;
- test.stack = sourceFromStacktrace( 2 );
test.queue();
},
@@ -338,8 +352,59 @@ QUnit = {
config.current.expected = asserts;
},
- // Asserts true.
- // @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
+ start: function( count ) {
+ 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;
+ }
+ // A slight delay, to avoid any current callbacks
+ if ( defined.setTimeout ) {
+ window.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 = window.setTimeout(function() {
+ QUnit.ok( false, "Test timed out" );
+ config.semaphore = 1;
+ QUnit.start();
+ }, config.testTimeout );
+ }
+ }
+};
+
+// Asssert helpers
+// All of these must call either QUnit.push() or manually do:
+// - runLoggingCallbacks( "log", .. );
+// - config.current.assertions.push({ .. });
+QUnit.assert = {
+ /**
+ * Asserts rough true-ish result.
+ * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
+ */
ok: function( result, msg ) {
if ( !config.current ) {
throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) );
@@ -369,8 +434,11 @@ QUnit = {
});
},
- // Checks that the first two arguments are equal, with an optional message. Prints out both actual and expected values.
- // @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes." );
+ /**
+ * Assert that the first two arguments are equal, with an optional message.
+ * Prints out both actual and expected values.
+ * @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" );
+ */
equal: function( actual, expected, message ) {
QUnit.push( expected == actual, actual, expected, message );
},
@@ -404,11 +472,13 @@ QUnit = {
expected = null;
}
+ config.current.ignoreGlobalErrors = true;
try {
block.call( config.current.testEnvironment );
} catch (e) {
actual = e;
}
+ config.current.ignoreGlobalErrors = false;
if ( actual ) {
// we don't want to validate thrown error
@@ -426,51 +496,22 @@ QUnit = {
}
}
- QUnit.ok( ok, message );
- },
-
- start: function( count ) {
- 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;
- }
- // A slight delay, to avoid any current callbacks
- if ( defined.setTimeout ) {
- window.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 );
- }
- },
+ QUnit.push( ok, actual, null, message );
+ }
+};
- stop: function( count ) {
- config.semaphore += count || 1;
- config.blocking = true;
+// @deprecated: Kept assertion helpers in root for backwards compatibility
+extend( QUnit, QUnit.assert );
- if ( config.testTimeout && defined.setTimeout ) {
- clearTimeout( config.timeout );
- config.timeout = window.setTimeout(function() {
- QUnit.ok( false, "Test timed out" );
- config.semaphore = 1;
- QUnit.start();
- }, config.testTimeout );
- }
- }
+/**
+ * @deprecated: Kept for backwards compatibility
+ * next step: remove entirely
+ */
+QUnit.equals = function() {
+ QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" );
+};
+QUnit.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
@@ -482,17 +523,11 @@ QUnit = {
QUnit.constructor = F;
}());
-// deprecated; still export them to window to provide clear error messages
-// next step: remove entirely
-QUnit.equals = function() {
- QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" );
-};
-QUnit.same = function() {
- QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" );
-};
-
-// Maintain internal state
-// `config` initialized at top of scope
+/**
+ * Config object: Maintain internal state
+ * Later exposed as QUnit.config
+ * `config` initialized at top of scope
+ */
config = {
// The queue of tests to run
queue: [],
@@ -511,6 +546,9 @@ config = {
// by default, modify document.title when suite is done
altertitle: true,
+ // when enabled, all tests must call expect()
+ requireExpects: false,
+
urlConfig: [ "noglobals", "notrycatch" ],
// logging callback queues
@@ -523,7 +561,7 @@ config = {
moduleDone: []
};
-// Load paramaters
+// Initialize more QUnit.config and QUnit.urlParams
(function() {
var i,
location = window.location || { search: "", protocol: "file:" },
@@ -543,20 +581,30 @@ config = {
}
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:";
}());
-// Expose the API as global variables, unless an 'exports' object exists,
-// in that case we assume we're in CommonJS - export everything at the end
+// 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 );
+
+ // Expose QUnit object
window.QUnit = QUnit;
}
-// define these after exposing globals to keep them in these QUnit namespace only
+// Extend QUnit object,
+// these after set here because they should not be exposed as global functions
extend( QUnit, {
config: config,
@@ -723,6 +771,10 @@ extend( QUnit, {
},
pushFailure: function( message, source ) {
+ if ( !config.current ) {
+ throw new Error( "pushFailure() assertion outside test context, was " + sourceFromStacktrace(2) );
+ }
+
var output,
details = {
result: false,
@@ -764,25 +816,37 @@ extend( QUnit, {
extend: extend,
id: id,
addEvent: addEvent
+ // load, equiv, jsDump, diff: Attached later
});
-// QUnit.constructor is set to the empty F() above so that we can add to it's prototype later
-// Doing this allows us to tell if the following methods have been overwritten on the actual
-// QUnit object, which is a deprecated way of using the callbacks.
+/**
+ * @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 }
testDone: registerLoggingCallback( "testDone" ),
+
// moduleStart: { name }
moduleStart: registerLoggingCallback( "moduleStart" ),
+
// moduleDone: { name, failed, passed, total }
moduleDone: registerLoggingCallback( "moduleDone" )
});
@@ -884,15 +948,36 @@ QUnit.load = function() {
addEvent( window, "load", QUnit.load );
-// addEvent(window, "error" ) gives us a useless event object
-window.onerror = function( message, file, line ) {
- if ( QUnit.config.current ) {
- QUnit.pushFailure( message, file + ":" + line );
- } else {
- QUnit.test( "global failure", function() {
- QUnit.pushFailure( message, file + ":" + line );
- });
+// `onErrorFnPrev` initialized at top of scope
+// Preserve other handlers
+onErrorFnPrev = window.onerror;
+
+// Cover uncaught exceptions
+// Returning true will surpress 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 surpressed.
+ if ( ret !== true ) {
+ if ( QUnit.config.current ) {
+ if ( QUnit.config.current.ignoreGlobalErrors ) {
+ return true;
+ }
+ QUnit.pushFailure( error, filePath + ":" + linerNr );
+ } else {
+ QUnit.test( "global failure", function() {
+ QUnit.pushFailure( error, filePath + ":" + linerNr );
+ });
+ }
+ return false;
+ }
+
+ return ret;
};
function done() {
@@ -962,39 +1047,46 @@ function done() {
});
}
-function validTest( name ) {
- var not,
- filter = config.filter,
- run = false;
+/** @return Boolean: true if this test should be ran */
+function validTest( test ) {
+ var include,
+ filter = config.filter && config.filter.toLowerCase(),
+ module = config.module,
+ fullName = (test.module + ": " + test.testName).toLowerCase();
- if ( !filter ) {
- return true;
+ if ( config.testNumber ) {
+ return test.testNumber === config.testNumber;
}
- not = filter.charAt( 0 ) === "!";
+ if ( module && test.module !== module ) {
+ return false;
+ }
- if ( not ) {
- filter = filter.slice( 1 );
+ if ( !filter ) {
+ return true;
}
- if ( name.indexOf( filter ) !== -1 ) {
- return !not;
+ include = filter.charAt( 0 ) !== "!";
+ if ( !include ) {
+ filter = filter.slice( 1 );
}
- if ( not ) {
- run = true;
+ // If the filter matches, we need to honour include
+ if ( fullName.indexOf( filter ) !== -1 ) {
+ return include;
}
- return run;
+ // 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 || 3;
+ offset = offset === undefined ? 3 : offset;
- var stack;
+ var stack, include, i, regex;
if ( e.stacktrace ) {
// Opera
@@ -1005,6 +1097,18 @@ function extractStacktrace( e, offset ) {
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
@@ -1419,11 +1523,11 @@ QUnit.jsDump = (function() {
type = "null";
} else if ( typeof obj === "undefined" ) {
type = "undefined";
- } else if ( QUnit.is( "RegExp", obj) ) {
+ } else if ( QUnit.is( "regexp", obj) ) {
type = "regexp";
- } else if ( QUnit.is( "Date", obj) ) {
+ } else if ( QUnit.is( "date", obj) ) {
type = "date";
- } else if ( QUnit.is( "Function", obj) ) {
+ } else if ( QUnit.is( "function", obj) ) {
type = "function";
} else if ( typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined" ) {
type = "window";