Behaviour of 'expectApproxEqAbs()'

To test that a function returns roughly what is expected, the standard library’s

inline fn expectApproxEqAbs(expected: anytype, actual: anytype, tolerance: anytype) !void

looks promising. In master (0.12) there is a problem in my understanding for the following simple case (test.zig):

const std = @import("std");

fn thrice(number: f32) f32 {
    return 3.0 * number;
}
    
test "Expecting this to compile and to pass" {
     try std.testing.expectApproxEqAbs(3.0, thrice(1.000001), 0.01);
}

I.e., $ zig test test.zig

test.zig:8:50: error: unable to resolve comptime value
    try std.testing.expectApproxEqAbs(3.0, thrice(1.000001), 0.01);
                                           ~~~~~~^~~~~~~~~~
test.zig:8:50: note: value being casted to 'comptime_float' must be comptime-known

Wouldn’t the function’s return type (f32) make second argument’s type comptime known? Why must its value also be comptime known?

Switch the first two arguments and the test passes:

const std = @import("std");

fn thrice(number: f32) f32 {
    return 3.0 * number;
}
    
test "Expecting this to compile and to pass" {
     try std.testing.expectApproxEqAbs(thrice(1.000001), 3.0, 0.01);
}

$ zig test testworks.zig

All 1 tests passed.

Although the value 3.0 would be the expected result within the specified tolerance, why does it have to be passed as actual to make the test work?

Your first example compiles and runs just fine for me using a very recent master (0.12.0-dev.2046+d3a163f86). What version of master are you using? The new signatures for expectEqual and related functions were only merged into master three days ago, so if your version is older than that you still have the old

fn expectApproxEqAbs(expected: anytype, actual: @TypeOf(expected), tolerance: @TypeOf(expected)) !void

version of expectApproxEqAbs.

3 Likes

Maybe:

try std.testing.expectApproxEqAbs(@as(f32, 3.0), thrice(1.000001), 0.01);

A float literal like 3.0 is a comptime_float so the test expects a comptime_float from thrice. Basically the first argument dictates what type the test expects to compare.

2 Likes

Confirmed! It was a slightly older version (0.12.0-dev.1856+94c63f31f), and the expected bahaviour is obtained for 0.12.0-dev.2063+804cee3b9.