diff --git a/test_suite/stdlib.jsonnet b/test_suite/stdlib.jsonnet index 0a854c3a..3acb1886 100644 --- a/test_suite/stdlib.jsonnet +++ b/test_suite/stdlib.jsonnet @@ -33,12 +33,30 @@ std.assertEqual(std.makeArray(10, function(i) i + 1), [1, 2, 3, 4, 5, 6, 7, 8, 9 std.assertEqual(std.makeArray(0, function(i) null), []) && local assertClose(a, b) = + // Using 1e-12 as tolerance. Jsonnet uses double-precision floats with machine epsilon of 2**-53 ≈ 1.11e-16. + // This tolerance is ~9000x the machine epsilon, which is quite lenient and should work across + // different platforms and math libraries. + // + // We use a combination of absolute and relative error to handle both small and large values: + // - For values near zero, we use absolute error to avoid division issues + // - For larger values, we use relative error to maintain precision + // + // This correctly handles cases like: + // assertClose(1e-15, 0) - should pass (both are essentially zero) + // assertClose(-100, 0) - should fail (significant difference) + // assertClose(std.sin(std.pi), 0) - should pass (tiny floating point error) + local abs_a = std.abs(a); + local abs_b = std.abs(b); + local diff = std.abs(a - b); + local max_abs = std.max(abs_a, abs_b); local err = - if b == 0 then - a - b + if abs_a == 0 && abs_b == 0 then + 0 // Both are exactly zero, so no error + else if max_abs < 1e-12 then + diff // For very small values, use absolute error else - if a / b - 1 > 0 then a / b - 1 else 1 - a / b; - if err > 0.000005 then + diff / max_abs; // For larger values, use relative error + if err > 1e-12 then error 'Assertion failed (error ' + err + '). ' + a + ' !~ ' + b else true;