From a67479f4bc880559caea96228395343fdfbd7f04 Mon Sep 17 00:00:00 2001 From: Jonatan Nilsson Date: Fri, 20 Sep 2024 19:33:50 +0000 Subject: [PATCH] assert: Add equalWithMargin for floating and other number comparison with error margin --- README.md | 2 ++ lib/assert.mjs | 8 ++++++++ package.json | 2 +- test/assert.test.mjs | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2b1fdfe..db6bf9c 100644 --- a/README.md +++ b/README.md @@ -111,9 +111,11 @@ $ eltro --watch my_watch_name --npm build Not only does eltro allow you to use any assertion library of your own choosing, it also comes with it's own assertion library based on node's default [assert](https://nodejs.org/api/assert.html) with a few extra methods: + * `assert.equalWithMargin(value, test, margin, [message])`: Check if number value is equal to test with error margin. * `assert.notOk(value, [message])`: Assert value is not ok. * `assert.match(value, test, [message])`: Check if value matches RegExp test. * `assert.notMatch(value, [message])`: Check if value does not match RegExp test. + * `assert.throwsAndCatch(fn, [message])`: Checks if function fn throws and returns the thrown error. * `assert.isFulfilled(promise, [message])`: Assert the promise resolves. * `assert.isRejected(promise, [message])`: Assert the promise gets rejects. diff --git a/lib/assert.mjs b/lib/assert.mjs index e4fa038..6fc3f94 100644 --- a/lib/assert.mjs +++ b/lib/assert.mjs @@ -57,6 +57,14 @@ assert.throwsAndCatch = (fn, message) => { return err } +assert.equalWithMargin = (value, test, margin = 0.005, message) => { + assert.strictEqual(typeof value, 'number', 'Value should be number') + assert.strictEqual(typeof test, 'number', 'Test should be number') + + let difference = Math.abs(value - test) + assert.ok(difference <= margin, message || `${value} ± ${margin} != ${test} (difference of ${difference} > ${margin})`) +} + assert.isFulfilled = (promise, message) => { return Promise.resolve(true) .then(() => promise) diff --git a/package.json b/package.json index 662bcae..1a1f67e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "eltro", - "version": "1.4.6", + "version": "1.5.0", "description": "Eltro is a tiny no-dependancy test framework for node", "main": "index.mjs", "scripts": { diff --git a/test/assert.test.mjs b/test/assert.test.mjs index 69d16f2..b87378e 100644 --- a/test/assert.test.mjs +++ b/test/assert.test.mjs @@ -29,6 +29,41 @@ t.describe('#notOk()', function() { }) }) +t.describe('#equalWithMargin()', function() { + t.test('should support default margin for floating point math', function() { + let check = 0.1 + 0.2 + + assertExtended.throws(function() { + assertExtended.strictEqual(check, 0.3) + }, assertExtended.AssertionError) + + assertExtended.equalWithMargin(check, 0.3) + }) + + t.test('should support custom margin', function() { + assertExtended.equalWithMargin(1, 2, 1) + }) + + t.test('should fail if margin is too small', function() { + assertExtended.throws(function() { + assertExtended.equalWithMargin(1, 2, 0.9) + }, assertExtended.AssertionError) + }) + + t.test('should support custom message', function () { + const assertMessage = 'Hello world' + let error = null + + try { + assertExtended.equalWithMargin(1, 2, 0, assertMessage) + } catch (err) { + error = err + } + assert.ok(error) + assert.match(error.message, new RegExp(assertMessage)) + }) +}) + t.describe('#throwAndCatch()', function() { t.test('should work and return the original error', function() { const assertError = new Error('Speed')