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

.to.deep.equal() with tolerance #709

Closed
Turbo87 opened this issue May 18, 2016 · 8 comments
Closed

.to.deep.equal() with tolerance #709

Turbo87 opened this issue May 18, 2016 · 8 comments

Comments

@Turbo87
Copy link
Contributor

Turbo87 commented May 18, 2016

I would like to use expect(a).to.deep.equal(b) to compare two JSON objects, but the objects contain floating-point numbers that are only roughly the same. Is there some way to compare those two objects with a tolerance when comparing numbers? i.e. when the algorithm compares numbers it will accept a difference of up to 0.001% or something like that.

@keithamus
Copy link
Member

Hey @Turbo87 thanks for the issue.

We've got a discussion going on over here: #644 which would probably cater your needs. I'll close this for now, but if you dont think #644 is the right solution then let me know here or over on that issue 😄

@Turbo87
Copy link
Contributor Author

Turbo87 commented May 18, 2016

I'm not sure if #644 will enable what I would like to do. Basically I'm testing some computation-heavy code that results in a large JSON object with several numbers that need to be checked. I then load a second JSON object fixture and would like to compare those two objects with as little code as possible.

expect(result).to.roughly(0.0001).deep.equal(expected);

@keithamus
Copy link
Member

You can use closeTo individual properties and assert that they are close to a number, within a given delta. For example:

expect(1.5).to.be.closeTo(1, 0.5);

Deep Equal will currently only compare like for like, but the plan with #644 is to get it to offer that kind of flexibility, so you could write something like:

expect({
  foo: 1.5
}).to.deep.equal({
  foo: expect.to.be.closeTo(1, 0.5)
});

While your example would solve your specific use case, I'm not sure it would be generic enough to put into chai core. Having said that, when #644 is done there could be the scope for you to create a plugin to modify how deep.equal compares values - so your example code would be possible then.

@Turbo87
Copy link
Contributor Author

Turbo87 commented May 18, 2016

how about something roughly like this:

function compare(a, b) {
  if (typeof a === 'number' && typeof b === 'number') {
    // using the expect() semantics here might not be the best idea...
    expect(a).to.be.closeTo(b, 0.0001);
  } else {
    return this._super(a, b);
  }
}

expect(result).to.deep.equal(expected, compare);

@keithamus
Copy link
Member

Hopefully that will be somewhat close to what we end up with, with #644. Comparators will be able to be passed to deep-eql, which we will use to fuel #644 😄

@keithamus
Copy link
Member

You should comment in #644 with the above example, and we can track it in that issue - as it is still going to be a ways off but would be useful to track in one place.

@Turbo87
Copy link
Contributor Author

Turbo87 commented May 18, 2016

@keithamus FWIW I implemented my first example as a chai plugin: https://github.com/Turbo87/chai-roughly

it's using my branch from chaijs/deep-eql#10 underneath

@keithamus
Copy link
Member

Great work @Turbo87 😄

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

No branches or pull requests

2 participants