mocha icon indicating copy to clipboard operation
mocha copied to clipboard

Does not show diff when contains any Symbol

Open bigomega opened this issue 9 years ago • 9 comments

    expect({ 
      a: Symbol('test'),
      b: 'bar',
    }).to.deep.equal({ 
      a: 'foo', 
      b: 'bar',
    })

Fails but does not show the diff.

If Symbol('test') is replaced by 'test', It works image

bigomega avatar Apr 02 '16 10:04 bigomega

Thanks for the issue! I'd recommend opening an issue with the assertion library (chai?) since they define err.expected/err.actual. For example, using just node:

$ cat test.js
var expect = require('chai').expect;

expect({
  a: Symbol('test'),
  b: 'bar',
}).to.deep.equal({
  a: 'foo',
  b: 'bar',
})

$ node test.js

/Users/danielstjules/Desktop/test/node_modules/chai/lib/chai/assertion.js:107
      throw new AssertionError(msg, {
      ^
AssertionError: expected { a: {}, b: 'bar' } to deeply equal { a: 'foo', b: 'bar' }

danielstjules avatar Apr 27 '16 09:04 danielstjules

Allow me to put in a good word for unexpected, which supports Symbols natively:

var expect = require('unexpected');
expect({ 
    a: Symbol('test'),
    b: 'bar'
}, 'to equal', {
    a: 'foo', 
    b: 'bar'
});

symboldiff

papandreou avatar Apr 27 '16 09:04 papandreou

@danielstjules You see the problem is the diff is not being shown. I've already checked with https://github.com/chaijs/chai/issues/654 before coming here. And they don't seem to be involved in showing the diff.

In the example you gave, when i run with mocha

$ cat test.js
var expect = require('chai').expect;

describe('Symbols', () => {
  it('should pass through', () => {
    expect({
      a: Symbol('test'),
      b: 'bar',
    }).to.deep.equal({
      a: 'foo',
      b: 'bar',
    })
  })
})

$ mocha test.js

  Symbols
    1) should pass through

  0 passing (663ms)
  1 failing

whereas changing Symbol('test') to {} returns

$ mocha test.js

  Symbols
    1) should pass through

  0 passing (561ms)
  1 failing

  1) Symbols should pass through:

      AssertionError: expected { a: {}, b: 'bar' } to deeply equal { a: 'foo', b: 'bar' }
      + expected - actual

       {
      -  "a": {}
      +  "a": "foo"
         "b": "bar"
       }

      at Assertion.assertEqual (node_modules/chai/lib/chai/core/assertions.js:485:19)
      at Assertion.ctx.(anonymous function) [as equal] (node_modules/chai/lib/chai/utils/addMethod.js:41:25)
      at Context.<anonymous> (test.js:8:16)

Though in both cases chai is throwing the same AssertionError you've mentioned

bigomega avatar Apr 27 '16 09:04 bigomega

You're right! It was a bit late for me, so substitute diff with err.expected and err.actual - both are provided by the assertion framework. In this case, chai isn't giving the best string representation of a Symbol, however, mocha should still be printing them 😅

danielstjules avatar Apr 27 '16 16:04 danielstjules

NVM... My problem was the use of 'contain' versus 'have.value' - this is working as expected,

Don't know if this is related, but I'm having a similar problem with the diff not showing: My test is:

    it('it shows the text in the text box', () => {
      expect(textarea).to.contain('sample comment');
    });

and the failure output is:

  1) commentBox entering text it shows the text in the text box:
     AssertionError: expected { Object (0, length, ...) } to contain 'sample comment'
      at Context.<anonymous> (comment_box_test.js:4:1)

  2) commentBox entering text it clears the text box on submit:
     AssertionError: expected false to be true
      at Context.<anonymous> (comment_box_test.js:4:1)

Note that the "expected false to be true" works as expected

JESii avatar May 12 '16 23:05 JESii

This has been fixed sometime between when this ticket was opened and the latest release of mocha.

screenshot 2017-07-27 20 02 35

Full code can be found here - https://github.com/johnkpaul/mocha-issue-2183

johnkpaul avatar Jul 28 '17 00:07 johnkpaul

Good to see that Chai is making this work.

It does seem to be the case that Mocha (still) does not show diffs if one of the expected or actual values is a Symbol (possibly as part of a broader policy about not stringifying objects? I haven't looked at the diff-generating code lately):

describe("symbol diff", function() {
  it("expected", function() {
    const error = new Error("HI")
    error.expected = Symbol("bye")
    error.actual = "Bye!"
    throw error
  })
  it("actual", function() {
    const error = new Error("HI")
    error.expected = "Bye!"
    error.actual = Symbol("bye")
    throw error
  })
  it("vs string", function() {
    const error = new Error("HI")
    error.expected = "Bye!"
    error.actual = "bye"
    throw error
  })
})
  symbol diff
    1) expected
    2) actual
    3) vs string


  0 passing (231ms)
  3 failing

  1) symbol diff expected:
     Error: HI
      at Context.<anonymous> (test\test.js:3:19)

  2) symbol diff actual:
     Error: HI
      at Context.<anonymous> (test\test.js:9:19)

  3) symbol diff vs string:

      Error: HI
      + expected - actual

      -bye
      +Bye!

      at Context.<anonymous> (test\test.js:15:19)

ScottFreeCode avatar Aug 02 '17 05:08 ScottFreeCode

I think this is almost working as intended. These output lines from the cases with Symbols look off:

 1) symbol diff
       expected:
     Error: HI
  2) symbol diff
       actual:
     Error: HI

Note the lack of text after expected: and actual:. That strikes me as a bug that should be fixed.

As for whether diffs should be shown: my hunch is no, but I'm not 100% on that. Symbols are generally used pretty sparingly in code and for names unique names. I don't see a strong use case for wanting to diff them as if they were text strings. cc @mochajs/maintenance-crew for additional input.

JoshuaKGoldberg avatar Jan 15 '24 05:01 JoshuaKGoldberg

Confirmed, for now let's just treat this as a bug specifically with Symbols in Error properties.

@voxpelli has mentioned having/using other diff libraries (amusingly, e.g. jest-diff). But that can be tracked as a separate issue.

JoshuaKGoldberg avatar Feb 27 '24 16:02 JoshuaKGoldberg