Spaces:
Configuration error
Configuration error
function compare(a, b) { | |
if (a === b) { | |
return 0; | |
} | |
var x = a.length; | |
var y = b.length; | |
for (var i = 0, len = Math.min(x, y); i < len; ++i) { | |
if (a[i] !== b[i]) { | |
x = a[i]; | |
y = b[i]; | |
break; | |
} | |
} | |
if (x < y) { | |
return -1; | |
} | |
if (y < x) { | |
return 1; | |
} | |
return 0; | |
} | |
var hasOwn = Object.prototype.hasOwnProperty; | |
var objectKeys = Object.keys || function (obj) { | |
var keys = []; | |
for (var key in obj) { | |
if (hasOwn.call(obj, key)) keys.push(key); | |
} | |
return keys; | |
}; | |
// based on node assert, original notice: | |
// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 | |
// | |
// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! | |
// | |
// Originally from narwhal.js (http://narwhaljs.org) | |
// Copyright (c) 2009 Thomas Robinson <280north.com> | |
// | |
// Permission is hereby granted, free of charge, to any person obtaining a copy | |
// of this software and associated documentation files (the 'Software'), to | |
// deal in the Software without restriction, including without limitation the | |
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or | |
// sell copies of the Software, and to permit persons to whom the Software is | |
// furnished to do so, subject to the following conditions: | |
// | |
// The above copyright notice and this permission notice shall be included in | |
// all copies or substantial portions of the Software. | |
// | |
// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | |
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |
import {isBuffer} from 'buffer'; | |
import {isPrimitive, inherits, isError, isFunction, isRegExp, isDate, inspect as utilInspect} from 'util'; | |
var pSlice = Array.prototype.slice; | |
var _functionsHaveNames; | |
function functionsHaveNames() { | |
if (typeof _functionsHaveNames !== 'undefined') { | |
return _functionsHaveNames; | |
} | |
return _functionsHaveNames = (function () { | |
return function foo() {}.name === 'foo'; | |
}()); | |
} | |
function pToString (obj) { | |
return Object.prototype.toString.call(obj); | |
} | |
function isView(arrbuf) { | |
if (isBuffer(arrbuf)) { | |
return false; | |
} | |
if (typeof global.ArrayBuffer !== 'function') { | |
return false; | |
} | |
if (typeof ArrayBuffer.isView === 'function') { | |
return ArrayBuffer.isView(arrbuf); | |
} | |
if (!arrbuf) { | |
return false; | |
} | |
if (arrbuf instanceof DataView) { | |
return true; | |
} | |
if (arrbuf.buffer && arrbuf.buffer instanceof ArrayBuffer) { | |
return true; | |
} | |
return false; | |
} | |
// 1. The assert module provides functions that throw | |
// AssertionError's when particular conditions are not met. The | |
// assert module must conform to the following interface. | |
function assert(value, message) { | |
if (!value) fail(value, true, message, '==', ok); | |
} | |
export default assert; | |
// 2. The AssertionError is defined in assert. | |
// new assert.AssertionError({ message: message, | |
// actual: actual, | |
// expected: expected }) | |
var regex = /\s*function\s+([^\(\s]*)\s*/; | |
// based on https://github.com/ljharb/function.prototype.name/blob/adeeeec8bfcc6068b187d7d9fb3d5bb1d3a30899/implementation.js | |
function getName(func) { | |
if (!isFunction(func)) { | |
return; | |
} | |
if (functionsHaveNames()) { | |
return func.name; | |
} | |
var str = func.toString(); | |
var match = str.match(regex); | |
return match && match[1]; | |
} | |
assert.AssertionError = AssertionError; | |
export function AssertionError(options) { | |
this.name = 'AssertionError'; | |
this.actual = options.actual; | |
this.expected = options.expected; | |
this.operator = options.operator; | |
if (options.message) { | |
this.message = options.message; | |
this.generatedMessage = false; | |
} else { | |
this.message = getMessage(this); | |
this.generatedMessage = true; | |
} | |
var stackStartFunction = options.stackStartFunction || fail; | |
if (Error.captureStackTrace) { | |
Error.captureStackTrace(this, stackStartFunction); | |
} else { | |
// non v8 browsers so we can have a stacktrace | |
var err = new Error(); | |
if (err.stack) { | |
var out = err.stack; | |
// try to strip useless frames | |
var fn_name = getName(stackStartFunction); | |
var idx = out.indexOf('\n' + fn_name); | |
if (idx >= 0) { | |
// once we have located the function frame | |
// we need to strip out everything before it (and its line) | |
var next_line = out.indexOf('\n', idx + 1); | |
out = out.substring(next_line + 1); | |
} | |
this.stack = out; | |
} | |
} | |
} | |
// assert.AssertionError instanceof Error | |
inherits(AssertionError, Error); | |
function truncate(s, n) { | |
if (typeof s === 'string') { | |
return s.length < n ? s : s.slice(0, n); | |
} else { | |
return s; | |
} | |
} | |
function inspect(something) { | |
if (functionsHaveNames() || !isFunction(something)) { | |
return utilInspect(something); | |
} | |
var rawname = getName(something); | |
var name = rawname ? ': ' + rawname : ''; | |
return '[Function' + name + ']'; | |
} | |
function getMessage(self) { | |
return truncate(inspect(self.actual), 128) + ' ' + | |
self.operator + ' ' + | |
truncate(inspect(self.expected), 128); | |
} | |
// At present only the three keys mentioned above are used and | |
// understood by the spec. Implementations or sub modules can pass | |
// other keys to the AssertionError's constructor - they will be | |
// ignored. | |
// 3. All of the following functions must throw an AssertionError | |
// when a corresponding condition is not met, with a message that | |
// may be undefined if not provided. All assertion methods provide | |
// both the actual and expected values to the assertion error for | |
// display purposes. | |
export function fail(actual, expected, message, operator, stackStartFunction) { | |
throw new AssertionError({ | |
message: message, | |
actual: actual, | |
expected: expected, | |
operator: operator, | |
stackStartFunction: stackStartFunction | |
}); | |
} | |
// EXTENSION! allows for well behaved errors defined elsewhere. | |
assert.fail = fail; | |
// 4. Pure assertion tests whether a value is truthy, as determined | |
// by !!guard. | |
// assert.ok(guard, message_opt); | |
// This statement is equivalent to assert.equal(true, !!guard, | |
// message_opt);. To test strictly for the value true, use | |
// assert.strictEqual(true, guard, message_opt);. | |
export function ok(value, message) { | |
if (!value) fail(value, true, message, '==', ok); | |
} | |
assert.ok = ok; | |
export {ok as assert}; | |
// 5. The equality assertion tests shallow, coercive equality with | |
// ==. | |
// assert.equal(actual, expected, message_opt); | |
assert.equal = equal; | |
export function equal(actual, expected, message) { | |
if (actual != expected) fail(actual, expected, message, '==', equal); | |
} | |
// 6. The non-equality assertion tests for whether two objects are not equal | |
// with != assert.notEqual(actual, expected, message_opt); | |
assert.notEqual = notEqual; | |
export function notEqual(actual, expected, message) { | |
if (actual == expected) { | |
fail(actual, expected, message, '!=', notEqual); | |
} | |
} | |
// 7. The equivalence assertion tests a deep equality relation. | |
// assert.deepEqual(actual, expected, message_opt); | |
assert.deepEqual = deepEqual; | |
export function deepEqual(actual, expected, message) { | |
if (!_deepEqual(actual, expected, false)) { | |
fail(actual, expected, message, 'deepEqual', deepEqual); | |
} | |
} | |
assert.deepStrictEqual = deepStrictEqual; | |
export function deepStrictEqual(actual, expected, message) { | |
if (!_deepEqual(actual, expected, true)) { | |
fail(actual, expected, message, 'deepStrictEqual', deepStrictEqual); | |
} | |
} | |
function _deepEqual(actual, expected, strict, memos) { | |
// 7.1. All identical values are equivalent, as determined by ===. | |
if (actual === expected) { | |
return true; | |
} else if (isBuffer(actual) && isBuffer(expected)) { | |
return compare(actual, expected) === 0; | |
// 7.2. If the expected value is a Date object, the actual value is | |
// equivalent if it is also a Date object that refers to the same time. | |
} else if (isDate(actual) && isDate(expected)) { | |
return actual.getTime() === expected.getTime(); | |
// 7.3 If the expected value is a RegExp object, the actual value is | |
// equivalent if it is also a RegExp object with the same source and | |
// properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). | |
} else if (isRegExp(actual) && isRegExp(expected)) { | |
return actual.source === expected.source && | |
actual.global === expected.global && | |
actual.multiline === expected.multiline && | |
actual.lastIndex === expected.lastIndex && | |
actual.ignoreCase === expected.ignoreCase; | |
// 7.4. Other pairs that do not both pass typeof value == 'object', | |
// equivalence is determined by ==. | |
} else if ((actual === null || typeof actual !== 'object') && | |
(expected === null || typeof expected !== 'object')) { | |
return strict ? actual === expected : actual == expected; | |
// If both values are instances of typed arrays, wrap their underlying | |
// ArrayBuffers in a Buffer each to increase performance | |
// This optimization requires the arrays to have the same type as checked by | |
// Object.prototype.toString (aka pToString). Never perform binary | |
// comparisons for Float*Arrays, though, since e.g. +0 === -0 but their | |
// bit patterns are not identical. | |
} else if (isView(actual) && isView(expected) && | |
pToString(actual) === pToString(expected) && | |
!(actual instanceof Float32Array || | |
actual instanceof Float64Array)) { | |
return compare(new Uint8Array(actual.buffer), | |
new Uint8Array(expected.buffer)) === 0; | |
// 7.5 For all other Object pairs, including Array objects, equivalence is | |
// determined by having the same number of owned properties (as verified | |
// with Object.prototype.hasOwnProperty.call), the same set of keys | |
// (although not necessarily the same order), equivalent values for every | |
// corresponding key, and an identical 'prototype' property. Note: this | |
// accounts for both named and indexed properties on Arrays. | |
} else if (isBuffer(actual) !== isBuffer(expected)) { | |
return false; | |
} else { | |
memos = memos || {actual: [], expected: []}; | |
var actualIndex = memos.actual.indexOf(actual); | |
if (actualIndex !== -1) { | |
if (actualIndex === memos.expected.indexOf(expected)) { | |
return true; | |
} | |
} | |
memos.actual.push(actual); | |
memos.expected.push(expected); | |
return objEquiv(actual, expected, strict, memos); | |
} | |
} | |
function isArguments(object) { | |
return Object.prototype.toString.call(object) == '[object Arguments]'; | |
} | |
function objEquiv(a, b, strict, actualVisitedObjects) { | |
if (a === null || a === undefined || b === null || b === undefined) | |
return false; | |
// if one is a primitive, the other must be same | |
if (isPrimitive(a) || isPrimitive(b)) | |
return a === b; | |
if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) | |
return false; | |
var aIsArgs = isArguments(a); | |
var bIsArgs = isArguments(b); | |
if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) | |
return false; | |
if (aIsArgs) { | |
a = pSlice.call(a); | |
b = pSlice.call(b); | |
return _deepEqual(a, b, strict); | |
} | |
var ka = objectKeys(a); | |
var kb = objectKeys(b); | |
var key, i; | |
// having the same number of owned properties (keys incorporates | |
// hasOwnProperty) | |
if (ka.length !== kb.length) | |
return false; | |
//the same set of keys (although not necessarily the same order), | |
ka.sort(); | |
kb.sort(); | |
//~~~cheap key test | |
for (i = ka.length - 1; i >= 0; i--) { | |
if (ka[i] !== kb[i]) | |
return false; | |
} | |
//equivalent values for every corresponding key, and | |
//~~~possibly expensive deep test | |
for (i = ka.length - 1; i >= 0; i--) { | |
key = ka[i]; | |
if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects)) | |
return false; | |
} | |
return true; | |
} | |
// 8. The non-equivalence assertion tests for any deep inequality. | |
// assert.notDeepEqual(actual, expected, message_opt); | |
assert.notDeepEqual = notDeepEqual; | |
export function notDeepEqual(actual, expected, message) { | |
if (_deepEqual(actual, expected, false)) { | |
fail(actual, expected, message, 'notDeepEqual', notDeepEqual); | |
} | |
} | |
assert.notDeepStrictEqual = notDeepStrictEqual; | |
export function notDeepStrictEqual(actual, expected, message) { | |
if (_deepEqual(actual, expected, true)) { | |
fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual); | |
} | |
} | |
// 9. The strict equality assertion tests strict equality, as determined by ===. | |
// assert.strictEqual(actual, expected, message_opt); | |
assert.strictEqual = strictEqual; | |
export function strictEqual(actual, expected, message) { | |
if (actual !== expected) { | |
fail(actual, expected, message, '===', strictEqual); | |
} | |
} | |
// 10. The strict non-equality assertion tests for strict inequality, as | |
// determined by !==. assert.notStrictEqual(actual, expected, message_opt); | |
assert.notStrictEqual = notStrictEqual; | |
export function notStrictEqual(actual, expected, message) { | |
if (actual === expected) { | |
fail(actual, expected, message, '!==', notStrictEqual); | |
} | |
} | |
function expectedException(actual, expected) { | |
if (!actual || !expected) { | |
return false; | |
} | |
if (Object.prototype.toString.call(expected) == '[object RegExp]') { | |
return expected.test(actual); | |
} | |
try { | |
if (actual instanceof expected) { | |
return true; | |
} | |
} catch (e) { | |
// Ignore. The instanceof check doesn't work for arrow functions. | |
} | |
if (Error.isPrototypeOf(expected)) { | |
return false; | |
} | |
return expected.call({}, actual) === true; | |
} | |
function _tryBlock(block) { | |
var error; | |
try { | |
block(); | |
} catch (e) { | |
error = e; | |
} | |
return error; | |
} | |
function _throws(shouldThrow, block, expected, message) { | |
var actual; | |
if (typeof block !== 'function') { | |
throw new TypeError('"block" argument must be a function'); | |
} | |
if (typeof expected === 'string') { | |
message = expected; | |
expected = null; | |
} | |
actual = _tryBlock(block); | |
message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + | |
(message ? ' ' + message : '.'); | |
if (shouldThrow && !actual) { | |
fail(actual, expected, 'Missing expected exception' + message); | |
} | |
var userProvidedMessage = typeof message === 'string'; | |
var isUnwantedException = !shouldThrow && isError(actual); | |
var isUnexpectedException = !shouldThrow && actual && !expected; | |
if ((isUnwantedException && | |
userProvidedMessage && | |
expectedException(actual, expected)) || | |
isUnexpectedException) { | |
fail(actual, expected, 'Got unwanted exception' + message); | |
} | |
if ((shouldThrow && actual && expected && | |
!expectedException(actual, expected)) || (!shouldThrow && actual)) { | |
throw actual; | |
} | |
} | |
// 11. Expected to throw an error: | |
// assert.throws(block, Error_opt, message_opt); | |
assert.throws = throws; | |
export function throws(block, /*optional*/error, /*optional*/message) { | |
_throws(true, block, error, message); | |
} | |
// EXTENSION! This is annoying to write outside this module. | |
assert.doesNotThrow = doesNotThrow; | |
export function doesNotThrow(block, /*optional*/error, /*optional*/message) { | |
_throws(false, block, error, message); | |
} | |
assert.ifError = ifError; | |
export function ifError(err) { | |
if (err) throw err; | |
} | |