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

deep.equal() and deep.include() doesn't work with Error #1009

Closed
marian-r opened this issue Jul 26, 2017 · 6 comments
Closed

deep.equal() and deep.include() doesn't work with Error #1009

marian-r opened this issue Jul 26, 2017 · 6 comments
Labels

Comments

@marian-r
Copy link

marian-r commented Jul 26, 2017

deep.equal() and deep.include() doesn't compare the object keys as I expect it to. I found the issue when upgrading to v4 as the deep.equal() works fine in v3.5. It stopped working in v4+.

Here is a code to confirm the issue: https://jsfiddle.net/wLzrucae/3/.

I tried adding error to the allowed types for include() assertion, but it still failed on comparison. Any ideas?

@meeber
Copy link
Contributor

meeber commented Jul 26, 2017

Thanks for the issue @marian-r.

The behavior of deep.equal is expected. The deep equality algorithm was rewritten for v4. Error objects are now checked for referential equality (per #608). That issue goes into detail, but essentially it was decided that if two Error objects have different stack traces, then they're not deeply equal.

The behavior of deep.include is a bug. The .include assertion should accept any object, including Error objects. The fix isn't as straightforward as adding error to the _.expectTypes check, but it is fixable.

@meeber meeber added the bug label Jul 26, 2017
@vieiralucas
Copy link
Member

@meeber does this fixes it?

  function include (val, msg) {
    if (msg) flag(this, 'message', msg);

    _.expectTypes(this, [
      'array', 'error', 'object', // added error here
      'string', 'map', 'set',
      'weakset'
    ]);

    var obj = flag(this, 'object')
      , objType = _.type(obj).toLowerCase();

    // This block is for asserting a subset of properties in an object.
    if (objType === 'object' || objType === 'error') { // added error here
      var props = Object.keys(val)
        , negate = flag(this, 'negate')
        , firstErr = null
        , numErrs = 0;
....
....

@meeber
Copy link
Contributor

meeber commented Jul 27, 2017

@vieiralucas Yup that fixes the problem for error objects. I'm just wondering if the way we're using type-detect here will cause problems for other types of objects, particularly custom objects.

@shvaikalesh
Copy link
Contributor

shvaikalesh commented Jul 29, 2017

I've had the same issue with .deep.include when updating Chai to v4.

Real code (GitHub diff): link does not pass _.expectTypes because of custom @@toStringTag.

Simplified example:

expect({ a: 1 }).to.include({ a: 1 }) // pass
expect({ a: 1, [Symbol.toStringTag]: "foo" }).to.include({ a: 1 }) // fail

I believe we should not special-case Error, but make this branch work for all objects (expect for arrays/collections of course), regardless of what Object#toString returns.

@marian-r
Copy link
Author

marian-r commented Aug 2, 2017

@meeber thanks and sorry I haven't seen notifications before. I will try the fix tomorrow.

@marian-r
Copy link
Author

marian-r commented Aug 3, 2017

@meeber I confirm that the fix for .include() works. Thanks 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants