power-assert-js/power-assert

assert.deepEqual() with tolerance

Turbo87 opened this issue · 4 comments

I would like to use assert.deepEqual() 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.

twada commented

@Turbo87 Thank you for your question.

power-assert aims to be completely compliant to Node.js Assert API. Therefore, API issues and improvements should be done in Node.js first.

When I compare two floating point values, single value comparison would look like:

assert(Math.abs(actual - expected) < Number.EPSILON);

However here you want to compare two deep structure having floating point values somewhere.
In that case, unfortunately, you are forced to create your own deepEqualWithTolerance function.
(see universal-deep-strict-equal)

assert(deepEqualWithTolerance(actual, expected, delta));

BTW, you can use JSON.stringify if and only if two objects and its value conversion logic is simple enough.

function tolerant (obj) {
    return JSON.parse(JSON.stringify(obj, function replacer(key, value) {
        if (typeof value === 'number') {
            return (YOUR VALUE CONVERSION LOGIC HERE);
        }
        return value;
    }));
}

var expected = {
    deep: {
        val: 0.3
    }
};
var actual = {
    deep: {
        val: 0.2 + 0.1
    }
};
assert.deepEqual(tolerant(actual), tolerant(expected));

In that case, unfortunately, you are forced to create your own deepEqualWithTolerance function.

I was afraid of that... I guess in that case I won't get any special power-assert diffing magic though, correct?

twada commented

I guess in that case I won't get any special power-assert diffing magic though, correct?

Correct.

twada commented

Closed this issue since this is not related to power-assert feature.