jest-extended
jest-extended copied to clipboard
New matcher: toBeNear(value, range)
Feature Request
Description: It would be nice to have a way of checking that a value is "close enough" to the expected result (e.g. due to roundoff errors). Using toBeWithin() can accomplish this, but it's a fairly verbose way of doing it. Possible solution: Should be equivalent to .toBeWithin(value - range, value + range)
so something like this?
I feel this is a pretty simple thing to have, maybe have a default of range 1 when its not passed.
describe('test examples', () => {
it('toBeWithin simple', () => {
const example = 1.25
expect(Math.round(example)).toBeWithin(1, 2)
})
it('toBeWithin complex', () => {
const example = 1.25
const range = 1
expect(Math.round(example)).toBeWithin(example - range, example + range)
})
it('toBeNear with 1 arg as toBeWithin', () => {
const example = 1.25
const range = 2
expect(Math.round(example)).toBeWithin(example - 1, example + 1)
// *** The toBeNear alternative ***
// expect(Math.round(example)).toBeNear(example)
// returns true as it + or - 1 from the input.
})
it('toBeNear with 2 arg as toBeWithin', () => {
const example = 1.25
const range = 2
expect(Math.round(example)).toBeWithin(example - range, example + range)
// *** The toBeNear alternative ***
// expect(Math.round(example)).toBeNear(example, range)
})
})
so in short, these should all pass?
it('toBeNear', () => {
expect(10.31415).toBeNear(10)
expect(10.31415).toBeNear(10, 2)
expect(10.31415).not.toBeNear(10, 0.3)
})
Yeah, that's pretty much what I had in mind. I'm not sure about the default value though. 1 might make sense in some cases, but be an absurdly large (or small) range in others.
Also consider that for large values, a default range of 1 is effectively useless since (with floating point numbers) adding 1 might have no effect
> (1e99 + 1) == 1e99
true
I think it would make more sense for the second argument to be required, so the developer is forced to pick something that makes sense in context.
fair, that that makes sense. I would like to see this myself, but i don't know what others would think
Hey @JShabtai @benjaminkay93 I like this matcher, nice work! I agree that the second range argument should be required.
Do either of you fancy sending a PR for this?
I could give it a go, but I'm not sure when I'll have time. If nobody else wants to do it, I'll get around to it eventually, but that might be a while.
Looking at the toBeCloseTo matcher built into expect, I'm wondering if having two similar functions with similar names might cause too much confusion?
Frankly, I don't like that function, since it takes the number of decimal places to consider, rather than just a range (you may want to use this for large numbers with nothing after the decimal place, or ranges like 0.004 instead of 0.01 or 0.001), but having confusing names can potentially cause more problems than it solves. Thoughts?
Same with: https://github.com/jest-community/jest-extended/issues/126
This seems simple enough. I'll give this a crack over the coming weekend. Are we agreed on just having both arguments be required then?
What is the situation with this / is any help needed? This would be great to have!
@natealcedo have you started on this yet? If not @marharyta your help will be greatly appreciated :)
hey @marharyta ! Please go ahead. I was gonna do it over the weekend but I had other commitments. Just shoot if you need any help. :)
I'd like to implement this. Should tests pass when the received value is equal to value plus or minus range?
// should these tests pass or fail
test('toBeNear', () => {
expect(1).toBeNear(2, 1);
expect(3).toBeNear(2, 1);
});
Also, I think naming the second argument epsilon would make it slightly more clear. Any thoughts on that?
@phapp88 I don't think it should matter too much whether the bounds match, but I would lean towards saying the tests you posted should pass. This use case is already for fairly fuzzy tests, having one more passing value shouldn't be a problem.
I'm not sure if epsilon is a better name. I think that's really only going to be clear to people with a background in math/science. Maybe 'marginOfError', 'offset' or 'radius'?
@JShabtai Yeah, you make a good point that epsilon might not be clear for some people. I think 'offset' works pretty well.
@brian-lives-outdoors has given a solution on SO, which I've been using successfully for the past several months.
Is it still relevant ? Maybe this can be either closed for housekeeping purpose, or I could open a new PR for this.
I think closing it makes the most sense. There are some reasonable alternatives in the comments above.