Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Odd Behavior: No Stack Trace and Double Output #1179

Closed
skeggse opened this issue Mar 31, 2014 · 4 comments
Closed

Odd Behavior: No Stack Trace and Double Output #1179

skeggse opened this issue Mar 31, 2014 · 4 comments

Comments

@skeggse
Copy link
Contributor

skeggse commented Mar 31, 2014

I'm not sure how to go about debugging this scenario. I've narrowed it down to the following snippet. It's plausible that chai is causing this, but I don't know enough about the guts of either chai or mocha to figure out which it is.

Node v0.10.26, Mocha 1.18.2, Chai 1.9.1

Given

var chai = require('chai');
chai.config.includeStack = true;
var expect = chai.expect;

describe('Woops', function() {
  it('should not fail', function() {
    var a = {}, b = {};
    a.b = b;
    b.a = a;
    expect(a).to.eql({});
  });
});

Output

Mocha No Stack

Given

This next bit is probably just an extension of the above issue, but it exhibits slightly weirder behavior.

var chai = require('chai');
chai.config.includeStack = true;
var expect = chai.expect;

describe('Woops', function() {
  it('should not fail', function() {
    var a = {}, b = {};
    a.b = b;
    b.a = a;
    expect(a).to.eql({});
  });

  it('should succeed', function() {});
});

Output

Mocha Double Output

@skeggse skeggse changed the title Odd Behavior: No Stack Trace or Double Output Odd Behavior: No Stack Trace and Double Output Mar 31, 2014
@skozin
Copy link

skozin commented Apr 24, 2014

I've got the same issue. This happens because JSON.stringify (which is used by Mocha to produce diffs) throws on attempt to process an object with cyclic structure:

var expect = require('chai').expect;

describe('failed test with cyclic dependencies', function() {
  it('should not break Mocha', function() {
    var c = {}; c.c = c;
    expect({}).to.equal(c);
  });

  it('should not interfere with other tests', function() {
    expect(true).to.be.true;
  });
});

// Uncaught TypeError: Converting circular structure to JSON
//      at Object.stringify (native)
//      at stringify (/usr/local/lib/node_modules/mocha/lib/reporters/base.js:456:15)
//      at /usr/local/lib/node_modules/mocha/lib/reporters/base.js:184:33
//      at Array.forEach (native)
//      ...

I temporarily solved this by patching JSON.stringify, but it would be great to see the fix in Mocha. Throwing on cyclic structures is described in the spec:

If stack contains value then throw a TypeError exception because the structure is cyclical.

The most simple solution is to wrap the JSON.stringify call in a try...catch block here:

function stringify(obj) {
  if (obj instanceof RegExp) return obj.toString();
  try {
    return JSON.stringify(obj, null, 2);
  } catch (e) {
    return '' + obj;
  }
}

But it would be probably better to modify the canonicalize function so that it replaces circular references with placeholder values:

function canonicalize(obj, stack) {
  stack = stack || [];

  // if (utils.indexOf(stack, obj) !== -1) return obj;
  if (utils.indexOf(stack, obj) !== -1) return '[Circular]';

  var canonicalizedObj;

  if ('[object Array]' == {}.toString.call(obj)) {
    stack.push(obj);
    canonicalizedObj = utils.map(obj, function(item) {
      return canonicalize(item, stack);
    });
    stack.pop();
  } else if (typeof obj === 'object' && obj !== null) {
    stack.push(obj);
    canonicalizedObj = {};
    utils.forEach(utils.keys(obj).sort(), function(key) {
      canonicalizedObj[key] = canonicalize(obj[key], stack);
    });
    stack.pop();
  } else {
    canonicalizedObj = obj;
  }

  return canonicalizedObj;
}

@skeggse
Copy link
Contributor Author

skeggse commented May 28, 2014

You could also use the inspect function from the util module, which takes care of pretty-printing lots of special cases including cyclic structures.

@gasi
Copy link

gasi commented Jul 11, 2014

👍 Seeing the same issue with chai and cyclic JSON structures.

@skeggse
Copy link
Contributor Author

skeggse commented Jul 19, 2014

Thanks!

tandrewnichols pushed a commit to tandrewnichols/mocha that referenced this issue Dec 15, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants