chai: deepEqual doesn't always show an object diff

I have seen lots of things like AssertionError: expected [ Array(2) ] to deeply equal [ Array(2) ] when the objects being compared are very similar and a diff would be useful. I think I have seen chai do this often in the past but not at 3.0.0.

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Reactions: 13
  • Comments: 20 (9 by maintainers)

Most upvoted comments

This currently works for me (using Karma as the test runner):

chai.config.truncateThreshold = 0

Without it I only see “expected [ Array(1) ] to deeply equal [ Array(1) ]”

Also, I’m going to reiterate this point again:

Chai does not do diffs. If you’re not seeing diffs, then that is an issue with your test runner (e.g. mocha). You should totally file an issue with your test runner about this, here is one for mocha’s html reporter: https://github.com/mochajs/mocha/issues/1348

I came across this issue because I was running into the same problem. There’s an important thing you need to check for: did the error report happen outside of your tests?

That was my problem: I had an expect() statement sitting inside a describe() block, when it should have been sitting inside an it() block. That makes all the difference to mocha.

To go back to your original issue @gaye - I think there are two subtly different problems here.

One is to do with diffing - we’ve already solved this, it is in the test harness domain, so if you are not seeing useful diffs, I’d kindly ask you raise the issue with your test harness, for example Mocha.

There is another part of the puzzle though, and that’s chai’s inspection engine. The message which says 'AssertionError: expected [ Array(2) ] to deeply equal [ Array(2) ]' is from Chai, and we use our own inspection library (found here) to create these.

I think here we have a lot of room to make things better. [ Array(2) ] isn’t that useful, [ [1, 2] ] would be more useful I’m guessing - but we need to strike a good balance between too much info and too little.

Can I suggest we move the topic of conversation on how to deal with these small arrays and objects within messages? Here’s the code for formatting Arrays - we could place in some length checks and try to output the full contents of short Arrays, or truncate them in the middle and only show [0…2, n-2…n].

Hey @gaye thanks for the issue.

As @csnover mentioned, Chai’s AssertionError has actual and expected properties, which test runners like Mocha can (and do) use. If you’re not seeing diffs, it’s likely a problem with the test runner (e.g. Mocha) as we always throw AssertionErrors with the properties set.

What test runner are you using?

What do you mean about “regular Error”? We don’t throw any Errors, only AssertionErrors.

The issue lies in the test runner itself

@gaye Mocha (among others) actually already knows specific information about our error messages, and has for as long as I can remember. Here’s Mocha’s base reporter, picking up err.actual and err.expected.

By the way, the .actual and .expected aren’t conventions specific to Chai, they’re in Node proper, for example:

> var assert = require('assert');
> var err; try { assert.ok(false) } catch(e) { err = e }
{ [AssertionError: false == true]
  name: 'AssertionError',
  actual: false,
  expected: true,
  operator: '==',
  message: 'false == true',
  generatedMessage: true }

Your ideal of having Mocha’s responsibility of just showing an error message is not the current situation, in fact it is the opposite. Chai has no diffing engine, chai does not do diffs. It creates an AssertionError which has the standard .message, .stack, .expected, and .actual properties - and then throws that error. Mocha (and others) do the heavy lifting there end, by showing diff output, stack traces etc.

This is precisely how it should be - as @csnover explained. Chai is sending the raw info (the values) to the test harness (e.g. Mocha), and the test harness does things that best suit its environment. This might be outputting XML, or fancy diffs to console, or it might be something entirely new. The point being, this output is the responsibility of the Reporter.

Chai provides actual and expected information as part of the thrown assertion error, it is up to the test system you are using to display an object diff. Intern for example provides an accurate object diff on assertion failure against objects.