| Index: third_party/WebKit/LayoutTests/webaudio/resources/audio-testing.js
|
| diff --git a/third_party/WebKit/LayoutTests/webaudio/resources/audio-testing.js b/third_party/WebKit/LayoutTests/webaudio/resources/audio-testing.js
|
| deleted file mode 100644
|
| index 41c7edc8574878019c26a4d3871c33de8c1b330c..0000000000000000000000000000000000000000
|
| --- a/third_party/WebKit/LayoutTests/webaudio/resources/audio-testing.js
|
| +++ /dev/null
|
| @@ -1,921 +0,0 @@
|
| -/* global self */
|
| -
|
| -// testharness.js has the higher priority.
|
| -var TESTHARNESS = true;
|
| -var JSTEST = false;
|
| -
|
| -(function () {
|
| - // Selected properies from testharness.js
|
| - var testharnessProperties = [
|
| - 'test', 'async_test', 'promise_test', 'promise_rejects',
|
| - 'generate_tests', 'setup', 'done', 'assert_true', 'assert_false'
|
| - ];
|
| -
|
| - // Selected properties from js-test.js
|
| - var jsTestProperties = [
|
| - 'isJsTest', 'testPassed', 'testFailed', 'gc', 'finishJSTest'
|
| - ];
|
| -
|
| - // Check if testharness.js is properly loaded and set up a flag for it.
|
| - for (var name in testharnessProperties) {
|
| - if (!self.hasOwnProperty(testharnessProperties[name])) {
|
| - TESTHARNESS = false;
|
| - break;
|
| - }
|
| - }
|
| -
|
| - // Immediately return here because testharness.js is ready.
|
| - if (TESTHARNESS)
|
| - return;
|
| -
|
| - // Because testharness.js is not loaded, let us assume that js-test.js might
|
| - // be in use. Check if js-test.js is properly loaded and set up a flag for
|
| - // it.
|
| - JSTEST = true;
|
| - for (var name in jsTestProperties) {
|
| - if (!self.hasOwnProperty(jsTestProperties[name])) {
|
| - JSTEST = false;
|
| - break;
|
| - }
|
| - }
|
| -
|
| - // If both are not loaded at all, throw here.
|
| - if (!JSTEST)
|
| - throw new Error('Cannot proceed. No test infrastructure is loaded.');
|
| -})();
|
| -
|
| -
|
| -// |Audit| is a task runner for web audio test. It makes asynchronous web audio
|
| -// testing simple and manageable.
|
| -//
|
| -// EXAMPLE:
|
| -//
|
| -// var audit = Audit.createTaskRunner();
|
| -// // Define test routine. Make sure to call done() when reached at the end.
|
| -// audit.defineTask('foo', function (done) {
|
| -// var context = new AudioContext();
|
| -// // do things
|
| -// context.oncomplete = function () {
|
| -// // verification here
|
| -// done();
|
| -// };
|
| -// });
|
| -//
|
| -// audit.defineTask('bar', function (done) {
|
| -// // your code here
|
| -// done();
|
| -// });
|
| -//
|
| -// // Queue tasks by readable task names.
|
| -// audit.runTasks('foo', 'bar');
|
| -//
|
| -// // Alternatively, if you want to run all of the defined tasks in the order in which they were
|
| -// // defined, use no arguments:
|
| -// audit.runTasks();
|
| - var Audit = (function () {
|
| -
|
| - 'use strict';
|
| -
|
| - function Tasks() {
|
| - this.tasks = {};
|
| - this.queue = [];
|
| - this.currentTask = 0;
|
| - }
|
| -
|
| - // This is to prime the task runner for the testharness.js async operation.
|
| - Tasks.prototype._initialize = function () {
|
| - if (TESTHARNESS) {
|
| - setup(new Function(), {
|
| - explicit_done: true
|
| - });
|
| - }
|
| - };
|
| -
|
| - // Finalize the task runner by notifying testharness and testRunner that
|
| - // all the task is completed.
|
| - Tasks.prototype._finalize = function () {
|
| - if (TESTHARNESS) {
|
| - // From testharness.js
|
| - done();
|
| - }
|
| - };
|
| -
|
| - Tasks.prototype.defineTask = function (taskName, taskFunc) {
|
| - // Check if there is a task defined with the same name. If found, do
|
| - // not add the task to the roster.
|
| - if (this.tasks.hasOwnProperty(taskName)) {
|
| - debug('>> Audit.defineTask:: Duplicate task definition. ("' + taskName + '")');
|
| - return;
|
| - }
|
| -
|
| - this.tasks[taskName] = taskFunc;
|
| -
|
| - // Push the task name in the order of definition.
|
| - this.queue.push(taskName);
|
| - };
|
| -
|
| - // If arguments are given, only run the requested tasks. Check for any
|
| - // undefined or duplicate task in the requested task arguments. If there
|
| - // is no argument, run all the defined tasks.
|
| - Tasks.prototype.runTasks = function () {
|
| -
|
| - this._initialize();
|
| -
|
| - if (arguments.length > 0) {
|
| -
|
| - // Reset task queue and refill it with the with the given arguments,
|
| - // in argument order.
|
| - this.queue = [];
|
| -
|
| - for (var i = 0; i < arguments.length; i++) {
|
| - if (!this.tasks.hasOwnProperty(arguments[i]))
|
| - debug('>> Audit.runTasks:: Ignoring undefined task. ("' + arguments[i] + '")');
|
| - else if (this.queue.indexOf(arguments[i]) > -1)
|
| - debug('>> Audit.runTasks:: Ignoring duplicate task request. ("' + arguments[i] + '")');
|
| - else
|
| - this.queue.push(arguments[i]);
|
| - }
|
| - }
|
| -
|
| - if (this.queue.length === 0) {
|
| - debug('>> Audit.runTasks:: No task to run.');
|
| - return;
|
| - }
|
| -
|
| - // taskDone() callback from each task. Increase the task index and call
|
| - // the next task. Note that explicit signaling by taskDone() in each
|
| - // task is needed because some of tests run asynchronously.
|
| - var taskDone = function () {
|
| - if (this.currentTask !== this.queue.length - 1) {
|
| - ++this.currentTask;
|
| - // debug('>> Audit.runTasks: ' + this.queue[this.currentTask]);
|
| - this.tasks[this.queue[this.currentTask]](taskDone);
|
| - } else {
|
| - this._finalize();
|
| - }
|
| - return;
|
| - }.bind(this);
|
| -
|
| - // Start the first task.
|
| - // debug('>> Audit.runTasks: ' + this.queue[this.currentTask]);
|
| - this.tasks[this.queue[this.currentTask]](taskDone);
|
| - };
|
| -
|
| - return {
|
| - createTaskRunner: function () {
|
| - return new Tasks();
|
| - }
|
| - };
|
| -
|
| -})();
|
| -
|
| -
|
| -// |Should| JS layout test utility.
|
| -// Dependency: ../resources/js-test.js
|
| -var Should = (function () {
|
| -
|
| - 'use strict';
|
| -
|
| - // ShouldModel internal class. For the exposed (factory) method, it is the
|
| - // return value of this closure.
|
| - function ShouldModel(desc, target, opts) {
|
| - this.desc = desc;
|
| - this.target = target;
|
| -
|
| - // Check if the target contains any NaN value.
|
| - this._checkNaN(this.target, 'ACTUAL');
|
| -
|
| - // |_testPassed| and |_testFailed| set this appropriately.
|
| - this._success = false;
|
| -
|
| - // If the number of errors is greater than this, the rest of error
|
| - // messages are suppressed. the value is fairly arbitrary, but shouldn't
|
| - // be too small or too large.
|
| - this.NUM_ERRORS_LOG = opts.numberOfErrorLog;
|
| -
|
| - // If the number of array elements is greater than this, the rest of
|
| - // elements will be omitted.
|
| - this.NUM_ARRAY_LOG = opts.numberOfArrayLog;
|
| -
|
| - // If true, verbose output for the failure case is printed, for methods where this makes
|
| - // sense.
|
| - this.verbose = !opts.brief;
|
| -
|
| - // If set, this is the precision with which numbers will be printed.
|
| - this.PRINT_PRECISION = opts.precision;
|
| - }
|
| -
|
| - // Internal methods starting with a underscore.
|
| - ShouldModel.prototype._testPassed = function (msg, addNewline) {
|
| - this._success = true;
|
| - var newLine = addNewline ? '\n' : '';
|
| - if (TESTHARNESS) {
|
| - // Using testharness.js
|
| - test(function () {
|
| - assert_true(true);
|
| - }, this.desc + ' ' + msg + '.' + newLine);
|
| - } else {
|
| - // Using js-test.js
|
| - testPassed(this.desc + ' ' + msg + '.' + newLine);
|
| - }
|
| - };
|
| -
|
| - ShouldModel.prototype._testFailed = function (msg, addNewline) {
|
| - this._success = false;
|
| - var that = this;
|
| - var newLine = addNewline ? '\n' : '';
|
| - if (TESTHARNESS) {
|
| - test(function () {
|
| - assert_true(false, that.desc + ' ' + msg + '.' + newLine);
|
| - }, this.desc);
|
| - } else {
|
| - testFailed(this.desc + ' ' + msg + '.' + newLine);
|
| - }
|
| - };
|
| -
|
| - ShouldModel.prototype._isArray = function (arg) {
|
| - return arg instanceof Array || arg instanceof Float32Array || arg instanceof Uint8Array ||
|
| - arg instanceof Uint16Array || arg instanceof Uint32Array || arg instanceof Int8Array ||
|
| - arg instanceof Int16Array || arg instanceof Int32Array || arg instanceof Uint8ClampedArray ||
|
| - arg instanceof Float64Array;
|
| - };
|
| -
|
| - ShouldModel.prototype._assert = function (expression, reason, value) {
|
| - if (expression)
|
| - return;
|
| -
|
| - var failureMessage = 'Assertion failed: ' + reason + ' ' + this.desc +'.';
|
| - if (arguments.length >= 3)
|
| - failureMessage += ": " + value;
|
| -
|
| - if (TESTHARNESS) {
|
| - test(function () {
|
| - assert_true(false, reason + ' (' + value + ')');
|
| - }, this.desc)
|
| - } else {
|
| - testFailed(failureMessage);
|
| - }
|
| -
|
| - throw failureMessage;
|
| - };
|
| -
|
| - // Check the expected value if it is a NaN (Number) or has NaN(s) in
|
| - // its content (Array or Float32Array). Returns a string depends on the
|
| - // result of check.
|
| - ShouldModel.prototype._checkNaN = function (value, label) {
|
| - var failureMessage = 'NaN found in ' + label + ' while testing "' +
|
| - this.desc + '"';
|
| -
|
| - // Checking a single variable first.
|
| - if (Number.isNaN(value)) {
|
| - if (TESTHARNESS) {
|
| - test(function () {
|
| - assert_true(false, failureMessage);
|
| - }, this.desc)
|
| - } else {
|
| - testFailed(failureMessage);
|
| - }
|
| -
|
| - throw failureMessage;
|
| - }
|
| -
|
| - // If the value is not a NaN nor array, we can assume it is safe.
|
| - if (!this._isArray(value))
|
| - return;
|
| -
|
| - // Otherwise, check the array array.
|
| - var indices = [];
|
| - for (var i = 0; i < value.length; i++) {
|
| - if (Number.isNaN(value[i]))
|
| - indices.push(i);
|
| - }
|
| -
|
| - if (indices.length === 0)
|
| - return;
|
| -
|
| - var failureDetail = ' (' + indices.length + ' instances total)\n';
|
| - for (var n = 0; n < indices.length; n++) {
|
| - failureDetail += ' >> [' + indices[n] + '] = NaN\n';
|
| - if (n >= this.NUM_ERRORS_LOG) {
|
| - failureDetail += ' and ' + (indices.length - n) +
|
| - ' more NaNs...';
|
| - break;
|
| - }
|
| - }
|
| -
|
| - if (TESTHARNESS) {
|
| - test(function () {
|
| - assert_true(false, failureMessage + failureDetail);
|
| - }, this.desc)
|
| - } else {
|
| - testFailed(failureMessage + failureDetail);
|
| - }
|
| -
|
| - throw failureMessage;
|
| - };
|
| -
|
| - // Check if |target| exists.
|
| - //
|
| - // Example:
|
| - // Should('Object', {}).exist();
|
| - // Result:
|
| - // "PASS Object exists."
|
| - ShouldModel.prototype.exist = function () {
|
| - if (this.target !== null && this.target !== undefined) {
|
| - this._testPassed('exists');
|
| - } else {
|
| - this._testFailed('does not exist');
|
| - }
|
| -
|
| - return this._success;
|
| - };
|
| -
|
| - // Check if |target| is equal to |value|.
|
| - //
|
| - // Example:
|
| - // Should('Zero', 0).beEqualTo(0);
|
| - // Result:
|
| - // "PASS Zero is equal to 0."
|
| - ShouldModel.prototype.beEqualTo = function (value) {
|
| - if (value != null) {
|
| - var type = typeof value;
|
| - this._assert(type === 'number' || type === 'string' || type === 'boolean',
|
| - 'value should be number, string, or boolean for', value);
|
| - }
|
| -
|
| - this._checkNaN(value, 'EXPECTED');
|
| -
|
| - var outputValue = value;
|
| - if (type === 'string')
|
| - outputValue = '"' + outputValue + '"';
|
| - if (this.target === value) {
|
| - var outputValue = (type === 'string') ? '"' + value + '"' : value;
|
| - this._testPassed('is equal to ' + outputValue);
|
| - } else {
|
| - var targetValue = this.target;
|
| - if (typeof this.target === 'string')
|
| - targetValue = '"' + targetValue + '"';
|
| - this._testFailed('was ' + targetValue + ' instead of ' + outputValue);
|
| - }
|
| - return this._success;
|
| - };
|
| -
|
| - // Check if |target| is not equal to |value|.
|
| - //
|
| - // Example:
|
| - // Should('One', one).notBeEqualTo(0);
|
| - // Result:
|
| - // "PASS One is not equal to 0."
|
| - ShouldModel.prototype.notBeEqualTo = function (value) {
|
| - var type = typeof value;
|
| - this._assert(type === 'number' || type === 'string' || type === "boolean",
|
| - 'value should be number, string, or boolean for', value);
|
| -
|
| - this._checkNaN(value, 'EXPECTED');
|
| -
|
| - if (this.target === value)
|
| - this._testFailed('should not be equal to ' + value);
|
| - else
|
| - this._testPassed('is not equal to ' + value);
|
| - return this._success;
|
| - };
|
| -
|
| - // Check if |target| is greater than or equal to |value|.
|
| - //
|
| - // Example:
|
| - // Should("SNR", snr).beGreaterThanOrEqualTo(100);
|
| - // Result:
|
| - // "PASS SNR exceeds 100"
|
| - // "FAIL SNR (n) is not greater than or equal to 100"
|
| - ShouldModel.prototype.beGreaterThanOrEqualTo = function (value) {
|
| - var type = typeof value;
|
| - this._assert(type === 'number' || type === 'string',
|
| - 'value should be number or string for', value);
|
| -
|
| - this._checkNaN(value, 'EXPECTED');
|
| -
|
| - var prefix = '(' + this.target + ') ';
|
| -
|
| - if (this.target >= value) {
|
| - if (!this.verbose)
|
| - prefix = '';
|
| - this._testPassed(prefix + "is greater than or equal to " + value);
|
| - } else {
|
| - this._testFailed(prefix + "is not greater than or equal to " + value);
|
| - }
|
| - return this._success;
|
| - }
|
| -
|
| - // Check if |target| is greater than |value|.
|
| - //
|
| - // Example:
|
| - // Should("SNR", snr).beGreaterThan(100);
|
| - // Result:
|
| - // "PASS SNR is greater than 100"
|
| - // "FAIL SNR (n) is not greater than 100"
|
| - ShouldModel.prototype.beGreaterThan = function (value) {
|
| - var type = typeof value;
|
| - this._assert(type === 'number' || type === 'string',
|
| - 'value should be number or string for', value);
|
| -
|
| - this._checkNaN(value, 'EXPECTED');
|
| -
|
| - if (this.target > value)
|
| - this._testPassed("is greater than " + value);
|
| - else
|
| - this._testFailed("(" + this.target + ") is not greater than " + value);
|
| - return this._success;
|
| - }
|
| -
|
| - // Check if |target| is lest than or equal to |value|.
|
| - //
|
| - // Example:
|
| - // maxError = 1e-6;
|
| - // Should("max error", maxError).beLessThanOrEqualTo(1e-5);
|
| - // Should("max error", maxError).beLessThanOrEqualTo(-1);
|
| - // Result:
|
| - // "PASS max error is less than or equal to 1e-5"
|
| - // "FAIL max error (1e-6) is not less than or equal to -1"
|
| - ShouldModel.prototype.beLessThanOrEqualTo = function (value) {
|
| - var type = typeof value;
|
| - this._assert(type === 'number', 'value should be number or string for', value);
|
| -
|
| - this._checkNaN(value, 'EXPECTED');
|
| -
|
| - var prefix = '(' + this.target + ') ';
|
| -
|
| - if (this.target <= value) {
|
| - if (!this.verbose)
|
| - prefix = '';
|
| - this._testPassed(prefix + "is less than or equal to " + value);
|
| - } else {
|
| - this._testFailed(prefix + "is not less than or equal to " + value);
|
| - }
|
| - return this._success;
|
| - }
|
| -
|
| - // Check if |target| is close to |value| using the given relative error |threshold|. |value|
|
| - // should not be zero, but no check is made for that. The |target| value is printed to
|
| - // precision |precision|, with |precision| defaulting to 7.
|
| - //
|
| - // If |value| is 0, however, |threshold| is treated as an absolute threshold.
|
| - //
|
| - // Example:
|
| - // Should("One", 1.001).beCloseTo(1, .1);
|
| - // Should("One", 2).beCloseTo(1, .1);
|
| - // Result:
|
| - // "PASS One is 1 within a relative error of 0.1."
|
| - // "FAIL One is not 1 within a relative error of 0.1: 2"
|
| - ShouldModel.prototype.beCloseTo = function (value, errorThreshold) {
|
| - var type = typeof value;
|
| - this._assert(type === 'number', 'value should be number for', value);
|
| -
|
| - this._checkNaN(value, 'EXPECTED');
|
| -
|
| - if (value) {
|
| - var relativeError = Math.abs(this.target - value) / Math.abs(value);
|
| - if (relativeError <= errorThreshold) {
|
| - this._testPassed("is " + value.toPrecision(this.PRINT_PRECISION) +
|
| - " within a relative error of " + errorThreshold);
|
| - } else {
|
| - // Include actual relative error so the failed test case can be updated with the actual
|
| - // relative error, if appropriate.
|
| - this._testFailed("is not " + value.toPrecision(this.PRINT_PRECISION) +
|
| - " within a relative error of " + errorThreshold +
|
| - ": " + this.target + " with relative error " + relativeError
|
| - );
|
| - }
|
| - } else {
|
| - var absoluteError = Math.abs(this.target - value);
|
| - if (absoluteError <= errorThreshold) {
|
| - this._testPassed("is " + value.toPrecision(this.PRINT_PRECISION) +
|
| - " within an absolute error of " + errorThreshold);
|
| - } else {
|
| - // Include actual absolute error so the failed test case can be updated with the
|
| - // actual error, if appropriate.
|
| - this._testFailed("is not " + value.toPrecision(this.PRINT_PRECISION) +
|
| - " within an absolute error of " + errorThreshold +
|
| - ": " + this.target + " with absolute error " + absoluteError
|
| - );
|
| - }
|
| - }
|
| - return this._success;
|
| - }
|
| -
|
| - // Check if |func| throws an exception with a certain |errorType| correctly.
|
| - // |errorType| is optional.
|
| - //
|
| - // Example:
|
| - // Should('A bad code', function () { var a = b; }).throw();
|
| - // Result:
|
| - // "PASS A bad code threw an exception."
|
| - // Example:
|
| - // Should('var c = d', function () { var c = d; }).throw('ReferenceError');
|
| - // "PASS var c = d threw ReferenceError."
|
| - ShouldModel.prototype.throw = function (errorType) {
|
| - if (typeof this.target !== 'function') {
|
| - console.log('target is not a function. test halted.');
|
| - return;
|
| - }
|
| -
|
| - try {
|
| - this.target();
|
| - this._testFailed('did not throw an exception');
|
| - } catch (error) {
|
| - if (errorType === undefined)
|
| - this._testPassed('threw an exception of type ' + error.name);
|
| - else if (error.name === errorType)
|
| - this._testPassed('threw ' + errorType + ': ' + error.message);
|
| - else if (self.hasOwnProperty(errorType) && error instanceof self[errorType])
|
| - this._testPassed('threw ' + errorType + ': ' + error.message);
|
| - else
|
| - this._testFailed('threw ' + error.name + ' instead of ' + errorType);
|
| - }
|
| - return this._success;
|
| - };
|
| -
|
| - // Check if |func| does not throw an exception.
|
| - //
|
| - // Example:
|
| - // Should('var foo = "bar"', function () { var foo = 'bar'; }).notThrow();
|
| - // Result:
|
| - // "PASS var foo = "bar" did not throw an exception."
|
| - ShouldModel.prototype.notThrow = function () {
|
| - try {
|
| - this.target();
|
| - this._testPassed('did not throw an exception');
|
| - } catch (error) {
|
| - this._testFailed('threw ' + error.name + ': ' + error.message);
|
| - }
|
| - return this._success;
|
| - };
|
| -
|
| - // Check if |target| array is filled with constant values.
|
| - //
|
| - // Example:
|
| - // Should('[2, 2, 2]', [2, 2, 2]).beConstantValueOf(2);
|
| - // Result:
|
| - // "PASS [2, 2, 2] has constant values of 2."
|
| - ShouldModel.prototype.beConstantValueOf = function (value) {
|
| - this._checkNaN(value, 'EXPECTED');
|
| -
|
| - var mismatches = {};
|
| - for (var i = 0; i < this.target.length; i++) {
|
| - if (this.target[i] !== value)
|
| - mismatches[i] = this.target[i];
|
| - }
|
| -
|
| - var numberOfmismatches = Object.keys(mismatches).length;
|
| -
|
| - if (numberOfmismatches === 0) {
|
| - this._testPassed('contains only the constant ' + value);
|
| - } else {
|
| - var counter = 0;
|
| - var failureMessage = 'contains ' + numberOfmismatches +
|
| - ' values that are NOT equal to ' + value + ':';
|
| - for (var index in mismatches) {
|
| - failureMessage += '\n[' + index + '] : ' + mismatches[index];
|
| - if (++counter >= this.NUM_ERRORS_LOG) {
|
| - failureMessage += '\nand ' + (numberOfmismatches - counter) +
|
| - ' more differences...';
|
| - break;
|
| - }
|
| - }
|
| - this._testFailed(failureMessage);
|
| - }
|
| - return this._success;
|
| - };
|
| -
|
| - // Check if |target| array is identical to |expected| array element-wise.
|
| - //
|
| - // Example:
|
| - // Should('[1, 2, 3]', [1, 2, 3]).beEqualToArray([1, 2, 3]);
|
| - // Result:
|
| - // "PASS [1, 2, 3] is identical to the array [1,2,3]."
|
| - ShouldModel.prototype.beEqualToArray = function (array) {
|
| - this._assert(this._isArray(array) && this.target.length === array.length,
|
| - 'Invalid array or the length does not match.', array);
|
| -
|
| - this._checkNaN(array, 'EXPECTED');
|
| -
|
| - var mismatches = {};
|
| - for (var i = 0; i < this.target.length; i++) {
|
| - if (this.target[i] !== array[i])
|
| - mismatches[i] = this.target[i];
|
| - }
|
| -
|
| - var numberOfmismatches = Object.keys(mismatches).length;
|
| - var arrSlice = array.slice(0, this.NUM_ARRAY_LOG);
|
| - var arrStr = arrSlice[0].toPrecision(this.PRINT_PRECISION);
|
| - for (var k = 1; k < arrSlice.length; ++k)
|
| - arrStr += ',' + arrSlice[k].toPrecision(this.PRINT_PRECISION);
|
| - if (array.length > this.NUM_ARRAY_LOG)
|
| - arrStr += ',...';
|
| -
|
| - if (numberOfmismatches === 0) {
|
| - this._testPassed('is identical to the array [' + arrStr + ']');
|
| - } else {
|
| - var counter = 0;
|
| - var failureMessage = 'is not equal to the array [' + arrStr + ']';
|
| - if (this.verbose)
|
| - failureMessage += '\nindex\tActual\t\tExpected';
|
| - for (var index in mismatches) {
|
| - failureMessage += '\n[' + index + '] : ' + mismatches[index];
|
| - if (this.verbose)
|
| - failureMessage += '\t' + array[index];
|
| - if (++counter >= this.NUM_ERRORS_LOG) {
|
| - failureMessage += '\nand ' + (numberOfmismatches - counter) +
|
| - ' more differences...';
|
| - break;
|
| - }
|
| - }
|
| -
|
| - this._testFailed(failureMessage);
|
| - }
|
| - return this._success;
|
| - };
|
| -
|
| - // Check if |target| array is close to |expected| array element-wise within
|
| - // an certain error bound given by |absoluteThresholdOrOptions|.
|
| - //
|
| - // The error criterion is:
|
| - //
|
| - // Math.abs(target[k] - expected[k]) < Math.max(abserr, relerr * Math.abs(expected))
|
| - //
|
| - // If |absoluteThresholdOrOptions| is a number, t, then abserr = t and relerr = 0. That is the
|
| - // max difference is bounded by t.
|
| - //
|
| - // If |absoluteThresholdOrOptions| is a property bag, then abserr is the value of the
|
| - // absoluteThreshold property and relerr is the value of the relativeThreshold property. If
|
| - // nothing is given, then abserr = relerr = 0. If abserr = 0, then the error criterion is a
|
| - // relative error. A non-zero abserr value produces a mix intended to handle the case where the
|
| - // expected value is 0, allowing the target value to differ by abserr from the expected.
|
| - //
|
| - // Example:
|
| - // Should('My array', [0.11, 0.19]).beCloseToArray([0.1, 0.2], 0.02);
|
| - // Result:
|
| - // "PASS My array equals [0.1,0.2] within an element-wise tolerance of 0.02."
|
| - ShouldModel.prototype.beCloseToArray = function (expected, absoluteThresholdOrOptions) {
|
| - // For the comparison, the target length must be bigger than the expected.
|
| - this._assert(this.target.length >= expected.length,
|
| - 'The target array length must be longer than ' + expected.length +
|
| - ' but got ' + this.target.length + '.');
|
| -
|
| - this._checkNaN(expected, 'EXPECTED');
|
| -
|
| - var absoluteErrorThreshold = 0;
|
| - var relativeErrorThreshold = 0;
|
| -
|
| - // A collection of all of the values that satisfy the error criterion. This holds the
|
| - // absolute difference between the target element and the expected element.
|
| - var mismatches = {};
|
| -
|
| - // Keep track of the max absolute error found
|
| - var maxAbsError = -Infinity;
|
| - var maxAbsErrorIndex = -1;
|
| - // Keep trac of the max relative error found, ignoring cases where the relative error is
|
| - // Infinity because the expected value is 0.
|
| - var maxRelError = -Infinity;
|
| - var maxRelErrorIndex = -1;
|
| -
|
| - // A number or string for printing out the actual thresholds used for the error criterion.
|
| - var maxAllowedError;
|
| -
|
| - // Set up the thresholds based on |absoluteThresholdOrOptions|.
|
| - if (typeof(absoluteThresholdOrOptions) === 'number') {
|
| - absoluteErrorThreshold = absoluteThresholdOrOptions;
|
| - maxAllowedError = absoluteErrorThreshold;
|
| - } else {
|
| - var opts = absoluteThresholdOrOptions;
|
| - if (opts.hasOwnProperty('absoluteThreshold'))
|
| - absoluteErrorThreshold = opts.absoluteThreshold;
|
| - if (opts.hasOwnProperty('relativeThreshold'))
|
| - relativeErrorThreshold = opts.relativeThreshold;
|
| - maxAllowedError = '{absoluteThreshold: ' + absoluteErrorThreshold
|
| - + ', relativeThreshold: ' + relativeErrorThreshold
|
| - + '}';
|
| - }
|
| -
|
| - for (var i = 0; i < expected.length; i++) {
|
| - var diff = Math.abs(this.target[i] - expected[i]);
|
| - if (diff > Math.max(absoluteErrorThreshold, relativeErrorThreshold * Math.abs(expected[i]))) {
|
| - mismatches[i] = diff;
|
| - // Keep track of the location of the absolute max difference.
|
| - if (diff > maxAbsError) {
|
| - maxAbsErrorIndex = i;
|
| - maxAbsError = diff;
|
| - }
|
| - // Keep track of the location of the max relative error, ignoring cases where the
|
| - // relative error is NaN.
|
| - var relError = diff / Math.abs(expected[i]);
|
| - if (!isNaN(relError) && relError > maxRelError) {
|
| - maxRelErrorIndex = i;
|
| - maxRelError = relError;
|
| - }
|
| - }
|
| - }
|
| -
|
| - var numberOfmismatches = Object.keys(mismatches).length;
|
| - var arrSlice = expected.slice(0, Math.min(expected.length, this.NUM_ARRAY_LOG));
|
| - var arrStr;
|
| -
|
| - arrStr = arrSlice[0].toPrecision(this.PRINT_PRECISION);
|
| - for (var k = 1; k < arrSlice.length; ++k)
|
| - arrStr += ',' + arrSlice[k].toPrecision(this.PRINT_PRECISION);
|
| -
|
| - if (expected.length > this.NUM_ARRAY_LOG)
|
| - arrStr += ',...';
|
| - if (numberOfmismatches === 0) {
|
| - this._testPassed('equals [' + arrStr +
|
| - '] with an element-wise tolerance of ' + maxAllowedError);
|
| - } else {
|
| - var counter = 0;
|
| - var failureMessage = 'does not equal [' + arrStr +
|
| - '] with an element-wise tolerance of ' + maxAllowedError;
|
| -
|
| - // Print a nice header for the table to follow.
|
| - if (this.verbose)
|
| - failureMessage += "\nIndex Actual Expected Diff Relative";
|
| - else
|
| - failureMessage += "\nDifference between expected and actual:";
|
| -
|
| - for (var index in mismatches) {
|
| - failureMessage += '\n[' + index + ']: ';
|
| - if (this.verbose) {
|
| - // When verbose, print out actual, expected, absolute error, and relative error.
|
| - // TODO: print these out in nice columns to make it easier to read.
|
| - var relError = Math.abs(this.target[index] - expected[index]) / Math.abs(expected[index]);
|
| - failureMessage += this.target[index].toExponential(16) + ' '
|
| - + expected[index].toExponential(16) + ' '
|
| - + mismatches[index].toExponential(16) + ' '
|
| - + relError.toExponential(16) + ' '
|
| - + Math.max(absoluteErrorThreshold,
|
| - relativeErrorThreshold * Math.abs(expected[index]));
|
| - } else {
|
| - // Otherwise, just the print the absolute error.
|
| - failureMessage += mismatches[index];
|
| - }
|
| - if (++counter >= this.NUM_ERRORS_LOG) {
|
| - failureMessage += '\nand ' + (numberOfmismatches - counter) +
|
| - ' more differences, with max absolute error';
|
| - if (this.verbose) {
|
| - // When verbose, print out the location of both the max absolute error and
|
| - // the max relative error so we can adjust thresholds appropriately in the
|
| - // test.
|
| - var relError = Math.abs(this.target[maxAbsErrorIndex] - expected[maxAbsErrorIndex])
|
| - / Math.abs(expected[maxAbsErrorIndex]);
|
| - failureMessage += ' at index ' + maxAbsErrorIndex + ':';
|
| - failureMessage += '\n[' + maxAbsErrorIndex + ']: ';
|
| - failureMessage += this.target[maxAbsErrorIndex].toExponential(16) + ' '
|
| - + expected[maxAbsErrorIndex].toExponential(16) + ' '
|
| - + mismatches[maxAbsErrorIndex].toExponential(16) + ' '
|
| - + relError.toExponential(16) + ' '
|
| - + Math.max(absoluteErrorThreshold,
|
| - relativeErrorThreshold * Math.abs(expected[maxAbsErrorIndex]));
|
| - failureMessage += '\nand max relative error';
|
| - failureMessage += ' at index ' + maxRelErrorIndex + ':';
|
| - failureMessage += '\n[' + maxRelErrorIndex + ']: ';
|
| - failureMessage += this.target[maxRelErrorIndex].toExponential(16) + ' '
|
| - + expected[maxRelErrorIndex].toExponential(16) + ' '
|
| - + mismatches[maxRelErrorIndex].toExponential(16) + ' '
|
| - + maxRelError.toExponential(16) + ' '
|
| - + Math.max(absoluteErrorThreshold,
|
| - relativeErrorThreshold * Math.abs(expected[maxRelErrorIndex]));
|
| - } else {
|
| - // Not verbose, so just print out the max absolute error
|
| - failureMessage += ' of ' + maxAbsError + ' at index ' + maxAbsErrorIndex;
|
| - }
|
| - break;
|
| - }
|
| - }
|
| -
|
| - this._testFailed(failureMessage);
|
| - }
|
| - return this._success;
|
| - };
|
| -
|
| - // Check if |target| array contains a set of values in a certain order.
|
| - //
|
| - // Example:
|
| - // Should('My random array', [1, 1, 3, 3, 2]).containValues([1, 3, 2]);
|
| - // Result:
|
| - // "PASS My random array contains all the expected values in the correct
|
| - // order: [1,3,2]."
|
| - ShouldModel.prototype.containValues = function (expected) {
|
| - this._checkNaN(expected, 'EXPECTED');
|
| -
|
| - var indexExpected = 0, indexActual = 0;
|
| - while (indexExpected < expected.length && indexActual < this.target.length) {
|
| - if (expected[indexExpected] === this.target[indexActual])
|
| - indexActual++;
|
| - else
|
| - indexExpected++;
|
| - }
|
| -
|
| - if (indexExpected < expected.length-1 || indexActual < this.target.length-1) {
|
| - this._testFailed('contains an unexpected value ' + this.target[indexActual] +
|
| - ' at index ' + indexActual);
|
| - } else {
|
| - this._testPassed('contains all the expected values in the correct order: [' +
|
| - expected + ']');
|
| - }
|
| - return this._success;
|
| - };
|
| -
|
| - // Check if |target| array does not have any glitches. Note that |threshold|
|
| - // is not optional and is to define the desired threshold value.
|
| - //
|
| - // Example:
|
| - // Should('Channel #0', chanL).notGlitch(0.0005);
|
| - // Result:
|
| - // "PASS Channel #0 has no glitch above the threshold of 0.0005."
|
| - ShouldModel.prototype.notGlitch = function (threshold) {
|
| - this._checkNaN(threshold, 'EXPECTED');
|
| -
|
| - for (var i = 1; i < this.target.length; i++) {
|
| - var diff = Math.abs(this.target[i-1] - this.target[i]);
|
| - if (diff >= threshold) {
|
| - this._testFailed('has a glitch at index ' + i + ' of size ' + diff);
|
| - return this._success;
|
| - }
|
| - }
|
| - this._testPassed('has no glitch above the threshold of ' + threshold);
|
| - return this._success;
|
| - };
|
| -
|
| - // Check if the target promise is resolved correctly.
|
| - //
|
| - // Example:
|
| - // Should('My promise', promise).beResolved().then(nextStuff);
|
| - // Result:
|
| - // "PASS My promise resolved correctly."
|
| - // "FAIL My promise rejected incorrectly (with _ERROR_)."
|
| - ShouldModel.prototype.beResolved = function () {
|
| - return this.target.then(function () {
|
| - this._testPassed('resolved correctly');
|
| - }.bind(this), function (err) {
|
| - this._testFailed('rejected incorrectly (with ' + err + ')');
|
| - }.bind(this));
|
| - };
|
| -
|
| - // Check if the target promise is rejected correctly.
|
| - //
|
| - // Example:
|
| - // Should('My promise', promise).beRejected().then(nextStuff);
|
| - // Result:
|
| - // "PASS My promise rejected correctly (with _ERROR_)."
|
| - // "FAIL My promise resolved incorrectly."
|
| - ShouldModel.prototype.beRejected = function () {
|
| - return this.target.then(function () {
|
| - this._testFailed('resolved incorrectly');
|
| - }.bind(this), function (err) {
|
| - this._testPassed('rejected correctly (with ' + err + ')');
|
| - }.bind(this));
|
| - };
|
| -
|
| - // A summary message
|
| - //
|
| - // Example:
|
| - // Should("Summary1", true).summarize("passed1", "failed1");
|
| - // Should("Summary2", false).summarize("passed2", "failed2");
|
| - // Result:
|
| - // "PASS Summary1: passed1."
|
| - // "FAIL Summary2: failed2."
|
| - ShouldModel.prototype.summarize = function (pass, fail) {
|
| - // It's really nice to have blank lines after the summary, but
|
| - // testharness thinks the whole testsuite fails if we do that.
|
| - if (this.target)
|
| - this._testPassed(pass, false);
|
| - else
|
| - this._testFailed(fail, false);
|
| - return this._success;
|
| - }
|
| -
|
| - // Should() method.
|
| - //
|
| - // |desc| is the description of the task or check and |target| is a value
|
| - // needs to be checked or a task to be performed. |opt| contains options for
|
| - // printing out log messages: options are |opt.numberOfErrorLog| and
|
| - // |opts.numberOfArrayLog|.
|
| - return function (desc, target, opts) {
|
| - var _opts = {
|
| - numberOfErrorLog: 8,
|
| - numberOfArrayLog: 16,
|
| - verbose: true
|
| - };
|
| -
|
| - if (opts instanceof Object) {
|
| - if (opts.hasOwnProperty('numberOfErrorLog'))
|
| - _opts.numberOfErrorLog = opts.numberOfErrorLog;
|
| - if (opts.hasOwnProperty('numberOfArrayLog'))
|
| - _opts.numberOfArrayLog = opts.numberOfArrayLog;
|
| - if (opts.hasOwnProperty('brief'))
|
| - _opts.brief = opts.brief;
|
| - if (opts.hasOwnProperty('precision'))
|
| - _opts.precision = opts.precision;
|
| - }
|
| -
|
| - return new ShouldModel(desc, target, _opts);
|
| - };
|
| -
|
| -})();
|
|
|