123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964 |
- /*!
- * 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;
|