bluebird75 / luaunit

LuaUnit is a popular unit-testing framework for Lua, with an interface typical of xUnit libraries (Python unittest, Junit, NUnit, ...). It supports several output formats (Text, TAP, JUnit, ...) to be used directly or work with Continuous Integration platforms (Jenkins, Maven, ...).
Other
572 stars 137 forks source link

[feat req] `assert_almost_equals()` margin relative to precision of expected number #157

Open midrare opened 1 year ago

midrare commented 1 year ago

I'd like a way to auto-calculate the margin for assert_almost_equals() based on lua's default tostring() decimal precision. This lets you copy and paste the result of a known good calculation and use it as the expected result for an assert.

For example:

print(3 / 7)  -- prints "0.42857142857143"
luaunit.assert_almost_equals(3 / 7, 0.42857142857143, 'default') -- passes

I came up with a possible implementation (posted here under public domain).

local default_margin_precision = #(tostring(math.pi)) - 1  -- sub 1 for dot char

local function calc_margin(n, prec)
    prec = (prec == nil and default_margin_precision) or prec
    assert(prec > 0, "precision must be an int greater than zero")
    local digits_over_zero = math.ceil(math.log(math.abs(n), 10))
    local digits_below_zero = prec - digits_over_zero
    return 1.0 / 10^math.min(digits_below_zero, math.max(0, prec - 1))
end

assert(calc_margin(3.4883172844444) == 0.0000000000001)
assert(calc_margin(34883.172844444) == 00000.000000001)
assert(calc_margin(0.3488317284444) == 0.0000000000001)
assert(calc_margin(348831728444.44) == 000000000000.01)
assert(calc_margin(0.0000348831728) == 0.0000000000001)

luaunit.assert_almost_equals(3/7, 0.42857142857143, calc_margin(0.42857142857143))