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

Prop equal against circular structures #776

Closed

Conversation

BraulioVM
Copy link
Contributor

Made this pull request to fix issue #411

The problem within this issue was that propEqual was using the utility function objectValues, which does not check against circular structures, and then compared the result of both objectValues with a normal QUnit.equiv. As this approach does not work, I decided to split QUnit.equiv into two separate functions:

  • QUnit.equiv.deep: which performs the old QUnit.equiv computations
  • QUnit.equiv.props: which compares object properties, ignoring their constructor. This function does check against circular structures and allows propEqual to work as it should. If this function is passed a non-object parameter, a QUnit.equiv.deep will be called.

I also created some tests for this new function (mostly copied them from deepEqual.js tests).

Fixes #411

@BraulioVM
Copy link
Contributor Author

I have signed the CLA several times now, but don't know why it doesn't seem so to jquerybot

@@ -60,7 +60,8 @@ grunt.initConfig({
},
all: [
"<%= jshint.all %>",
"!test/deepEqual.js"
"!test/deepEqual.js",
"!test/propEqual.js"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's not add more exceptions. We should fix any issues in new files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added test/propEqual.js to the exceptions because the tests in both files are almost the same

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, but we shouldn't duplicate crappy code.

@jzaefferer
Copy link
Member

It looks like propEqual now replicates a lot of the deepEqual implementation. Maybe we're on the wrong track here. Maybe we should drop propEqual and remove the prototype check in deepEqual. That's what the io.js project did for their assert module: nodejs/node#621

@jzaefferer
Copy link
Member

Not sure why the CLA check is failing, as far as I can tell your signature is fine. You can ignore that, I've pinged someone about that.

@BraulioVM
Copy link
Contributor Author

As you said, I already removed objectValues and put ownObjectKeys in equiv.js. I also made QUnit.equiv backwards compatible. I didn't fix the formatting issues in test/propEqual.js as that could take a really long long time.

Talking about #776 (comment), I think that when comparing objects, what most people actually want is comparing like propEqual does, but can't really know for sure.

propEquiv.apply(this, args.splice( 1, args.length - 1 ) ) );

},
innerEquiv = deepEquiv; // default equivalence check
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might as well drop innerEquiv and assign deepEquiv.props directly, then return that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that would totally make sense. How could propEquiv be a member of deepEquiv? They are kind of opposite. Something that could possibly be more natural would be to drop deepEquiv and assign innerEquiv and innerEquiv.props directly. The point of this is not having that "linguistic contradiction" with propEquiv being a subproperty of deepEquiv.

Does that make any sense?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sticking with innerEquiv is fine.

@jzaefferer
Copy link
Member

@Krinkle @JamesMGreene @leobalter any input on the discussion about general changes to deepEqual (or propEqual)?

@leobalter
Copy link
Member

I'm sorry I didn't give the proper attention to this PR, should we continue and update?

@jzaefferer
Copy link
Member

I still think this is a valuable PR and we should try to pick it up and finish it. I just looked over the current stage again and while there's probably some minor details to fix (I noticed a missing end-of-file newline, so there are probably more style issues), overall this should be good to land.

@jzaefferer
Copy link
Member

Before we put more time into this though, we should figure out what to do about #865. If we contribute our implementation to an external module and make use of that, we can (as easily) share code between propEqual and deepEqual anymore.

@leobalter
Copy link
Member

does anyone want to continue the work on this? Should we close this at this point?

@trentmwillis
Copy link
Member

I think this is still worth pursuing, but unless @BraulioVM wants to take this up again, it'd be best to close and open a new PR.

@trentmwillis
Copy link
Member

It's been a couple more months, so I'm going to close this and hopefully we can address it in another PR.

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

Successfully merging this pull request may close these issues.

assert.propEqual not guarded against circular structures
6 participants