Update vendors, builds, and docs.

Former-commit-id: 08cad493d719ec3ebaa85e0ff279c49f1e2b3655
This commit is contained in:
John-David Dalton
2013-07-03 23:14:06 -07:00
parent 112cdb4842
commit 63a1c8b63e
25 changed files with 4175 additions and 1522 deletions

21
vendor/qunit/MIT-LICENSE.txt vendored Normal file
View File

@@ -0,0 +1,21 @@
Copyright 2013 jQuery Foundation and other contributors
http://jquery.com/
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@@ -1,62 +0,0 @@
[QUnit](http://qunitjs.com) - A JavaScript Unit Testing framework.
================================
QUnit is a powerful, easy-to-use, JavaScript test suite. It's used by the jQuery
project to test its code and plugins but is capable of testing any generic
JavaScript code (and even capable of testing JavaScript code on the server-side).
QUnit is especially useful for regression testing: Whenever a bug is reported,
write a test that asserts the existence of that particular bug. Then fix it and
commit both. Every time you work on the code again, run the tests. If the bug
comes up again - a regression - you'll spot it immediately and know how to fix
it, because you know what code you just changed.
Having good unit test coverage makes safe refactoring easy and cheap. You can
run the tests after each small refactoring step and always know what change
broke something.
QUnit is similar to other unit testing frameworks like JUnit, but makes use of
the features JavaScript provides and helps with testing code in the browser, e.g.
with its stop/start facilities for testing asynchronous code.
If you are interested in helping developing QUnit, you are in the right place.
For related discussions, visit the
[QUnit and Testing forum](http://forum.jquery.com/qunit-and-testing).
Development
-----------
To submit patches, fork the repository, create a branch for the change. Then implement
the change, run `grunt` to lint and test it, then commit, push and create a pull request.
Include some background for the change in the commit message and `Fixes #nnn`, referring
to the issue number you're addressing.
To run `grunt`, you need `node` and `npm`, then `npm install grunt -g`. That gives you a global
grunt binary. For additional grunt tasks, also run `npm install`.
Releases
--------
Install git-extras and run `git changelog` to update History.md.
Update qunit/qunit.js|css and package.json to the release version, commit and
tag, update them again to the next version, commit and push commits and tags
(`git push --tags origin master`).
Put the 'v' in front of the tag, e.g. `v1.8.0`. Clean up the changelog, removing merge commits
or whitespace cleanups.
To upload to code.jquery.com (replace $version accordingly), ssh to code.origin.jquery.com:
cp qunit/qunit.js /var/www/html/code.jquery.com/qunit/qunit-$version.js
cp qunit/qunit.css /var/www/html/code.jquery.com/qunit/qunit-$version.css
Then update /var/www/html/code.jquery.com/index.html and purge it with:
curl -s http://code.origin.jquery.com/?reload
Update web-base-template to link to those files for qunitjs.com.
Publish to npm via
npm publish

View File

@@ -1,5 +1,5 @@
/**
* QUnit v1.11.0 - A JavaScript Unit Testing Framework
* QUnit v1.12.0 - A JavaScript Unit Testing Framework
*
* http://qunitjs.com
*

View File

@@ -1,11 +1,11 @@
/**
* QUnit v1.11.0 - A JavaScript Unit Testing Framework
* QUnit v1.12.0 - A JavaScript Unit Testing Framework
*
* http://qunitjs.com
*
* Copyright 2012 jQuery Foundation and other contributors
* Copyright 2013 jQuery Foundation and other contributors
* Released under the MIT license.
* http://jquery.org/license
* https://jquery.org/license/
*/
(function( window ) {
@@ -20,6 +20,7 @@ var QUnit,
hasOwn = Object.prototype.hasOwnProperty,
// Keep a local reference to Date (GH-283)
Date = window.Date,
setTimeout = window.setTimeout,
defined = {
setTimeout: typeof window.setTimeout !== "undefined",
sessionStorage: (function() {
@@ -115,8 +116,16 @@ Test.prototype = {
}
},
setup: function() {
if ( this.module !== config.previousModule ) {
if ( config.previousModule ) {
if (
// Emit moduleStart when we're switching from one module to another
this.module !== config.previousModule ||
// They could be equal (both undefined) but if the previousModule property doesn't
// yet exist it means this is the first test in a suite that isn't wrapped in a
// module, in which case we'll just emit a moduleStart event for 'undefined'.
// Without this, reporters can get testStart before moduleStart which is a problem.
!hasOwn.call( config, "previousModule" )
) {
if ( hasOwn.call( config, "previousModule" ) ) {
runLoggingCallbacks( "moduleDone", QUnit, {
name: config.previousModule,
failed: config.moduleStats.bad,
@@ -129,10 +138,6 @@ Test.prototype = {
runLoggingCallbacks( "moduleStart", QUnit, {
name: this.module
});
} else if ( config.autorun ) {
runLoggingCallbacks( "moduleStart", QUnit, {
name: this.module
});
}
config.current = this;
@@ -148,19 +153,27 @@ Test.prototype = {
module: this.module
});
// allow utility functions to access the current test environment
// TODO why??
/*jshint camelcase:false */
/**
* Expose the current test environment.
*
* @deprecated since 1.12.0: Use QUnit.config.current.testEnvironment instead.
*/
QUnit.current_testEnvironment = this.testEnvironment;
/*jshint camelcase:true */
if ( !config.pollution ) {
saveGlobal();
}
if ( config.notrycatch ) {
this.testEnvironment.setup.call( this.testEnvironment );
this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert );
return;
}
try {
this.testEnvironment.setup.call( this.testEnvironment );
this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert );
} catch( e ) {
QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
}
@@ -208,11 +221,11 @@ Test.prototype = {
if ( typeof this.callbackRuntime === "undefined" ) {
this.callbackRuntime = +new Date() - this.callbackStarted;
}
this.testEnvironment.teardown.call( this.testEnvironment );
this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert );
return;
} else {
try {
this.testEnvironment.teardown.call( this.testEnvironment );
this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert );
} catch( e ) {
QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) );
}
@@ -419,7 +432,7 @@ QUnit = {
test.queue();
},
// Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
// 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;
@@ -454,7 +467,7 @@ QUnit = {
}
// A slight delay, to avoid any current callbacks
if ( defined.setTimeout ) {
window.setTimeout(function() {
setTimeout(function() {
if ( config.semaphore > 0 ) {
return;
}
@@ -477,7 +490,7 @@ QUnit = {
if ( config.testTimeout && defined.setTimeout ) {
clearTimeout( config.timeout );
config.timeout = window.setTimeout(function() {
config.timeout = setTimeout(function() {
QUnit.ok( false, "Test timed out" );
config.semaphore = 1;
QUnit.start();
@@ -487,7 +500,7 @@ QUnit = {
};
// `assert` initialized at top of scope
// Asssert helpers
// Assert helpers
// All of these must either call QUnit.push() or manually do:
// - runLoggingCallbacks( "log", .. );
// - config.current.assertions.push({ .. });
@@ -505,6 +518,7 @@ assert = {
throw new Error( "ok() assertion outside test context, was " + sourceFromStacktrace(2) );
}
result = !!result;
msg = msg || (result ? "okay" : "failed" );
var source,
details = {
@@ -514,8 +528,7 @@ assert = {
message: msg
};
msg = escapeText( msg || (result ? "okay" : "failed" ) );
msg = "<span class='test-message'>" + msg + "</span>";
msg = "<span class='test-message'>" + escapeText( msg ) + "</span>";
if ( !result ) {
source = sourceFromStacktrace( 2 );
@@ -642,13 +655,13 @@ assert = {
QUnit.push( ok, actual, expectedOutput, message );
} else {
QUnit.pushFailure( message, null, 'No exception was thrown.' );
QUnit.pushFailure( message, null, "No exception was thrown." );
}
}
};
/**
* @deprecate since 1.8.0
* @deprecated since 1.8.0
* Kept assertion helpers in root for backwards compatibility.
*/
extend( QUnit, assert );
@@ -737,7 +750,7 @@ config = {
// 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 );
extend( window, QUnit.constructor.prototype );
// Expose QUnit object
window.QUnit = QUnit;
@@ -836,6 +849,11 @@ extend( QUnit, {
},
// 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 ) {
@@ -985,11 +1003,10 @@ extend( QUnit, {
querystring = "?";
for ( key in params ) {
if ( !hasOwn.call( params, key ) ) {
continue;
if ( hasOwn.call( params, key ) ) {
querystring += encodeURIComponent( key ) + "=" +
encodeURIComponent( params[ key ] ) + "&";
}
querystring += encodeURIComponent( key ) + "=" +
encodeURIComponent( params[ key ] ) + "&";
}
return window.location.protocol + "//" + window.location.host +
window.location.pathname + querystring.slice( 0, -1 );
@@ -997,7 +1014,10 @@ extend( QUnit, {
extend: extend,
id: id,
addEvent: addEvent
addEvent: addEvent,
addClass: addClass,
hasClass: hasClass,
removeClass: removeClass
// load, equiv, jsDump, diff: Attached later
});
@@ -1044,6 +1064,7 @@ QUnit.load = function() {
var banner, filter, i, label, len, main, ol, toolbar, userAgent, val,
urlConfigCheckboxesContainer, urlConfigCheckboxes, moduleFilter,
numModules = 0,
moduleNames = [],
moduleFilterHtml = "",
urlConfigHtml = "",
oldconfig = extend( {}, config );
@@ -1072,18 +1093,24 @@ QUnit.load = function() {
"'><label for='qunit-urlconfig-" + escapeText( val.id ) +
"' title='" + escapeText( val.tooltip ) + "'>" + val.label + "</label>";
}
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 += "<label for='qunit-modulefilter'>Module: </label><select id='qunit-modulefilter' name='modulefilter'><option value='' " +
( config.module === undefined ? "selected='selected'" : "" ) +
">< All Modules ></option>";
for ( i in config.modules ) {
if ( config.modules.hasOwnProperty( i ) ) {
numModules += 1;
moduleFilterHtml += "<option value='" + escapeText( encodeURIComponent(i) ) + "' " +
( config.module === i ? "selected='selected'" : "" ) +
">" + escapeText(i) + "</option>";
}
for ( i = 0; i < numModules; i++) {
moduleFilterHtml += "<option value='" + escapeText( encodeURIComponent(moduleNames[i]) ) + "' " +
( config.module === moduleNames[i] ? "selected='selected'" : "" ) +
">" + escapeText(moduleNames[i]) + "</option>";
}
moduleFilterHtml += "</select>";
@@ -1137,7 +1164,7 @@ QUnit.load = function() {
// `label` initialized at top of scope
label = document.createElement( "label" );
label.setAttribute( "for", "qunit-filter-pass" );
label.setAttribute( "title", "Only show tests and assertons that fail. Stored in sessionStorage." );
label.setAttribute( "title", "Only show tests and assertions that fail. Stored in sessionStorage." );
label.innerHTML = "Hide passed tests";
toolbar.appendChild( label );
@@ -1157,14 +1184,19 @@ QUnit.load = function() {
toolbar.appendChild( urlConfigCheckboxesContainer );
if (numModules > 1) {
moduleFilter = document.createElement( 'span' );
moduleFilter.setAttribute( 'id', 'qunit-modulefilter-container' );
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 } );
window.location = QUnit.url({
module: ( selectedModule === "" ) ? undefined : selectedModule,
// Remove any existing filters
filter: undefined,
testNumber: undefined
});
});
toolbar.appendChild(moduleFilter);
}
@@ -1188,7 +1220,7 @@ addEvent( window, "load", QUnit.load );
onErrorFnPrev = window.onerror;
// Cover uncaught exceptions
// Returning true will surpress the default browser handler,
// Returning true will suppress the default browser handler,
// returning false will let it run.
window.onerror = function ( error, filePath, linerNr ) {
var ret = false;
@@ -1197,7 +1229,7 @@ window.onerror = function ( error, filePath, linerNr ) {
}
// Treat return value as window.onerror itself does,
// Only do our handling if not surpressed.
// Only do our handling if not suppressed.
if ( ret !== true ) {
if ( QUnit.config.current ) {
if ( QUnit.config.current.ignoreGlobalErrors ) {
@@ -1227,6 +1259,7 @@ function done() {
total: config.moduleStats.all
});
}
delete config.previousModule;
var i, key,
banner = id( "qunit-banner" ),
@@ -1386,16 +1419,16 @@ function escapeText( s ) {
// Both single quotes and double quotes (for attributes)
return s.replace( /['"<>&]/g, function( s ) {
switch( s ) {
case '\'':
return '&#039;';
case '"':
return '&quot;';
case '<':
return '&lt;';
case '>':
return '&gt;';
case '&':
return '&amp;';
case "'":
return "&#039;";
case "\"":
return "&quot;";
case "<":
return "&lt;";
case ">":
return "&gt;";
case "&":
return "&amp;";
}
});
}
@@ -1419,7 +1452,7 @@ function process( last ) {
if ( !defined.setTimeout || config.updateRate <= 0 || ( ( new Date().getTime() - start ) < config.updateRate ) ) {
config.queue.shift()();
} else {
window.setTimeout( next, 13 );
setTimeout( next, 13 );
break;
}
}
@@ -1434,11 +1467,13 @@ function saveGlobal() {
if ( config.noglobals ) {
for ( var key in window ) {
// in Opera sometimes DOM element ids show up here, ignore them
if ( !hasOwn.call( window, key ) || /^qunit-test-output/.test( key ) ) {
continue;
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 );
}
config.pollution.push( key );
}
}
}
@@ -1480,12 +1515,15 @@ function diff( a, b ) {
function extend( a, b ) {
for ( var prop in b ) {
if ( b[ prop ] === undefined ) {
delete a[ prop ];
// Avoid "Member not found" error in IE8 caused by setting window.constructor
} else if ( prop !== "constructor" || a !== window ) {
a[ prop ] = b[ prop ];
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 ];
}
}
}
}
@@ -1535,8 +1573,8 @@ function removeClass( elem, name ) {
while ( set.indexOf(" " + name + " ") > -1 ) {
set = set.replace(" " + name + " " , " ");
}
// If possible, trim it for prettiness, but not neccecarily
elem.className = window.jQuery ? jQuery.trim( set ) : ( set.trim ? set.trim() : set );
// 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 ) {
@@ -1585,8 +1623,10 @@ QUnit.equiv = (function() {
callers = [],
// stack to avoiding loops from circular referencing
parents = [],
parentsB = [],
getProto = Object.getPrototypeOf || function ( obj ) {
/*jshint camelcase:false */
return obj.__proto__;
},
callbacks = (function () {
@@ -1595,7 +1635,7 @@ QUnit.equiv = (function() {
function useStrictEquality( b, a ) {
/*jshint eqeqeq:false */
if ( b instanceof a.constructor || a instanceof b.constructor ) {
// to catch short annotaion VS 'new' annotation of a
// to catch short annotation VS 'new' annotation of a
// declaration
// e.g. var i = 1;
// var j = new Number(1);
@@ -1624,7 +1664,7 @@ QUnit.equiv = (function() {
return QUnit.objectType( b ) === "regexp" &&
// the regex itself
a.source === b.source &&
// and its modifers
// and its modifiers
a.global === b.global &&
// (gmi) ...
a.ignoreCase === b.ignoreCase &&
@@ -1641,7 +1681,7 @@ QUnit.equiv = (function() {
},
"array": function( b, a ) {
var i, j, len, loop;
var i, j, len, loop, aCircular, bCircular;
// b could be an object literal here
if ( QUnit.objectType( b ) !== "array" ) {
@@ -1656,24 +1696,36 @@ QUnit.equiv = (function() {
// track reference to avoid circular references
parents.push( a );
parentsB.push( b );
for ( i = 0; i < len; i++ ) {
loop = false;
for ( j = 0; j < parents.length; j++ ) {
if ( parents[j] === a[i] ) {
loop = true;// dont rewalk array
aCircular = parents[j] === a[i];
bCircular = parentsB[j] === b[i];
if ( aCircular || bCircular ) {
if ( a[i] === b[i] || aCircular && bCircular ) {
loop = true;
} else {
parents.pop();
parentsB.pop();
return false;
}
}
}
if ( !loop && !innerEquiv(a[i], b[i]) ) {
parents.pop();
parentsB.pop();
return false;
}
}
parents.pop();
parentsB.pop();
return true;
},
"object": function( b, a ) {
var i, j, loop,
/*jshint forin:false */
var i, j, loop, aCircular, bCircular,
// Default to true
eq = true,
aProperties = [],
@@ -1692,28 +1744,36 @@ QUnit.equiv = (function() {
// stack constructor before traversing properties
callers.push( a.constructor );
// track reference to avoid circular references
parents.push( a );
parentsB.push( b );
for ( i in a ) { // be strict: don't ensures hasOwnProperty
// and go deep
// be strict: don't ensure hasOwnProperty and go deep
for ( i in a ) {
loop = false;
for ( j = 0; j < parents.length; j++ ) {
if ( parents[j] === a[i] ) {
// don't go down the same path twice
loop = true;
aCircular = parents[j] === a[i];
bCircular = parentsB[j] === b[i];
if ( aCircular || bCircular ) {
if ( a[i] === b[i] || aCircular && bCircular ) {
loop = true;
} else {
eq = false;
break;
}
}
}
aProperties.push(i); // collect a's properties
if (!loop && !innerEquiv( a[i], b[i] ) ) {
aProperties.push(i);
if ( !loop && !innerEquiv(a[i], b[i]) ) {
eq = false;
break;
}
}
callers.pop(); // unstack, we are done
parents.pop();
parentsB.pop();
callers.pop(); // unstack, we are done
for ( i in b ) {
bProperties.push( i ); // collect b's properties
@@ -1743,7 +1803,7 @@ QUnit.equiv = (function() {
}
// apply transition with (1..n) arguments
}( args[0], args[1] ) && arguments.callee.apply( this, args.splice(1, args.length - 1 )) );
}( args[0], args[1] ) && innerEquiv.apply( this, args.splice(1, args.length - 1 )) );
};
return innerEquiv;
@@ -1761,7 +1821,7 @@ QUnit.equiv = (function() {
*/
QUnit.jsDump = (function() {
function quote( str ) {
return '"' + str.toString().replace( /"/g, '\\"' ) + '"';
return "\"" + str.toString().replace( /"/g, "\\\"" ) + "\"";
}
function literal( o ) {
return o + "";
@@ -1854,13 +1914,13 @@ QUnit.jsDump = (function() {
if ( this.HTML ) {
chr = chr.replace( /\t/g, " " ).replace( / /g, "&nbsp;" );
}
return new Array( this._depth_ + (extra||0) ).join(chr);
return new Array( this.depth + ( extra || 0 ) ).join(chr);
},
up: function( a ) {
this._depth_ += a || 1;
this.depth += a || 1;
},
down: function( a ) {
this._depth_ -= a || 1;
this.depth -= a || 1;
},
setParser: function( name, parser ) {
this.parsers[name] = parser;
@@ -1870,7 +1930,7 @@ QUnit.jsDump = (function() {
literal: literal,
join: join,
//
_depth_: 1,
depth: 1,
// This is the list of parsers, to modify them, use jsDump.setParser
parsers: {
window: "[Window]",
@@ -1898,6 +1958,7 @@ QUnit.jsDump = (function() {
nodelist: array,
"arguments": array,
object: function( map, stack ) {
/*jshint forin:false */
var ret = [ ], keys, key, val, i;
QUnit.jsDump.up();
keys = [];
@@ -2036,18 +2097,17 @@ QUnit.diff = (function() {
}
for ( i in ns ) {
if ( !hasOwn.call( ns, i ) ) {
continue;
}
if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) {
n[ ns[i].rows[0] ] = {
text: n[ ns[i].rows[0] ],
row: os[i].rows[0]
};
o[ os[i].rows[0] ] = {
text: o[ os[i].rows[0] ],
row: ns[i].rows[0]
};
if ( hasOwn.call( ns, i ) ) {
if ( ns[i].rows.length === 1 && hasOwn.call( os, i ) && os[i].rows.length === 1 ) {
n[ ns[i].rows[0] ] = {
text: n[ ns[i].rows[0] ],
row: os[i].rows[0]
};
o[ os[i].rows[0] ] = {
text: o[ os[i].rows[0] ],
row: ns[i].rows[0]
};
}
}
}
@@ -2143,9 +2203,9 @@ QUnit.diff = (function() {
};
}());
// for CommonJS enviroments, export everything
// for CommonJS environments, export everything
if ( typeof exports !== "undefined" ) {
extend( exports, QUnit );
extend( exports, QUnit.constructor.prototype );
}
// get at whatever the global object is, like window in browsers