authorgravatar for rohlemF@gmail.comrohlem <rohlemF@gmail.com> 2024-06-18 19:01:05+02:00
committergravatar for rohlemF@gmail.comrohlem <rohlemF@gmail.com> 2024-06-18 19:01:05+02:00
log17ce3e5a17e617bd83d1cf2f5f464fb098b92ec7
treee8d7beee0a50b2c68b374627635ee89e92e6a265
parent04e08ea883f94d2de7a91daee72ccc9613a18a43

fix std.testing.expectEqual for comptime-only union

switch from `inline for` with `std.mem.eql` to `inline else` and tag comparison; expectEqualDeep(Inner) was already doing this. add a previously-failing test case.

1 files changed, 14 insertions(+), 12 deletions(-)

lib/std/testing.zig+14-12
...@@ -147,18 +147,10 @@ fn expectEqualInner(comptime T: type, expected: T, actual: T) !void {...@@ -147,18 +147,10 @@ fn expectEqualInner(comptime T: type, expected: T, actual: T) !void {
147147
148 try expectEqual(expectedTag, actualTag);148 try expectEqual(expectedTag, actualTag);
149149
150 // we only reach this loop if the tags are equal150 // we only reach this switch if the tags are equal
151 inline for (std.meta.fields(@TypeOf(actual))) |fld| {151 switch (expected) {
152 if (std.mem.eql(u8, fld.name, @tagName(actualTag))) {152 inline else => |val, tag| try expectEqual(val, @field(actual, @tagName(tag))),
153 try expectEqual(@field(expected, fld.name), @field(actual, fld.name));
154 return;
155 }
156 }153 }
157
158 // we iterate over *all* union fields
159 // => we should never get here as the loop above is
160 // including all possible values.
161 unreachable;
162 },154 },
163155
164 .Optional => {156 .Optional => {
...@@ -208,6 +200,16 @@ test "expectEqual.union(enum)" {...@@ -208,6 +200,16 @@ test "expectEqual.union(enum)" {
208 try expectEqual(a10, a10);200 try expectEqual(a10, a10);
209}201}
210202
203test "expectEqual union with comptime-only field" {
204 const U = union(enum) {
205 a: void,
206 b: void,
207 c: comptime_int,
208 };
209
210 try expectEqual(U{ .a = {} }, .a);
211}
212
211/// This function is intended to be used only in tests. When the formatted result of the template213/// This function is intended to be used only in tests. When the formatted result of the template
212/// and its arguments does not equal the expected text, it prints diagnostics to stderr to show how214/// and its arguments does not equal the expected text, it prints diagnostics to stderr to show how
213/// they are not equal, then returns an error. It depends on `expectEqualStrings()` for printing215/// they are not equal, then returns an error. It depends on `expectEqualStrings()` for printing
...@@ -809,7 +811,7 @@ fn expectEqualDeepInner(comptime T: type, expected: T, actual: T) error{TestExpe...@@ -809,7 +811,7 @@ fn expectEqualDeepInner(comptime T: type, expected: T, actual: T) error{TestExpe
809811
810 try expectEqual(expectedTag, actualTag);812 try expectEqual(expectedTag, actualTag);
811813
812 // we only reach this loop if the tags are equal814 // we only reach this switch if the tags are equal
813 switch (expected) {815 switch (expected) {
814 inline else => |val, tag| {816 inline else => |val, tag| {
815 try expectEqualDeep(val, @field(actual, @tagName(tag)));817 try expectEqualDeep(val, @field(actual, @tagName(tag)));