assert: use util.inspect() to create error messages
authorcjihrig <cjihrig@gmail.com>
Fri, 30 Jan 2015 15:25:32 +0000 (10:25 -0500)
committercjihrig <cjihrig@gmail.com>
Sat, 31 Jan 2015 14:34:50 +0000 (09:34 -0500)
Currently, JSON.stringify() is used to create error messages
on failed assertions. This causes an error when stringifying
objects with circular references. This commit switches out
JSON.stringify() for util.inspect(), which can handle
circular references.

PR-URL: https://github.com/iojs/io.js/pull/668
Reviewed-By: Julien Gilli <julien.gilli@joyent.com>
Reviewed-By: Bert Belder <bertbelder@gmail.com>
Reviewed-By: Chris Dickinson <christopher.s.dickinson@gmail.com>
lib/assert.js
test/parallel/test-assert.js

index aa3f0a3..a13cc50 100644 (file)
@@ -58,19 +58,6 @@ assert.AssertionError = function AssertionError(options) {
 // assert.AssertionError instanceof 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) {
   if (util.isString(s)) {
     return s.length < n ? s : s.slice(0, n);
@@ -80,9 +67,9 @@ function truncate(s, n) {
 }
 
 function getMessage(self) {
-  return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' +
+  return truncate(util.inspect(self.actual), 128) + ' ' +
          self.operator + ' ' +
-         truncate(JSON.stringify(self.expected, replacer), 128);
+         truncate(util.inspect(self.expected), 128);
 }
 
 // At present only the three keys mentioned above are used and
index 5d5e70e..044dfba 100644 (file)
@@ -249,36 +249,41 @@ a.throws(makeBlock(a.deepEqual, args, []));
 assert.ok(gotError);
 
 
-// #217
+var circular = {y: 1};
+circular.x = circular;
+
 function testAssertionMessage(actual, expected) {
   try {
     assert.equal(actual, '');
   } catch (e) {
     assert.equal(e.toString(),
-        ['AssertionError:', expected, '==', '""'].join(' '));
+        ['AssertionError:', expected, '==', '\'\''].join(' '));
     assert.ok(e.generatedMessage, "Message not marked as generated");
   }
 }
-testAssertionMessage(undefined, '"undefined"');
+
+testAssertionMessage(undefined, 'undefined');
 testAssertionMessage(null, 'null');
 testAssertionMessage(true, 'true');
 testAssertionMessage(false, 'false');
 testAssertionMessage(0, '0');
 testAssertionMessage(100, '100');
-testAssertionMessage(NaN, '"NaN"');
-testAssertionMessage(Infinity, '"Infinity"');
-testAssertionMessage(-Infinity, '"-Infinity"');
+testAssertionMessage(NaN, 'NaN');
+testAssertionMessage(Infinity, 'Infinity');
+testAssertionMessage(-Infinity, '-Infinity');
 testAssertionMessage('', '""');
-testAssertionMessage('foo', '"foo"');
+testAssertionMessage('foo', '\'foo\'');
 testAssertionMessage([], '[]');
-testAssertionMessage([1, 2, 3], '[1,2,3]');
-testAssertionMessage(/a/, '"/a/"');
-testAssertionMessage(/abc/gim, '"/abc/gim"');
-testAssertionMessage(function f() {}, '"function f() {}"');
+testAssertionMessage([1, 2, 3], '[ 1, 2, 3 ]');
+testAssertionMessage(/a/, '/a/');
+testAssertionMessage(/abc/gim, '/abc/gim');
+testAssertionMessage(function f() {}, '[Function: f]');
+testAssertionMessage(function () {}, '[Function]');
 testAssertionMessage({}, '{}');
-testAssertionMessage({a: undefined, b: null}, '{"a":"undefined","b":null}');
+testAssertionMessage(circular, '{ y: 1, x: [Circular] }');
+testAssertionMessage({a: undefined, b: null}, '{ a: undefined, b: null }');
 testAssertionMessage({a: NaN, b: Infinity, c: -Infinity},
-    '{"a":"NaN","b":"Infinity","c":"-Infinity"}');
+    '{ a: NaN, b: Infinity, c: -Infinity }');
 
 // #2893
 try {