Comparing version 1.12.0 to 1.13.0
@@ -0,0 +0,0 @@ # PhantomJS Runner # |
@@ -50,4 +50,8 @@ /* | ||
result = message.data; | ||
failed = !result || result.failed; | ||
failed = !result || !result.total || result.failed; | ||
if (!result.total) { | ||
console.error('No tests were executed. Are you loading tests asynchronously?'); | ||
} | ||
phantom.exit(failed ? 1 : 0); | ||
@@ -54,0 +58,0 @@ } |
@@ -76,1 +76,5 @@ Jörn Zaefferer <joern.zaefferer@gmail.com> | ||
David Vollbracht <david.vollbracht@gmail.com> | ||
Katie Gengler <katie@kmg.io> | ||
Joshua Peek <josh@joshpeek.com> | ||
Leonardo Balter <leonardo.balter@gmail.com> | ||
Jeff Cooper <jeff@kickstorming.com> |
@@ -5,2 +5,2 @@ Welcome! Thanks for your interest in contributing to QUnit. You're **almost** in the right place. More information on how to contribute to this and all other jQuery Foundation projects is over at [contribute.jquery.org](http://contribute.jquery.org). You'll definitely want to take a look at the articles on contributing [code](http://contribute.jquery.org/code). | ||
You can find us on [IRC](http://irc.jquery.org), specifically in [#jquery-dev](irc://irc.freenode.net/#jquery-dev) should you have any questions. If you've never contributed to open source before, we've put together [a short guide with tips, tricks, and ideas on getting started](http://contribute.jquery.org/open-source/). | ||
You can find us on [IRC](http://irc.jquery.org), specifically in #jquery-dev should you have any questions. If you've never contributed to open source before, we've put together [a short guide with tips, tricks, and ideas on getting started](http://contribute.jquery.org/open-source/). |
129
Gruntfile.js
@@ -5,2 +5,3 @@ /*jshint node:true */ | ||
grunt.loadNpmTasks( "grunt-git-authors" ); | ||
grunt.loadNpmTasks( "grunt-contrib-concat" ); | ||
grunt.loadNpmTasks( "grunt-contrib-jshint" ); | ||
@@ -10,10 +11,38 @@ grunt.loadNpmTasks( "grunt-contrib-qunit" ); | ||
function process( code ) { | ||
return code | ||
// Embed version | ||
.replace( /@VERSION/g, grunt.config( "pkg" ).version ) | ||
// Embed date (yyyy-mm-ddThh:mmZ) | ||
.replace( /@DATE/g, ( new Date() ).toISOString().replace( /:\d+\.\d+Z$/, "Z" ) ); | ||
} | ||
grunt.initConfig({ | ||
qunit: { | ||
qunit: [ | ||
"test/index.html", | ||
"test/async.html", | ||
"test/logs.html", | ||
"test/setTimeout.html" | ||
] | ||
pkg: grunt.file.readJSON( "package.json" ), | ||
concat: { | ||
"src-js": { | ||
options: { process: process }, | ||
src: [ | ||
"src/intro.js", | ||
"src/core.js", | ||
"src/test.js", | ||
"src/assert.js", | ||
"src/equiv.js", | ||
"src/dump.js", | ||
"src/diff.js", | ||
"src/export.js", | ||
"src/outro.js" | ||
], | ||
dest: "dist/qunit.js" | ||
}, | ||
"src-css": { | ||
options: { process: process }, | ||
src: [ | ||
"src/qunit.css" | ||
], | ||
dest: "dist/qunit.css" | ||
} | ||
}, | ||
@@ -25,3 +54,3 @@ jshint: { | ||
gruntfile: [ "Gruntfile.js" ], | ||
qunit: [ "qunit/**/*.js" ], | ||
dist: [ "dist/*.js" ], | ||
addons: { | ||
@@ -44,4 +73,12 @@ options: { | ||
}, | ||
qunit: { | ||
qunit: [ | ||
"test/index.html", | ||
"test/async.html", | ||
"test/logs.html", | ||
"test/setTimeout.html" | ||
] | ||
}, | ||
watch: { | ||
files: [ "*", ".jshintrc", "{addons,qunit,test}/**/{*,.*}" ], | ||
files: [ "*", ".jshintrc", "{addons,src,test}/**/{*,.*}" ], | ||
tasks: "default" | ||
@@ -51,15 +88,2 @@ } | ||
grunt.registerTask( "build-git", function( sha ) { | ||
function processor( content ) { | ||
var tagline = " - A JavaScript Unit Testing Framework"; | ||
return content.replace( tagline, "-" + sha + " " + grunt.template.today("isoDate") + tagline ); | ||
} | ||
grunt.file.copy( "qunit/qunit.css", "dist/qunit-git.css", { | ||
process: processor | ||
}); | ||
grunt.file.copy( "qunit/qunit.js", "dist/qunit-git.js", { | ||
process: processor | ||
}); | ||
}); | ||
grunt.registerTask( "testswarm", function( commit, configFile ) { | ||
@@ -70,5 +94,7 @@ var testswarm = require( "testswarm" ), | ||
done = this.async(); | ||
["index", "async", "setTimeout"].forEach(function (suite) { | ||
runs[suite] = config.testUrl + commit + "/test/" + suite + ".html"; | ||
}); | ||
testswarm.createClient( { | ||
@@ -86,3 +112,4 @@ url: config.swarmUrl, | ||
{ | ||
name: "QUnit commit #<a href='https://github.com/jquery/qunit/commit/" + commit + "'>" + commit.substr( 0, 10 ) + "</a>", | ||
name: "Commit <a href='https://github.com/jquery/qunit/commit/" + commit + "'>" + | ||
commit.substr( 0, 10 ) + "</a>", | ||
runs: runs, | ||
@@ -99,4 +126,58 @@ browserSets: config.browserSets | ||
grunt.registerTask("default", ["jshint", "qunit"]); | ||
// TODO: Extract this task later, if feasible | ||
// Also spawn a separate process to keep tests atomic | ||
grunt.registerTask( "test-on-node", function() { | ||
var testActive = false, | ||
runDone = false, | ||
done = this.async(), | ||
QUnit = require( "./dist/qunit" ); | ||
// Make the current tests work in the Node.js environment by appending | ||
// a bunch of properties into the `global` object | ||
[ "test", "asyncTest", "start", "stop", "expect" ].forEach(function( method ) { | ||
global[ method ] = QUnit[ method ]; | ||
}); | ||
global.QUnit = QUnit; | ||
QUnit.testStart(function() { | ||
testActive = true; | ||
}); | ||
QUnit.log(function( details ) { | ||
if ( !testActive || details.result ) { | ||
return; | ||
} | ||
var message = "name: " + details.name + " module: " + details.module + | ||
" message: " + details.message; | ||
grunt.log.error( message ); | ||
}); | ||
QUnit.testDone(function() { | ||
testActive = false; | ||
}); | ||
QUnit.done(function( details ) { | ||
if ( runDone ) { | ||
return; | ||
} | ||
var succeeded = ( details.failed === 0 ), | ||
message = details.total + " assertions in (" + details.runtime + "ms), passed: " + | ||
details.passed + ", failed: " + details.failed; | ||
if ( succeeded ) { | ||
grunt.log.ok( message ); | ||
} else { | ||
grunt.log.error( message ); | ||
} | ||
done( succeeded ); | ||
runDone = true; | ||
}); | ||
QUnit.config.autorun = false; | ||
require( "./test/logs" ); | ||
require( "./test/test" ); | ||
require( "./test/deepEqual" ); | ||
QUnit.load(); | ||
}); | ||
grunt.registerTask( "build", [ "concat" ] ); | ||
grunt.registerTask( "default", [ "build", "jshint", "qunit", "test-on-node" ] ); | ||
}; |
@@ -0,1 +1,16 @@ | ||
1.13.0 / 2014-01-04 | ||
================== | ||
* Tests: Stop using the expected argument in test() calls | ||
* Logging: Add runtime property to testDone, deprecate duration | ||
* Assert: Remove raises (deprecated 2012), replace with failed assertion | ||
* Grunt: Add non-browser test as grunt task. Runs existing tests in node. | ||
* Export: Only export to the variable that we check for. | ||
* Core: Properly check for existence of document | ||
* Core: Remove triggerEvent, which isn't used or documented anywhere. | ||
* Core: Silence addEvent in non-browser env | ||
* The Grand QUnit Split of 2013 | ||
* Use `id` function for selection elements in two places that were not using it. Closes gh-463 | ||
* Add bower.json. Fixes #461 | ||
1.12.0 / 2013-06-21 | ||
@@ -2,0 +17,0 @@ =================== |
@@ -0,0 +0,0 @@ Copyright 2013 jQuery Foundation and other contributors |
@@ -5,12 +5,8 @@ { | ||
"description": "An easy-to-use JavaScript Unit Testing framework.", | ||
"version": "1.12.0", | ||
"version": "1.13.0", | ||
"homepage": "http://qunitjs.com", | ||
"author": { | ||
"name": "jQuery Foundation and other contributors", | ||
"url": "https://github.com/jquery/qunit/blob/master/AUTHORS.txt" | ||
"url": "https://github.com/jquery/qunit/blob/1.13.0/AUTHORS.txt" | ||
}, | ||
"contributors": [ | ||
"John Resig <jeresig@gmail.com> (http://ejohn.org/)", | ||
"Jörn Zaefferer <joern.zaefferer@gmail.com> (http://bassistance.de/)" | ||
], | ||
"homepage": "http://qunitjs.com", | ||
"repository": { | ||
@@ -20,9 +16,2 @@ "type": "git", | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/jquery/qunit/issues" | ||
}, | ||
"license": { | ||
"name": "MIT", | ||
"url": "http://www.opensource.org/licenses/mit-license.php" | ||
}, | ||
"keywords": [ | ||
@@ -33,14 +22,26 @@ "testing", | ||
], | ||
"main": "qunit/qunit.js", | ||
"bugs": { | ||
"url": "https://github.com/jquery/qunit/issues" | ||
}, | ||
"licenses": [ | ||
{ | ||
"type": "MIT", | ||
"url": "https://github.com/jquery/qunit/blob/1.13.0/MIT-LICENSE.txt" | ||
} | ||
], | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"grunt": "0.4.2", | ||
"grunt-contrib-concat": "0.3.0", | ||
"grunt-contrib-jshint": "0.7.2", | ||
"grunt-contrib-qunit": "0.3.0", | ||
"grunt-contrib-watch": "0.5.3", | ||
"grunt-git-authors": "1.2.0", | ||
"testswarm": "1.1.0" | ||
}, | ||
"scripts": { | ||
"test": "grunt" | ||
"test": "grunt", | ||
"prepublish": "grunt build" | ||
}, | ||
"devDependencies": { | ||
"grunt": "~0.4.0", | ||
"grunt-contrib-jshint": "~0.2.0", | ||
"grunt-contrib-qunit": "~0.2.0", | ||
"grunt-contrib-watch": "~0.3.0", | ||
"grunt-git-authors": "~1.2.0", | ||
"testswarm": "~1.0.1" | ||
} | ||
"main": "dist/qunit.js" | ||
} |
1098
qunit/qunit.js
@@ -1,9 +0,10 @@ | ||
/** | ||
* QUnit v1.12.0 - A JavaScript Unit Testing Framework | ||
/*! | ||
* QUnit 1.13.0 | ||
* http://qunitjs.com/ | ||
* | ||
* http://qunitjs.com | ||
* Copyright 2013 jQuery Foundation and other contributors | ||
* Released under the MIT license | ||
* http://jquery.org/license | ||
* | ||
* Copyright 2013 jQuery Foundation and other contributors | ||
* Released under the MIT license. | ||
* https://jquery.org/license/ | ||
* Date: 2014-01-04T17:09Z | ||
*/ | ||
@@ -25,2 +26,3 @@ | ||
defined = { | ||
document: typeof window.document !== "undefined", | ||
setTimeout: typeof window.setTimeout !== "undefined", | ||
@@ -88,299 +90,3 @@ sessionStorage: (function() { | ||
function Test( settings ) { | ||
extend( this, settings ); | ||
this.assertions = []; | ||
this.testNumber = ++Test.count; | ||
} | ||
Test.count = 0; | ||
Test.prototype = { | ||
init: function() { | ||
var a, b, li, | ||
tests = id( "qunit-tests" ); | ||
if ( tests ) { | ||
b = document.createElement( "strong" ); | ||
b.innerHTML = this.nameHtml; | ||
// `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++; | ||
tests.appendChild( li ); | ||
} | ||
}, | ||
setup: function() { | ||
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, | ||
passed: config.moduleStats.all - config.moduleStats.bad, | ||
total: config.moduleStats.all | ||
}); | ||
} | ||
config.previousModule = this.module; | ||
config.moduleStats = { all: 0, bad: 0 }; | ||
runLoggingCallbacks( "moduleStart", QUnit, { | ||
name: this.module | ||
}); | ||
} | ||
config.current = this; | ||
this.testEnvironment = extend({ | ||
setup: function() {}, | ||
teardown: function() {} | ||
}, this.moduleTestEnvironment ); | ||
this.started = +new Date(); | ||
runLoggingCallbacks( "testStart", QUnit, { | ||
name: this.testName, | ||
module: this.module | ||
}); | ||
/*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, QUnit.assert ); | ||
return; | ||
} | ||
try { | ||
this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert ); | ||
} catch( e ) { | ||
QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) ); | ||
} | ||
}, | ||
run: function() { | ||
config.current = this; | ||
var running = id( "qunit-testresult" ); | ||
if ( running ) { | ||
running.innerHTML = "Running: <br/>" + this.nameHtml; | ||
} | ||
if ( this.async ) { | ||
QUnit.stop(); | ||
} | ||
this.callbackStarted = +new Date(); | ||
if ( config.notrycatch ) { | ||
this.callback.call( this.testEnvironment, QUnit.assert ); | ||
this.callbackRuntime = +new Date() - this.callbackStarted; | ||
return; | ||
} | ||
try { | ||
this.callback.call( this.testEnvironment, QUnit.assert ); | ||
this.callbackRuntime = +new Date() - this.callbackStarted; | ||
} catch( e ) { | ||
this.callbackRuntime = +new Date() - this.callbackStarted; | ||
QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) ); | ||
// else next test will carry the responsibility | ||
saveGlobal(); | ||
// Restart the tests if they're blocking | ||
if ( config.blocking ) { | ||
QUnit.start(); | ||
} | ||
} | ||
}, | ||
teardown: function() { | ||
config.current = this; | ||
if ( config.notrycatch ) { | ||
if ( typeof this.callbackRuntime === "undefined" ) { | ||
this.callbackRuntime = +new Date() - this.callbackStarted; | ||
} | ||
this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert ); | ||
return; | ||
} else { | ||
try { | ||
this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert ); | ||
} catch( e ) { | ||
QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) ); | ||
} | ||
} | ||
checkPollution(); | ||
}, | ||
finish: function() { | ||
config.current = this; | ||
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 i, assertion, a, b, time, li, ol, | ||
test = this, | ||
good = 0, | ||
bad = 0, | ||
tests = id( "qunit-tests" ); | ||
this.runtime = +new Date() - this.started; | ||
config.stats.all += this.assertions.length; | ||
config.moduleStats.all += this.assertions.length; | ||
if ( tests ) { | ||
ol = document.createElement( "ol" ); | ||
ol.className = "qunit-assert-list"; | ||
for ( i = 0; i < this.assertions.length; i++ ) { | ||
assertion = this.assertions[i]; | ||
li = document.createElement( "li" ); | ||
li.className = assertion.result ? "pass" : "fail"; | ||
li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" ); | ||
ol.appendChild( li ); | ||
if ( assertion.result ) { | ||
good++; | ||
} else { | ||
bad++; | ||
config.stats.bad++; | ||
config.moduleStats.bad++; | ||
} | ||
} | ||
// store result when possible | ||
if ( QUnit.config.reorder && defined.sessionStorage ) { | ||
if ( bad ) { | ||
sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad ); | ||
} else { | ||
sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName ); | ||
} | ||
} | ||
if ( bad === 0 ) { | ||
addClass( ol, "qunit-collapsed" ); | ||
} | ||
// `b` initialized at top of scope | ||
b = document.createElement( "strong" ); | ||
b.innerHTML = this.nameHtml + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>"; | ||
addEvent(b, "click", function() { | ||
var next = b.parentNode.lastChild, | ||
collapsed = hasClass( next, "qunit-collapsed" ); | ||
( collapsed ? removeClass : addClass )( next, "qunit-collapsed" ); | ||
}); | ||
addEvent(b, "dblclick", function( e ) { | ||
var target = e && e.target ? e.target : window.event.srcElement; | ||
if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) { | ||
target = target.parentNode; | ||
} | ||
if ( window.location && target.nodeName.toLowerCase() === "strong" ) { | ||
window.location = QUnit.url({ testNumber: test.testNumber }); | ||
} | ||
}); | ||
// `time` initialized at top of scope | ||
time = document.createElement( "span" ); | ||
time.className = "runtime"; | ||
time.innerHTML = this.runtime + " ms"; | ||
// `li` initialized at top of scope | ||
li = id( this.id ); | ||
li.className = bad ? "fail" : "pass"; | ||
li.removeChild( li.firstChild ); | ||
a = li.firstChild; | ||
li.appendChild( b ); | ||
li.appendChild( a ); | ||
li.appendChild( time ); | ||
li.appendChild( ol ); | ||
} else { | ||
for ( i = 0; i < this.assertions.length; i++ ) { | ||
if ( !this.assertions[i].result ) { | ||
bad++; | ||
config.stats.bad++; | ||
config.moduleStats.bad++; | ||
} | ||
} | ||
} | ||
runLoggingCallbacks( "testDone", QUnit, { | ||
name: this.testName, | ||
module: this.module, | ||
failed: bad, | ||
passed: this.assertions.length - bad, | ||
total: this.assertions.length, | ||
duration: this.runtime | ||
}); | ||
QUnit.reset(); | ||
config.current = undefined; | ||
}, | ||
queue: function() { | ||
var bad, | ||
test = this; | ||
synchronize(function() { | ||
test.init(); | ||
}); | ||
function run() { | ||
// each of these can by async | ||
synchronize(function() { | ||
test.setup(); | ||
}); | ||
synchronize(function() { | ||
test.run(); | ||
}); | ||
synchronize(function() { | ||
test.teardown(); | ||
}); | ||
synchronize(function() { | ||
test.finish(); | ||
}); | ||
} | ||
// `bad` initialized at top of scope | ||
// defer when previous test run passed, if storage is available | ||
bad = QUnit.config.reorder && defined.sessionStorage && | ||
+sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName ); | ||
if ( bad ) { | ||
run(); | ||
} else { | ||
synchronize( run, true ); | ||
} | ||
} | ||
}; | ||
// Root QUnit object. | ||
@@ -504,188 +210,4 @@ // `QUnit` initialized at top of scope | ||
// `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 = { | ||
/** | ||
* Asserts rough true-ish result. | ||
* @name ok | ||
* @function | ||
* @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) ); | ||
} | ||
result = !!result; | ||
msg = msg || (result ? "okay" : "failed" ); | ||
var source, | ||
details = { | ||
module: config.current.module, | ||
name: config.current.testName, | ||
result: result, | ||
message: msg | ||
}; | ||
msg = "<span class='test-message'>" + escapeText( msg ) + "</span>"; | ||
if ( !result ) { | ||
source = sourceFromStacktrace( 2 ); | ||
if ( source ) { | ||
details.source = source; | ||
msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + escapeText( source ) + "</pre></td></tr></table>"; | ||
} | ||
} | ||
runLoggingCallbacks( "log", QUnit, details ); | ||
config.current.assertions.push({ | ||
result: result, | ||
message: msg | ||
}); | ||
}, | ||
/** | ||
* Assert that the first two arguments are equal, with an optional message. | ||
* Prints out both actual and expected values. | ||
* @name equal | ||
* @function | ||
* @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" ); | ||
*/ | ||
equal: function( actual, expected, message ) { | ||
/*jshint eqeqeq:false */ | ||
QUnit.push( expected == actual, actual, expected, message ); | ||
}, | ||
/** | ||
* @name notEqual | ||
* @function | ||
*/ | ||
notEqual: function( actual, expected, message ) { | ||
/*jshint eqeqeq:false */ | ||
QUnit.push( expected != actual, actual, expected, message ); | ||
}, | ||
/** | ||
* @name propEqual | ||
* @function | ||
*/ | ||
propEqual: function( actual, expected, message ) { | ||
actual = objectValues(actual); | ||
expected = objectValues(expected); | ||
QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); | ||
}, | ||
/** | ||
* @name notPropEqual | ||
* @function | ||
*/ | ||
notPropEqual: function( actual, expected, message ) { | ||
actual = objectValues(actual); | ||
expected = objectValues(expected); | ||
QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); | ||
}, | ||
/** | ||
* @name deepEqual | ||
* @function | ||
*/ | ||
deepEqual: function( actual, expected, message ) { | ||
QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); | ||
}, | ||
/** | ||
* @name notDeepEqual | ||
* @function | ||
*/ | ||
notDeepEqual: function( actual, expected, message ) { | ||
QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); | ||
}, | ||
/** | ||
* @name strictEqual | ||
* @function | ||
*/ | ||
strictEqual: function( actual, expected, message ) { | ||
QUnit.push( expected === actual, actual, expected, message ); | ||
}, | ||
/** | ||
* @name notStrictEqual | ||
* @function | ||
*/ | ||
notStrictEqual: function( actual, expected, message ) { | ||
QUnit.push( expected !== actual, actual, expected, message ); | ||
}, | ||
"throws": function( block, expected, message ) { | ||
var actual, | ||
expectedOutput = expected, | ||
ok = false; | ||
// 'expected' is optional | ||
if ( typeof expected === "string" ) { | ||
message = expected; | ||
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 | ||
if ( !expected ) { | ||
ok = true; | ||
expectedOutput = null; | ||
// expected is a regexp | ||
} else if ( QUnit.objectType( expected ) === "regexp" ) { | ||
ok = expected.test( 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; | ||
ok = true; | ||
} | ||
QUnit.push( ok, actual, expectedOutput, message ); | ||
} else { | ||
QUnit.pushFailure( message, null, "No exception was thrown." ); | ||
} | ||
} | ||
}; | ||
/** | ||
* @deprecated since 1.8.0 | ||
* Kept assertion helpers in root for backwards compatibility. | ||
*/ | ||
extend( QUnit, assert ); | ||
/** | ||
* @deprecated since 1.9.0 | ||
* Kept root "raises()" for backwards compatibility. | ||
* (Note that we don't introduce assert.raises). | ||
*/ | ||
QUnit.raises = assert[ "throws" ]; | ||
/** | ||
* @deprecated since 1.0.0, replaced with error pushes since 1.3.0 | ||
* Kept to avoid TypeErrors for undefined methods. | ||
*/ | ||
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 | ||
// We use the prototype to distinguish between properties that should | ||
// be exposed as globals (and in exports) and those that shouldn't | ||
(function() { | ||
@@ -753,11 +275,2 @@ function F() {} | ||
// 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 | ||
@@ -796,6 +309,3 @@ (function() { | ||
// Extend QUnit object, | ||
// these after set here because they should not be exposed as global functions | ||
extend( QUnit, { | ||
assert: assert, | ||
@@ -869,16 +379,2 @@ config: config, | ||
// 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 | ||
@@ -891,7 +387,8 @@ is: function( type, obj ) { | ||
if ( typeof obj === "undefined" ) { | ||
return "undefined"; | ||
// consider: typeof null === object | ||
return "undefined"; | ||
} | ||
// Consider: typeof null === object | ||
if ( obj === null ) { | ||
return "null"; | ||
return "null"; | ||
} | ||
@@ -1053,3 +550,3 @@ | ||
// testDone: { name, failed, passed, total, duration } | ||
// testDone: { name, failed, passed, total, runtime } | ||
testDone: registerLoggingCallback( "testDone" ), | ||
@@ -1064,3 +561,3 @@ | ||
if ( typeof document === "undefined" || document.readyState === "complete" ) { | ||
if ( !defined.document || document.readyState === "complete" ) { | ||
config.autorun = true; | ||
@@ -1148,3 +645,3 @@ } | ||
var tmp, | ||
ol = document.getElementById( "qunit-tests" ); | ||
ol = id( "qunit-tests" ); | ||
@@ -1169,3 +666,3 @@ if ( filter.checked ) { | ||
// `ol` initialized at top of scope | ||
ol = document.getElementById( "qunit-tests" ); | ||
ol = id( "qunit-tests" ); | ||
ol.className = ol.className + " hidepass"; | ||
@@ -1227,3 +724,5 @@ } | ||
addEvent( window, "load", QUnit.load ); | ||
if ( defined.document ) { | ||
addEvent( window, "load", QUnit.load ); | ||
} | ||
@@ -1266,5 +765,5 @@ // `onErrorFnPrev` initialized at top of scope | ||
// Log the last module results | ||
if ( config.currentModule ) { | ||
if ( config.previousModule ) { | ||
runLoggingCallbacks( "moduleDone", QUnit, { | ||
name: config.currentModule, | ||
name: config.previousModule, | ||
failed: config.moduleStats.bad, | ||
@@ -1303,3 +802,3 @@ passed: config.moduleStats.all - config.moduleStats.bad, | ||
if ( config.altertitle && typeof document !== "undefined" && document.title ) { | ||
if ( config.altertitle && defined.document && document.title ) { | ||
// show ✖ for good, ✔ for bad suite result in title | ||
@@ -1553,8 +1052,14 @@ // use escape sequences in case file gets loaded with non-utf-8-charset | ||
function addEvent( elem, type, fn ) { | ||
// Standards-based browsers | ||
if ( elem.addEventListener ) { | ||
// Standards-based browsers | ||
elem.addEventListener( type, fn, false ); | ||
// IE | ||
} else if ( elem.attachEvent ) { | ||
// support: IE <9 | ||
elem.attachEvent( "on" + type, fn ); | ||
} else { | ||
elem.attachEvent( "on" + type, fn ); | ||
// Caller must ensure support for event listeners is present | ||
throw new Error( "addEvent() was called in a context without event listener support" ); | ||
} | ||
@@ -1596,4 +1101,3 @@ } | ||
function id( name ) { | ||
return !!( typeof document !== "undefined" && document && document.getElementById ) && | ||
document.getElementById( name ); | ||
return defined.document && document.getElementById && document.getElementById( name ); | ||
} | ||
@@ -1620,2 +1124,502 @@ | ||
// 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 = []; | ||
this.testNumber = ++Test.count; | ||
} | ||
Test.count = 0; | ||
Test.prototype = { | ||
init: function() { | ||
var a, b, li, | ||
tests = id( "qunit-tests" ); | ||
if ( tests ) { | ||
b = document.createElement( "strong" ); | ||
b.innerHTML = this.nameHtml; | ||
// `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++; | ||
tests.appendChild( li ); | ||
} | ||
}, | ||
setup: function() { | ||
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, | ||
passed: config.moduleStats.all - config.moduleStats.bad, | ||
total: config.moduleStats.all | ||
}); | ||
} | ||
config.previousModule = this.module; | ||
config.moduleStats = { all: 0, bad: 0 }; | ||
runLoggingCallbacks( "moduleStart", QUnit, { | ||
name: this.module | ||
}); | ||
} | ||
config.current = this; | ||
this.testEnvironment = extend({ | ||
setup: function() {}, | ||
teardown: function() {} | ||
}, this.moduleTestEnvironment ); | ||
this.started = +new Date(); | ||
runLoggingCallbacks( "testStart", QUnit, { | ||
name: this.testName, | ||
module: this.module | ||
}); | ||
/*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, QUnit.assert ); | ||
return; | ||
} | ||
try { | ||
this.testEnvironment.setup.call( this.testEnvironment, QUnit.assert ); | ||
} catch( e ) { | ||
QUnit.pushFailure( "Setup failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) ); | ||
} | ||
}, | ||
run: function() { | ||
config.current = this; | ||
var running = id( "qunit-testresult" ); | ||
if ( running ) { | ||
running.innerHTML = "Running: <br/>" + this.nameHtml; | ||
} | ||
if ( this.async ) { | ||
QUnit.stop(); | ||
} | ||
this.callbackStarted = +new Date(); | ||
if ( config.notrycatch ) { | ||
this.callback.call( this.testEnvironment, QUnit.assert ); | ||
this.callbackRuntime = +new Date() - this.callbackStarted; | ||
return; | ||
} | ||
try { | ||
this.callback.call( this.testEnvironment, QUnit.assert ); | ||
this.callbackRuntime = +new Date() - this.callbackStarted; | ||
} catch( e ) { | ||
this.callbackRuntime = +new Date() - this.callbackStarted; | ||
QUnit.pushFailure( "Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + ( e.message || e ), extractStacktrace( e, 0 ) ); | ||
// else next test will carry the responsibility | ||
saveGlobal(); | ||
// Restart the tests if they're blocking | ||
if ( config.blocking ) { | ||
QUnit.start(); | ||
} | ||
} | ||
}, | ||
teardown: function() { | ||
config.current = this; | ||
if ( config.notrycatch ) { | ||
if ( typeof this.callbackRuntime === "undefined" ) { | ||
this.callbackRuntime = +new Date() - this.callbackStarted; | ||
} | ||
this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert ); | ||
return; | ||
} else { | ||
try { | ||
this.testEnvironment.teardown.call( this.testEnvironment, QUnit.assert ); | ||
} catch( e ) { | ||
QUnit.pushFailure( "Teardown failed on " + this.testName + ": " + ( e.message || e ), extractStacktrace( e, 1 ) ); | ||
} | ||
} | ||
checkPollution(); | ||
}, | ||
finish: function() { | ||
config.current = this; | ||
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 i, assertion, a, b, time, li, ol, | ||
test = this, | ||
good = 0, | ||
bad = 0, | ||
tests = id( "qunit-tests" ); | ||
this.runtime = +new Date() - this.started; | ||
config.stats.all += this.assertions.length; | ||
config.moduleStats.all += this.assertions.length; | ||
if ( tests ) { | ||
ol = document.createElement( "ol" ); | ||
ol.className = "qunit-assert-list"; | ||
for ( i = 0; i < this.assertions.length; i++ ) { | ||
assertion = this.assertions[i]; | ||
li = document.createElement( "li" ); | ||
li.className = assertion.result ? "pass" : "fail"; | ||
li.innerHTML = assertion.message || ( assertion.result ? "okay" : "failed" ); | ||
ol.appendChild( li ); | ||
if ( assertion.result ) { | ||
good++; | ||
} else { | ||
bad++; | ||
config.stats.bad++; | ||
config.moduleStats.bad++; | ||
} | ||
} | ||
// store result when possible | ||
if ( QUnit.config.reorder && defined.sessionStorage ) { | ||
if ( bad ) { | ||
sessionStorage.setItem( "qunit-test-" + this.module + "-" + this.testName, bad ); | ||
} else { | ||
sessionStorage.removeItem( "qunit-test-" + this.module + "-" + this.testName ); | ||
} | ||
} | ||
if ( bad === 0 ) { | ||
addClass( ol, "qunit-collapsed" ); | ||
} | ||
// `b` initialized at top of scope | ||
b = document.createElement( "strong" ); | ||
b.innerHTML = this.nameHtml + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>"; | ||
addEvent(b, "click", function() { | ||
var next = b.parentNode.lastChild, | ||
collapsed = hasClass( next, "qunit-collapsed" ); | ||
( collapsed ? removeClass : addClass )( next, "qunit-collapsed" ); | ||
}); | ||
addEvent(b, "dblclick", function( e ) { | ||
var target = e && e.target ? e.target : window.event.srcElement; | ||
if ( target.nodeName.toLowerCase() === "span" || target.nodeName.toLowerCase() === "b" ) { | ||
target = target.parentNode; | ||
} | ||
if ( window.location && target.nodeName.toLowerCase() === "strong" ) { | ||
window.location = QUnit.url({ testNumber: test.testNumber }); | ||
} | ||
}); | ||
// `time` initialized at top of scope | ||
time = document.createElement( "span" ); | ||
time.className = "runtime"; | ||
time.innerHTML = this.runtime + " ms"; | ||
// `li` initialized at top of scope | ||
li = id( this.id ); | ||
li.className = bad ? "fail" : "pass"; | ||
li.removeChild( li.firstChild ); | ||
a = li.firstChild; | ||
li.appendChild( b ); | ||
li.appendChild( a ); | ||
li.appendChild( time ); | ||
li.appendChild( ol ); | ||
} else { | ||
for ( i = 0; i < this.assertions.length; i++ ) { | ||
if ( !this.assertions[i].result ) { | ||
bad++; | ||
config.stats.bad++; | ||
config.moduleStats.bad++; | ||
} | ||
} | ||
} | ||
runLoggingCallbacks( "testDone", QUnit, { | ||
name: this.testName, | ||
module: this.module, | ||
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, | ||
}); | ||
QUnit.reset(); | ||
config.current = undefined; | ||
}, | ||
queue: function() { | ||
var bad, | ||
test = this; | ||
synchronize(function() { | ||
test.init(); | ||
}); | ||
function run() { | ||
// each of these can by async | ||
synchronize(function() { | ||
test.setup(); | ||
}); | ||
synchronize(function() { | ||
test.run(); | ||
}); | ||
synchronize(function() { | ||
test.teardown(); | ||
}); | ||
synchronize(function() { | ||
test.finish(); | ||
}); | ||
} | ||
// `bad` initialized at top of scope | ||
// defer when previous test run passed, if storage is available | ||
bad = QUnit.config.reorder && defined.sessionStorage && | ||
+sessionStorage.getItem( "qunit-test-" + this.module + "-" + this.testName ); | ||
if ( bad ) { | ||
run(); | ||
} else { | ||
synchronize( run, true ); | ||
} | ||
} | ||
}; | ||
// `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({ .. }); | ||
assert = QUnit.assert = { | ||
/** | ||
* Asserts rough true-ish result. | ||
* @name ok | ||
* @function | ||
* @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) ); | ||
} | ||
result = !!result; | ||
msg = msg || ( result ? "okay" : "failed" ); | ||
var source, | ||
details = { | ||
module: config.current.module, | ||
name: config.current.testName, | ||
result: result, | ||
message: msg | ||
}; | ||
msg = "<span class='test-message'>" + escapeText( msg ) + "</span>"; | ||
if ( !result ) { | ||
source = sourceFromStacktrace( 2 ); | ||
if ( source ) { | ||
details.source = source; | ||
msg += "<table><tr class='test-source'><th>Source: </th><td><pre>" + | ||
escapeText( source ) + | ||
"</pre></td></tr></table>"; | ||
} | ||
} | ||
runLoggingCallbacks( "log", QUnit, details ); | ||
config.current.assertions.push({ | ||
result: result, | ||
message: msg | ||
}); | ||
}, | ||
/** | ||
* Assert that the first two arguments are equal, with an optional message. | ||
* Prints out both actual and expected values. | ||
* @name equal | ||
* @function | ||
* @example equal( format( "Received {0} bytes.", 2), "Received 2 bytes.", "format() replaces {0} with next argument" ); | ||
*/ | ||
equal: function( actual, expected, message ) { | ||
/*jshint eqeqeq:false */ | ||
QUnit.push( expected == actual, actual, expected, message ); | ||
}, | ||
/** | ||
* @name notEqual | ||
* @function | ||
*/ | ||
notEqual: function( actual, expected, message ) { | ||
/*jshint eqeqeq:false */ | ||
QUnit.push( expected != actual, actual, expected, message ); | ||
}, | ||
/** | ||
* @name propEqual | ||
* @function | ||
*/ | ||
propEqual: function( actual, expected, message ) { | ||
actual = objectValues(actual); | ||
expected = objectValues(expected); | ||
QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); | ||
}, | ||
/** | ||
* @name notPropEqual | ||
* @function | ||
*/ | ||
notPropEqual: function( actual, expected, message ) { | ||
actual = objectValues(actual); | ||
expected = objectValues(expected); | ||
QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); | ||
}, | ||
/** | ||
* @name deepEqual | ||
* @function | ||
*/ | ||
deepEqual: function( actual, expected, message ) { | ||
QUnit.push( QUnit.equiv(actual, expected), actual, expected, message ); | ||
}, | ||
/** | ||
* @name notDeepEqual | ||
* @function | ||
*/ | ||
notDeepEqual: function( actual, expected, message ) { | ||
QUnit.push( !QUnit.equiv(actual, expected), actual, expected, message ); | ||
}, | ||
/** | ||
* @name strictEqual | ||
* @function | ||
*/ | ||
strictEqual: function( actual, expected, message ) { | ||
QUnit.push( expected === actual, actual, expected, message ); | ||
}, | ||
/** | ||
* @name notStrictEqual | ||
* @function | ||
*/ | ||
notStrictEqual: function( actual, expected, message ) { | ||
QUnit.push( expected !== actual, actual, expected, message ); | ||
}, | ||
"throws": function( block, expected, message ) { | ||
var actual, | ||
expectedOutput = expected, | ||
ok = false; | ||
// 'expected' is optional | ||
if ( typeof expected === "string" ) { | ||
message = expected; | ||
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 | ||
if ( !expected ) { | ||
ok = true; | ||
expectedOutput = null; | ||
// expected is a regexp | ||
} else if ( QUnit.objectType( expected ) === "regexp" ) { | ||
ok = expected.test( 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; | ||
ok = true; | ||
} | ||
QUnit.push( ok, actual, expectedOutput, message ); | ||
} else { | ||
QUnit.pushFailure( message, null, "No exception was thrown." ); | ||
} | ||
} | ||
}; | ||
/** | ||
* @deprecated since 1.8.0 | ||
* Kept assertion helpers in root for backwards compatibility. | ||
*/ | ||
extend( QUnit.constructor.prototype, assert ); | ||
/** | ||
* @deprecated since 1.9.0 | ||
* Kept to avoid TypeErrors for undefined methods. | ||
*/ | ||
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.constructor.prototype.equals = function() { | ||
QUnit.push( false, false, false, "QUnit.equals has been deprecated since 2009 (e88049a0), use QUnit.equal instead" ); | ||
}; | ||
QUnit.constructor.prototype.same = function() { | ||
QUnit.push( false, false, false, "QUnit.same has been deprecated since 2009 (e88049a0), use QUnit.deepEqual instead" ); | ||
}; | ||
// Test for equality any JavaScript type. | ||
@@ -2060,17 +2064,2 @@ // Author: Philippe Rathé <prathe@gmail.com> | ||
// 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; | ||
} | ||
/* | ||
@@ -2224,8 +2213,17 @@ * Javascript Diff Algorithm | ||
// 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; | ||
})() )); |
@@ -40,24 +40,20 @@ [![Build Status](http://jenkins.jquery.com/job/QUnit/badge/icon)](http://jenkins.jquery.com/job/QUnit/) | ||
Install git-extras and run `git changelog` to update History.md. Clean up the | ||
changelog, removing merge commits or whitespace cleanups. | ||
Use [jquery-release](https://github.com/jquery/jquery-release). The following aren't yet handled there: | ||
Update qunit/qunit.js|css and package.json to the release version, commit and | ||
tag (Put the 'v' in front of the tag, e.g. `v1.8.0`), update them again to | ||
the next version, commit and push commits and tags: | ||
Install [git-extras](https://github.com/visionmedia/git-extras) and run `git changelog` to update History.md. Clean up the changelog, removing merge commits or whitespace cleanups. Commit this before using the release script. | ||
git push --tags origin master | ||
Then run the script. | ||
To upload to code.jquery.com (replace $version accordingly), ssh to code.origin.jquery.com: | ||
Check out the new tag, then publish to npm via | ||
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 | ||
npm publish | ||
Then update /var/www/html/code.jquery.com/index.html and purge it with: | ||
Update web sites, replacing previous versions with new ones: | ||
curl -s http://code.origin.jquery.com/?reload | ||
* jquery/jquery-wp-content themes/jquery/footer-qunit.php | ||
* jquery/qunitjs.com pages/index.html | ||
Update web-base-template to link to those files for qunitjs.com. | ||
Finally announce on Twitter @qunitjs | ||
Publish to npm via | ||
npm publish | ||
Released v@VERSION: https://github.com/jquery/qunit/tree/v@VERSION | ||
Changelog: https://github.com/jquery/qunit/blob/v@VERSION/History.md |
@@ -0,0 +0,0 @@ QUnit.start(); |
@@ -1,2 +0,2 @@ | ||
module("equiv"); | ||
QUnit.module("equiv"); | ||
@@ -3,0 +3,0 @@ |
@@ -41,5 +41,6 @@ // TODO disable reordering for this suite! | ||
module("logs1"); | ||
QUnit.module("logs1"); | ||
test("test1", 15, function( assert ) { | ||
test("test1", function( assert ) { | ||
expect( 15 ); | ||
assert.equal( begin, 1, "QUnit.begin calls" ); | ||
@@ -89,3 +90,5 @@ assert.equal( moduleStart, 1, "QUnit.moduleStart calls" ); | ||
}); | ||
test("test2", 11, function( assert ) { | ||
test("test2", function( assert ) { | ||
expect( 11 ); | ||
assert.equal( begin, 1, "QUnit.begin calls" ); | ||
@@ -97,3 +100,5 @@ assert.equal( moduleStart, 1, "QUnit.moduleStart calls" ); | ||
assert.ok( typeof testDoneContext.duration === "number" , "testDone context: duration" ); | ||
assert.equal( typeof testDoneContext.runtime, "number" , "testDone context: runtime" ); | ||
delete testDoneContext.runtime; | ||
// DEPRECATED: remove this delete when removing the duration property | ||
delete testDoneContext.duration; | ||
@@ -119,5 +124,6 @@ assert.deepEqual( testDoneContext, { | ||
module("logs2"); | ||
QUnit.module("logs2"); | ||
test( "test1", 9, function( assert ) { | ||
test( "test1", function( assert ) { | ||
expect( 9 ); | ||
assert.equal( begin, 1, "QUnit.begin calls" ); | ||
@@ -145,3 +151,4 @@ assert.equal( moduleStart, 2, "QUnit.moduleStart calls" ); | ||
}); | ||
test( "test2", 8, function( assert ) { | ||
test( "test2", function( assert ) { | ||
expect( 8 ); | ||
assert.equal( begin, 1, "QUnit.begin calls" ); | ||
@@ -168,3 +175,3 @@ assert.equal( moduleStart, 2, "QUnit.moduleStart calls" ); | ||
if (!testAutorun) { | ||
if ( !testAutorun ) { | ||
return; | ||
@@ -180,13 +187,15 @@ } | ||
// the module starts/ends after each test. | ||
module("autorun"); | ||
QUnit.module( "autorun" ); | ||
test("first", function( assert ) { | ||
assert.equal(moduleStart, 1, "test started"); | ||
assert.equal(moduleDone, 0, "test in progress"); | ||
}); | ||
setTimeout(function() { | ||
test( "first", function( assert ) { | ||
assert.equal( moduleStart, 1, "test started" ); | ||
assert.equal( moduleDone, 0, "test in progress" ); | ||
}); | ||
test("second", function( assert ) { | ||
assert.equal(moduleStart, 2, "test started"); | ||
assert.equal(moduleDone, 1, "test in progress"); | ||
}); | ||
test( "second", function( assert ) { | ||
assert.equal( moduleStart, 2, "test started" ); | ||
assert.equal( moduleDone, 1, "test in progress" ); | ||
}); | ||
}, 5000 ); | ||
}); |
/*jshint node:true, undef:false */ | ||
/*globals QUnit:true */ | ||
// Run with: $ narwhal test/narwhal-test.js | ||
var QUnit = require("../qunit/qunit"); | ||
var QUnit = require("../dist/qunit"); | ||
@@ -22,3 +23,6 @@ QUnit.log(function(details) { | ||
assert.equal(true, false, "gotta fail"); | ||
x.y.z; // Throws ReferenceError | ||
// Throws ReferenceError | ||
x.y.z; | ||
}); | ||
QUnit.load(); |
/*jshint node:true, undef:false */ | ||
/*globals QUnit:true */ | ||
// Run with: $ node test/node-test.js | ||
var QUnit = require("../qunit/qunit"); | ||
var QUnit = require("../dist/qunit"); | ||
@@ -22,3 +23,6 @@ QUnit.log(function(details) { | ||
assert.equal(true, false, "gotta fail"); | ||
x.y.z; // Throws ReferenceError | ||
// Throws ReferenceError | ||
x.y.z; | ||
}); | ||
QUnit.load(); |
@@ -0,0 +0,0 @@ QUnit.config.updateRate = 1; |
@@ -0,0 +0,0 @@ // load testswarm agent |
192
test/test.js
@@ -0,1 +1,3 @@ | ||
(function( window ) { | ||
function getPreviousTests( rTestName, rModuleName ) { | ||
@@ -46,3 +48,4 @@ var testSpan, moduleSpan, | ||
test("expect in test", 3, function( assert ) { | ||
test("expect in test", function( assert ) { | ||
expect( 3 ); | ||
assert.ok(true); | ||
@@ -53,3 +56,4 @@ assert.ok(true); | ||
test("expect in test", 1, function( assert ) { | ||
test("expect in test", function( assert ) { | ||
expect( 1 ); | ||
assert.ok(true); | ||
@@ -67,5 +71,6 @@ }); | ||
QUnit.module("assertion helpers"); | ||
QUnit.module( "assertion helpers" ); | ||
QUnit.test( "QUnit.assert compatibility", 5, function( assert ) { | ||
QUnit.test( "QUnit.assert compatibility", function( assert ) { | ||
expect( 5 ); | ||
assert.ok( true, "Calling method on `assert` argument to test() callback" ); | ||
@@ -87,3 +92,3 @@ | ||
module("setup test", { | ||
QUnit.module( "setup test", { | ||
setup: function( assert ) { | ||
@@ -99,37 +104,47 @@ assert.ok(true); | ||
test("module with setup, expect in test call", 2, function( assert ) { | ||
test("module with setup, expect in test call", function( assert ) { | ||
expect( 2 ); | ||
assert.ok(true); | ||
}); | ||
module("<script id='qunit-unescaped-module'>'module';</script>", { | ||
setup: function() { | ||
}, | ||
teardown: function( assert ) { | ||
// We can't use ok(false) inside script tags since some browsers | ||
// don't evaluate script tags inserted through innerHTML after domready. | ||
// Counting them before/after doesn't cover everything either as qunit-modulefilter | ||
// is created before any test is ran. So use ids instead. | ||
if (document.getElementById('qunit-unescaped-module')) { | ||
// This can either be from in #qunit-modulefilter or #qunit-testresult | ||
assert.ok(false, 'Unescaped module name'); | ||
// TODO: More to the html-reporter test once we have that. | ||
if ( typeof document !== "undefined" ) { | ||
QUnit.module( "<script id='qunit-unescaped-module'>'module';</script>", { | ||
setup: function() { | ||
}, | ||
teardown: function( assert ) { | ||
// We can't use ok(false) inside script tags since some browsers | ||
// don't evaluate script tags inserted through innerHTML after domready. | ||
// Counting them before/after doesn't cover everything either as qunit-modulefilter | ||
// is created before any test is ran. So use ids instead. | ||
if ( document.getElementById( "qunit-unescaped-module" ) ) { | ||
// This can either be from in #qunit-modulefilter or #qunit-testresult | ||
assert.ok( false, "Unescaped module name" ); | ||
} | ||
if ( document.getElementById( "qunit-unescaped-test" ) ) { | ||
assert.ok( false, "Unescaped test name" ); | ||
} | ||
if ( document.getElementById( "qunit-unescaped-assertion" ) ) { | ||
assert.ok( false, "Unescaped test name" ); | ||
} | ||
} | ||
if (document.getElementById('qunit-unescaped-test')) { | ||
assert.ok(false, 'Unescaped test name'); | ||
} | ||
if (document.getElementById('qunit-unescaped-assertion')) { | ||
assert.ok(false, 'Unescaped test name'); | ||
} | ||
} | ||
}); | ||
}); | ||
test("<script id='qunit-unescaped-test'>'test';</script>", 1, function( assert ) { | ||
assert.ok(true, "<script id='qunit-unescaped-asassertionsert'>'assertion';</script>"); | ||
}); | ||
test( "<script id='qunit-unescaped-test'>'test';</script>", function( assert ) { | ||
expect( 1 ); | ||
assert.ok( true, "<script id='qunit-unescaped-asassertionsert'>'assertion';</script>" ); | ||
}); | ||
} | ||
var state; | ||
module("setup/teardown test", { | ||
QUnit.module( "setup/teardown test", { | ||
setup: function( assert ) { | ||
state = true; | ||
assert.ok(true); | ||
// Assert that we can introduce and delete globals in setup/teardown | ||
@@ -169,3 +184,3 @@ // without noglobals sounding any alarm. | ||
module("setup/teardown test 2"); | ||
QUnit.module( "setup/teardown test 2" ); | ||
@@ -177,14 +192,14 @@ test("module without setup/teardown", function( assert ) { | ||
var orgDate; | ||
var OrgDate; | ||
module("Date test", { | ||
QUnit.module( "Date test", { | ||
setup: function( assert ) { | ||
orgDate = Date; | ||
OrgDate = Date; | ||
window.Date = function () { | ||
assert.ok( false, 'QUnit should internally be independent from Date-related manipulation and testing' ); | ||
return new orgDate(); | ||
return new OrgDate(); | ||
}; | ||
}, | ||
teardown: function() { | ||
window.Date = orgDate; | ||
window.Date = OrgDate; | ||
} | ||
@@ -201,3 +216,3 @@ }); | ||
module("teardown and stop", { | ||
QUnit.module( "teardown and stop", { | ||
teardown: function( assert ) { | ||
@@ -242,3 +257,3 @@ assert.equal(state, "done", "Test teardown."); | ||
module("async setup test", { | ||
QUnit.module( "async setup test", { | ||
setup: function( assert ) { | ||
@@ -259,3 +274,3 @@ stop(); | ||
module("async teardown test", { | ||
QUnit.module( "async teardown test", { | ||
teardown: function( assert ) { | ||
@@ -276,5 +291,6 @@ stop(); | ||
module("asyncTest"); | ||
QUnit.module( "asyncTest" ); | ||
asyncTest("asyncTest", 2, function( assert ) { | ||
asyncTest("asyncTest", function( assert ) { | ||
expect( 2 ); | ||
assert.ok(true); | ||
@@ -298,3 +314,4 @@ setTimeout(function() { | ||
test("sync", 2, function( assert ) { | ||
test("sync", function( assert ) { | ||
expect( 2 ); | ||
stop(); | ||
@@ -312,3 +329,4 @@ setTimeout(function() { | ||
test("test synchronous calls to stop", 2, function( assert ) { | ||
test("test synchronous calls to stop", function( assert ) { | ||
expect( 2 ); | ||
stop(); | ||
@@ -327,3 +345,3 @@ setTimeout(function() { | ||
module("save scope", { | ||
QUnit.module( "save scope", { | ||
setup: function() { | ||
@@ -341,3 +359,3 @@ this.foo = "bar"; | ||
module("simple testEnvironment setup", { | ||
QUnit.module( "simple testEnvironment setup", { | ||
foo: "bar", | ||
@@ -358,3 +376,3 @@ // example of meta-data | ||
module("testEnvironment with object", { | ||
QUnit.module( "testEnvironment with object", { | ||
options: { | ||
@@ -385,3 +403,3 @@ recipe: "soup", | ||
module("testEnvironment tests"); | ||
QUnit.module( "testEnvironment tests" ); | ||
@@ -395,11 +413,9 @@ function makeurl() { | ||
test("makeurl working", 3, function( assert ) { | ||
test("makeurl working", function( assert ) { | ||
expect( 2 ); | ||
assert.equal( QUnit.config.current.testEnvironment, this, 'The current testEnvironment QUnit.config'); | ||
/*jshint camelcase:false */ | ||
assert.equal( QUnit.current_testEnvironment, this, 'The current testEnvironment is in QUnit.config (old way)'); | ||
/*jshint camelcase:true */ | ||
assert.equal( makeurl(), 'http://example.com/search?q=a%20search%20test', 'makeurl returns a default url if nothing specified in the testEnvironment'); | ||
}); | ||
module("testEnvironment with makeurl settings", { | ||
QUnit.module( "testEnvironment with makeurl settings", { | ||
url: 'http://google.com/', | ||
@@ -412,3 +428,3 @@ q: 'another_search_test' | ||
module("jsDump"); | ||
QUnit.module( "jsDump" ); | ||
test("jsDump output", function( assert ) { | ||
@@ -423,5 +439,6 @@ assert.equal( QUnit.jsDump.parse([1, 2]), "[\n 1,\n 2\n]" ); | ||
module("assertions"); | ||
QUnit.module( "assertions" ); | ||
test("propEqual", 5, function( assert ) { | ||
test("propEqual", function( assert ) { | ||
expect( 5 ); | ||
var objectCreate = Object.create || function ( origin ) { | ||
@@ -502,4 +519,4 @@ function O() {} | ||
test("raises", 9, function( assert ) { | ||
/*jshint es5:true */ | ||
test("throws", function( assert ) { | ||
expect(8); | ||
function CustomError( message ) { | ||
@@ -574,19 +591,11 @@ this.message = message; | ||
this.CustomError = CustomError; | ||
this.CustomError = CustomError; | ||
assert.throws( | ||
function() { | ||
throw new this.CustomError("some error description"); | ||
}, | ||
/description/, | ||
"throw error from property of 'this' context" | ||
); | ||
raises( | ||
function() { | ||
throw "error"; | ||
}, | ||
"simple throw, asserting with deprecated raises() function" | ||
); | ||
assert.throws( | ||
function() { | ||
throw new this.CustomError("some error description"); | ||
}, | ||
/description/, | ||
"throw error from property of 'this' context" | ||
); | ||
}); | ||
@@ -596,3 +605,3 @@ | ||
module("fixture"); | ||
QUnit.module( "fixture" ); | ||
test("setup", function() { | ||
@@ -623,3 +632,3 @@ expect(0); | ||
module("timing", { | ||
QUnit.module( "timing", { | ||
setup: function() { | ||
@@ -633,7 +642,9 @@ if ( delayNextSetup ) { | ||
test("setup", 0, function() { | ||
test("setup", function() { | ||
expect( 0 ); | ||
delayNextSetup = true; | ||
}); | ||
test("basics", 2, function( assert ) { | ||
test("basics", function( assert ) { | ||
expect( 2 ); | ||
var previous = getPreviousTests(/^setup$/, /^timing$/)[0], | ||
@@ -645,3 +656,4 @@ runtime = previous.lastChild.previousSibling; | ||
test("values", 2, function( assert ) { | ||
test("values", function( assert ) { | ||
expect( 2 ); | ||
var basics = getPreviousTests(/^setup$/, /^timing$/)[0], | ||
@@ -656,3 +668,3 @@ slow = getPreviousTests(/^basics$/, /^timing$/)[0]; | ||
module("custom assertions"); | ||
QUnit.module( "custom assertions" ); | ||
(function() { | ||
@@ -663,3 +675,4 @@ QUnit.assert.mod2 = function( value, expected, message ) { | ||
}; | ||
test("mod2", 2, function( assert ) { | ||
test("mod2", function( assert ) { | ||
expect( 2 ); | ||
assert.mod2(2, 0, "2 % 2 == 0"); | ||
@@ -671,3 +684,3 @@ assert.mod2(3, 1, "3 % 2 == 1"); | ||
module("recursions"); | ||
QUnit.module( "recursions" ); | ||
@@ -784,3 +797,3 @@ function Wrap(x) { | ||
var reset = QUnit.reset; | ||
module("reset"); | ||
QUnit.module( "reset" ); | ||
test("reset runs assertions", function( assert ) { | ||
@@ -806,3 +819,3 @@ expect(0); | ||
// work we use this test to check the assertion count. | ||
module("check previous test's assertion counts"); | ||
QUnit.module( "check previous test's assertion counts" ); | ||
test('count previous two test\'s assertions', function ( assert ) { | ||
@@ -818,3 +831,3 @@ var tests = getPreviousTests(/^ensure has correct number of assertions/, /^Synchronous test after load of page$/); | ||
module("Synchronous test after load of page"); | ||
QUnit.module( "Synchronous test after load of page" ); | ||
@@ -828,3 +841,4 @@ asyncTest('Async test', function( assert ) { | ||
test(testName, 99, function( assert ) { | ||
test(testName, function( assert ) { | ||
expect( 99 ); | ||
for (var i = 1; i < 100; i++) { | ||
@@ -837,3 +851,4 @@ assert.ok(i); | ||
// don't move between tests. | ||
test(testName + ' 2', 99, function( assert ) { | ||
test(testName + ' 2', function( assert ) { | ||
expect( 99 ); | ||
for (var i = 1; i < 100; i++) { | ||
@@ -844,3 +859,2 @@ assert.ok(i); | ||
} | ||
@@ -851,1 +865,7 @@ | ||
} | ||
// Get a reference to the global object, like window in browsers | ||
}( (function() { | ||
return this; | ||
}.call()) )); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Misc. License Issues
License(Experimental) A package's licensing information has fine-grained problems.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
262538
42
0
6845
0
7
58