For example a have two AST trees, each node of these AST trees has uniqueId property which is random string.
Now i want to deep equal this AST trees and equal fails because uniqueId properties are not the same.
So, it would be nice to describe in deepEqual array with property names which would be ignored during deepEqual

Hi @sanex3339, thanks for you issue!
Your request seems to make sense to me, even though you could simply traverse the whole object using Object.getOwnPropertyNames + Object.getPrototypeOf that would be too much work in a single test.
But, when thinking about how we would do that I'm not sure there will be a clean way to create such an assertion. The only acceptable syntax that comes to my mind is expect(objOne).to.be.deepEqual(objTwo).exceptFor('keyName') but unfortunately we wouldn't be able to apply exceptFor to the deepEqual assertion since it comes later.
IMO that would be an useful feature to have, but only if we had a clean way of expressing that through code.
If anyone has a better idea or disagrees, please share your thoughts 馃槃
Sadly i can't help with brain storm, but it would be amazing if this feature will be implemented (with assert interface).
Hey @sanex3339, thanks for the proposal.
I've tried using Chai's .deep.equal to compare ASTs and strongly feel that exclude property would be of much help to ignore whitespaces (PostCSS's raws) and sources. So definitely 馃憤 .
On implementation: we can add options object as second parameter to .equal.
FWIW I think this might be a kind of duplicate of https://github.com/chaijs/chai/issues/644. Part of the work with deep-eql's recent huge refactoring was to enable these kind of behaviour alterations within the deep-eql algo. The plan in https://github.com/chaijs/chai/issues/644 is different but I'd like to see some more discussion around that. I won't close this one, but let's keep both in mind when discussing.
@lucasfcosta - It might help to simply change the word order. It would still be very readable to say:
expect(objOne).excluding('keyName').to.deep.equal(objTwo)
The logic could be that the "excluding" method creates a copy of the object and deletes the named property if it exists, which is how I've just written my test now that I've thought through this problem.
@GeoffreyEmerson I made a simple plugin to do something like this. Hopefully it is helpful to some. https://github.com/mesaugat/chai-exclude
In the meantime, If you don't mind to use Lodash, you could achieve that by something like this:
expect(_.omit(objOne, 'keyName')).to.deep.equal(_.omit(objTwo, 'keyName'));
For nested objects by using property paths like this:
let objOne = { first: { nested: { keyName: '' } } };
expect(_.omit(objOne, 'first.nested.keyName'))
.to.deep.equal(_.omit(objTwo, 'first.nested.keyName'));`
And for multiple props:
expect(_.omit(objOne, ['keyName1', 'keyName2']))
.to.deep.equal(_.omit(objTwo, ['keyName1', 'keyName2']));
We've added this to our Roadmap https://github.com/chaijs/chai/projects/2! We'll be releasing chai 5 soon, but for now I'll close this issue because it is tracked on our roadmap.
@keithamus
What is the current status of this issue?
I don't see it in roadmap anymore.
@porlov this will be covered by https://github.com/chaijs/chai/projects/2#card-10444260 which allows for expectations within deep-eql:
expect(objOne).to.eql({
keyName1: expect.to.be.a.string(),
keyName2: expect.to.not.exist()
})
@keithamus could you please review your last example code. Where should the objTwo be defined? In the initial example / issue, there are two objects (such as objOne and objTwo). The goal is to compare the whole object except uniqueId(keyName2).
Most helpful comment
@lucasfcosta - It might help to simply change the word order. It would still be very readable to say:
expect(objOne).excluding('keyName').to.deep.equal(objTwo)The logic could be that the "excluding" method creates a copy of the object and deletes the named property if it exists, which is how I've just written my test now that I've thought through this problem.