From c5f75c47f3d56056c5e875d36b4e76f10ec063dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristj=C3=A1n=20Oddsson?= Date: Wed, 22 Jan 2025 12:20:27 +0000 Subject: [PATCH] fix floating point precision in closeTo assertion --- lib/chai/core/assertions.js | 6 +++++- test/assert.js | 4 ++++ test/expect.js | 6 ++++++ test/should.js | 10 ++++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/chai/core/assertions.js b/lib/chai/core/assertions.js index 80a1ce7e..039c2654 100644 --- a/lib/chai/core/assertions.js +++ b/lib/chai/core/assertions.js @@ -3149,8 +3149,12 @@ function closeTo(expected, delta, msg) { const abs = (x) => (x < 0n ? -x : x); + // Used to round floating point number precision arithmetics + // See: https://stackoverflow.com/a/3644302 + const strip = (number) => parseFloat(parseFloat(number).toPrecision(12)); + this.assert( - abs(obj - expected) <= delta, + strip(abs(obj - expected)) <= delta, 'expected #{this} to be close to ' + expected + ' +/- ' + delta, 'expected #{this} not to be close to ' + expected + ' +/- ' + delta ); diff --git a/test/assert.js b/test/assert.js index 89395b05..d7934db7 100644 --- a/test/assert.js +++ b/test/assert.js @@ -1894,6 +1894,8 @@ describe('assert', function () { assert.closeTo(10, 20, 20); assert.closeTo(-10, 20, 30); assert.closeTo(10, 10, 0); + assert.closeTo(1682.6, 1682.7, 0.1); + assert.closeTo(1n, 2n, 1n); err(function(){ assert.closeTo(2, 1.0, 0.5, 'blah'); @@ -1924,6 +1926,8 @@ describe('assert', function () { assert.approximately(1.5, 1.0, 0.5); assert.approximately(10, 20, 20); assert.approximately(-10, 20, 30); + assert.approximately(10, 10, 0); + assert.approximately(1682.6, 1682.7, 0.1); assert.approximately(1n, 2n, 1n); err(function(){ diff --git a/test/expect.js b/test/expect.js index c9549d77..ed74a90f 100644 --- a/test/expect.js +++ b/test/expect.js @@ -3267,6 +3267,9 @@ describe('expect', function () { expect(1.5).to.be.closeTo(1.0, 0.5); expect(10).to.be.closeTo(20, 20); expect(-10).to.be.closeTo(20, 30); + expect(10).to.be.closeTo(10, 0); + expect(1682.6).to.be.closeTo(1682.7, 0.1); + expect(1n).to.be.closeTo(2n, 1n); err(function(){ expect(2).to.be.closeTo(1.0, 0.5, 'blah'); @@ -3313,6 +3316,9 @@ describe('expect', function () { expect(1.5).to.be.approximately(1.0, 0.5); expect(10).to.be.approximately(20, 20); expect(-10).to.be.approximately(20, 30); + expect(10).to.be.approximately(10, 0); + expect(1682.6).to.be.approximately(1682.7, 0.1); + expect(1n).to.be.approximately(2n, 1n); err(function(){ expect(2).to.be.approximately(1.0, 0.5, 'blah'); diff --git a/test/should.js b/test/should.js index 4b7fbc48..5bae60dc 100644 --- a/test/should.js +++ b/test/should.js @@ -2749,6 +2749,11 @@ describe('should', function() { it('closeTo', function(){ (1.5).should.be.closeTo(1.0, 0.5); + (10).should.be.closeTo(20, 20); + (-10).should.be.closeTo(20, 30); + (10).should.be.closeTo(10, 0); + (1682.6).should.be.closeTo(1682.7, 0.1); + (1n).should.be.closeTo(2n, 1n); err(function(){ (2).should.be.closeTo(1.0, 0.5, 'blah'); @@ -2773,6 +2778,11 @@ describe('should', function() { it('approximately', function(){ (1.5).should.be.approximately(1.0, 0.5); + (10).should.be.approximately(20, 20); + (-10).should.be.approximately(20, 30); + (10).should.be.approximately(10, 0); + (1682.6).should.be.approximately(1682.7, 0.1); + (1n).should.be.approximately(2n, 1n); err(function(){ (2).should.be.approximately(1.0, 0.5, 'blah');