expectEqualInner
Function parameters
Parameters
- T:type
- expected:T
- actual:T
Type definitions in this namespace
Types
- Reader
- A `std.Io.Reader` that writes a predetermined list of buffers during `stream`.
- ReaderIndirect
- A `std.Io.Reader` that gets its data from another `std.Io.Reader`, and always
This function is intended to be used only in tests.
Functions
- expectError
- This function is intended to be used only in tests.
- expectEqual
- This function is intended to be used only in tests.
- expectFmt
- This function is intended to be used only in tests.
- expectApproxEqAbs
- This function is intended to be used only in tests.
- expectApproxEqRel
- This function is intended to be used only in tests.
- expectEqualSlices
- This function is intended to be used only in tests.
- expectEqualSentinel
- This function is intended to be used only in tests.
- expect
- This function is intended to be used only in tests.
- expectEqualDeep
- This function is intended to be used only in tests.
- checkAllAllocationFailures
- Exhaustively check that allocation failures within `test_fn` are handled without
- refAllDecls
- Given a type, references all the declarations inside, so that the semantic analyzer sees them.
- refAllDeclsRecursive
- Given a type, recursively references all the declarations inside, so that the semantic analyzer sees them.
- fuzz
- Inline to avoid coverage instrumentation.
Provides deterministic randomness in unit tests.
Values
- random_seed
- Provides deterministic randomness in unit tests.
- failing_allocator
- = failing_allocator_instance.allocator()
- allocator
- This should only be used in temporary test programs.
- log_level
- TODO https://github.com/ziglang/zig/issues/5738
- backend_can_print
- = switch (builtin.zig_backend) { .stage2_aarch64, .stage2_powerpc, .stage2_riscv64, .stage2_spirv, => false, else => true, }
Source
Implementation
fn expectEqualInner(comptime T: type, expected: T, actual: T) !void {
switch (@typeInfo(@TypeOf(actual))) {
.noreturn,
.@"opaque",
.frame,
.@"anyframe",
=> @compileError("value of type " ++ @typeName(@TypeOf(actual)) ++ " encountered"),
.undefined,
.null,
.void,
=> return,
.type => {
if (actual != expected) {
print("expected type {s}, found type {s}\n", .{ @typeName(expected), @typeName(actual) });
return error.TestExpectedEqual;
}
},
.bool,
.int,
.float,
.comptime_float,
.comptime_int,
.enum_literal,
.@"enum",
.@"fn",
.error_set,
=> {
if (actual != expected) {
print("expected {any}, found {any}\n", .{ expected, actual });
return error.TestExpectedEqual;
}
},
.pointer => |pointer| {
switch (pointer.size) {
.one, .many, .c => {
if (actual != expected) {
print("expected {*}, found {*}\n", .{ expected, actual });
return error.TestExpectedEqual;
}
},
.slice => {
if (actual.ptr != expected.ptr) {
print("expected slice ptr {*}, found {*}\n", .{ expected.ptr, actual.ptr });
return error.TestExpectedEqual;
}
if (actual.len != expected.len) {
print("expected slice len {}, found {}\n", .{ expected.len, actual.len });
return error.TestExpectedEqual;
}
},
}
},
.array => |array| try expectEqualSlices(array.child, &expected, &actual),
.vector => |info| {
var i: usize = 0;
while (i < info.len) : (i += 1) {
if (!std.meta.eql(expected[i], actual[i])) {
print("index {d} incorrect. expected {any}, found {any}\n", .{
i, expected[i], actual[i],
});
return error.TestExpectedEqual;
}
}
},
.@"struct" => |structType| {
inline for (structType.fields) |field| {
try expectEqual(@field(expected, field.name), @field(actual, field.name));
}
},
.@"union" => |union_info| {
if (union_info.tag_type == null) {
const first_size = @bitSizeOf(union_info.fields[0].type);
inline for (union_info.fields) |field| {
if (@bitSizeOf(field.type) != first_size) {
@compileError("Unable to compare untagged unions with varying field sizes for type " ++ @typeName(@TypeOf(actual)));
}
}
const BackingInt = std.meta.Int(.unsigned, @bitSizeOf(T));
return expectEqual(
@as(BackingInt, @bitCast(expected)),
@as(BackingInt, @bitCast(actual)),
);
}
const Tag = std.meta.Tag(@TypeOf(expected));
const expectedTag = @as(Tag, expected);
const actualTag = @as(Tag, actual);
try expectEqual(expectedTag, actualTag);
// we only reach this switch if the tags are equal
switch (expected) {
inline else => |val, tag| try expectEqual(val, @field(actual, @tagName(tag))),
}
},
.optional => {
if (expected) |expected_payload| {
if (actual) |actual_payload| {
try expectEqual(expected_payload, actual_payload);
} else {
print("expected {any}, found null\n", .{expected_payload});
return error.TestExpectedEqual;
}
} else {
if (actual) |actual_payload| {
print("expected null, found {any}\n", .{actual_payload});
return error.TestExpectedEqual;
}
}
},
.error_union => {
if (expected) |expected_payload| {
if (actual) |actual_payload| {
try expectEqual(expected_payload, actual_payload);
} else |actual_err| {
print("expected {any}, found {}\n", .{ expected_payload, actual_err });
return error.TestExpectedEqual;
}
} else |expected_err| {
if (actual) |actual_payload| {
print("expected {}, found {any}\n", .{ expected_err, actual_payload });
return error.TestExpectedEqual;
} else |actual_err| {
try expectEqual(expected_err, actual_err);
}
}
},
}
}