123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631 |
- // Currently in sync with Node.js lib/assert.js
- // https://github.com/nodejs/node/commit/2a51ae424a513ec9a6aa3466baa0cc1d55dd4f3b
- // 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.
- 'use strict';
- function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
- var _require = require('./internal/errors'),
- _require$codes = _require.codes,
- ERR_AMBIGUOUS_ARGUMENT = _require$codes.ERR_AMBIGUOUS_ARGUMENT,
- ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE,
- ERR_INVALID_ARG_VALUE = _require$codes.ERR_INVALID_ARG_VALUE,
- ERR_INVALID_RETURN_VALUE = _require$codes.ERR_INVALID_RETURN_VALUE,
- ERR_MISSING_ARGS = _require$codes.ERR_MISSING_ARGS;
- var AssertionError = require('./internal/assert/assertion_error');
- var _require2 = require('util/'),
- inspect = _require2.inspect;
- var _require$types = require('util/').types,
- isPromise = _require$types.isPromise,
- isRegExp = _require$types.isRegExp;
- var objectAssign = Object.assign ? Object.assign : require('es6-object-assign').assign;
- var objectIs = Object.is ? Object.is : require('object-is');
- var errorCache = new Map();
- var isDeepEqual;
- var isDeepStrictEqual;
- var parseExpressionAt;
- var findNodeAround;
- var decoder;
- function lazyLoadComparison() {
- var comparison = require('./internal/util/comparisons');
- isDeepEqual = comparison.isDeepEqual;
- isDeepStrictEqual = comparison.isDeepStrictEqual;
- } // Escape control characters but not \n and \t to keep the line breaks and
- // indentation intact.
- // eslint-disable-next-line no-control-regex
- var escapeSequencesRegExp = /[\x00-\x08\x0b\x0c\x0e-\x1f]/g;
- var meta = ["\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007", '\\b', '', '', "\\u000b", '\\f', '', "\\u000e", "\\u000f", "\\u0010", "\\u0011", "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017", "\\u0018", "\\u0019", "\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f"];
- var escapeFn = function escapeFn(str) {
- return meta[str.charCodeAt(0)];
- };
- var warned = false; // The assert module provides functions that throw
- // AssertionError's when particular conditions are not met. The
- // assert module must conform to the following interface.
- var assert = module.exports = ok;
- var NO_EXCEPTION_SENTINEL = {}; // 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.
- function innerFail(obj) {
- if (obj.message instanceof Error) throw obj.message;
- throw new AssertionError(obj);
- }
- function fail(actual, expected, message, operator, stackStartFn) {
- var argsLen = arguments.length;
- var internalMessage;
- if (argsLen === 0) {
- internalMessage = 'Failed';
- } else if (argsLen === 1) {
- message = actual;
- actual = undefined;
- } else {
- if (warned === false) {
- warned = true;
- var warn = process.emitWarning ? process.emitWarning : console.warn.bind(console);
- warn('assert.fail() with more than one argument is deprecated. ' + 'Please use assert.strictEqual() instead or only pass a message.', 'DeprecationWarning', 'DEP0094');
- }
- if (argsLen === 2) operator = '!=';
- }
- if (message instanceof Error) throw message;
- var errArgs = {
- actual: actual,
- expected: expected,
- operator: operator === undefined ? 'fail' : operator,
- stackStartFn: stackStartFn || fail
- };
- if (message !== undefined) {
- errArgs.message = message;
- }
- var err = new AssertionError(errArgs);
- if (internalMessage) {
- err.message = internalMessage;
- err.generatedMessage = true;
- }
- throw err;
- }
- assert.fail = fail; // The AssertionError is defined in internal/error.
- assert.AssertionError = AssertionError;
- function innerOk(fn, argLen, value, message) {
- if (!value) {
- var generatedMessage = false;
- if (argLen === 0) {
- generatedMessage = true;
- message = 'No value argument passed to `assert.ok()`';
- } else if (message instanceof Error) {
- throw message;
- }
- var err = new AssertionError({
- actual: value,
- expected: true,
- message: message,
- operator: '==',
- stackStartFn: fn
- });
- err.generatedMessage = generatedMessage;
- throw err;
- }
- } // Pure assertion tests whether a value is truthy, as determined
- // by !!value.
- function ok() {
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
- args[_key] = arguments[_key];
- }
- innerOk.apply(void 0, [ok, args.length].concat(args));
- }
- assert.ok = ok; // The equality assertion tests shallow, coercive equality with ==.
- /* eslint-disable no-restricted-properties */
- assert.equal = function equal(actual, expected, message) {
- if (arguments.length < 2) {
- throw new ERR_MISSING_ARGS('actual', 'expected');
- } // eslint-disable-next-line eqeqeq
- if (actual != expected) {
- innerFail({
- actual: actual,
- expected: expected,
- message: message,
- operator: '==',
- stackStartFn: equal
- });
- }
- }; // The non-equality assertion tests for whether two objects are not
- // equal with !=.
- assert.notEqual = function notEqual(actual, expected, message) {
- if (arguments.length < 2) {
- throw new ERR_MISSING_ARGS('actual', 'expected');
- } // eslint-disable-next-line eqeqeq
- if (actual == expected) {
- innerFail({
- actual: actual,
- expected: expected,
- message: message,
- operator: '!=',
- stackStartFn: notEqual
- });
- }
- }; // The equivalence assertion tests a deep equality relation.
- assert.deepEqual = function deepEqual(actual, expected, message) {
- if (arguments.length < 2) {
- throw new ERR_MISSING_ARGS('actual', 'expected');
- }
- if (isDeepEqual === undefined) lazyLoadComparison();
- if (!isDeepEqual(actual, expected)) {
- innerFail({
- actual: actual,
- expected: expected,
- message: message,
- operator: 'deepEqual',
- stackStartFn: deepEqual
- });
- }
- }; // The non-equivalence assertion tests for any deep inequality.
- assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
- if (arguments.length < 2) {
- throw new ERR_MISSING_ARGS('actual', 'expected');
- }
- if (isDeepEqual === undefined) lazyLoadComparison();
- if (isDeepEqual(actual, expected)) {
- innerFail({
- actual: actual,
- expected: expected,
- message: message,
- operator: 'notDeepEqual',
- stackStartFn: notDeepEqual
- });
- }
- };
- /* eslint-enable */
- assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) {
- if (arguments.length < 2) {
- throw new ERR_MISSING_ARGS('actual', 'expected');
- }
- if (isDeepEqual === undefined) lazyLoadComparison();
- if (!isDeepStrictEqual(actual, expected)) {
- innerFail({
- actual: actual,
- expected: expected,
- message: message,
- operator: 'deepStrictEqual',
- stackStartFn: deepStrictEqual
- });
- }
- };
- assert.notDeepStrictEqual = notDeepStrictEqual;
- function notDeepStrictEqual(actual, expected, message) {
- if (arguments.length < 2) {
- throw new ERR_MISSING_ARGS('actual', 'expected');
- }
- if (isDeepEqual === undefined) lazyLoadComparison();
- if (isDeepStrictEqual(actual, expected)) {
- innerFail({
- actual: actual,
- expected: expected,
- message: message,
- operator: 'notDeepStrictEqual',
- stackStartFn: notDeepStrictEqual
- });
- }
- }
- assert.strictEqual = function strictEqual(actual, expected, message) {
- if (arguments.length < 2) {
- throw new ERR_MISSING_ARGS('actual', 'expected');
- }
- if (!objectIs(actual, expected)) {
- innerFail({
- actual: actual,
- expected: expected,
- message: message,
- operator: 'strictEqual',
- stackStartFn: strictEqual
- });
- }
- };
- assert.notStrictEqual = function notStrictEqual(actual, expected, message) {
- if (arguments.length < 2) {
- throw new ERR_MISSING_ARGS('actual', 'expected');
- }
- if (objectIs(actual, expected)) {
- innerFail({
- actual: actual,
- expected: expected,
- message: message,
- operator: 'notStrictEqual',
- stackStartFn: notStrictEqual
- });
- }
- };
- var Comparison = function Comparison(obj, keys, actual) {
- var _this = this;
- _classCallCheck(this, Comparison);
- keys.forEach(function (key) {
- if (key in obj) {
- if (actual !== undefined && typeof actual[key] === 'string' && isRegExp(obj[key]) && obj[key].test(actual[key])) {
- _this[key] = actual[key];
- } else {
- _this[key] = obj[key];
- }
- }
- });
- };
- function compareExceptionKey(actual, expected, key, message, keys, fn) {
- if (!(key in actual) || !isDeepStrictEqual(actual[key], expected[key])) {
- if (!message) {
- // Create placeholder objects to create a nice output.
- var a = new Comparison(actual, keys);
- var b = new Comparison(expected, keys, actual);
- var err = new AssertionError({
- actual: a,
- expected: b,
- operator: 'deepStrictEqual',
- stackStartFn: fn
- });
- err.actual = actual;
- err.expected = expected;
- err.operator = fn.name;
- throw err;
- }
- innerFail({
- actual: actual,
- expected: expected,
- message: message,
- operator: fn.name,
- stackStartFn: fn
- });
- }
- }
- function expectedException(actual, expected, msg, fn) {
- if (typeof expected !== 'function') {
- if (isRegExp(expected)) return expected.test(actual); // assert.doesNotThrow does not accept objects.
- if (arguments.length === 2) {
- throw new ERR_INVALID_ARG_TYPE('expected', ['Function', 'RegExp'], expected);
- } // Handle primitives properly.
- if (_typeof(actual) !== 'object' || actual === null) {
- var err = new AssertionError({
- actual: actual,
- expected: expected,
- message: msg,
- operator: 'deepStrictEqual',
- stackStartFn: fn
- });
- err.operator = fn.name;
- throw err;
- }
- var keys = Object.keys(expected); // Special handle errors to make sure the name and the message are compared
- // as well.
- if (expected instanceof Error) {
- keys.push('name', 'message');
- } else if (keys.length === 0) {
- throw new ERR_INVALID_ARG_VALUE('error', expected, 'may not be an empty object');
- }
- if (isDeepEqual === undefined) lazyLoadComparison();
- keys.forEach(function (key) {
- if (typeof actual[key] === 'string' && isRegExp(expected[key]) && expected[key].test(actual[key])) {
- return;
- }
- compareExceptionKey(actual, expected, key, msg, keys, fn);
- });
- return true;
- } // Guard instanceof against arrow functions as they don't have a prototype.
- if (expected.prototype !== undefined && actual instanceof expected) {
- return true;
- }
- if (Error.isPrototypeOf(expected)) {
- return false;
- }
- return expected.call({}, actual) === true;
- }
- function getActual(fn) {
- if (typeof fn !== 'function') {
- throw new ERR_INVALID_ARG_TYPE('fn', 'Function', fn);
- }
- try {
- fn();
- } catch (e) {
- return e;
- }
- return NO_EXCEPTION_SENTINEL;
- }
- function checkIsPromise(obj) {
- // Accept native ES6 promises and promises that are implemented in a similar
- // way. Do not accept thenables that use a function as `obj` and that have no
- // `catch` handler.
- // TODO: thenables are checked up until they have the correct methods,
- // but according to documentation, the `then` method should receive
- // the `fulfill` and `reject` arguments as well or it may be never resolved.
- return isPromise(obj) || obj !== null && _typeof(obj) === 'object' && typeof obj.then === 'function' && typeof obj.catch === 'function';
- }
- function waitForActual(promiseFn) {
- return Promise.resolve().then(function () {
- var resultPromise;
- if (typeof promiseFn === 'function') {
- // Return a rejected promise if `promiseFn` throws synchronously.
- resultPromise = promiseFn(); // Fail in case no promise is returned.
- if (!checkIsPromise(resultPromise)) {
- throw new ERR_INVALID_RETURN_VALUE('instance of Promise', 'promiseFn', resultPromise);
- }
- } else if (checkIsPromise(promiseFn)) {
- resultPromise = promiseFn;
- } else {
- throw new ERR_INVALID_ARG_TYPE('promiseFn', ['Function', 'Promise'], promiseFn);
- }
- return Promise.resolve().then(function () {
- return resultPromise;
- }).then(function () {
- return NO_EXCEPTION_SENTINEL;
- }).catch(function (e) {
- return e;
- });
- });
- }
- function expectsError(stackStartFn, actual, error, message) {
- if (typeof error === 'string') {
- if (arguments.length === 4) {
- throw new ERR_INVALID_ARG_TYPE('error', ['Object', 'Error', 'Function', 'RegExp'], error);
- }
- if (_typeof(actual) === 'object' && actual !== null) {
- if (actual.message === error) {
- throw new ERR_AMBIGUOUS_ARGUMENT('error/message', "The error message \"".concat(actual.message, "\" is identical to the message."));
- }
- } else if (actual === error) {
- throw new ERR_AMBIGUOUS_ARGUMENT('error/message', "The error \"".concat(actual, "\" is identical to the message."));
- }
- message = error;
- error = undefined;
- } else if (error != null && _typeof(error) !== 'object' && typeof error !== 'function') {
- throw new ERR_INVALID_ARG_TYPE('error', ['Object', 'Error', 'Function', 'RegExp'], error);
- }
- if (actual === NO_EXCEPTION_SENTINEL) {
- var details = '';
- if (error && error.name) {
- details += " (".concat(error.name, ")");
- }
- details += message ? ": ".concat(message) : '.';
- var fnType = stackStartFn.name === 'rejects' ? 'rejection' : 'exception';
- innerFail({
- actual: undefined,
- expected: error,
- operator: stackStartFn.name,
- message: "Missing expected ".concat(fnType).concat(details),
- stackStartFn: stackStartFn
- });
- }
- if (error && !expectedException(actual, error, message, stackStartFn)) {
- throw actual;
- }
- }
- function expectsNoError(stackStartFn, actual, error, message) {
- if (actual === NO_EXCEPTION_SENTINEL) return;
- if (typeof error === 'string') {
- message = error;
- error = undefined;
- }
- if (!error || expectedException(actual, error)) {
- var details = message ? ": ".concat(message) : '.';
- var fnType = stackStartFn.name === 'doesNotReject' ? 'rejection' : 'exception';
- innerFail({
- actual: actual,
- expected: error,
- operator: stackStartFn.name,
- message: "Got unwanted ".concat(fnType).concat(details, "\n") + "Actual message: \"".concat(actual && actual.message, "\""),
- stackStartFn: stackStartFn
- });
- }
- throw actual;
- }
- assert.throws = function throws(promiseFn) {
- for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
- args[_key2 - 1] = arguments[_key2];
- }
- expectsError.apply(void 0, [throws, getActual(promiseFn)].concat(args));
- };
- assert.rejects = function rejects(promiseFn) {
- for (var _len3 = arguments.length, args = new Array(_len3 > 1 ? _len3 - 1 : 0), _key3 = 1; _key3 < _len3; _key3++) {
- args[_key3 - 1] = arguments[_key3];
- }
- return waitForActual(promiseFn).then(function (result) {
- return expectsError.apply(void 0, [rejects, result].concat(args));
- });
- };
- assert.doesNotThrow = function doesNotThrow(fn) {
- for (var _len4 = arguments.length, args = new Array(_len4 > 1 ? _len4 - 1 : 0), _key4 = 1; _key4 < _len4; _key4++) {
- args[_key4 - 1] = arguments[_key4];
- }
- expectsNoError.apply(void 0, [doesNotThrow, getActual(fn)].concat(args));
- };
- assert.doesNotReject = function doesNotReject(fn) {
- for (var _len5 = arguments.length, args = new Array(_len5 > 1 ? _len5 - 1 : 0), _key5 = 1; _key5 < _len5; _key5++) {
- args[_key5 - 1] = arguments[_key5];
- }
- return waitForActual(fn).then(function (result) {
- return expectsNoError.apply(void 0, [doesNotReject, result].concat(args));
- });
- };
- assert.ifError = function ifError(err) {
- if (err !== null && err !== undefined) {
- var 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 += inspect(err);
- }
- var newErr = new AssertionError({
- actual: err,
- expected: null,
- operator: 'ifError',
- message: message,
- stackStartFn: ifError
- }); // Make sure we actually have a stack trace!
- var origStack = err.stack;
- if (typeof origStack === 'string') {
- // This will remove any duplicated frames from the error frames taken
- // from within `ifError` and add the original error frames to the newly
- // created ones.
- var tmp2 = origStack.split('\n');
- tmp2.shift(); // Filter all frames existing in err.stack.
- var tmp1 = newErr.stack.split('\n');
- for (var i = 0; i < tmp2.length; i++) {
- // Find the first occurrence of the frame.
- var pos = tmp1.indexOf(tmp2[i]);
- if (pos !== -1) {
- // Only keep new frames.
- tmp1 = tmp1.slice(0, pos);
- break;
- }
- }
- newErr.stack = "".concat(tmp1.join('\n'), "\n").concat(tmp2.join('\n'));
- }
- throw newErr;
- }
- }; // Expose a strict only variant of assert
- function strict() {
- for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
- args[_key6] = arguments[_key6];
- }
- innerOk.apply(void 0, [strict, args.length].concat(args));
- }
- assert.strict = objectAssign(strict, assert, {
- equal: assert.strictEqual,
- deepEqual: assert.deepStrictEqual,
- notEqual: assert.notStrictEqual,
- notDeepEqual: assert.notDeepStrictEqual
- });
- assert.strict.strict = assert.strict;
|