Browse Source

update to add deapStrictEqual and some minor formating issues to make it good upto node 6 (#18)

buffer-dep
Calvin Metcalf 9 years ago
parent
commit
96b415190e
  1. 28
      .travis.yml
  2. 287
      assert.js
  3. 8
      package.json
  4. 567
      test.js

28
.travis.yml

@ -1,6 +1,30 @@
language: node_js language: node_js
node_js: before_install:
- '0.10' - npm install -g npm@2
- npm install -g npm
matrix:
include:
- node_js: '0.8'
env: TASK=test-node
- node_js: '0.10'
env: TASK=test-node
- node_js: '0.11'
env: TASK=test-node
- node_js: '0.12'
env: TASK=test-node
- node_js: 1
env: TASK=test-node
- node_js: 2
env: TASK=test-node
- node_js: 3
env: TASK=test-node
- node_js: 4
env: TASK=test-node
- node_js: 5
env: TASK=test-node
- node_js: '0.10'
env: TASK=test-browser
script: "npm run $TASK"
env: env:
global: global:
- secure: qThuKBZQtkooAvzaYldECGNqvKGPRTnXx62IVyhSbFlsCY1VCmjhLldhyPDiZQ3JqL1XvSkK8OMDupiHqZnNE0nGijoO4M/kaEdjBB+jpjg3f8I6te2SNU935SbkfY9KHAaFXMZwdcq7Fk932AxWEu+FMSDM+080wNKpEATXDe4= - secure: qThuKBZQtkooAvzaYldECGNqvKGPRTnXx62IVyhSbFlsCY1VCmjhLldhyPDiZQ3JqL1XvSkK8OMDupiHqZnNE0nGijoO4M/kaEdjBB+jpjg3f8I6te2SNU935SbkfY9KHAaFXMZwdcq7Fk932AxWEu+FMSDM+080wNKpEATXDe4=

287
assert.js

@ -1,5 +1,7 @@
// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 // 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) // Originally from narwhal.js (http://narwhaljs.org)
// Copyright (c) 2009 Thomas Robinson <280north.com> // Copyright (c) 2009 Thomas Robinson <280north.com>
// //
@ -20,14 +22,56 @@
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // 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. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// when used in node, this will actually load the util module we depend on 'use strict';
// versus loading the builtin util module as happens otherwise
// this is a bug in node module loading as far as I am concerned
var util = require('util/');
var pSlice = Array.prototype.slice; // UTILITY
function compare(bufa, bufb) {
var cmpLen = Math.min(bufa, bufb);
if (cmpLen <= 0) {
return 0;
}
var i = -1;
var a,b;
while (++i < cmpLen) {
a = bufa[i];
b = bufb[i];
if (a < b) {
return -1;
} else if (a > b) {
return 1;
}
}
return 0;
}
var util = require('util/');
var Buffer = require('buffer').Buffer;
var BufferShim = require('buffer-shims');
var hasOwn = Object.prototype.hasOwnProperty; var hasOwn = Object.prototype.hasOwnProperty;
var pSlice = Array.prototype.slice;
var functionsHaveNames = (function () {
return function foo() {}.name === 'foo';
}());
function pToString (obj) {
return Object.prototype.toString.call(obj);
}
function isView(arrbuf) {
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 // 1. The assert module provides functions that throw
// AssertionError's when particular conditions are not met. The // AssertionError's when particular conditions are not met. The
// assert module must conform to the following interface. // assert module must conform to the following interface.
@ -39,6 +83,19 @@ var assert = module.exports = ok;
// actual: actual, // actual: actual,
// expected: expected }) // 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 (!util.isFunction(func)) {
return;
}
if (functionsHaveNames) {
return func.name;
}
var str = func.toString();
var match = str.match(regex);
return match && match[1];
}
assert.AssertionError = function AssertionError(options) { assert.AssertionError = function AssertionError(options) {
this.name = 'AssertionError'; this.name = 'AssertionError';
this.actual = options.actual; this.actual = options.actual;
@ -52,59 +109,51 @@ assert.AssertionError = function AssertionError(options) {
this.generatedMessage = true; this.generatedMessage = true;
} }
var stackStartFunction = options.stackStartFunction || fail; var stackStartFunction = options.stackStartFunction || fail;
if (Error.captureStackTrace) { if (Error.captureStackTrace) {
Error.captureStackTrace(this, stackStartFunction); Error.captureStackTrace(this, stackStartFunction);
} } else {
else { // non v8 browsers so we can have a stacktrace
// non v8 browsers so we can have a stacktrace var err = new Error();
var err = new Error(); if (err.stack) {
if (err.stack) { var out = err.stack;
var out = err.stack;
// try to strip useless frames
// try to strip useless frames var fn_name = getName(stackStartFunction);
var fn_name = stackStartFunction.name; var idx = out.indexOf('\n' + fn_name);
var idx = out.indexOf('\n' + fn_name); if (idx >= 0) {
if (idx >= 0) { // once we have located the function frame
// once we have located the function frame // we need to strip out everything before it (and its line)
// we need to strip out everything before it (and its line) var next_line = out.indexOf('\n', idx + 1);
var next_line = out.indexOf('\n', idx + 1); out = out.substring(next_line + 1);
out = out.substring(next_line + 1); }
}
this.stack = out;
this.stack = out; }
}
} }
}; };
// assert.AssertionError instanceof Error // assert.AssertionError instanceof Error
util.inherits(assert.AssertionError, Error); util.inherits(assert.AssertionError, Error);
function replacer(key, value) {
if (util.isUndefined(value)) {
return '' + value;
}
if (util.isNumber(value) && !isFinite(value)) {
return value.toString();
}
if (util.isFunction(value) || util.isRegExp(value)) {
return value.toString();
}
return value;
}
function truncate(s, n) { function truncate(s, n) {
if (util.isString(s)) { if (typeof s === 'string') {
return s.length < n ? s : s.slice(0, n); return s.length < n ? s : s.slice(0, n);
} else { } else {
return s; return s;
} }
} }
function inspect(something) {
if (functionsHaveNames || !util.isFunction(something)) {
return util.inspect(something);
}
var rawname = getName(something);
var name = rawname ? ': ' + rawname : '';
return '[Function' + name + ']';
}
function getMessage(self) { function getMessage(self) {
return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + return truncate(inspect(self.actual), 128) + ' ' +
self.operator + ' ' + self.operator + ' ' +
truncate(JSON.stringify(self.expected, replacer), 128); truncate(inspect(self.expected), 128);
} }
// At present only the three keys mentioned above are used and // At present only the three keys mentioned above are used and
@ -164,24 +213,23 @@ assert.notEqual = function notEqual(actual, expected, message) {
// assert.deepEqual(actual, expected, message_opt); // assert.deepEqual(actual, expected, message_opt);
assert.deepEqual = function deepEqual(actual, expected, message) { assert.deepEqual = function deepEqual(actual, expected, message) {
if (!_deepEqual(actual, expected)) { if (!_deepEqual(actual, expected, false)) {
fail(actual, expected, message, 'deepEqual', assert.deepEqual); fail(actual, expected, message, 'deepEqual', assert.deepEqual);
} }
}; };
function _deepEqual(actual, expected) { assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) {
if (!_deepEqual(actual, expected, true)) {
fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual);
}
};
function _deepEqual(actual, expected, strict, memos) {
// 7.1. All identical values are equivalent, as determined by ===. // 7.1. All identical values are equivalent, as determined by ===.
if (actual === expected) { if (actual === expected) {
return true; return true;
} else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) {
} else if (util.isBuffer(actual) && util.isBuffer(expected)) { return compare(actual, expected) === 0;
if (actual.length != expected.length) return false;
for (var i = 0; i < actual.length; i++) {
if (actual[i] !== expected[i]) return false;
}
return true;
// 7.2. If the expected value is a Date object, the actual value is // 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. // equivalent if it is also a Date object that refers to the same time.
@ -200,8 +248,22 @@ function _deepEqual(actual, expected) {
// 7.4. Other pairs that do not both pass typeof value == 'object', // 7.4. Other pairs that do not both pass typeof value == 'object',
// equivalence is determined by ==. // equivalence is determined by ==.
} else if (!util.isObject(actual) && !util.isObject(expected)) { } else if ((actual === null || typeof actual !== 'object') &&
return actual == expected; (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(BufferShim.from(actual.buffer),
BufferShim.from(expected.buffer)) === 0;
// 7.5 For all other Object pairs, including Array objects, equivalence is // 7.5 For all other Object pairs, including Array objects, equivalence is
// determined by having the same number of owned properties (as verified // determined by having the same number of owned properties (as verified
@ -210,7 +272,19 @@ function _deepEqual(actual, expected) {
// corresponding key, and an identical 'prototype' property. Note: this // corresponding key, and an identical 'prototype' property. Note: this
// accounts for both named and indexed properties on Arrays. // accounts for both named and indexed properties on Arrays.
} else { } else {
return objEquiv(actual, expected); 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);
} }
} }
@ -218,44 +292,44 @@ function isArguments(object) {
return Object.prototype.toString.call(object) == '[object Arguments]'; return Object.prototype.toString.call(object) == '[object Arguments]';
} }
function objEquiv(a, b) { function objEquiv(a, b, strict, actualVisitedObjects) {
if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) if (a === null || a === undefined || b === null || b === undefined)
return false; return false;
// an identical 'prototype' property.
if (a.prototype !== b.prototype) return false;
// if one is a primitive, the other must be same // if one is a primitive, the other must be same
if (util.isPrimitive(a) || util.isPrimitive(b)) { if (util.isPrimitive(a) || util.isPrimitive(b))
return a === b; return a === b;
} if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b))
var aIsArgs = isArguments(a), return false;
bIsArgs = isArguments(b); var aIsArgs = isArguments(a);
var bIsArgs = isArguments(b);
if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs))
return false; return false;
if (aIsArgs) { if (aIsArgs) {
a = pSlice.call(a); a = pSlice.call(a);
b = pSlice.call(b); b = pSlice.call(b);
return _deepEqual(a, b); return _deepEqual(a, b, strict);
} }
var ka = objectKeys(a), var ka = objectKeys(a);
kb = objectKeys(b), var kb = objectKeys(b);
key, i; var key, i;
// having the same number of owned properties (keys incorporates // having the same number of owned properties (keys incorporates
// hasOwnProperty) // hasOwnProperty)
if (ka.length != kb.length) if (ka.length !== kb.length)
return false; return false;
//the same set of keys (although not necessarily the same order), //the same set of keys (although not necessarily the same order),
ka.sort(); ka.sort();
kb.sort(); kb.sort();
//~~~cheap key test //~~~cheap key test
for (i = ka.length - 1; i >= 0; i--) { for (i = ka.length - 1; i >= 0; i--) {
if (ka[i] != kb[i]) if (ka[i] !== kb[i])
return false; return false;
} }
//equivalent values for every corresponding key, and //equivalent values for every corresponding key, and
//~~~possibly expensive deep test //~~~possibly expensive deep test
for (i = ka.length - 1; i >= 0; i--) { for (i = ka.length - 1; i >= 0; i--) {
key = ka[i]; key = ka[i];
if (!_deepEqual(a[key], b[key])) return false; if (!_deepEqual(a[key], b[key], strict, actualVisitedObjects))
return false;
} }
return true; return true;
} }
@ -264,11 +338,19 @@ function objEquiv(a, b) {
// assert.notDeepEqual(actual, expected, message_opt); // assert.notDeepEqual(actual, expected, message_opt);
assert.notDeepEqual = function notDeepEqual(actual, expected, message) { assert.notDeepEqual = function notDeepEqual(actual, expected, message) {
if (_deepEqual(actual, expected)) { if (_deepEqual(actual, expected, false)) {
fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual);
} }
}; };
assert.notDeepStrictEqual = notDeepStrictEqual;
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 ===. // 9. The strict equality assertion tests strict equality, as determined by ===.
// assert.strictEqual(actual, expected, message_opt); // assert.strictEqual(actual, expected, message_opt);
@ -294,28 +376,46 @@ function expectedException(actual, expected) {
if (Object.prototype.toString.call(expected) == '[object RegExp]') { if (Object.prototype.toString.call(expected) == '[object RegExp]') {
return expected.test(actual); return expected.test(actual);
} else if (actual instanceof expected) {
return true;
} else if (expected.call({}, actual) === true) {
return true;
} }
return false; 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) { function _throws(shouldThrow, block, expected, message) {
var actual; var actual;
if (util.isString(expected)) { if (typeof block !== 'function') {
throw new TypeError('"block" argument must be a function');
}
if (typeof expected === 'string') {
message = expected; message = expected;
expected = null; expected = null;
} }
try { actual = _tryBlock(block);
block();
} catch (e) {
actual = e;
}
message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') +
(message ? ' ' + message : '.'); (message ? ' ' + message : '.');
@ -324,7 +424,14 @@ function _throws(shouldThrow, block, expected, message) {
fail(actual, expected, 'Missing expected exception' + message); fail(actual, expected, 'Missing expected exception' + message);
} }
if (!shouldThrow && expectedException(actual, expected)) { var userProvidedMessage = typeof message === 'string';
var isUnwantedException = !shouldThrow && util.isError(actual);
var isUnexpectedException = !shouldThrow && actual && !expected;
if ((isUnwantedException &&
userProvidedMessage &&
expectedException(actual, expected)) ||
isUnexpectedException) {
fail(actual, expected, 'Got unwanted exception' + message); fail(actual, expected, 'Got unwanted exception' + message);
} }
@ -338,15 +445,15 @@ function _throws(shouldThrow, block, expected, message) {
// assert.throws(block, Error_opt, message_opt); // assert.throws(block, Error_opt, message_opt);
assert.throws = function(block, /*optional*/error, /*optional*/message) { assert.throws = function(block, /*optional*/error, /*optional*/message) {
_throws.apply(this, [true].concat(pSlice.call(arguments))); _throws(true, block, error, message);
}; };
// EXTENSION! This is annoying to write outside this module. // EXTENSION! This is annoying to write outside this module.
assert.doesNotThrow = function(block, /*optional*/message) { assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) {
_throws.apply(this, [false].concat(pSlice.call(arguments))); _throws(false, block, error, message);
}; };
assert.ifError = function(err) { if (err) {throw err;}}; assert.ifError = function(err) { if (err) throw err; };
var objectKeys = Object.keys || function (obj) { var objectKeys = Object.keys || function (obj) {
var keys = []; var keys = [];

8
package.json

@ -12,14 +12,18 @@
}, },
"main": "./assert.js", "main": "./assert.js",
"dependencies": { "dependencies": {
"buffer-shims": "1.0.0",
"util": "0.10.3" "util": "0.10.3"
}, },
"devDependencies": { "devDependencies": {
"zuul": "~1.10.2", "zuul": "~3.9.0",
"mocha": "~1.21.4" "mocha": "~1.21.4"
}, },
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"test": "mocha --ui qunit test.js && zuul -- test.js" "test-node": "mocha --ui qunit test.js",
"test-browser": "zuul -- test.js",
"test": "npm run test-node && npm run test-browser",
"test-native": "TEST_NATIVE=true mocha --ui qunit test.js"
} }
} }

