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:
4
js/tests/vendor/qunit.css
vendored
4
js/tests/vendor/qunit.css
vendored
@@ -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 */
|
||||||
|
563
js/tests/vendor/qunit.js
vendored
563
js/tests/vendor/qunit.js
vendored
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user