1
0
mirror of https://github.com/twbs/bootstrap.git synced 2025-08-16 10:34:07 +02:00

Upgrade QUnit to 2.3.3

This commit is contained in:
Johann-S
2017-06-14 10:29:09 +02:00
parent d7867377d9
commit 1ec68d748b
2 changed files with 326 additions and 241 deletions

View File

@@ -1,12 +1,12 @@
/*! /*!
* QUnit 2.3.2 * QUnit 2.3.3
* https://qunitjs.com/ * https://qunitjs.com/
* *
* Copyright jQuery Foundation and other contributors * Copyright jQuery Foundation and other contributors
* Released under the MIT license * Released under the MIT license
* https://jquery.org/license * https://jquery.org/license
* *
* Date: 2017-04-18T02:19Z * Date: 2017-06-02T14:07Z
*/ */
/** Font Family and Sizes */ /** Font Family and Sizes */

View File

@@ -1,12 +1,12 @@
/*! /*!
* QUnit 2.3.2 * QUnit 2.3.3
* https://qunitjs.com/ * https://qunitjs.com/
* *
* Copyright jQuery Foundation and other contributors * Copyright jQuery Foundation and other contributors
* Released under the MIT license * Released under the MIT license
* https://jquery.org/license * https://jquery.org/license
* *
* Date: 2017-04-18T02:19Z * Date: 2017-06-02T14:07Z
*/ */
(function (global$1) { (function (global$1) {
'use strict'; 'use strict';
@@ -14,6 +14,7 @@
global$1 = 'default' in global$1 ? global$1['default'] : global$1; global$1 = 'default' in global$1 ? global$1['default'] : global$1;
var window = global$1.window; var window = global$1.window;
var self$1 = global$1.self;
var console = global$1.console; var console = global$1.console;
var setTimeout = global$1.setTimeout; var setTimeout = global$1.setTimeout;
var clearTimeout = global$1.clearTimeout; var clearTimeout = global$1.clearTimeout;
@@ -238,6 +239,27 @@
return objectType(obj) === type; return objectType(obj) === type;
} }
// Based on Java's String.hashCode, a simple but not
// rigorously collision resistant hashing function
function generateHash(module, testName) {
var str = module + "\x1C" + testName;
var hash = 0;
for (var i = 0; i < str.length; i++) {
hash = (hash << 5) - hash + str.charCodeAt(i);
hash |= 0;
}
// Convert the possibly negative integer hash code into an 8 character hex string, which isn't
// strictly necessary but increases user understanding that the id is a SHA-like hash
var hex = (0x100000000 + hash).toString(16);
if (hex.length < 8) {
hex = "0000000" + hex;
}
return hex.slice(-8);
}
// Test for equality any JavaScript type. // Test for equality any JavaScript type.
// Authors: Philippe Rathé <prathe@gmail.com>, David Chan <david@troi.org> // Authors: Philippe Rathé <prathe@gmail.com>, David Chan <david@troi.org>
var equiv = (function () { var equiv = (function () {
@@ -608,21 +630,19 @@
// Set of all modules. // Set of all modules.
modules: [], modules: [],
// Stack of nested modules
moduleStack: [],
// The first unnamed module // The first unnamed module
currentModule: { currentModule: {
name: "", name: "",
tests: [], tests: [],
childModules: [], childModules: [],
testsRun: 0 testsRun: 0,
unskippedTestsRun: 0
}, },
callbacks: {}, callbacks: {},
// The storage module to use for reordering tests // The storage module to use for reordering tests
storage: sessionStorage storage: localSessionStorage
}; };
// take a predefined QUnit.config and extend the defaults // take a predefined QUnit.config and extend the defaults
@@ -1064,6 +1084,135 @@
return extractStacktrace(error, offset); return extractStacktrace(error, offset);
} }
var priorityCount = 0;
var unitSampler = void 0;
/**
* Advances the ProcessingQueue to the next item if it is ready.
* @param {Boolean} last
*/
function advance() {
var start = now();
config.depth = (config.depth || 0) + 1;
while (config.queue.length && !config.blocking) {
var elapsedTime = now() - start;
if (!defined.setTimeout || config.updateRate <= 0 || elapsedTime < config.updateRate) {
if (priorityCount > 0) {
priorityCount--;
}
config.queue.shift()();
} else {
setTimeout(advance, 13);
break;
}
}
config.depth--;
if (!config.blocking && !config.queue.length && config.depth === 0) {
done();
}
}
function addToQueueImmediate(callback) {
if (objectType(callback) === "array") {
while (callback.length) {
addToQueueImmediate(callback.pop());
}
return;
}
config.queue.unshift(callback);
priorityCount++;
}
/**
* Adds a function to the ProcessingQueue for execution.
* @param {Function|Array} callback
* @param {Boolean} priority
* @param {String} seed
*/
function addToQueue(callback, prioritize, seed) {
if (prioritize) {
config.queue.splice(priorityCount++, 0, callback);
} else if (seed) {
if (!unitSampler) {
unitSampler = unitSamplerGenerator(seed);
}
// Insert into a random position after all prioritized items
var index = Math.floor(unitSampler() * (config.queue.length - priorityCount + 1));
config.queue.splice(priorityCount + index, 0, callback);
} else {
config.queue.push(callback);
}
}
/**
* Creates a seeded "sample" generator which is used for randomizing tests.
*/
function unitSamplerGenerator(seed) {
// 32-bit xorshift, requires only a nonzero seed
// http://excamera.com/sphinx/article-xorshift.html
var sample = parseInt(generateHash(seed), 16) || -1;
return function () {
sample ^= sample << 13;
sample ^= sample >>> 17;
sample ^= sample << 5;
// ECMAScript has no unsigned number type
if (sample < 0) {
sample += 0x100000000;
}
return sample / 0x100000000;
};
}
/**
* This function is called when the ProcessingQueue is done processing all
* items. It handles emitting the final run events.
*/
function done() {
var storage = config.storage;
ProcessingQueue.finished = true;
var runtime = now() - config.started;
var passed = config.stats.all - config.stats.bad;
emit("runEnd", globalSuite.end(true));
runLoggingCallbacks("done", {
passed: passed,
failed: config.stats.bad,
total: config.stats.all,
runtime: runtime
});
// Clear own storage items if all tests passed
if (storage && config.stats.bad === 0) {
for (var i = storage.length - 1; i >= 0; i--) {
var key = storage.key(i);
if (key.indexOf("qunit-test-") === 0) {
storage.removeItem(key);
}
}
}
}
var ProcessingQueue = {
finished: false,
add: addToQueue,
addImmediate: addToQueueImmediate,
advance: advance
};
var TestReport = function () { var TestReport = function () {
function TestReport(name, suite, options) { function TestReport(name, suite, options) {
classCallCheck(this, TestReport); classCallCheck(this, TestReport);
@@ -1077,6 +1226,8 @@
this.skipped = !!options.skip; this.skipped = !!options.skip;
this.todo = !!options.todo; this.todo = !!options.todo;
this.valid = options.valid;
this._startTime = 0; this._startTime = 0;
this._endTime = 0; this._endTime = 0;
@@ -1149,13 +1300,24 @@
value: function getAssertions() { value: function getAssertions() {
return this.assertions.slice(); return this.assertions.slice();
} }
// Remove actual and expected values from assertions. This is to prevent
// leaking memory throughout a test suite.
}, {
key: "slimAssertions",
value: function slimAssertions() {
this.assertions = this.assertions.map(function (assertion) {
delete assertion.actual;
delete assertion.expected;
return assertion;
});
}
}]); }]);
return TestReport; return TestReport;
}(); }();
var unitSampler;
var focused = false; var focused = false;
var priorityCount = 0;
function Test(settings) { function Test(settings) {
var i, l; var i, l;
@@ -1166,14 +1328,14 @@
extend(this, settings); extend(this, settings);
this.assertions = []; this.assertions = [];
this.semaphore = 0; this.semaphore = 0;
this.usedAsync = false;
this.module = config.currentModule; this.module = config.currentModule;
this.stack = sourceFromStacktrace(3); this.stack = sourceFromStacktrace(3);
this.steps = []; this.steps = [];
this.testReport = new TestReport(settings.testName, this.module.suiteReport, { this.testReport = new TestReport(settings.testName, this.module.suiteReport, {
todo: settings.todo, todo: settings.todo,
skip: settings.skip skip: settings.skip,
valid: this.valid()
}); });
// Register unique strings // Register unique strings
@@ -1187,7 +1349,8 @@
this.module.tests.push({ this.module.tests.push({
name: this.testName, name: this.testName,
testId: this.testId testId: this.testId,
skip: !!settings.skip
}); });
if (settings.skip) { if (settings.skip) {
@@ -1234,12 +1397,6 @@
config.current = this; config.current = this;
if (module.testEnvironment) {
delete module.testEnvironment.before;
delete module.testEnvironment.beforeEach;
delete module.testEnvironment.afterEach;
delete module.testEnvironment.after;
}
this.testEnvironment = extend({}, module.testEnvironment); this.testEnvironment = extend({}, module.testEnvironment);
this.started = now(); this.started = now();
@@ -1297,14 +1454,14 @@
test = this; test = this;
return function runHook() { return function runHook() {
if (hookName === "before") { if (hookName === "before") {
if (hookOwner.testsRun !== 0) { if (hookOwner.unskippedTestsRun !== 0) {
return; return;
} }
test.preserveEnvironment = true; test.preserveEnvironment = true;
} }
if (hookName === "after" && hookOwner.testsRun !== numberOfTests(hookOwner) - 1) { if (hookName === "after" && hookOwner.unskippedTestsRun !== numberOfUnskippedTests(hookOwner) - 1 && config.queue.length > 2) {
return; return;
} }
@@ -1334,8 +1491,8 @@
if (module.parentModule) { if (module.parentModule) {
processHooks(test, module.parentModule); processHooks(test, module.parentModule);
} }
if (module.testEnvironment && objectType(module.testEnvironment[handler]) === "function") { if (module.hooks && objectType(module.hooks[handler]) === "function") {
hooks.push(test.queueHook(module.testEnvironment[handler], handler, module)); hooks.push(test.queueHook(module.hooks[handler], handler, module));
} }
} }
@@ -1378,7 +1535,7 @@
} }
} }
notifyTestsRan(module); notifyTestsRan(module, skipped);
// Store result when possible // Store result when possible
if (storage) { if (storage) {
@@ -1389,7 +1546,11 @@
} }
} }
// After emitting the js-reporters event we cleanup the assertion data to
// avoid leaking it. It is not used by the legacy testDone callbacks.
emit("testEnd", this.testReport.end(true)); emit("testEnd", this.testReport.end(true));
this.testReport.slimAssertions();
runLoggingCallbacks("testDone", { runLoggingCallbacks("testDone", {
name: testName, name: testName,
module: moduleName, module: moduleName,
@@ -1409,6 +1570,20 @@
}); });
if (module.testsRun === numberOfTests(module)) { if (module.testsRun === numberOfTests(module)) {
logSuiteEnd(module);
// Check if the parent modules, iteratively, are done. If that the case,
// we emit the `suiteEnd` event and trigger `moduleDone` callback.
var parent = module.parentModule;
while (parent && parent.testsRun === numberOfTests(parent)) {
logSuiteEnd(parent);
parent = parent.parentModule;
}
}
config.current = undefined;
function logSuiteEnd(module) {
emit("suiteEnd", module.suiteReport.end(true)); emit("suiteEnd", module.suiteReport.end(true));
runLoggingCallbacks("moduleDone", { runLoggingCallbacks("moduleDone", {
name: module.name, name: module.name,
@@ -1419,8 +1594,6 @@
runtime: now() - module.stats.started runtime: now() - module.stats.started
}); });
} }
config.current = undefined;
}, },
preserveTestEnvironment: function preserveTestEnvironment() { preserveTestEnvironment: function preserveTestEnvironment() {
@@ -1431,18 +1604,16 @@
}, },
queue: function queue() { queue: function queue() {
var priority, var test = this;
previousFailCount,
test = this;
if (!this.valid()) { if (!this.valid()) {
return; return;
} }
function run() { function runTest() {
// Each of these can by async // Each of these can by async
synchronize([function () { ProcessingQueue.addImmediate([function () {
test.before(); test.before();
}, test.hooks("before"), function () { }, test.hooks("before"), function () {
test.preserveTestEnvironment(); test.preserveTestEnvironment();
@@ -1455,17 +1626,26 @@
}]); }]);
} }
previousFailCount = config.storage && +config.storage.getItem("qunit-test-" + this.module.name + "-" + this.testName); var previousFailCount = config.storage && +config.storage.getItem("qunit-test-" + this.module.name + "-" + this.testName);
// Prioritize previously failed tests, detected from storage // Prioritize previously failed tests, detected from storage
priority = config.reorder && previousFailCount; var prioritize = config.reorder && !!previousFailCount;
this.previousFailure = !!previousFailCount; this.previousFailure = !!previousFailCount;
return synchronize(run, priority, config.seed); ProcessingQueue.add(runTest, prioritize, config.seed);
// If the queue has already finished, we manually process the new test
if (ProcessingQueue.finished) {
ProcessingQueue.advance();
}
}, },
pushResult: function pushResult(resultInfo) { pushResult: function pushResult(resultInfo) {
if (this !== config.current) {
throw new Error("Assertion occured after test had finished.");
}
// Destructure of resultInfo = { result, actual, expected, message, negative } // Destructure of resultInfo = { result, actual, expected, message, negative }
var source, var source,
@@ -1503,7 +1683,7 @@
throw new Error("pushFailure() assertion outside test context, was " + sourceFromStacktrace(2)); throw new Error("pushFailure() assertion outside test context, was " + sourceFromStacktrace(2));
} }
this.assert.pushResult({ this.pushResult({
result: false, result: false,
message: message || "error", message: message || "error",
actual: actual || null, actual: actual || null,
@@ -1643,79 +1823,6 @@
return currentTest.pushFailure.apply(currentTest, arguments); return currentTest.pushFailure.apply(currentTest, arguments);
} }
// Based on Java's String.hashCode, a simple but not
// rigorously collision resistant hashing function
function generateHash(module, testName) {
var hex,
i = 0,
hash = 0,
str = module + "\x1C" + testName,
len = str.length;
for (; i < len; i++) {
hash = (hash << 5) - hash + str.charCodeAt(i);
hash |= 0;
}
// Convert the possibly negative integer hash code into an 8 character hex string, which isn't
// strictly necessary but increases user understanding that the id is a SHA-like hash
hex = (0x100000000 + hash).toString(16);
if (hex.length < 8) {
hex = "0000000" + hex;
}
return hex.slice(-8);
}
function synchronize(callback, priority, seed) {
var last = !priority,
index;
if (objectType(callback) === "array") {
while (callback.length) {
synchronize(callback.shift());
}
return;
}
if (priority) {
config.queue.splice(priorityCount++, 0, callback);
} else if (seed) {
if (!unitSampler) {
unitSampler = unitSamplerGenerator(seed);
}
// Insert into a random position after all priority items
index = Math.floor(unitSampler() * (config.queue.length - priorityCount + 1));
config.queue.splice(priorityCount + index, 0, callback);
} else {
config.queue.push(callback);
}
if (internalState.autorun && !config.blocking) {
process(last);
}
}
function unitSamplerGenerator(seed) {
// 32-bit xorshift, requires only a nonzero seed
// http://excamera.com/sphinx/article-xorshift.html
var sample = parseInt(generateHash(seed), 16) || -1;
return function () {
sample ^= sample << 13;
sample ^= sample >>> 17;
sample ^= sample << 5;
// ECMAScript has no unsigned number type
if (sample < 0) {
sample += 0x100000000;
}
return sample / 0x100000000;
};
}
function saveGlobal() { function saveGlobal() {
config.pollution = []; config.pollution = [];
@@ -1888,24 +1995,40 @@
} }
} }
function numberOfTests(module) { function collectTests(module) {
var count = module.tests.length, var tests = [].concat(module.tests);
modules = [].concat(toConsumableArray(module.childModules)); var modules = [].concat(toConsumableArray(module.childModules));
// Do a breadth-first traversal of the child modules // Do a breadth-first traversal of the child modules
while (modules.length) { while (modules.length) {
var nextModule = modules.shift(); var nextModule = modules.shift();
count += nextModule.tests.length; tests.push.apply(tests, nextModule.tests);
modules.push.apply(modules, toConsumableArray(nextModule.childModules)); modules.push.apply(modules, toConsumableArray(nextModule.childModules));
} }
return count; return tests;
} }
function notifyTestsRan(module) { function numberOfTests(module) {
return collectTests(module).length;
}
function numberOfUnskippedTests(module) {
return collectTests(module).filter(function (test) {
return !test.skip;
}).length;
}
function notifyTestsRan(module, skipped) {
module.testsRun++; module.testsRun++;
if (!skipped) {
module.unskippedTestsRun++;
}
while (module = module.parentModule) { while (module = module.parentModule) {
module.testsRun++; module.testsRun++;
if (!skipped) {
module.unskippedTestsRun++;
}
} }
} }
@@ -1978,18 +2101,22 @@
}, { }, {
key: "async", key: "async",
value: function async(count) { value: function async(count) {
var test$$1 = this.test, var test$$1 = this.test;
popped = false,
var popped = false,
acceptCallCount = count; acceptCallCount = count;
if (typeof acceptCallCount === "undefined") { if (typeof acceptCallCount === "undefined") {
acceptCallCount = 1; acceptCallCount = 1;
} }
test$$1.usedAsync = true;
var resume = internalStop(test$$1); var resume = internalStop(test$$1);
return function done() { return function done() {
if (config.current !== test$$1) {
throw Error("assert.async callback called after test finished.");
}
if (popped) { if (popped) {
test$$1.pushFailure("Too many calls to the `assert.async` callback", sourceFromStacktrace(2)); test$$1.pushFailure("Too many calls to the `assert.async` callback", sourceFromStacktrace(2));
return; return;
@@ -2027,8 +2154,8 @@
value: function pushResult(resultInfo) { value: function pushResult(resultInfo) {
// Destructure of resultInfo = { result, actual, expected, message, negative } // Destructure of resultInfo = { result, actual, expected, message, negative }
var assert = this, var assert = this;
currentTest = assert instanceof Assert && assert.test || config.current; var currentTest = assert instanceof Assert && assert.test || config.current;
// Backwards compatibility fix. // Backwards compatibility fix.
// Allows the direct use of global exported assertions and QUnit.assert.* // Allows the direct use of global exported assertions and QUnit.assert.*
@@ -2039,12 +2166,6 @@
throw new Error("assertion outside test context, in " + sourceFromStacktrace(2)); throw new Error("assertion outside test context, in " + sourceFromStacktrace(2));
} }
if (currentTest.usedAsync === true && currentTest.semaphore === 0) {
currentTest.pushFailure("Assertion after the final `assert.async` was resolved", sourceFromStacktrace(2));
// Allow this assertion to continue running anyway...
}
if (!(assert instanceof Assert)) { if (!(assert instanceof Assert)) {
assert = currentTest.assert; assert = currentTest.assert;
} }
@@ -2181,8 +2302,9 @@
key: "throws", key: "throws",
value: function throws(block, expected, message) { value: function throws(block, expected, message) {
var actual = void 0, var actual = void 0,
result = false, result = false;
currentTest = this instanceof Assert && this.test || config.current;
var currentTest = this instanceof Assert && this.test || config.current;
// 'expected' is optional unless doing string comparison // 'expected' is optional unless doing string comparison
if (objectType(expected) === "string") { if (objectType(expected) === "string") {
@@ -2306,6 +2428,11 @@
}); });
QUnit.config.autostart = false; QUnit.config.autostart = false;
} }
// For Web/Service Workers
if (self$1 && self$1.WorkerGlobalScope && self$1 instanceof self$1.WorkerGlobalScope) {
self$1.QUnit = QUnit;
}
} }
var SuiteReport = function () { var SuiteReport = function () {
@@ -2386,8 +2513,11 @@
var counts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { passed: 0, failed: 0, skipped: 0, todo: 0, total: 0 }; var counts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : { passed: 0, failed: 0, skipped: 0, todo: 0, total: 0 };
counts = this.tests.reduce(function (counts, test) { counts = this.tests.reduce(function (counts, test) {
counts[test.getStatus()]++; if (test.valid) {
counts.total++; counts[test.getStatus()]++;
counts.total++;
}
return counts; return counts;
}, counts); }, counts);
@@ -2451,27 +2581,49 @@
// it since each module has a suiteReport associated with it. // it since each module has a suiteReport associated with it.
config.currentModule.suiteReport = globalSuite; config.currentModule.suiteReport = globalSuite;
var moduleStack = [];
var globalStartCalled = false; var globalStartCalled = false;
var runStarted = false; var runStarted = false;
var internalState = {
autorun: false
};
// Figure out if we're running the tests from a server or not // Figure out if we're running the tests from a server or not
QUnit.isLocal = !(defined.document && window.location.protocol !== "file:"); QUnit.isLocal = !(defined.document && window.location.protocol !== "file:");
// Expose the current QUnit version // Expose the current QUnit version
QUnit.version = "2.2.0"; QUnit.version = "2.3.3";
function createModule(name, testEnvironment) {
var parentModule = moduleStack.length ? moduleStack.slice(-1)[0] : null;
var moduleName = parentModule !== null ? [parentModule.name, name].join(" > ") : name;
var parentSuite = parentModule ? parentModule.suiteReport : globalSuite;
var module = {
name: moduleName,
parentModule: parentModule,
tests: [],
moduleId: generateHash(moduleName),
testsRun: 0,
unskippedTestsRun: 0,
childModules: [],
suiteReport: new SuiteReport(name, parentSuite)
};
var env = {};
if (parentModule) {
parentModule.childModules.push(module);
extend(env, parentModule.testEnvironment);
}
extend(env, testEnvironment);
module.testEnvironment = env;
config.modules.push(module);
return module;
}
extend(QUnit, { extend(QUnit, {
on: on, on: on,
// Call on start of module test to prepend name to all tests // Call on start of module test to prepend name to all tests
module: function module(name, testEnvironment, executeNow) { module: function module(name, testEnvironment, executeNow) {
var module, moduleFns;
var currentModule = config.currentModule;
if (arguments.length === 2) { if (arguments.length === 2) {
if (objectType(testEnvironment) === "function") { if (objectType(testEnvironment) === "function") {
executeNow = testEnvironment; executeNow = testEnvironment;
@@ -2479,57 +2631,40 @@
} }
} }
module = createModule(); var module = createModule(name, testEnvironment);
moduleFns = { // Move any hooks to a 'hooks' object
if (module.testEnvironment) {
module.hooks = {
before: module.testEnvironment.before,
beforeEach: module.testEnvironment.beforeEach,
afterEach: module.testEnvironment.afterEach,
after: module.testEnvironment.after
};
delete module.testEnvironment.before;
delete module.testEnvironment.beforeEach;
delete module.testEnvironment.afterEach;
delete module.testEnvironment.after;
}
var moduleFns = {
before: setHook(module, "before"), before: setHook(module, "before"),
beforeEach: setHook(module, "beforeEach"), beforeEach: setHook(module, "beforeEach"),
afterEach: setHook(module, "afterEach"), afterEach: setHook(module, "afterEach"),
after: setHook(module, "after") after: setHook(module, "after")
}; };
var currentModule = config.currentModule;
if (objectType(executeNow) === "function") { if (objectType(executeNow) === "function") {
config.moduleStack.push(module); moduleStack.push(module);
setCurrentModule(module); config.currentModule = module;
executeNow.call(module.testEnvironment, moduleFns); executeNow.call(module.testEnvironment, moduleFns);
config.moduleStack.pop(); moduleStack.pop();
module = module.parentModule || currentModule; module = module.parentModule || currentModule;
} }
setCurrentModule(module); config.currentModule = module;
function createModule() {
var parentModule = config.moduleStack.length ? config.moduleStack.slice(-1)[0] : null;
var moduleName = parentModule !== null ? [parentModule.name, name].join(" > ") : name;
var parentSuite = parentModule ? parentModule.suiteReport : globalSuite;
var module = {
name: moduleName,
parentModule: parentModule,
tests: [],
moduleId: generateHash(moduleName),
testsRun: 0,
childModules: [],
suiteReport: new SuiteReport(name, parentSuite)
};
var env = {};
if (parentModule) {
parentModule.childModules.push(module);
extend(env, parentModule.testEnvironment);
delete env.beforeEach;
delete env.afterEach;
}
extend(env, testEnvironment);
module.testEnvironment = env;
config.modules.push(module);
return module;
}
function setCurrentModule(module) {
config.currentModule = module;
}
}, },
test: test, test: test,
@@ -2664,73 +2799,16 @@
} }
config.blocking = false; config.blocking = false;
process(true); ProcessingQueue.advance();
}
function process(last) {
function next() {
process(last);
}
var start = now();
config.depth = (config.depth || 0) + 1;
while (config.queue.length && !config.blocking) {
if (!defined.setTimeout || config.updateRate <= 0 || now() - start < config.updateRate) {
if (config.current) {
// Reset async tracking for each phase of the Test lifecycle
config.current.usedAsync = false;
}
config.queue.shift()();
} else {
setTimeout(next, 13);
break;
}
}
config.depth--;
if (last && !config.blocking && !config.queue.length && config.depth === 0) {
done();
}
}
function done() {
var runtime,
passed,
i,
key,
storage = config.storage;
internalState.autorun = true;
runtime = now() - config.started;
passed = config.stats.all - config.stats.bad;
emit("runEnd", globalSuite.end(true));
runLoggingCallbacks("done", {
failed: config.stats.bad,
passed: passed,
total: config.stats.all,
runtime: runtime
});
// Clear own storage items if all tests passed
if (storage && config.stats.bad === 0) {
for (i = storage.length - 1; i >= 0; i--) {
key = storage.key(i);
if (key.indexOf("qunit-test-") === 0) {
storage.removeItem(key);
}
}
}
} }
function setHook(module, hookName) { function setHook(module, hookName) {
if (module.testEnvironment === undefined) { if (!module.hooks) {
module.testEnvironment = {}; module.hooks = {};
} }
return function (callback) { return function (callback) {
module.testEnvironment[hookName] = callback; module.hooks[hookName] = callback;
}; };
} }
@@ -3588,13 +3666,19 @@
message += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText(actual) + "</pre></td></tr>"; message += "<tr class='test-actual'><th>Result: </th><td><pre>" + escapeText(actual) + "</pre></td></tr>";
// Don't show diff if actual or expected are booleans if (typeof details.actual === "number" && typeof details.expected === "number") {
if (!/^(true|false)$/.test(actual) && !/^(true|false)$/.test(expected)) { if (!isNaN(details.actual) && !isNaN(details.expected)) {
showDiff = true;
diff = details.actual - details.expected;
diff = (diff > 0 ? "+" : "") + diff;
}
} else if (typeof details.actual !== "boolean" && typeof details.expected !== "boolean") {
diff = QUnit.diff(expected, actual); diff = QUnit.diff(expected, actual);
// don't show diff if there is zero overlap
showDiff = stripHtml(diff).length !== stripHtml(expected).length + stripHtml(actual).length; showDiff = stripHtml(diff).length !== stripHtml(expected).length + stripHtml(actual).length;
} }
// Don't show diff if expected and actual are totally different
if (showDiff) { if (showDiff) {
message += "<tr class='test-diff'><th>Diff: </th><td><pre>" + diff + "</pre></td></tr>"; message += "<tr class='test-diff'><th>Diff: </th><td><pre>" + diff + "</pre></td></tr>";
} }
@@ -3691,6 +3775,7 @@
var todoLabel = document$$1.createElement("em"); var todoLabel = document$$1.createElement("em");
todoLabel.className = "qunit-todo-label"; todoLabel.className = "qunit-todo-label";
todoLabel.innerHTML = "todo"; todoLabel.innerHTML = "todo";
testItem.className += " todo";
testItem.insertBefore(todoLabel, testTitle); testItem.insertBefore(todoLabel, testTitle);
} }