567
test.js

@ -19,9 +19,14 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE.
var assert = require('./'); var nodeAssert = require('assert');
var ourAssert = require('./');
var keys = Object.keys; var keys = Object.keys;
if (process.env.TEST_NATIVE === true) {
tests(nodeAssert, 'node assert');
} else {
tests(ourAssert, 'our assert');
}
function makeBlock(f) { function makeBlock(f) {
var args = Array.prototype.slice.call(arguments, 1); var args = Array.prototype.slice.call(arguments, 1);
@ -30,314 +35,296 @@ function makeBlock(f) {
}; };
} }
test('assert.ok', function () { function tests (assert, what) {
assert.throws(makeBlock(assert, false), assert.AssertionError, 'ok(false)'); test('assert.ok', function () {
assert.throws(makeBlock(assert, false), assert.AssertionError, 'ok(false)');
assert.doesNotThrow(makeBlock(assert, true), assert.AssertionError, 'ok(true)');
assert.doesNotThrow(makeBlock(assert, 'test', 'ok(\'test\')'));
assert.throws(makeBlock(assert.ok, false),
assert.AssertionError, 'ok(false)');
assert.doesNotThrow(makeBlock(assert, true), assert.AssertionError, 'ok(true)'); assert.doesNotThrow(makeBlock(assert.ok, true),
assert.AssertionError, 'ok(true)');
assert.doesNotThrow(makeBlock(assert, 'test', 'ok(\'test\')')); assert.doesNotThrow(makeBlock(assert.ok, 'test'), 'ok(\'test\')');
});
test('assert.equal', function () {
assert.throws(makeBlock(assert.equal, true, false), assert.AssertionError, 'equal');
assert.throws(makeBlock(assert.ok, false), assert.doesNotThrow(makeBlock(assert.equal, null, null), 'equal');
assert.AssertionError, 'ok(false)');
assert.doesNotThrow(makeBlock(assert.ok, true), assert.doesNotThrow(makeBlock(assert.equal, undefined, undefined), 'equal');
assert.AssertionError, 'ok(true)');
assert.doesNotThrow(makeBlock(assert.ok, 'test'), 'ok(\'test\')'); assert.doesNotThrow(makeBlock(assert.equal, null, undefined), 'equal');
});
test('assert.equal', function () { assert.doesNotThrow(makeBlock(assert.equal, true, true), 'equal');
assert.throws(makeBlock(assert.equal, true, false), assert.AssertionError, 'equal');
assert.doesNotThrow(makeBlock(assert.equal, null, null), 'equal'); assert.doesNotThrow(makeBlock(assert.equal, 2, '2'), 'equal');
assert.doesNotThrow(makeBlock(assert.equal, undefined, undefined), 'equal'); assert.doesNotThrow(makeBlock(assert.notEqual, true, false), 'notEqual');
assert.doesNotThrow(makeBlock(assert.equal, null, undefined), 'equal'); assert.throws(makeBlock(assert.notEqual, true, true),
assert.AssertionError, 'notEqual');
});
assert.doesNotThrow(makeBlock(assert.equal, true, true), 'equal'); test('assert.strictEqual', function () {
assert.throws(makeBlock(assert.strictEqual, 2, '2'),
assert.AssertionError, 'strictEqual');
assert.doesNotThrow(makeBlock(assert.equal, 2, '2'), 'equal'); assert.throws(makeBlock(assert.strictEqual, null, undefined),
assert.AssertionError, 'strictEqual');
assert.doesNotThrow(makeBlock(assert.notStrictEqual, 2, '2'), 'notStrictEqual');
});
assert.doesNotThrow(makeBlock(assert.notEqual, true, false), 'notEqual'); test('assert.deepStrictEqual', function () {
assert.throws(makeBlock(assert.deepStrictEqual, [2], ['2']),
assert.AssertionError, 'deepStrictEqual');
assert.throws(makeBlock(assert.notEqual, true, true), assert.throws(makeBlock(assert.deepStrictEqual, [null], [undefined]),
assert.AssertionError, 'notEqual'); assert.AssertionError, 'deepStrictEqual');
});
test('assert.strictEqual', function () { assert.doesNotThrow(makeBlock(assert.notDeepStrictEqual, [2], ['2']), 'notDeepStrictEqual');
assert.throws(makeBlock(assert.strictEqual, 2, '2'), });
assert.AssertionError, 'strictEqual');
assert.throws(makeBlock(assert.strictEqual, null, undefined), test('assert.deepEqual - 7.2', function () {
assert.AssertionError, 'strictEqual'); assert.doesNotThrow(makeBlock(assert.deepEqual, new Date(2000, 3, 14),
new Date(2000, 3, 14)), 'deepEqual date');
assert.doesNotThrow(makeBlock(assert.notStrictEqual, 2, '2'), 'notStrictEqual'); assert.throws(makeBlock(assert.deepEqual, new Date(), new Date(2000, 3, 14)),
}); assert.AssertionError,
'deepEqual date');
});
test('assert.deepEqual - 7.2', function () { test('assert.deepEqual - 7.3', function () {
assert.doesNotThrow(makeBlock(assert.deepEqual, new Date(2000, 3, 14), assert.doesNotThrow(makeBlock(assert.deepEqual, /a/, /a/));
new Date(2000, 3, 14)), 'deepEqual date'); assert.doesNotThrow(makeBlock(assert.deepEqual, /a/g, /a/g));
assert.doesNotThrow(makeBlock(assert.deepEqual, /a/i, /a/i));
assert.doesNotThrow(makeBlock(assert.deepEqual, /a/m, /a/m));
assert.doesNotThrow(makeBlock(assert.deepEqual, /a/igm, /a/igm));
assert.throws(makeBlock(assert.deepEqual, /ab/, /a/));
assert.throws(makeBlock(assert.deepEqual, /a/g, /a/));
assert.throws(makeBlock(assert.deepEqual, /a/i, /a/));
assert.throws(makeBlock(assert.deepEqual, /a/m, /a/));
assert.throws(makeBlock(assert.deepEqual, /a/igm, /a/im));
var re1 = /a/;
re1.lastIndex = 3;
assert.throws(makeBlock(assert.deepEqual, re1, /a/));
});
assert.throws(makeBlock(assert.deepEqual, new Date(), new Date(2000, 3, 14)), test('assert.deepEqual - 7.4', function () {
assert.doesNotThrow(makeBlock(assert.deepEqual, 4, '4'), 'deepEqual == check');
assert.doesNotThrow(makeBlock(assert.deepEqual, true, 1), 'deepEqual == check');
assert.throws(makeBlock(assert.deepEqual, 4, '5'),
assert.AssertionError, assert.AssertionError,
'deepEqual date'); 'deepEqual == check');
}); });
test('assert.deepEqual - 7.3', function () {
assert.doesNotThrow(makeBlock(assert.deepEqual, /a/, /a/));
assert.doesNotThrow(makeBlock(assert.deepEqual, /a/g, /a/g));
assert.doesNotThrow(makeBlock(assert.deepEqual, /a/i, /a/i));
assert.doesNotThrow(makeBlock(assert.deepEqual, /a/m, /a/m));
assert.doesNotThrow(makeBlock(assert.deepEqual, /a/igm, /a/igm));
assert.throws(makeBlock(assert.deepEqual, /ab/, /a/));
assert.throws(makeBlock(assert.deepEqual, /a/g, /a/));
assert.throws(makeBlock(assert.deepEqual, /a/i, /a/));
assert.throws(makeBlock(assert.deepEqual, /a/m, /a/));
assert.throws(makeBlock(assert.deepEqual, /a/igm, /a/im));
var re1 = /a/;
re1.lastIndex = 3;
assert.throws(makeBlock(assert.deepEqual, re1, /a/));
});
test('assert.deepEqual - 7.4', function () {
assert.doesNotThrow(makeBlock(assert.deepEqual, 4, '4'), 'deepEqual == check');
assert.doesNotThrow(makeBlock(assert.deepEqual, true, 1), 'deepEqual == check');
assert.throws(makeBlock(assert.deepEqual, 4, '5'),
assert.AssertionError,
'deepEqual == check');
});
test('assert.deepEqual - 7.5', function () {
// having the same number of owned properties && the same set of keys
assert.doesNotThrow(makeBlock(assert.deepEqual, {a: 4}, {a: 4}));
assert.doesNotThrow(makeBlock(assert.deepEqual, {a: 4, b: '2'}, {a: 4, b: '2'}));
assert.doesNotThrow(makeBlock(assert.deepEqual, [4], ['4']));
assert.throws(makeBlock(assert.deepEqual, {a: 4}, {a: 4, b: true}),
assert.AssertionError);
assert.doesNotThrow(makeBlock(assert.deepEqual, ['a'], {0: 'a'}));
//(although not necessarily the same order),
assert.doesNotThrow(makeBlock(assert.deepEqual, {a: 4, b: '1'}, {b: '1', a: 4}));
var a1 = [1, 2, 3];
var a2 = [1, 2, 3];
a1.a = 'test';
a1.b = true;
a2.b = true;
a2.a = 'test';
assert.throws(makeBlock(assert.deepEqual, keys(a1), keys(a2)),
assert.AssertionError);
assert.doesNotThrow(makeBlock(assert.deepEqual, a1, a2));
});
test('assert.deepEqual - instances', function () {
// having an identical prototype property
var nbRoot = {
toString: function() { return this.first + ' ' + this.last; }
};
function nameBuilder(first, last) { test('assert.deepEqual - 7.5', function () {
this.first = first; // having the same number of owned properties && the same set of keys
this.last = last; assert.doesNotThrow(makeBlock(assert.deepEqual, {a: 4}, {a: 4}));
return this; assert.doesNotThrow(makeBlock(assert.deepEqual, {a: 4, b: '2'}, {a: 4, b: '2'}));
} assert.doesNotThrow(makeBlock(assert.deepEqual, [4], ['4']));
nameBuilder.prototype = nbRoot; assert.throws(makeBlock(assert.deepEqual, {a: 4}, {a: 4, b: true}),
assert.AssertionError);
function nameBuilder2(first, last) { assert.doesNotThrow(makeBlock(assert.deepEqual, ['a'], {0: 'a'}));
this.first = first; //(although not necessarily the same order),
this.last = last; assert.doesNotThrow(makeBlock(assert.deepEqual, {a: 4, b: '1'}, {b: '1', a: 4}));
return this; var a1 = [1, 2, 3];
} var a2 = [1, 2, 3];
nameBuilder2.prototype = nbRoot; a1.a = 'test';
a1.b = true;
var nb1 = new nameBuilder('Ryan', 'Dahl'); a2.b = true;
var nb2 = new nameBuilder2('Ryan', 'Dahl'); a2.a = 'test';
assert.throws(makeBlock(assert.deepEqual, keys(a1), keys(a2)),
assert.doesNotThrow(makeBlock(assert.deepEqual, nb1, nb2)); assert.AssertionError);
assert.doesNotThrow(makeBlock(assert.deepEqual, a1, a2));
nameBuilder2.prototype = Object; });
nb2 = new nameBuilder2('Ryan', 'Dahl');
assert.throws(makeBlock(assert.deepEqual, nb1, nb2), assert.AssertionError);
});
test('assert.deepEqual - ES6 primitives', function () {
assert.throws(makeBlock(assert.deepEqual, null, {}), assert.AssertionError);
assert.throws(makeBlock(assert.deepEqual, undefined, {}), assert.AssertionError);
assert.throws(makeBlock(assert.deepEqual, 'a', ['a']), assert.AssertionError);
assert.throws(makeBlock(assert.deepEqual, 'a', {0: 'a'}), assert.AssertionError);
assert.throws(makeBlock(assert.deepEqual, 1, {}), assert.AssertionError);
assert.throws(makeBlock(assert.deepEqual, true, {}), assert.AssertionError);
if (typeof Symbol === 'symbol') {
assert.throws(makeBlock(assert.deepEqual, Symbol(), {}), assert.AssertionError);
}
});
test('assert.deepEqual - object wrappers', function () {
assert.doesNotThrow(makeBlock(assert.deepEqual, new String('a'), ['a']));
assert.doesNotThrow(makeBlock(assert.deepEqual, new String('a'), {0: 'a'}));
assert.doesNotThrow(makeBlock(assert.deepEqual, new Number(1), {}));
assert.doesNotThrow(makeBlock(assert.deepEqual, new Boolean(true), {}));
});
function thrower(errorConstructor) {
throw new errorConstructor('test');
}
test('assert - Testing the throwing', function () { test('assert.deepEqual - ES6 primitives', function () {
var aethrow = makeBlock(thrower, assert.AssertionError); assert.throws(makeBlock(assert.deepEqual, null, {}), assert.AssertionError);
aethrow = makeBlock(thrower, assert.AssertionError); assert.throws(makeBlock(assert.deepEqual, undefined, {}), assert.AssertionError);
assert.throws(makeBlock(assert.deepEqual, 'a', ['a']), assert.AssertionError);
// the basic calls work assert.throws(makeBlock(assert.deepEqual, 'a', {0: 'a'}), assert.AssertionError);
assert.throws(makeBlock(thrower, assert.AssertionError), assert.throws(makeBlock(assert.deepEqual, 1, {}), assert.AssertionError);
assert.AssertionError, 'message'); assert.throws(makeBlock(assert.deepEqual, true, {}), assert.AssertionError);
assert.throws(makeBlock(thrower, assert.AssertionError), assert.AssertionError); if (typeof Symbol === 'symbol') {
assert.throws(makeBlock(thrower, assert.AssertionError)); assert.throws(makeBlock(assert.deepEqual, Symbol(), {}), assert.AssertionError);
}
// if not passing an error, catch all. });
assert.throws(makeBlock(thrower, TypeError));
test('assert.deepEqual - object wrappers', function () {
// when passing a type, only catch errors of the appropriate type assert.doesNotThrow(makeBlock(assert.deepEqual, new String('a'), ['a']));
var threw = false; assert.doesNotThrow(makeBlock(assert.deepEqual, new String('a'), {0: 'a'}));
try { assert.doesNotThrow(makeBlock(assert.deepEqual, new Number(1), {}));
assert.throws(makeBlock(thrower, TypeError), assert.AssertionError); assert.doesNotThrow(makeBlock(assert.deepEqual, new Boolean(true), {}));
} catch (e) { });
threw = true;
assert.ok(e instanceof TypeError, 'type'); function thrower(errorConstructor) {
} throw new errorConstructor('test');
assert.equal(true, threw,
'a.throws with an explicit error is eating extra errors',
assert.AssertionError);
threw = false;
// doesNotThrow should pass through all errors
try {
assert.doesNotThrow(makeBlock(thrower, TypeError), assert.AssertionError);
} catch (e) {
threw = true;
assert.ok(e instanceof TypeError);
}
assert.equal(true, threw,
'a.doesNotThrow with an explicit error is eating extra errors');
// key difference is that throwing our correct error makes an assertion error
try {
assert.doesNotThrow(makeBlock(thrower, TypeError), TypeError);
} catch (e) {
threw = true;
assert.ok(e instanceof assert.AssertionError);
}
assert.equal(true, threw,
'a.doesNotThrow is not catching type matching errors');
});
test('assert.ifError', function () {
assert.throws(function() {assert.ifError(new Error('test error'))});
assert.doesNotThrow(function() {assert.ifError(null)});
assert.doesNotThrow(function() {assert.ifError()});
});
test('assert - make sure that validating using constructor really works', function () {
var threw = false;
try {
assert.throws(
function() {
throw ({});
},
Array
);
} catch (e) {
threw = true;
}
assert.ok(threw, 'wrong constructor validation');
});
test('assert - use a RegExp to validate error message', function () {
assert.throws(makeBlock(thrower, TypeError), /test/);
});
test('assert - se a fn to validate error object', function () {
assert.throws(makeBlock(thrower, TypeError), function(err) {
if ((err instanceof TypeError) && /test/.test(err)) {
return true;
}
});
});
test('assert - Make sure deepEqual doesn\'t loop forever on circular refs', function () {
var b = {};
b.b = b;
var c = {};
c.b = c;
var gotError = false;
try {
assert.deepEqual(b, c);
} catch (e) {
gotError = true;
}
assert.ok(gotError);
});
test('assert - Ensure reflexivity of deepEqual with `arguments` objects', function() {
var args = (function() { return arguments; })();
assert.throws(makeBlock(assert.deepEqual, [], args), assert.AssertionError);
assert.throws(makeBlock(assert.deepEqual, args, []), assert.AssertionError);
});
test('assert - test assertion message', function () {
function testAssertionMessage(actual, expected) {
try {
assert.equal(actual, '');
} catch (e) {
assert.equal(e.toString(),
['AssertionError:', expected, '==', '""'].join(' '));
} }
}
testAssertionMessage(undefined, '"undefined"'); test('assert - Testing the throwing', function () {
testAssertionMessage(null, 'null'); var aethrow = makeBlock(thrower, assert.AssertionError);
testAssertionMessage(true, 'true'); aethrow = makeBlock(thrower, assert.AssertionError);
testAssertionMessage(false, 'false');
testAssertionMessage(0, '0'); // the basic calls work
testAssertionMessage(100, '100'); assert.throws(makeBlock(thrower, assert.AssertionError),
testAssertionMessage(NaN, '"NaN"'); assert.AssertionError, 'message');
testAssertionMessage(Infinity, '"Infinity"'); assert.throws(makeBlock(thrower, assert.AssertionError), assert.AssertionError);
testAssertionMessage(-Infinity, '"-Infinity"'); assert.throws(makeBlock(thrower, assert.AssertionError));
testAssertionMessage('', '""');
testAssertionMessage('foo', '"foo"'); // if not passing an error, catch all.
testAssertionMessage([], '[]'); assert.throws(makeBlock(thrower, TypeError));
testAssertionMessage([1, 2, 3], '[1,2,3]');
testAssertionMessage(/a/, '"/a/"'); // when passing a type, only catch errors of the appropriate type
testAssertionMessage(function f() {}, '"function f() {}"'); var threw = false;
testAssertionMessage({}, '{}'); try {
testAssertionMessage({a: undefined, b: null}, '{"a":"undefined","b":null}'); assert.throws(makeBlock(thrower, TypeError), assert.AssertionError);
testAssertionMessage({a: NaN, b: Infinity, c: -Infinity}, } catch (e) {
'{"a":"NaN","b":"Infinity","c":"-Infinity"}'); threw = true;
}); assert.ok(e instanceof TypeError, 'type');
}
test('assert - regressions from node.js testcase', function () { assert.equal(true, threw,
var threw = false; 'a.throws with an explicit error is eating extra errors',
assert.AssertionError);
try { threw = false;
assert.throws(function () {
assert.ifError(null); // doesNotThrow should pass through all errors
try {
assert.doesNotThrow(makeBlock(thrower, TypeError), assert.AssertionError);
} catch (e) {
threw = true;
assert.ok(e instanceof TypeError);
}
assert.equal(true, threw,
'a.doesNotThrow with an explicit error is eating extra errors');
// key difference is that throwing our correct error makes an assertion error
try {
assert.doesNotThrow(makeBlock(thrower, TypeError), TypeError);
} catch (e) {
threw = true;
assert.ok(e instanceof assert.AssertionError);
}
assert.equal(true, threw,
'a.doesNotThrow is not catching type matching errors');
});
test('assert.ifError', function () {
assert.throws(function() {assert.ifError(new Error('test error'))});
assert.doesNotThrow(function() {assert.ifError(null)});
assert.doesNotThrow(function() {assert.ifError()});
});
test('assert - make sure that validating using constructor really works', function () {
var threw = false;
try {
assert.throws(
function() {
throw ({});
},
Array
);
} catch (e) {
threw = true;
}
assert.ok(threw, 'wrong constructor validation');
});
test('assert - use a RegExp to validate error message', function () {
assert.throws(makeBlock(thrower, TypeError), /test/);
});
test('assert - se a fn to validate error object', function () {
assert.throws(makeBlock(thrower, TypeError), function(err) {
if ((err instanceof TypeError) && /test/.test(err)) {
return true;
}
});
});
test('assert - Make sure deepEqual doesn\'t loop forever on circular refs', function () {
var b = {};
b.b = b;
var c = {};
c.b = c;
var gotError = false;
var equal = true;
try {
equal = assert.deepEqual(b, c);
} catch (e) {
gotError = true;
}
assert.ok(gotError || !equal, gotError ? 'got error': 'are equal');
});
test('assert - Ensure reflexivity of deepEqual with `arguments` objects', function() {
var args = (function() { return arguments; })();
assert.throws(makeBlock(assert.deepEqual, [], args), assert.AssertionError);
assert.throws(makeBlock(assert.deepEqual, args, []), assert.AssertionError);
}); });
} catch (e) {
threw = true; test('assert - test assertion message', function () {
assert.equal(e.message, 'Missing expected exception..'); function testAssertionMessage(actual, expected) {
} try {
assert.ok(threw); assert.equal(actual, '');
} catch (e) {
try { assert.equal(e.toString(),
assert.equal(1, 2); ['AssertionError:', expected, '==', '\'\''].join(' '));
} catch (e) { }
assert.equal(e.toString().split('\n')[0], 'AssertionError: 1 == 2'); }
} testAssertionMessage(undefined, 'undefined');
testAssertionMessage(null, 'null');
try { testAssertionMessage(true, 'true');
assert.equal(1, 2, 'oh no'); testAssertionMessage(false, 'false');
} catch (e) { testAssertionMessage(0, '0');
assert.equal(e.toString().split('\n')[0], 'AssertionError: oh no'); testAssertionMessage(100, '100');
} testAssertionMessage(NaN, 'NaN');
}); testAssertionMessage(Infinity, 'Infinity');
testAssertionMessage(-Infinity, '-Infinity');
testAssertionMessage('', '""');
testAssertionMessage('foo', '\'foo\'');
testAssertionMessage([], '[]');
testAssertionMessage([1, 2, 3], '[ 1, 2, 3 ]');
testAssertionMessage(/a/, '/a/');
testAssertionMessage(function f() {}, '[Function: f]');
testAssertionMessage({}, '{}');
testAssertionMessage({a: undefined, b: null}, '{ a: undefined, b: null }');
testAssertionMessage({a: NaN, b: Infinity, c: -Infinity},
'{ a: NaN, b: Infinity, c: -Infinity }');
});
test('assert - regressions from node.js testcase', function () {
var threw = false;
try {
assert.throws(function () {
assert.ifError(null);
});
} catch (e) {
threw = true;
assert.equal(e.message, 'Missing expected exception..');
}
assert.ok(threw);
try {
assert.equal(1, 2);
} catch (e) {
assert.equal(e.toString().split('\n')[0], 'AssertionError: 1 == 2');
}
try {
assert.equal(1, 2, 'oh no');
} catch (e) {
assert.equal(e.toString().split('\n')[0], 'AssertionError: oh no');
}
});
}

Loading…
Cancel
Save