├── .editorconfig ├── .gitattributes ├── .gitignore ├── .travis.yml ├── index.js ├── license ├── package.json ├── readme.md └── test ├── common.js ├── error-extend.js └── test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [{package.json,*.yml}] 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [*.md] 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 'stable' 4 | - '0.12' 5 | - '0.10' 6 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | // https://github.com/nodejs/node/commit/c1d82ac2ff15594840e2a1b9531b506ae067ed27 2 | // ------------------- // 3 | 4 | 5 | // http://wiki.commonjs.org/wiki/Unit_Testing/1.0 6 | // 7 | // THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! 8 | // 9 | // Originally from narwhal.js (http://narwhaljs.org) 10 | // Copyright (c) 2009 Thomas Robinson <280north.com> 11 | // 12 | // Permission is hereby granted, free of charge, to any person obtaining a copy 13 | // of this software and associated documentation files (the 'Software'), to 14 | // deal in the Software without restriction, including without limitation the 15 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16 | // sell copies of the Software, and to permit persons to whom the Software is 17 | // furnished to do so, subject to the following conditions: 18 | // 19 | // The above copyright notice and this permission notice shall be included in 20 | // all copies or substantial portions of the Software. 21 | // 22 | // THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | // AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 26 | // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 27 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | 29 | 'use strict'; 30 | 31 | 32 | // ------------------- // 33 | function isPrimitive(arg) { 34 | return arg === null || 35 | typeof arg !== 'object' && typeof arg !== 'function'; 36 | } 37 | // ------------------- // 38 | 39 | 40 | // UTILITY 41 | // var compare = process.binding('buffer').compare; 42 | 43 | // ------------------- // 44 | // Use a polyfill for Node.js 0.10 support 45 | var compare = require('buf-compare'); 46 | var isError = require('is-error'); 47 | // ------------------- // 48 | 49 | var util = require('util'); 50 | var Buffer = require('buffer').Buffer; 51 | var pSlice = Array.prototype.slice; 52 | 53 | // 1. The assert module provides functions that throw 54 | // AssertionError's when particular conditions are not met. The 55 | // assert module must conform to the following interface. 56 | 57 | var assert = module.exports = ok; 58 | 59 | // 2. The AssertionError is defined in assert. 60 | // new assert.AssertionError({ message: message, 61 | // actual: actual, 62 | // expected: expected }) 63 | 64 | assert.AssertionError = function AssertionError(options) { 65 | this.name = 'AssertionError'; 66 | this.actual = options.actual; 67 | this.expected = options.expected; 68 | this.operator = options.operator; 69 | if (options.message) { 70 | this.message = options.message; 71 | this.generatedMessage = false; 72 | } else { 73 | this.message = getMessage(this); 74 | this.generatedMessage = true; 75 | } 76 | var stackStartFunction = options.stackStartFunction || fail; 77 | Error.captureStackTrace(this, stackStartFunction); 78 | }; 79 | 80 | // assert.AssertionError instanceof Error 81 | util.inherits(assert.AssertionError, Error); 82 | 83 | function truncate(s, n) { 84 | if (typeof s === 'string') { 85 | return s.length < n ? s : s.slice(0, n); 86 | } else { 87 | return s; 88 | } 89 | } 90 | 91 | function getMessage(self) { 92 | return truncate(util.inspect(self.actual), 128) + ' ' + 93 | self.operator + ' ' + 94 | truncate(util.inspect(self.expected), 128); 95 | } 96 | 97 | // At present only the three keys mentioned above are used and 98 | // understood by the spec. Implementations or sub modules can pass 99 | // other keys to the AssertionError's constructor - they will be 100 | // ignored. 101 | 102 | // 3. All of the following functions must throw an AssertionError 103 | // when a corresponding condition is not met, with a message that 104 | // may be undefined if not provided. All assertion methods provide 105 | // both the actual and expected values to the assertion error for 106 | // display purposes. 107 | 108 | function fail(actual, expected, message, operator, stackStartFunction) { 109 | throw new assert.AssertionError({ 110 | message: message, 111 | actual: actual, 112 | expected: expected, 113 | operator: operator, 114 | stackStartFunction: stackStartFunction 115 | }); 116 | } 117 | 118 | // EXTENSION! allows for well behaved errors defined elsewhere. 119 | assert.fail = fail; 120 | 121 | // 4. Pure assertion tests whether a value is truthy, as determined 122 | // by !!guard. 123 | // assert.ok(guard, message_opt); 124 | // This statement is equivalent to assert.equal(true, !!guard, 125 | // message_opt);. To test strictly for the value true, use 126 | // assert.strictEqual(true, guard, message_opt);. 127 | 128 | function ok(value, message) { 129 | if (!value) fail(value, true, message, '==', assert.ok); 130 | } 131 | assert.ok = ok; 132 | 133 | // 5. The equality assertion tests shallow, coercive equality with 134 | // ==. 135 | // assert.equal(actual, expected, message_opt); 136 | 137 | assert.equal = function equal(actual, expected, message) { 138 | if (actual != expected) fail(actual, expected, message, '==', assert.equal); 139 | }; 140 | 141 | // 6. The non-equality assertion tests for whether two objects are not equal 142 | // with != assert.notEqual(actual, expected, message_opt); 143 | 144 | assert.notEqual = function notEqual(actual, expected, message) { 145 | if (actual == expected) { 146 | fail(actual, expected, message, '!=', assert.notEqual); 147 | } 148 | }; 149 | 150 | // 7. The equivalence assertion tests a deep equality relation. 151 | // assert.deepEqual(actual, expected, message_opt); 152 | 153 | assert.deepEqual = function deepEqual(actual, expected, message) { 154 | if (!_deepEqual(actual, expected, false)) { 155 | fail(actual, expected, message, 'deepEqual', assert.deepEqual); 156 | } 157 | }; 158 | 159 | assert.deepStrictEqual = function deepStrictEqual(actual, expected, message) { 160 | if (!_deepEqual(actual, expected, true)) { 161 | fail(actual, expected, message, 'deepStrictEqual', assert.deepStrictEqual); 162 | } 163 | }; 164 | 165 | function _deepEqual(actual, expected, strict) { 166 | // 7.1. All identical values are equivalent, as determined by ===. 167 | if (actual === expected) { 168 | return true; 169 | } else if (actual instanceof Buffer && expected instanceof Buffer) { 170 | return compare(actual, expected) === 0; 171 | 172 | // 7.2. If the expected value is a Date object, the actual value is 173 | // equivalent if it is also a Date object that refers to the same time. 174 | } else if (util.isDate(actual) && util.isDate(expected)) { 175 | return actual.getTime() === expected.getTime(); 176 | 177 | // 7.3 If the expected value is a RegExp object, the actual value is 178 | // equivalent if it is also a RegExp object with the same source and 179 | // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). 180 | } else if (util.isRegExp(actual) && util.isRegExp(expected)) { 181 | return actual.source === expected.source && 182 | actual.global === expected.global && 183 | actual.multiline === expected.multiline && 184 | actual.lastIndex === expected.lastIndex && 185 | actual.ignoreCase === expected.ignoreCase; 186 | 187 | // 7.4. Other pairs that do not both pass typeof value == 'object', 188 | // equivalence is determined by ==. 189 | } else if ((actual === null || typeof actual !== 'object') && 190 | (expected === null || typeof expected !== 'object')) { 191 | return strict ? actual === expected : actual == expected; 192 | 193 | // 7.5 For all other Object pairs, including Array objects, equivalence is 194 | // determined by having the same number of owned properties (as verified 195 | // with Object.prototype.hasOwnProperty.call), the same set of keys 196 | // (although not necessarily the same order), equivalent values for every 197 | // corresponding key, and an identical 'prototype' property. Note: this 198 | // accounts for both named and indexed properties on Arrays. 199 | } else { 200 | return objEquiv(actual, expected, strict); 201 | } 202 | } 203 | 204 | function isArguments(object) { 205 | return Object.prototype.toString.call(object) == '[object Arguments]'; 206 | } 207 | 208 | function objEquiv(a, b, strict) { 209 | if (a === null || a === undefined || b === null || b === undefined) 210 | return false; 211 | // if one is a primitive, the other must be same 212 | if (isPrimitive(a) || isPrimitive(b)) 213 | return a === b; 214 | if (strict && Object.getPrototypeOf(a) !== Object.getPrototypeOf(b)) 215 | return false; 216 | var aIsArgs = isArguments(a), 217 | bIsArgs = isArguments(b); 218 | if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) 219 | return false; 220 | if (aIsArgs) { 221 | a = pSlice.call(a); 222 | b = pSlice.call(b); 223 | return _deepEqual(a, b, strict); 224 | } 225 | var ka = Object.keys(a), 226 | kb = Object.keys(b), 227 | key, i; 228 | // having the same number of owned properties (keys incorporates 229 | // hasOwnProperty) 230 | if (ka.length !== kb.length) 231 | return false; 232 | //the same set of keys (although not necessarily the same order), 233 | ka.sort(); 234 | kb.sort(); 235 | //~~~cheap key test 236 | for (i = ka.length - 1; i >= 0; i--) { 237 | if (ka[i] !== kb[i]) 238 | return false; 239 | } 240 | //equivalent values for every corresponding key, and 241 | //~~~possibly expensive deep test 242 | for (i = ka.length - 1; i >= 0; i--) { 243 | key = ka[i]; 244 | if (!_deepEqual(a[key], b[key], strict)) return false; 245 | } 246 | return true; 247 | } 248 | 249 | // 8. The non-equivalence assertion tests for any deep inequality. 250 | // assert.notDeepEqual(actual, expected, message_opt); 251 | 252 | assert.notDeepEqual = function notDeepEqual(actual, expected, message) { 253 | if (_deepEqual(actual, expected, false)) { 254 | fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); 255 | } 256 | }; 257 | 258 | assert.notDeepStrictEqual = notDeepStrictEqual; 259 | function notDeepStrictEqual(actual, expected, message) { 260 | if (_deepEqual(actual, expected, true)) { 261 | fail(actual, expected, message, 'notDeepStrictEqual', notDeepStrictEqual); 262 | } 263 | } 264 | 265 | 266 | // 9. The strict equality assertion tests strict equality, as determined by ===. 267 | // assert.strictEqual(actual, expected, message_opt); 268 | 269 | assert.strictEqual = function strictEqual(actual, expected, message) { 270 | if (actual !== expected) { 271 | fail(actual, expected, message, '===', assert.strictEqual); 272 | } 273 | }; 274 | 275 | // 10. The strict non-equality assertion tests for strict inequality, as 276 | // determined by !==. assert.notStrictEqual(actual, expected, message_opt); 277 | 278 | assert.notStrictEqual = function notStrictEqual(actual, expected, message) { 279 | if (actual === expected) { 280 | fail(actual, expected, message, '!==', assert.notStrictEqual); 281 | } 282 | }; 283 | 284 | function expectedException(actual, expected) { 285 | if (!actual || !expected) { 286 | return false; 287 | } 288 | 289 | if (Object.prototype.toString.call(expected) == '[object RegExp]') { 290 | return expected.test(actual); 291 | } 292 | 293 | try { 294 | if (actual instanceof expected) { 295 | return true; 296 | } 297 | } catch (e) { 298 | // Ignore. The instanceof check doesn't work for arrow functions. 299 | } 300 | 301 | if (Error.isPrototypeOf && Error.isPrototypeOf(expected)) { 302 | return false; 303 | } 304 | 305 | return expected.call({}, actual) === true; 306 | } 307 | 308 | function _tryBlock(block) { 309 | var error; 310 | try { 311 | block(); 312 | } catch (e) { 313 | error = e; 314 | } 315 | return error; 316 | } 317 | 318 | function _throws(shouldThrow, block, expected, message) { 319 | var actual; 320 | 321 | if (typeof block !== 'function') { 322 | throw new TypeError('"block" argument must be a function'); 323 | } 324 | 325 | if (typeof expected === 'string') { 326 | message = expected; 327 | expected = null; 328 | } 329 | 330 | actual = _tryBlock(block); 331 | 332 | message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + 333 | (message ? ' ' + message : '.'); 334 | 335 | if (shouldThrow && !actual) { 336 | fail(actual, expected, 'Missing expected exception' + message); 337 | } 338 | 339 | var userProvidedMessage = typeof message === 'string'; 340 | var isUnwantedException = !shouldThrow && isError(actual); 341 | var isUnexpectedException = !shouldThrow && actual && !expected; 342 | 343 | if ((isUnwantedException && 344 | userProvidedMessage && 345 | expectedException(actual, expected)) || 346 | isUnexpectedException) { 347 | fail(actual, expected, 'Got unwanted exception' + message); 348 | } 349 | 350 | if ((shouldThrow && actual && expected && 351 | !expectedException(actual, expected)) || (!shouldThrow && actual)) { 352 | throw actual; 353 | } 354 | } 355 | 356 | // 11. Expected to throw an error: 357 | // assert.throws(block, Error_opt, message_opt); 358 | 359 | assert.throws = function(block, /*optional*/error, /*optional*/message) { 360 | _throws(true, block, error, message); 361 | }; 362 | 363 | // EXTENSION! This is annoying to write outside this module. 364 | assert.doesNotThrow = function(block, /*optional*/error, /*optional*/message) { 365 | _throws(false, block, error, message); 366 | }; 367 | 368 | assert.ifError = function(err) { if (err) throw err; }; 369 | 370 | 371 | // ------------------- // 372 | // exposing this for the `deep-strict-equal` module 373 | Object.defineProperty(assert, '__deepEqual', {value: _deepEqual}); 374 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Sindre Sorhus (sindresorhus.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "core-assert", 3 | "version": "1.0.0", 4 | "description": "Node.js `assert` as a standalone module", 5 | "license": "MIT", 6 | "repository": "sindresorhus/core-assert", 7 | "author": { 8 | "name": "Sindre Sorhus", 9 | "email": "sindresorhus@gmail.com", 10 | "url": "sindresorhus.com" 11 | }, 12 | "engines": { 13 | "node": ">=0.10.0" 14 | }, 15 | "scripts": { 16 | "test": "node test/test.js" 17 | }, 18 | "files": [ 19 | "index.js" 20 | ], 21 | "keywords": [ 22 | "builtin", 23 | "core", 24 | "ponyfill", 25 | "polyfill", 26 | "shim", 27 | "assert", 28 | "assertion", 29 | "test", 30 | "testing", 31 | "deep", 32 | "strict", 33 | "equal", 34 | "equality", 35 | "eq", 36 | "same" 37 | ], 38 | "dependencies": { 39 | "buf-compare": "^1.0.0", 40 | "is-error": "^2.2.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Deprecated 2 | 3 | I don't have time or interest in keeping it in sync with Node.js anymore. It should continue to work fine though. It's just missing some improvements from later Node.js versions. 4 | 5 | --- 6 | 7 | # core-assert [![Build Status](https://travis-ci.org/sindresorhus/core-assert.svg?branch=master)](https://travis-ci.org/sindresorhus/core-assert) 8 | 9 | > Node.js [`assert`](https://nodejs.org/api/assert.html) as a standalone module *([ponyfill](https://ponyfill.com))* 10 | 11 | Useful to ensure consistency between Node.js versions as the `assert` module has changed a lot. 12 | 13 | Lets you use the Node.js 4.0 `assert.deepStrictEqual()`/`assert.notDeepStrictEqual()` methods all the way back to Node.js 0.10. 14 | 15 | *Issues and improvements should be done in [Node.js](https://github.com/nodejs/node/issues) first.* 16 | 17 | 18 | ## Install 19 | 20 | ``` 21 | $ npm install --save core-assert 22 | ``` 23 | 24 | 25 | ## Usage 26 | 27 | ```js 28 | var assert = require('core-assert'); 29 | 30 | assert.strictEqual('unicorn', 'unicorn'); 31 | ``` 32 | 33 | 34 | ## Related 35 | 36 | - [deep-strict-equal](https://github.com/sindresorhus/deep-strict-equal) - Test for deep equality - Node.js `assert.deepStrictEqual()` algorithm as a standalone module 37 | 38 | 39 | ## License 40 | 41 | MIT © [Sindre Sorhus](http://sindresorhus.com) 42 | -------------------------------------------------------------------------------- /test/common.js: -------------------------------------------------------------------------------- 1 | // https://github.com/nodejs/node/blob/680dda802393ef1513a8a84a353dfc2ecfacacb2/test/common.js 2 | 'use strict'; 3 | 4 | function protoCtrChain(o) { 5 | var result = []; 6 | for (; o; o = o.__proto__) { result.push(o.constructor); } 7 | return result.join(); 8 | } 9 | 10 | exports.indirectInstanceOf = function(obj, cls) { 11 | if (obj instanceof cls) { return true; } 12 | var clsChain = protoCtrChain(cls.prototype); 13 | var objChain = protoCtrChain(obj); 14 | return objChain.slice(-clsChain.length) === clsChain; 15 | }; 16 | -------------------------------------------------------------------------------- /test/error-extend.js: -------------------------------------------------------------------------------- 1 | // https://github.com/nodejs/node/issues/3188 2 | threw = false; 3 | 4 | try { 5 | var ES6Error = class extends Error {}; 6 | 7 | var AnotherErrorType = class extends Error {}; 8 | 9 | const functionThatThrows = function() { 10 | throw new AnotherErrorType('foo'); 11 | }; 12 | 13 | assert.throws(functionThatThrows, ES6Error); 14 | } catch (e) { 15 | threw = true; 16 | assert(e instanceof AnotherErrorType, 17 | `expected AnotherErrorType, received ${e}`); 18 | } 19 | 20 | assert.ok(threw); 21 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | // https://github.com/nodejs/node/blob/c1d82ac2ff15594840e2a1b9531b506ae067ed27/test/parallel/test-assert.js 2 | 'use strict'; 3 | var common = require('./common'); 4 | var a = require('../'); 5 | var assert = a; 6 | 7 | function makeBlock(f) { 8 | var args = Array.prototype.slice.call(arguments, 1); 9 | return function() { 10 | return f.apply(this, args); 11 | }; 12 | } 13 | 14 | assert.ok(common.indirectInstanceOf(a.AssertionError.prototype, Error), 15 | 'a.AssertionError instanceof Error'); 16 | 17 | assert.throws(makeBlock(a, false), a.AssertionError, 'ok(false)'); 18 | 19 | assert.doesNotThrow(makeBlock(a, true), a.AssertionError, 'ok(true)'); 20 | 21 | assert.doesNotThrow(makeBlock(a, 'test', 'ok(\'test\')')); 22 | 23 | assert.throws(makeBlock(a.ok, false), 24 | a.AssertionError, 'ok(false)'); 25 | 26 | assert.doesNotThrow(makeBlock(a.ok, true), 27 | a.AssertionError, 'ok(true)'); 28 | 29 | assert.doesNotThrow(makeBlock(a.ok, 'test'), 'ok(\'test\')'); 30 | 31 | assert.throws(makeBlock(a.equal, true, false), a.AssertionError, 'equal'); 32 | 33 | assert.doesNotThrow(makeBlock(a.equal, null, null), 'equal'); 34 | 35 | assert.doesNotThrow(makeBlock(a.equal, undefined, undefined), 'equal'); 36 | 37 | assert.doesNotThrow(makeBlock(a.equal, null, undefined), 'equal'); 38 | 39 | assert.doesNotThrow(makeBlock(a.equal, true, true), 'equal'); 40 | 41 | assert.doesNotThrow(makeBlock(a.equal, 2, '2'), 'equal'); 42 | 43 | assert.doesNotThrow(makeBlock(a.notEqual, true, false), 'notEqual'); 44 | 45 | assert.throws(makeBlock(a.notEqual, true, true), 46 | a.AssertionError, 'notEqual'); 47 | 48 | assert.throws(makeBlock(a.strictEqual, 2, '2'), 49 | a.AssertionError, 'strictEqual'); 50 | 51 | assert.throws(makeBlock(a.strictEqual, null, undefined), 52 | a.AssertionError, 'strictEqual'); 53 | 54 | assert.doesNotThrow(makeBlock(a.notStrictEqual, 2, '2'), 'notStrictEqual'); 55 | 56 | // deepEquals joy! 57 | // 7.2 58 | assert.doesNotThrow(makeBlock(a.deepEqual, new Date(2000, 3, 14), 59 | new Date(2000, 3, 14)), 'deepEqual date'); 60 | 61 | assert.throws(makeBlock(a.deepEqual, new Date(), new Date(2000, 3, 14)), 62 | a.AssertionError, 63 | 'deepEqual date'); 64 | 65 | // 7.3 66 | assert.doesNotThrow(makeBlock(a.deepEqual, /a/, /a/)); 67 | assert.doesNotThrow(makeBlock(a.deepEqual, /a/g, /a/g)); 68 | assert.doesNotThrow(makeBlock(a.deepEqual, /a/i, /a/i)); 69 | assert.doesNotThrow(makeBlock(a.deepEqual, /a/m, /a/m)); 70 | assert.doesNotThrow(makeBlock(a.deepEqual, /a/igm, /a/igm)); 71 | assert.throws(makeBlock(a.deepEqual, /ab/, /a/)); 72 | assert.throws(makeBlock(a.deepEqual, /a/g, /a/)); 73 | assert.throws(makeBlock(a.deepEqual, /a/i, /a/)); 74 | assert.throws(makeBlock(a.deepEqual, /a/m, /a/)); 75 | assert.throws(makeBlock(a.deepEqual, /a/igm, /a/im)); 76 | 77 | var re1 = /a/; 78 | re1.lastIndex = 3; 79 | assert.throws(makeBlock(a.deepEqual, re1, /a/)); 80 | 81 | 82 | // 7.4 83 | assert.doesNotThrow(makeBlock(a.deepEqual, 4, '4'), 'deepEqual == check'); 84 | assert.doesNotThrow(makeBlock(a.deepEqual, true, 1), 'deepEqual == check'); 85 | assert.throws(makeBlock(a.deepEqual, 4, '5'), 86 | a.AssertionError, 87 | 'deepEqual == check'); 88 | 89 | // 7.5 90 | // having the same number of owned properties && the same set of keys 91 | assert.doesNotThrow(makeBlock(a.deepEqual, {a: 4}, {a: 4})); 92 | assert.doesNotThrow(makeBlock(a.deepEqual, {a: 4, b: '2'}, {a: 4, b: '2'})); 93 | assert.doesNotThrow(makeBlock(a.deepEqual, [4], ['4'])); 94 | assert.throws(makeBlock(a.deepEqual, {a: 4}, {a: 4, b: true}), 95 | a.AssertionError); 96 | assert.doesNotThrow(makeBlock(a.deepEqual, ['a'], {0: 'a'})); 97 | //(although not necessarily the same order), 98 | assert.doesNotThrow(makeBlock(a.deepEqual, {a: 4, b: '1'}, {b: '1', a: 4})); 99 | var a1 = [1, 2, 3]; 100 | var a2 = [1, 2, 3]; 101 | a1.a = 'test'; 102 | a1.b = true; 103 | a2.b = true; 104 | a2.a = 'test'; 105 | assert.throws(makeBlock(a.deepEqual, Object.keys(a1), Object.keys(a2)), 106 | a.AssertionError); 107 | assert.doesNotThrow(makeBlock(a.deepEqual, a1, a2)); 108 | 109 | // having an identical prototype property 110 | var nbRoot = { 111 | toString: function() { return this.first + ' ' + this.last; } 112 | }; 113 | 114 | function nameBuilder(first, last) { 115 | this.first = first; 116 | this.last = last; 117 | return this; 118 | } 119 | nameBuilder.prototype = nbRoot; 120 | 121 | function nameBuilder2(first, last) { 122 | this.first = first; 123 | this.last = last; 124 | return this; 125 | } 126 | nameBuilder2.prototype = nbRoot; 127 | 128 | var nb1 = new nameBuilder('Ryan', 'Dahl'); 129 | var nb2 = new nameBuilder2('Ryan', 'Dahl'); 130 | 131 | assert.doesNotThrow(makeBlock(a.deepEqual, nb1, nb2)); 132 | 133 | nameBuilder2.prototype = Object; 134 | nb2 = new nameBuilder2('Ryan', 'Dahl'); 135 | assert.doesNotThrow(makeBlock(a.deepEqual, nb1, nb2)); 136 | 137 | // primitives and object 138 | assert.throws(makeBlock(a.deepEqual, null, {}), a.AssertionError); 139 | assert.throws(makeBlock(a.deepEqual, undefined, {}), a.AssertionError); 140 | assert.throws(makeBlock(a.deepEqual, 'a', ['a']), a.AssertionError); 141 | assert.throws(makeBlock(a.deepEqual, 'a', {0: 'a'}), a.AssertionError); 142 | assert.throws(makeBlock(a.deepEqual, 1, {}), a.AssertionError); 143 | assert.throws(makeBlock(a.deepEqual, true, {}), a.AssertionError); 144 | if (typeof Symbol === 'symbol') { 145 | assert.throws(makeBlock(assert.deepEqual, Symbol(), {}), a.AssertionError); 146 | } 147 | 148 | // primitive wrappers and object 149 | assert.doesNotThrow(makeBlock(a.deepEqual, new String('a'), ['a']), 150 | a.AssertionError); 151 | assert.doesNotThrow(makeBlock(a.deepEqual, new String('a'), {0: 'a'}), 152 | a.AssertionError); 153 | assert.doesNotThrow(makeBlock(a.deepEqual, new Number(1), {}), 154 | a.AssertionError); 155 | assert.doesNotThrow(makeBlock(a.deepEqual, new Boolean(true), {}), 156 | a.AssertionError); 157 | 158 | //deepStrictEqual 159 | assert.doesNotThrow(makeBlock(a.deepStrictEqual, new Date(2000, 3, 14), 160 | new Date(2000, 3, 14)), 'deepStrictEqual date'); 161 | 162 | assert.throws(makeBlock(a.deepStrictEqual, new Date(), new Date(2000, 3, 14)), 163 | a.AssertionError, 164 | 'deepStrictEqual date'); 165 | 166 | // 7.3 - strict 167 | assert.doesNotThrow(makeBlock(a.deepStrictEqual, /a/, /a/)); 168 | assert.doesNotThrow(makeBlock(a.deepStrictEqual, /a/g, /a/g)); 169 | assert.doesNotThrow(makeBlock(a.deepStrictEqual, /a/i, /a/i)); 170 | assert.doesNotThrow(makeBlock(a.deepStrictEqual, /a/m, /a/m)); 171 | assert.doesNotThrow(makeBlock(a.deepStrictEqual, /a/igm, /a/igm)); 172 | assert.throws(makeBlock(a.deepStrictEqual, /ab/, /a/)); 173 | assert.throws(makeBlock(a.deepStrictEqual, /a/g, /a/)); 174 | assert.throws(makeBlock(a.deepStrictEqual, /a/i, /a/)); 175 | assert.throws(makeBlock(a.deepStrictEqual, /a/m, /a/)); 176 | assert.throws(makeBlock(a.deepStrictEqual, /a/igm, /a/im)); 177 | 178 | var re1 = /a/; 179 | re1.lastIndex = 3; 180 | assert.throws(makeBlock(a.deepStrictEqual, re1, /a/)); 181 | 182 | 183 | // 7.4 - strict 184 | assert.throws(makeBlock(a.deepStrictEqual, 4, '4'), 185 | a.AssertionError, 186 | 'deepStrictEqual === check'); 187 | 188 | assert.throws(makeBlock(a.deepStrictEqual, true, 1), 189 | a.AssertionError, 190 | 'deepStrictEqual === check'); 191 | 192 | assert.throws(makeBlock(a.deepStrictEqual, 4, '5'), 193 | a.AssertionError, 194 | 'deepStrictEqual === check'); 195 | 196 | // 7.5 - strict 197 | // having the same number of owned properties && the same set of keys 198 | assert.doesNotThrow(makeBlock(a.deepStrictEqual, {a: 4}, {a: 4})); 199 | assert.doesNotThrow(makeBlock(a.deepStrictEqual, 200 | {a: 4, b: '2'}, 201 | {a: 4, b: '2'})); 202 | assert.throws(makeBlock(a.deepStrictEqual, [4], ['4'])); 203 | assert.throws(makeBlock(a.deepStrictEqual, {a: 4}, {a: 4, b: true}), 204 | a.AssertionError); 205 | assert.throws(makeBlock(a.deepStrictEqual, ['a'], {0: 'a'})); 206 | //(although not necessarily the same order), 207 | assert.doesNotThrow(makeBlock(a.deepStrictEqual, 208 | {a: 4, b: '1'}, 209 | {b: '1', a: 4})); 210 | 211 | assert.throws(makeBlock(a.deepStrictEqual, 212 | [0, 1, 2, 'a', 'b'], 213 | [0, 1, 2, 'b', 'a']), 214 | a.AssertionError); 215 | 216 | assert.doesNotThrow(makeBlock(a.deepStrictEqual, a1, a2)); 217 | 218 | // Prototype check 219 | function Constructor1(first, last) { 220 | this.first = first; 221 | this.last = last; 222 | } 223 | 224 | function Constructor2(first, last) { 225 | this.first = first; 226 | this.last = last; 227 | } 228 | 229 | var obj1 = new Constructor1('Ryan', 'Dahl'); 230 | var obj2 = new Constructor2('Ryan', 'Dahl'); 231 | 232 | assert.throws(makeBlock(a.deepStrictEqual, obj1, obj2), a.AssertionError); 233 | 234 | Constructor2.prototype = Constructor1.prototype; 235 | obj2 = new Constructor2('Ryan', 'Dahl'); 236 | 237 | assert.doesNotThrow(makeBlock(a.deepStrictEqual, obj1, obj2)); 238 | // primitives 239 | assert.throws(makeBlock(assert.deepStrictEqual, 4, '4'), 240 | a.AssertionError); 241 | assert.throws(makeBlock(assert.deepStrictEqual, true, 1), 242 | a.AssertionError); 243 | 244 | if (typeof Symbol === 'symbol') { 245 | assert.throws(makeBlock(assert.deepStrictEqual, Symbol(), Symbol()), 246 | a.AssertionError); 247 | 248 | var s = Symbol(); 249 | assert.doesNotThrow(makeBlock(assert.deepStrictEqual, s, s)); 250 | } 251 | 252 | 253 | // primitives and object 254 | assert.throws(makeBlock(a.deepStrictEqual, null, {}), a.AssertionError); 255 | assert.throws(makeBlock(a.deepStrictEqual, undefined, {}), a.AssertionError); 256 | assert.throws(makeBlock(a.deepStrictEqual, 'a', ['a']), a.AssertionError); 257 | assert.throws(makeBlock(a.deepStrictEqual, 'a', {0: 'a'}), a.AssertionError); 258 | assert.throws(makeBlock(a.deepStrictEqual, 1, {}), a.AssertionError); 259 | assert.throws(makeBlock(a.deepStrictEqual, true, {}), a.AssertionError); 260 | 261 | if (typeof Symbol === 'symbol') { 262 | assert.throws(makeBlock(assert.deepStrictEqual, Symbol(), {}), 263 | a.AssertionError); 264 | } 265 | 266 | 267 | // primitive wrappers and object 268 | assert.throws(makeBlock(a.deepStrictEqual, new String('a'), ['a']), 269 | a.AssertionError); 270 | assert.throws(makeBlock(a.deepStrictEqual, new String('a'), {0: 'a'}), 271 | a.AssertionError); 272 | assert.throws(makeBlock(a.deepStrictEqual, new Number(1), {}), 273 | a.AssertionError); 274 | assert.throws(makeBlock(a.deepStrictEqual, new Boolean(true), {}), 275 | a.AssertionError); 276 | 277 | 278 | // Testing the throwing 279 | function thrower(errorConstructor) { 280 | throw new errorConstructor('test'); 281 | } 282 | var aethrow = makeBlock(thrower, a.AssertionError); 283 | aethrow = makeBlock(thrower, a.AssertionError); 284 | 285 | // the basic calls work 286 | assert.throws(makeBlock(thrower, a.AssertionError), 287 | a.AssertionError, 'message'); 288 | assert.throws(makeBlock(thrower, a.AssertionError), a.AssertionError); 289 | assert.throws(makeBlock(thrower, a.AssertionError)); 290 | 291 | // if not passing an error, catch all. 292 | assert.throws(makeBlock(thrower, TypeError)); 293 | 294 | // when passing a type, only catch errors of the appropriate type 295 | var threw = false; 296 | try { 297 | a.throws(makeBlock(thrower, TypeError), a.AssertionError); 298 | } catch (e) { 299 | threw = true; 300 | assert.ok(e instanceof TypeError, 'type'); 301 | } 302 | assert.equal(true, threw, 303 | 'a.throws with an explicit error is eating extra errors', 304 | a.AssertionError); 305 | threw = false; 306 | 307 | // doesNotThrow should pass through all errors 308 | try { 309 | a.doesNotThrow(makeBlock(thrower, TypeError), a.AssertionError); 310 | } catch (e) { 311 | threw = true; 312 | assert.ok(e instanceof TypeError); 313 | } 314 | assert.equal(true, threw, 315 | 'a.doesNotThrow with an explicit error is eating extra errors'); 316 | 317 | // key difference is that throwing our correct error makes an assertion error 318 | try { 319 | a.doesNotThrow(makeBlock(thrower, TypeError), TypeError); 320 | } catch (e) { 321 | threw = true; 322 | assert.ok(e instanceof a.AssertionError); 323 | } 324 | assert.equal(true, threw, 325 | 'a.doesNotThrow is not catching type matching errors'); 326 | 327 | assert.throws(function() {assert.ifError(new Error('test error'));}); 328 | assert.doesNotThrow(function() {assert.ifError(null);}); 329 | assert.doesNotThrow(function() {assert.ifError();}); 330 | 331 | assert.throws(function () { 332 | assert.doesNotThrow(makeBlock(thrower, Error), 'user message'); 333 | }, /Got unwanted exception. user message/, 334 | 'a.doesNotThrow ignores user message'); 335 | 336 | // make sure that validating using constructor really works 337 | threw = false; 338 | try { 339 | assert.throws( 340 | function() { 341 | throw ({}); 342 | }, 343 | Array 344 | ); 345 | } catch (e) { 346 | threw = true; 347 | } 348 | assert.ok(threw, 'wrong constructor validation'); 349 | 350 | // use a RegExp to validate error message 351 | a.throws(makeBlock(thrower, TypeError), /test/); 352 | 353 | // use a fn to validate error object 354 | a.throws(makeBlock(thrower, TypeError), function(err) { 355 | if ((err instanceof TypeError) && /test/.test(err)) { 356 | return true; 357 | } 358 | }); 359 | 360 | if (parseInt(process.version[0], 10) >= 4) { 361 | require('./error-extend'); 362 | } 363 | 364 | // GH-207. Make sure deepEqual doesn't loop forever on circular refs 365 | var b = {}; 366 | b.b = b; 367 | 368 | var c = {}; 369 | c.b = c; 370 | 371 | var gotError = false; 372 | try { 373 | assert.deepEqual(b, c); 374 | } catch (e) { 375 | gotError = true; 376 | } 377 | 378 | // GH-7178. Ensure reflexivity of deepEqual with `arguments` objects. 379 | var args = (function() { return arguments; })(); 380 | a.throws(makeBlock(a.deepEqual, [], args)); 381 | a.throws(makeBlock(a.deepEqual, args, [])); 382 | assert.ok(gotError); 383 | 384 | 385 | var circular = {y: 1}; 386 | circular.x = circular; 387 | 388 | function testAssertionMessage(actual, expected) { 389 | try { 390 | assert.equal(actual, ''); 391 | } catch (e) { 392 | assert.equal(e.toString(), 393 | ['AssertionError:', expected, '==', '\'\''].join(' ')); 394 | assert.ok(e.generatedMessage, 'Message not marked as generated'); 395 | } 396 | } 397 | 398 | testAssertionMessage(undefined, 'undefined'); 399 | testAssertionMessage(null, 'null'); 400 | testAssertionMessage(true, 'true'); 401 | testAssertionMessage(false, 'false'); 402 | testAssertionMessage(0, '0'); 403 | testAssertionMessage(100, '100'); 404 | testAssertionMessage(NaN, 'NaN'); 405 | testAssertionMessage(Infinity, 'Infinity'); 406 | testAssertionMessage(-Infinity, '-Infinity'); 407 | testAssertionMessage('', '""'); 408 | testAssertionMessage('foo', '\'foo\''); 409 | testAssertionMessage([], '[]'); 410 | testAssertionMessage([1, 2, 3], '[ 1, 2, 3 ]'); 411 | testAssertionMessage(/a/, '/a/'); 412 | testAssertionMessage(/abc/gim, '/abc/gim'); 413 | testAssertionMessage(function f() {}, '[Function: f]'); 414 | testAssertionMessage(function() {}, '[Function]'); 415 | testAssertionMessage({}, '{}'); 416 | testAssertionMessage(circular, '{ y: 1, x: [Circular] }'); 417 | testAssertionMessage({a: undefined, b: null}, '{ a: undefined, b: null }'); 418 | testAssertionMessage({a: NaN, b: Infinity, c: -Infinity}, 419 | '{ a: NaN, b: Infinity, c: -Infinity }'); 420 | 421 | // #2893 422 | try { 423 | assert.throws(function() { 424 | assert.ifError(null); 425 | }); 426 | } catch (e) { 427 | threw = true; 428 | assert.equal(e.message, 'Missing expected exception..'); 429 | } 430 | assert.ok(threw); 431 | 432 | // #5292 433 | try { 434 | assert.equal(1, 2); 435 | } catch (e) { 436 | assert.equal(e.toString().split('\n')[0], 'AssertionError: 1 == 2'); 437 | assert.ok(e.generatedMessage, 'Message not marked as generated'); 438 | } 439 | 440 | try { 441 | assert.equal(1, 2, 'oh no'); 442 | } catch (e) { 443 | assert.equal(e.toString().split('\n')[0], 'AssertionError: oh no'); 444 | assert.equal(e.generatedMessage, false, 445 | 'Message incorrectly marked as generated'); 446 | } 447 | 448 | // Verify that throws() and doesNotThrow() throw on non-function block 449 | function testBlockTypeError(method, block) { 450 | var threw = true; 451 | 452 | try { 453 | method(block); 454 | threw = false; 455 | } catch (e) { 456 | assert.equal(e.toString(), 'TypeError: "block" argument must be a function'); 457 | } 458 | 459 | assert.ok(threw); 460 | } 461 | 462 | testBlockTypeError(assert.throws, 'string'); 463 | testBlockTypeError(assert.doesNotThrow, 'string'); 464 | testBlockTypeError(assert.throws, 1); 465 | testBlockTypeError(assert.doesNotThrow, 1); 466 | testBlockTypeError(assert.throws, true); 467 | testBlockTypeError(assert.doesNotThrow, true); 468 | testBlockTypeError(assert.throws, false); 469 | testBlockTypeError(assert.doesNotThrow, false); 470 | testBlockTypeError(assert.throws, []); 471 | testBlockTypeError(assert.doesNotThrow, []); 472 | testBlockTypeError(assert.throws, {}); 473 | testBlockTypeError(assert.doesNotThrow, {}); 474 | testBlockTypeError(assert.throws, /foo/); 475 | testBlockTypeError(assert.doesNotThrow, /foo/); 476 | testBlockTypeError(assert.throws, null); 477 | testBlockTypeError(assert.doesNotThrow, null); 478 | testBlockTypeError(assert.throws, undefined); 479 | testBlockTypeError(assert.doesNotThrow, undefined); 480 | 481 | console.log('All OK'); 482 | --------------------------------------------------------------------------------