start werk

This commit is contained in:
Daniel Hübleitner
2019-09-17 23:18:00 +02:00
commit 615619e6e7
3598 changed files with 1238825 additions and 0 deletions
+964
View File
@@ -0,0 +1,964 @@
/*!
* assert.js - assertions for javascript
* Copyright (c) 2018, Christopher Jeffrey (MIT License).
* https://github.com/chjj/bsert
*/
'use strict';
/**
* AssertionError
*/
class AssertionError extends Error {
constructor(options) {
if (typeof options === 'string')
options = { message: options };
if (options === null || typeof options !== 'object')
options = {};
let message = null;
let operator = 'fail';
let generatedMessage = Boolean(options.generatedMessage);
if (options.message != null)
message = toString(options.message);
if (typeof options.operator === 'string')
operator = options.operator;
if (message == null) {
if (operator === 'fail') {
message = 'Assertion failed.';
} else {
const a = stringify(options.actual);
const b = stringify(options.expected);
message = `${a} ${operator} ${b}`;
}
generatedMessage = true;
}
super(message);
let start = this.constructor;
if (typeof options.stackStartFunction === 'function')
start = options.stackStartFunction;
else if (typeof options.stackStartFn === 'function')
start = options.stackStartFn;
this.type = 'AssertionError';
this.name = 'AssertionError [ERR_ASSERTION]';
this.code = 'ERR_ASSERTION';
this.generatedMessage = generatedMessage;
this.actual = options.actual;
this.expected = options.expected;
this.operator = operator;
if (Error.captureStackTrace)
Error.captureStackTrace(this, start);
}
}
/*
* Assert
*/
function assert(value, message) {
if (!value) {
let generatedMessage = false;
if (arguments.length === 0) {
message = 'No value argument passed to `assert()`.';
generatedMessage = true;
} else if (message == null) {
message = 'Assertion failed.';
generatedMessage = true;
} else if (isError(message)) {
throw message;
}
throw new AssertionError({
message,
actual: value,
expected: true,
operator: '==',
generatedMessage,
stackStartFn: assert
});
}
}
function equal(actual, expected, message) {
if (!Object.is(actual, expected)) {
if (isError(message))
throw message;
throw new AssertionError({
message,
actual,
expected,
operator: 'strictEqual',
stackStartFn: equal
});
}
}
function notEqual(actual, expected, message) {
if (Object.is(actual, expected)) {
if (isError(message))
throw message;
throw new AssertionError({
message,
actual,
expected,
operator: 'notStrictEqual',
stackStartFn: notEqual
});
}
}
function fail(message) {
let generatedMessage = false;
if (isError(message))
throw message;
if (message == null) {
message = 'Assertion failed.';
generatedMessage = true;
}
throw new AssertionError({
message,
actual: false,
expected: true,
operator: 'fail',
generatedMessage,
stackStartFn: fail
});
}
function throws(func, expected, message) {
if (typeof expected === 'string') {
message = expected;
expected = undefined;
}
let thrown = false;
let err = null;
enforce(typeof func === 'function', 'func', 'function');
try {
func();
} catch (e) {
thrown = true;
err = e;
}
if (!thrown) {
let generatedMessage = false;
if (message == null) {
message = 'Missing expected exception.';
generatedMessage = true;
}
throw new AssertionError({
message,
actual: undefined,
expected,
operator: 'throws',
generatedMessage,
stackStartFn: throws
});
}
if (!testError(err, expected, message, throws))
throw err;
}
function doesNotThrow(func, expected, message) {
if (typeof expected === 'string') {
message = expected;
expected = undefined;
}
let thrown = false;
let err = null;
enforce(typeof func === 'function', 'func', 'function');
try {
func();
} catch (e) {
thrown = true;
err = e;
}
if (!thrown)
return;
if (testError(err, expected, message, doesNotThrow)) {
let generatedMessage = false;
if (message == null) {
message = 'Got unwanted exception.';
generatedMessage = true;
}
throw new AssertionError({
message,
actual: err,
expected,
operator: 'doesNotThrow',
generatedMessage,
stackStartFn: doesNotThrow
});
}
throw err;
}
async function rejects(func, expected, message) {
if (typeof expected === 'string') {
message = expected;
expected = undefined;
}
let thrown = false;
let err = null;
if (typeof func !== 'function')
enforce(isPromise(func), 'func', 'promise');
try {
if (isPromise(func))
await func;
else
await func();
} catch (e) {
thrown = true;
err = e;
}
if (!thrown) {
let generatedMessage = false;
if (message == null) {
message = 'Missing expected rejection.';
generatedMessage = true;
}
throw new AssertionError({
message,
actual: undefined,
expected,
operator: 'rejects',
generatedMessage,
stackStartFn: rejects
});
}
if (!testError(err, expected, message, rejects))
throw err;
}
async function doesNotReject(func, expected, message) {
if (typeof expected === 'string') {
message = expected;
expected = undefined;
}
let thrown = false;
let err = null;
if (typeof func !== 'function')
enforce(isPromise(func), 'func', 'promise');
try {
if (isPromise(func))
await func;
else
await func();
} catch (e) {
thrown = true;
err = e;
}
if (!thrown)
return;
if (testError(err, expected, message, doesNotReject)) {
let generatedMessage = false;
if (message == null) {
message = 'Got unwanted rejection.';
generatedMessage = true;
}
throw new AssertionError({
message,
actual: undefined,
expected,
operator: 'doesNotReject',
generatedMessage,
stackStartFn: doesNotReject
});
}
throw err;
}
function ifError(err) {
if (err != null) {
let message = 'ifError got unwanted exception: ';
if (typeof err === 'object' && typeof err.message === 'string') {
if (err.message.length === 0 && err.constructor)
message += err.constructor.name;
else
message += err.message;
} else {
message += stringify(err);
}
throw new AssertionError({
message,
actual: err,
expected: null,
operator: 'ifError',
generatedMessage: true,
stackStartFn: ifError
});
}
}
function deepEqual(actual, expected, message) {
if (!isDeepEqual(actual, expected, false)) {
if (isError(message))
throw message;
throw new AssertionError({
message,
actual,
expected,
operator: 'deepStrictEqual',
stackStartFn: deepEqual
});
}
}
function notDeepEqual(actual, expected, message) {
if (isDeepEqual(actual, expected, true)) {
if (isError(message))
throw message;
throw new AssertionError({
message,
actual,
expected,
operator: 'notDeepStrictEqual',
stackStartFn: notDeepEqual
});
}
}
function bufferEqual(actual, expected, enc, message) {
if (!isEncoding(enc)) {
message = enc;
enc = null;
}
if (enc == null)
enc = 'hex';
expected = bufferize(actual, expected, enc);
enforce(isBuffer(actual), 'actual', 'buffer');
enforce(isBuffer(expected), 'expected', 'buffer');
if (actual !== expected && !actual.equals(expected)) {
if (isError(message))
throw message;
throw new AssertionError({
message,
actual: actual.toString(enc),
expected: expected.toString(enc),
operator: 'bufferEqual',
stackStartFn: bufferEqual
});
}
}
function notBufferEqual(actual, expected, enc, message) {
if (!isEncoding(enc)) {
message = enc;
enc = null;
}
if (enc == null)
enc = 'hex';
expected = bufferize(actual, expected, enc);
enforce(isBuffer(actual), 'actual', 'buffer');
enforce(isBuffer(expected), 'expected', 'buffer');
if (actual === expected || actual.equals(expected)) {
if (isError(message))
throw message;
throw new AssertionError({
message,
actual: actual.toString(enc),
expected: expected.toString(enc),
operator: 'notBufferEqual',
stackStartFn: notBufferEqual
});
}
}
function enforce(value, name, type) {
if (!value) {
let msg;
if (name == null) {
msg = 'Invalid type for parameter.';
} else {
if (type == null)
msg = `Invalid type for "${name}".`;
else
msg = `"${name}" must be a(n) ${type}.`;
}
const err = new TypeError(msg);
if (Error.captureStackTrace)
Error.captureStackTrace(err, enforce);
throw err;
}
}
function range(value, name) {
if (!value) {
const msg = name != null
? `"${name}" is out of range.`
: 'Parameter is out of range.';
const err = new RangeError(msg);
if (Error.captureStackTrace)
Error.captureStackTrace(err, range);
throw err;
}
}
/*
* Stringification
*/
function stringify(value) {
switch (typeof value) {
case 'undefined':
return 'undefined';
case 'object':
if (value === null)
return 'null';
return `[${objectName(value)}]`;
case 'boolean':
return `${value}`;
case 'number':
return `${value}`;
case 'string':
if (value.length > 80)
value = `${value.substring(0, 77)}...`;
return JSON.stringify(value);
case 'symbol':
return tryString(value);
case 'function':
return `[${funcName(value)}]`;
case 'bigint':
return `${value}n`;
default:
return `[${typeof value}]`;
}
}
function toString(value) {
if (typeof value === 'string')
return value;
if (isError(value))
return tryString(value);
return stringify(value);
}
function tryString(value) {
try {
return String(value);
} catch (e) {
return 'Object';
}
}
/*
* Error Testing
*/
function testError(err, expected, message, func) {
if (expected == null)
return true;
if (isRegExp(expected))
return expected.test(err);
if (typeof expected !== 'function') {
if (func === doesNotThrow || func === doesNotReject)
throw new TypeError('"expected" must not be an object.');
if (typeof expected !== 'object')
throw new TypeError('"expected" must be an object.');
let generatedMessage = false;
if (message == null) {
const name = func === rejects ? 'rejection' : 'exception';
message = `Missing expected ${name}.`;
generatedMessage = true;
}
if (err == null || typeof err !== 'object') {
throw new AssertionError({
actual: err,
expected,
message,
operator: func.name,
generatedMessage,
stackStartFn: func
});
}
const keys = Object.keys(expected);
if (isError(expected))
keys.push('name', 'message');
if (keys.length === 0)
throw new TypeError('"expected" may not be an empty object.');
for (const key of keys) {
const expect = expected[key];
const value = err[key];
if (typeof value === 'string'
&& isRegExp(expect)
&& expect.test(value)) {
continue;
}
if ((key in err) && isDeepEqual(value, expect, false))
continue;
throw new AssertionError({
actual: err,
expected: expected,
message,
operator: func.name,
generatedMessage,
stackStartFn: func
});
}
return true;
}
if (expected.prototype !== undefined && (err instanceof expected))
return true;
if (Error.isPrototypeOf(expected))
return false;
return expected.call({}, err) === true;
}
/*
* Comparisons
*/
function isDeepEqual(x, y, fail) {
try {
return compare(x, y, null);
} catch (e) {
return fail;
}
}
function compare(a, b, cache) {
// Primitives.
if (Object.is(a, b))
return true;
if (!isObject(a) || !isObject(b))
return false;
// Semi-primitives.
if (objectString(a) !== objectString(b))
return false;
if (Object.getPrototypeOf(a) !== Object.getPrototypeOf(b))
return false;
if (isBuffer(a) && isBuffer(b))
return a.equals(b);
if (isDate(a))
return Object.is(a.getTime(), b.getTime());
if (isRegExp(a)) {
return a.source === b.source
&& a.global === b.global
&& a.multiline === b.multiline
&& a.lastIndex === b.lastIndex
&& a.ignoreCase === b.ignoreCase;
}
if (isError(a)) {
if (a.message !== b.message)
return false;
}
if (isArrayBuffer(a)) {
a = new Uint8Array(a);
b = new Uint8Array(b);
}
if (isView(a) && !isBuffer(a)) {
if (isBuffer(b))
return false;
const x = new Uint8Array(a.buffer);
const y = new Uint8Array(b.buffer);
if (x.length !== y.length)
return false;
for (let i = 0; i < x.length; i++) {
if (x[i] !== y[i])
return false;
}
return true;
}
if (isSet(a)) {
if (a.size !== b.size)
return false;
const keys = new Set([...a, ...b]);
return keys.size === a.size;
}
// Recursive.
if (!cache) {
cache = {
a: new Map(),
b: new Map(),
p: 0
};
} else {
const aa = cache.a.get(a);
if (aa != null) {
const bb = cache.b.get(b);
if (bb != null)
return aa === bb;
}
cache.p += 1;
}
cache.a.set(a, cache.p);
cache.b.set(b, cache.p);
const ret = recurse(a, b, cache);
cache.a.delete(a);
cache.b.delete(b);
return ret;
}
function recurse(a, b, cache) {
if (isMap(a)) {
if (a.size !== b.size)
return false;
const keys = new Set([...a.keys(), ...b.keys()]);
if (keys.size !== a.size)
return false;
for (const key of keys) {
if (!compare(a.get(key), b.get(key), cache))
return false;
}
return true;
}
if (isArray(a)) {
if (a.length !== b.length)
return false;
for (let i = 0; i < a.length; i++) {
if (!compare(a[i], b[i], cache))
return false;
}
return true;
}
const ak = ownKeys(a);
const bk = ownKeys(b);
if (ak.length !== bk.length)
return false;
const keys = new Set([...ak, ...bk]);
if (keys.size !== ak.length)
return false;
for (const key of keys) {
if (!compare(a[key], b[key], cache))
return false;
}
return true;
}
function ownKeys(obj) {
const keys = Object.keys(obj);
if (!Object.getOwnPropertySymbols)
return keys;
if (!Object.getOwnPropertyDescriptor)
return keys;
const symbols = Object.getOwnPropertySymbols(obj);
for (const symbol of symbols) {
const desc = Object.getOwnPropertyDescriptor(obj, symbol);
if (desc && desc.enumerable)
keys.push(symbol);
}
return keys;
}
/*
* Helpers
*/
function objectString(obj) {
if (obj === undefined)
return '[object Undefined]';
if (obj === null)
return '[object Null]';
try {
return Object.prototype.toString.call(obj);
} catch (e) {
return '[object Object]';
}
}
function objectType(obj) {
return objectString(obj).slice(8, -1);
}
function objectName(obj) {
const type = objectType(obj);
if (obj == null)
return type;
if (type !== 'Object' && type !== 'Error')
return type;
let ctor, name;
try {
ctor = obj.constructor;
} catch (e) {
;
}
if (ctor == null)
return type;
try {
name = ctor.name;
} catch (e) {
return type;
}
if (typeof name !== 'string' || name.length === 0)
return type;
return name;
}
function funcName(func) {
let name;
try {
name = func.name;
} catch (e) {
;
}
if (typeof name !== 'string' || name.length === 0)
return 'Function';
return `Function: ${name}`;
}
function isArray(obj) {
return Array.isArray(obj);
}
function isArrayBuffer(obj) {
return obj instanceof ArrayBuffer;
}
function isBuffer(obj) {
return isObject(obj)
&& typeof obj.writeUInt32LE === 'function'
&& typeof obj.equals === 'function';
}
function isDate(obj) {
return obj instanceof Date;
}
function isError(obj) {
return obj instanceof Error;
}
function isMap(obj) {
return obj instanceof Map;
}
function isObject(obj) {
return obj && typeof obj === 'object';
}
function isPromise(obj) {
return obj instanceof Promise;
}
function isRegExp(obj) {
return obj instanceof RegExp;
}
function isSet(obj) {
return obj instanceof Set;
}
function isView(obj) {
return ArrayBuffer.isView(obj);
}
function isEncoding(enc) {
if (typeof enc !== 'string')
return false;
switch (enc) {
case 'ascii':
case 'binary':
case 'base64':
case 'hex':
case 'latin1':
case 'ucs2':
case 'utf8':
case 'utf16le':
return true;
}
return false;
}
function bufferize(actual, expected, enc) {
if (typeof expected === 'string') {
if (!isBuffer(actual))
return null;
const {constructor} = actual;
if (!constructor || typeof constructor.from !== 'function')
return null;
if (!isEncoding(enc))
return null;
if (enc === 'hex' && (expected.length & 1))
return null;
const raw = constructor.from(expected, enc);
if (enc === 'hex' && raw.length !== (expected.length >>> 1))
return null;
return raw;
}
return expected;
}
/*
* API
*/
assert.AssertionError = AssertionError;
assert.assert = assert;
assert.strict = assert;
assert.ok = assert;
assert.equal = equal;
assert.notEqual = notEqual;
assert.strictEqual = equal;
assert.notStrictEqual = notEqual;
assert.fail = fail;
assert.throws = throws;
assert.doesNotThrow = doesNotThrow;
assert.rejects = rejects;
assert.doesNotReject = doesNotReject;
assert.ifError = ifError;
assert.deepEqual = deepEqual;
assert.notDeepEqual = notDeepEqual;
assert.deepStrictEqual = deepEqual;
assert.notDeepStrictEqual = notDeepEqual;
assert.bufferEqual = bufferEqual;
assert.notBufferEqual = notBufferEqual;
assert.enforce = enforce;
assert.range = range;
/*
* Expose
*/
module.exports = assert;