| author | |
| committer | |
| log | fc79b22a981a5d8c1f0f27b2c68afc6c3c5b7474 |
| tree | 7a8a9c870439413e1015e9c79765737c18a12ed9 |
| parent | ecd520f6619c08cac17f8f662facc90595444ac5 |
| parent | 85869f8225dc3f2d21fe540559e05fd1fa94d5ed |
| signature |
Update `std.testing.expectEqual` and friends to use peer type resolution11 files changed, 108 insertions(+), 88 deletions(-)
lib/std/debug.zig+2-2| ... | @@ -853,8 +853,8 @@ test "machoSearchSymbols" { | ... | @@ -853,8 +853,8 @@ test "machoSearchSymbols" { |
| 853 | .{ .addr = 300, .strx = undefined, .size = undefined, .ofile = undefined }, | 853 | .{ .addr = 300, .strx = undefined, .size = undefined, .ofile = undefined }, |
| 854 | }; | 854 | }; |
| 855 | 855 | ||
| 856 | try testing.expectEqual(@as(?*const MachoSymbol, null), machoSearchSymbols(&symbols, 0)); | 856 | try testing.expectEqual(null, machoSearchSymbols(&symbols, 0)); |
| 857 | try testing.expectEqual(@as(?*const MachoSymbol, null), machoSearchSymbols(&symbols, 99)); | 857 | try testing.expectEqual(null, machoSearchSymbols(&symbols, 99)); |
| 858 | try testing.expectEqual(&symbols[0], machoSearchSymbols(&symbols, 100).?); | 858 | try testing.expectEqual(&symbols[0], machoSearchSymbols(&symbols, 100).?); |
| 859 | try testing.expectEqual(&symbols[0], machoSearchSymbols(&symbols, 150).?); | 859 | try testing.expectEqual(&symbols[0], machoSearchSymbols(&symbols, 150).?); |
| 860 | try testing.expectEqual(&symbols[0], machoSearchSymbols(&symbols, 199).?); | 860 | try testing.expectEqual(&symbols[0], machoSearchSymbols(&symbols, 199).?); |
lib/std/http.zig+2-2| ... | @@ -283,8 +283,8 @@ pub const Status = enum(u10) { | ... | @@ -283,8 +283,8 @@ pub const Status = enum(u10) { |
| 283 | } | 283 | } |
| 284 | 284 | ||
| 285 | test { | 285 | test { |
| 286 | try std.testing.expectEqual(@as(?Status.Class, Status.Class.success), Status.ok.class()); | 286 | try std.testing.expectEqual(Status.Class.success, Status.ok.class()); |
| 287 | try std.testing.expectEqual(@as(?Status.Class, Status.Class.client_error), Status.not_found.class()); | 287 | try std.testing.expectEqual(Status.Class.client_error, Status.not_found.class()); |
| 288 | } | 288 | } |
| 289 | }; | 289 | }; |
| 290 | 290 |
lib/std/json/static_test.zig+13-13| ... | @@ -373,19 +373,19 @@ test "test all types" { | ... | @@ -373,19 +373,19 @@ test "test all types" { |
| 373 | test "parse" { | 373 | test "parse" { |
| 374 | try testing.expectEqual(false, try parseFromSliceLeaky(bool, testing.allocator, "false", .{})); | 374 | try testing.expectEqual(false, try parseFromSliceLeaky(bool, testing.allocator, "false", .{})); |
| 375 | try testing.expectEqual(true, try parseFromSliceLeaky(bool, testing.allocator, "true", .{})); | 375 | try testing.expectEqual(true, try parseFromSliceLeaky(bool, testing.allocator, "true", .{})); |
| 376 | try testing.expectEqual(@as(u1, 1), try parseFromSliceLeaky(u1, testing.allocator, "1", .{})); | 376 | try testing.expectEqual(1, try parseFromSliceLeaky(u1, testing.allocator, "1", .{})); |
| 377 | try testing.expectError(error.Overflow, parseFromSliceLeaky(u1, testing.allocator, "50", .{})); | 377 | try testing.expectError(error.Overflow, parseFromSliceLeaky(u1, testing.allocator, "50", .{})); |
| 378 | try testing.expectEqual(@as(u64, 42), try parseFromSliceLeaky(u64, testing.allocator, "42", .{})); | 378 | try testing.expectEqual(42, try parseFromSliceLeaky(u64, testing.allocator, "42", .{})); |
| 379 | try testing.expectEqual(@as(f64, 42), try parseFromSliceLeaky(f64, testing.allocator, "42.0", .{})); | 379 | try testing.expectEqual(42, try parseFromSliceLeaky(f64, testing.allocator, "42.0", .{})); |
| 380 | try testing.expectEqual(@as(?bool, null), try parseFromSliceLeaky(?bool, testing.allocator, "null", .{})); | 380 | try testing.expectEqual(null, try parseFromSliceLeaky(?bool, testing.allocator, "null", .{})); |
| 381 | try testing.expectEqual(@as(?bool, true), try parseFromSliceLeaky(?bool, testing.allocator, "true", .{})); | 381 | try testing.expectEqual(true, try parseFromSliceLeaky(?bool, testing.allocator, "true", .{})); |
| 382 | 382 | ||
| 383 | try testing.expectEqual(@as([3]u8, "foo".*), try parseFromSliceLeaky([3]u8, testing.allocator, "\"foo\"", .{})); | 383 | try testing.expectEqual("foo".*, try parseFromSliceLeaky([3]u8, testing.allocator, "\"foo\"", .{})); |
| 384 | try testing.expectEqual(@as([3]u8, "foo".*), try parseFromSliceLeaky([3]u8, testing.allocator, "[102, 111, 111]", .{})); | 384 | try testing.expectEqual("foo".*, try parseFromSliceLeaky([3]u8, testing.allocator, "[102, 111, 111]", .{})); |
| 385 | try testing.expectEqual(@as([0]u8, undefined), try parseFromSliceLeaky([0]u8, testing.allocator, "[]", .{})); | 385 | try testing.expectEqual(undefined, try parseFromSliceLeaky([0]u8, testing.allocator, "[]", .{})); |
| 386 | 386 | ||
| 387 | try testing.expectEqual(@as(u64, 12345678901234567890), try parseFromSliceLeaky(u64, testing.allocator, "\"12345678901234567890\"", .{})); | 387 | try testing.expectEqual(12345678901234567890, try parseFromSliceLeaky(u64, testing.allocator, "\"12345678901234567890\"", .{})); |
| 388 | try testing.expectEqual(@as(f64, 123.456), try parseFromSliceLeaky(f64, testing.allocator, "\"123.456\"", .{})); | 388 | try testing.expectEqual(123.456, try parseFromSliceLeaky(f64, testing.allocator, "\"123.456\"", .{})); |
| 389 | } | 389 | } |
| 390 | 390 | ||
| 391 | test "parse into enum" { | 391 | test "parse into enum" { |
| ... | @@ -394,9 +394,9 @@ test "parse into enum" { | ... | @@ -394,9 +394,9 @@ test "parse into enum" { |
| 394 | Bar, | 394 | Bar, |
| 395 | @"with\\escape", | 395 | @"with\\escape", |
| 396 | }; | 396 | }; |
| 397 | try testing.expectEqual(@as(T, .Foo), try parseFromSliceLeaky(T, testing.allocator, "\"Foo\"", .{})); | 397 | try testing.expectEqual(.Foo, try parseFromSliceLeaky(T, testing.allocator, "\"Foo\"", .{})); |
| 398 | try testing.expectEqual(@as(T, .Foo), try parseFromSliceLeaky(T, testing.allocator, "42", .{})); | 398 | try testing.expectEqual(.Foo, try parseFromSliceLeaky(T, testing.allocator, "42", .{})); |
| 399 | try testing.expectEqual(@as(T, .@"with\\escape"), try parseFromSliceLeaky(T, testing.allocator, "\"with\\\\escape\"", .{})); | 399 | try testing.expectEqual(.@"with\\escape", try parseFromSliceLeaky(T, testing.allocator, "\"with\\\\escape\"", .{})); |
| 400 | try testing.expectError(error.InvalidEnumTag, parseFromSliceLeaky(T, testing.allocator, "5", .{})); | 400 | try testing.expectError(error.InvalidEnumTag, parseFromSliceLeaky(T, testing.allocator, "5", .{})); |
| 401 | try testing.expectError(error.InvalidEnumTag, parseFromSliceLeaky(T, testing.allocator, "\"Qux\"", .{})); | 401 | try testing.expectError(error.InvalidEnumTag, parseFromSliceLeaky(T, testing.allocator, "\"Qux\"", .{})); |
| 402 | } | 402 | } |
lib/std/math/float.zig+15-15| ... | @@ -138,11 +138,11 @@ test "math.inf" { | ... | @@ -138,11 +138,11 @@ test "math.inf" { |
| 138 | const inf_u64: u64 = 0x7FF0000000000000; | 138 | const inf_u64: u64 = 0x7FF0000000000000; |
| 139 | const inf_u80: u80 = 0x7FFF8000000000000000; | 139 | const inf_u80: u80 = 0x7FFF8000000000000000; |
| 140 | const inf_u128: u128 = 0x7FFF0000000000000000000000000000; | 140 | const inf_u128: u128 = 0x7FFF0000000000000000000000000000; |
| 141 | try expectEqual(inf_u16, @bitCast(inf(f16))); | 141 | try expectEqual(inf_u16, @as(u16, @bitCast(inf(f16)))); |
| 142 | try expectEqual(inf_u32, @bitCast(inf(f32))); | 142 | try expectEqual(inf_u32, @as(u32, @bitCast(inf(f32)))); |
| 143 | try expectEqual(inf_u64, @bitCast(inf(f64))); | 143 | try expectEqual(inf_u64, @as(u64, @bitCast(inf(f64)))); |
| 144 | try expectEqual(inf_u80, @bitCast(inf(f80))); | 144 | try expectEqual(inf_u80, @as(u80, @bitCast(inf(f80)))); |
| 145 | try expectEqual(inf_u128, @bitCast(inf(f128))); | 145 | try expectEqual(inf_u128, @as(u128, @bitCast(inf(f128)))); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | test "math.nan" { | 148 | test "math.nan" { |
| ... | @@ -151,11 +151,11 @@ test "math.nan" { | ... | @@ -151,11 +151,11 @@ test "math.nan" { |
| 151 | const qnan_u64: u64 = 0x7FF8000000000000; | 151 | const qnan_u64: u64 = 0x7FF8000000000000; |
| 152 | const qnan_u80: u80 = 0x7FFFC000000000000000; | 152 | const qnan_u80: u80 = 0x7FFFC000000000000000; |
| 153 | const qnan_u128: u128 = 0x7FFF8000000000000000000000000000; | 153 | const qnan_u128: u128 = 0x7FFF8000000000000000000000000000; |
| 154 | try expectEqual(qnan_u16, @bitCast(nan(f16))); | 154 | try expectEqual(qnan_u16, @as(u16, @bitCast(nan(f16)))); |
| 155 | try expectEqual(qnan_u32, @bitCast(nan(f32))); | 155 | try expectEqual(qnan_u32, @as(u32, @bitCast(nan(f32)))); |
| 156 | try expectEqual(qnan_u64, @bitCast(nan(f64))); | 156 | try expectEqual(qnan_u64, @as(u64, @bitCast(nan(f64)))); |
| 157 | try expectEqual(qnan_u80, @bitCast(nan(f80))); | 157 | try expectEqual(qnan_u80, @as(u80, @bitCast(nan(f80)))); |
| 158 | try expectEqual(qnan_u128, @bitCast(nan(f128))); | 158 | try expectEqual(qnan_u128, @as(u128, @bitCast(nan(f128)))); |
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | test "math.snan" { | 161 | test "math.snan" { |
| ... | @@ -167,9 +167,9 @@ test "math.snan" { | ... | @@ -167,9 +167,9 @@ test "math.snan" { |
| 167 | const snan_u64: u64 = 0x7FF4000000000000; | 167 | const snan_u64: u64 = 0x7FF4000000000000; |
| 168 | const snan_u80: u80 = 0x7FFFA000000000000000; | 168 | const snan_u80: u80 = 0x7FFFA000000000000000; |
| 169 | const snan_u128: u128 = 0x7FFF4000000000000000000000000000; | 169 | const snan_u128: u128 = 0x7FFF4000000000000000000000000000; |
| 170 | try expectEqual(snan_u16, @bitCast(snan(f16))); | 170 | try expectEqual(snan_u16, @as(u16, @bitCast(snan(f16)))); |
| 171 | try expectEqual(snan_u32, @bitCast(snan(f32))); | 171 | try expectEqual(snan_u32, @as(u32, @bitCast(snan(f32)))); |
| 172 | try expectEqual(snan_u64, @bitCast(snan(f64))); | 172 | try expectEqual(snan_u64, @as(u64, @bitCast(snan(f64)))); |
| 173 | try expectEqual(snan_u80, @bitCast(snan(f80))); | 173 | try expectEqual(snan_u80, @as(u80, @bitCast(snan(f80)))); |
| 174 | try expectEqual(snan_u128, @bitCast(snan(f128))); | 174 | try expectEqual(snan_u128, @as(u128, @bitCast(snan(f128)))); |
| 175 | } | 175 | } |
lib/std/mem.zig+6-4| ... | @@ -3262,7 +3262,7 @@ test "indexOfMax" { | ... | @@ -3262,7 +3262,7 @@ test "indexOfMax" { |
| 3262 | /// Finds the indices of the smallest and largest number in a slice. O(n). | 3262 | /// Finds the indices of the smallest and largest number in a slice. O(n). |
| 3263 | /// Returns an anonymous struct with the fields `index_min` and `index_max`. | 3263 | /// Returns an anonymous struct with the fields `index_min` and `index_max`. |
| 3264 | /// `slice` must not be empty. | 3264 | /// `slice` must not be empty. |
| 3265 | pub fn indexOfMinMax(comptime T: type, slice: []const T) struct { index_min: usize, index_max: usize } { | 3265 | pub fn indexOfMinMax(comptime T: type, slice: []const T) IndexOfMinMaxResult { |
| 3266 | assert(slice.len > 0); | 3266 | assert(slice.len > 0); |
| 3267 | var minVal = slice[0]; | 3267 | var minVal = slice[0]; |
| 3268 | var maxVal = slice[0]; | 3268 | var maxVal = slice[0]; |
| ... | @@ -3281,10 +3281,12 @@ pub fn indexOfMinMax(comptime T: type, slice: []const T) struct { index_min: usi | ... | @@ -3281,10 +3281,12 @@ pub fn indexOfMinMax(comptime T: type, slice: []const T) struct { index_min: usi |
| 3281 | return .{ .index_min = minIdx, .index_max = maxIdx }; | 3281 | return .{ .index_min = minIdx, .index_max = maxIdx }; |
| 3282 | } | 3282 | } |
| 3283 | 3283 | ||
| 3284 | pub const IndexOfMinMaxResult = struct { index_min: usize, index_max: usize }; | ||
| 3285 | |||
| 3284 | test "indexOfMinMax" { | 3286 | test "indexOfMinMax" { |
| 3285 | try testing.expectEqual(indexOfMinMax(u8, "abcdefg"), .{ .index_min = 0, .index_max = 6 }); | 3287 | try testing.expectEqual(IndexOfMinMaxResult{ .index_min = 0, .index_max = 6 }, indexOfMinMax(u8, "abcdefg")); |
| 3286 | try testing.expectEqual(indexOfMinMax(u8, "gabcdef"), .{ .index_min = 1, .index_max = 0 }); | 3288 | try testing.expectEqual(IndexOfMinMaxResult{ .index_min = 1, .index_max = 0 }, indexOfMinMax(u8, "gabcdef")); |
| 3287 | try testing.expectEqual(indexOfMinMax(u8, "a"), .{ .index_min = 0, .index_max = 0 }); | 3289 | try testing.expectEqual(IndexOfMinMaxResult{ .index_min = 0, .index_max = 0 }, indexOfMinMax(u8, "a")); |
| 3288 | } | 3290 | } |
| 3289 | 3291 | ||
| 3290 | pub fn swap(comptime T: type, a: *T, b: *T) void { | 3292 | pub fn swap(comptime T: type, a: *T, b: *T) void { |
lib/std/multi_array_list.zig+12-12| ... | @@ -842,24 +842,24 @@ test "union" { | ... | @@ -842,24 +842,24 @@ test "union" { |
| 842 | &.{ .a, .b, .b, .a, .a, .a, .a, .a, .a }, | 842 | &.{ .a, .b, .b, .a, .a, .a, .a, .a, .a }, |
| 843 | list.items(.tags), | 843 | list.items(.tags), |
| 844 | ); | 844 | ); |
| 845 | try testing.expectEqual(list.get(0), .{ .a = 1 }); | 845 | try testing.expectEqual(Foo{ .a = 1 }, list.get(0)); |
| 846 | try testing.expectEqual(list.get(1), .{ .b = "zigzag" }); | 846 | try testing.expectEqual(Foo{ .b = "zigzag" }, list.get(1)); |
| 847 | try testing.expectEqual(list.get(2), .{ .b = "foobar" }); | 847 | try testing.expectEqual(Foo{ .b = "foobar" }, list.get(2)); |
| 848 | try testing.expectEqual(list.get(3), .{ .a = 4 }); | 848 | try testing.expectEqual(Foo{ .a = 4 }, list.get(3)); |
| 849 | try testing.expectEqual(list.get(4), .{ .a = 5 }); | 849 | try testing.expectEqual(Foo{ .a = 5 }, list.get(4)); |
| 850 | try testing.expectEqual(list.get(5), .{ .a = 6 }); | 850 | try testing.expectEqual(Foo{ .a = 6 }, list.get(5)); |
| 851 | try testing.expectEqual(list.get(6), .{ .a = 7 }); | 851 | try testing.expectEqual(Foo{ .a = 7 }, list.get(6)); |
| 852 | try testing.expectEqual(list.get(7), .{ .a = 8 }); | 852 | try testing.expectEqual(Foo{ .a = 8 }, list.get(7)); |
| 853 | try testing.expectEqual(list.get(8), .{ .a = 9 }); | 853 | try testing.expectEqual(Foo{ .a = 9 }, list.get(8)); |
| 854 | 854 | ||
| 855 | list.shrinkAndFree(ally, 3); | 855 | list.shrinkAndFree(ally, 3); |
| 856 | 856 | ||
| 857 | try testing.expectEqual(@as(usize, 3), list.items(.tags).len); | 857 | try testing.expectEqual(@as(usize, 3), list.items(.tags).len); |
| 858 | try testing.expectEqualSlices(meta.Tag(Foo), list.items(.tags), &.{ .a, .b, .b }); | 858 | try testing.expectEqualSlices(meta.Tag(Foo), list.items(.tags), &.{ .a, .b, .b }); |
| 859 | 859 | ||
| 860 | try testing.expectEqual(list.get(0), .{ .a = 1 }); | 860 | try testing.expectEqual(Foo{ .a = 1 }, list.get(0)); |
| 861 | try testing.expectEqual(list.get(1), .{ .b = "zigzag" }); | 861 | try testing.expectEqual(Foo{ .b = "zigzag" }, list.get(1)); |
| 862 | try testing.expectEqual(list.get(2), .{ .b = "foobar" }); | 862 | try testing.expectEqual(Foo{ .b = "foobar" }, list.get(2)); |
| 863 | } | 863 | } |
| 864 | 864 | ||
| 865 | test "sorting a span" { | 865 | test "sorting a span" { |
lib/std/testing.zig+27-9| ... | @@ -52,8 +52,13 @@ pub fn expectError(expected_error: anyerror, actual_error_union: anytype) !void | ... | @@ -52,8 +52,13 @@ pub fn expectError(expected_error: anyerror, actual_error_union: anytype) !void |
| 52 | /// This function is intended to be used only in tests. When the two values are not | 52 | /// This function is intended to be used only in tests. When the two values are not |
| 53 | /// equal, prints diagnostics to stderr to show exactly how they are not equal, | 53 | /// equal, prints diagnostics to stderr to show exactly how they are not equal, |
| 54 | /// then returns a test failure error. | 54 | /// then returns a test failure error. |
| 55 | /// `actual` is casted to the type of `expected`. | 55 | /// `actual` and `expected` are coerced to a common type using peer type resolution. |
| 56 | pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) !void { | 56 | pub inline fn expectEqual(expected: anytype, actual: anytype) !void { |
| 57 | const T = @TypeOf(expected, actual); | ||
| 58 | return expectEqualInner(T, expected, actual); | ||
| 59 | } | ||
| 60 | |||
| 61 | fn expectEqualInner(comptime T: type, expected: T, actual: T) !void { | ||
| 57 | switch (@typeInfo(@TypeOf(actual))) { | 62 | switch (@typeInfo(@TypeOf(actual))) { |
| 58 | .NoReturn, | 63 | .NoReturn, |
| 59 | .Opaque, | 64 | .Opaque, |
| ... | @@ -224,9 +229,13 @@ pub fn expectFmt(expected: []const u8, comptime template: []const u8, args: anyt | ... | @@ -224,9 +229,13 @@ pub fn expectFmt(expected: []const u8, comptime template: []const u8, args: anyt |
| 224 | /// to show exactly how they are not equal, then returns a test failure error. | 229 | /// to show exactly how they are not equal, then returns a test failure error. |
| 225 | /// See `math.approxEqAbs` for more information on the tolerance parameter. | 230 | /// See `math.approxEqAbs` for more information on the tolerance parameter. |
| 226 | /// The types must be floating-point. | 231 | /// The types must be floating-point. |
| 227 | pub fn expectApproxEqAbs(expected: anytype, actual: @TypeOf(expected), tolerance: @TypeOf(expected)) !void { | 232 | /// `actual` and `expected` are coerced to a common type using peer type resolution. |
| 228 | const T = @TypeOf(expected); | 233 | pub inline fn expectApproxEqAbs(expected: anytype, actual: anytype, tolerance: anytype) !void { |
| 234 | const T = @TypeOf(expected, actual, tolerance); | ||
| 235 | return expectApproxEqAbsInner(T, expected, actual, tolerance); | ||
| 236 | } | ||
| 229 | 237 | ||
| 238 | fn expectApproxEqAbsInner(comptime T: type, expected: T, actual: T, tolerance: T) !void { | ||
| 230 | switch (@typeInfo(T)) { | 239 | switch (@typeInfo(T)) { |
| 231 | .Float => if (!math.approxEqAbs(T, expected, actual, tolerance)) { | 240 | .Float => if (!math.approxEqAbs(T, expected, actual, tolerance)) { |
| 232 | print("actual {}, not within absolute tolerance {} of expected {}\n", .{ actual, tolerance, expected }); | 241 | print("actual {}, not within absolute tolerance {} of expected {}\n", .{ actual, tolerance, expected }); |
| ... | @@ -256,9 +265,13 @@ test "expectApproxEqAbs" { | ... | @@ -256,9 +265,13 @@ test "expectApproxEqAbs" { |
| 256 | /// to show exactly how they are not equal, then returns a test failure error. | 265 | /// to show exactly how they are not equal, then returns a test failure error. |
| 257 | /// See `math.approxEqRel` for more information on the tolerance parameter. | 266 | /// See `math.approxEqRel` for more information on the tolerance parameter. |
| 258 | /// The types must be floating-point. | 267 | /// The types must be floating-point. |
| 259 | pub fn expectApproxEqRel(expected: anytype, actual: @TypeOf(expected), tolerance: @TypeOf(expected)) !void { | 268 | /// `actual` and `expected` are coerced to a common type using peer type resolution. |
| 260 | const T = @TypeOf(expected); | 269 | pub inline fn expectApproxEqRel(expected: anytype, actual: anytype, tolerance: anytype) !void { |
| 270 | const T = @TypeOf(expected, actual, tolerance); | ||
| 271 | return expectApproxEqRelInner(T, expected, actual, tolerance); | ||
| 272 | } | ||
| 261 | 273 | ||
| 274 | fn expectApproxEqRelInner(comptime T: type, expected: T, actual: T, tolerance: T) !void { | ||
| 262 | switch (@typeInfo(T)) { | 275 | switch (@typeInfo(T)) { |
| 263 | .Float => if (!math.approxEqRel(T, expected, actual, tolerance)) { | 276 | .Float => if (!math.approxEqRel(T, expected, actual, tolerance)) { |
| 264 | print("actual {}, not within relative tolerance {} of expected {}\n", .{ actual, tolerance, expected }); | 277 | print("actual {}, not within relative tolerance {} of expected {}\n", .{ actual, tolerance, expected }); |
| ... | @@ -653,17 +666,22 @@ pub fn expectStringEndsWith(actual: []const u8, expected_ends_with: []const u8) | ... | @@ -653,17 +666,22 @@ pub fn expectStringEndsWith(actual: []const u8, expected_ends_with: []const u8) |
| 653 | /// This function is intended to be used only in tests. When the two values are not | 666 | /// This function is intended to be used only in tests. When the two values are not |
| 654 | /// deeply equal, prints diagnostics to stderr to show exactly how they are not equal, | 667 | /// deeply equal, prints diagnostics to stderr to show exactly how they are not equal, |
| 655 | /// then returns a test failure error. | 668 | /// then returns a test failure error. |
| 656 | /// `actual` is casted to the type of `expected`. | 669 | /// `actual` and `expected` are coerced to a common type using peer type resolution. |
| 657 | /// | 670 | /// |
| 658 | /// Deeply equal is defined as follows: | 671 | /// Deeply equal is defined as follows: |
| 659 | /// Primitive types are deeply equal if they are equal using `==` operator. | 672 | /// Primitive types are deeply equal if they are equal using `==` operator. |
| 660 | /// Struct values are deeply equal if their corresponding fields are deeply equal. | 673 | /// Struct values are deeply equal if their corresponding fields are deeply equal. |
| 661 | /// Container types(like Array/Slice/Vector) deeply equal when their corresponding elements are deeply equal. | 674 | /// Container types(like Array/Slice/Vector) deeply equal when their corresponding elements are deeply equal. |
| 662 | /// Pointer values are deeply equal if values they point to are deeply equal. | 675 | /// Pointer values are deeply equal if values they point to are deeply equal. |
| 663 | /// | 676 | /// |
| 664 | /// Note: Self-referential structs are supported (e.g. things like std.SinglyLinkedList) | 677 | /// Note: Self-referential structs are supported (e.g. things like std.SinglyLinkedList) |
| 665 | /// but may cause infinite recursion or stack overflow when a container has a pointer to itself. | 678 | /// but may cause infinite recursion or stack overflow when a container has a pointer to itself. |
| 666 | pub fn expectEqualDeep(expected: anytype, actual: @TypeOf(expected)) error{TestExpectedEqual}!void { | 679 | pub inline fn expectEqualDeep(expected: anytype, actual: anytype) error{TestExpectedEqual}!void { |
| 680 | const T = @TypeOf(expected, actual); | ||
| 681 | return expectEqualDeepInner(T, expected, actual); | ||
| 682 | } | ||
| 683 | |||
| 684 | fn expectEqualDeepInner(comptime T: type, expected: T, actual: T) error{TestExpectedEqual}!void { | ||
| 667 | switch (@typeInfo(@TypeOf(actual))) { | 685 | switch (@typeInfo(@TypeOf(actual))) { |
| 668 | .NoReturn, | 686 | .NoReturn, |
| 669 | .Opaque, | 687 | .Opaque, |
test/behavior/cast.zig+1-1| ... | @@ -1156,7 +1156,7 @@ test "cast function with an opaque parameter" { | ... | @@ -1156,7 +1156,7 @@ test "cast function with an opaque parameter" { |
| 1156 | .func = @ptrCast(&Foo.funcImpl), | 1156 | .func = @ptrCast(&Foo.funcImpl), |
| 1157 | }; | 1157 | }; |
| 1158 | c.func(c.ctx); | 1158 | c.func(c.ctx); |
| 1159 | try std.testing.expectEqual(foo, .{ .x = 101, .y = 201 }); | 1159 | try std.testing.expectEqual(Foo{ .x = 101, .y = 201 }, foo); |
| 1160 | } | 1160 | } |
| 1161 | 1161 | ||
| 1162 | test "implicit ptr to *anyopaque" { | 1162 | test "implicit ptr to *anyopaque" { |
test/behavior/packed-struct.zig+25-25| ... | @@ -173,17 +173,17 @@ test "correct sizeOf and offsets in packed structs" { | ... | @@ -173,17 +173,17 @@ test "correct sizeOf and offsets in packed structs" { |
| 173 | try expectEqual(true, s1.bool_d); | 173 | try expectEqual(true, s1.bool_d); |
| 174 | try expectEqual(true, s1.bool_e); | 174 | try expectEqual(true, s1.bool_e); |
| 175 | try expectEqual(true, s1.bool_f); | 175 | try expectEqual(true, s1.bool_f); |
| 176 | try expectEqual(@as(u1, 1), s1.u1_a); | 176 | try expectEqual(1, s1.u1_a); |
| 177 | try expectEqual(false, s1.bool_g); | 177 | try expectEqual(false, s1.bool_g); |
| 178 | try expectEqual(@as(u1, 0), s1.u1_b); | 178 | try expectEqual(0, s1.u1_b); |
| 179 | try expectEqual(@as(u3, 3), s1.u3_a); | 179 | try expectEqual(3, s1.u3_a); |
| 180 | try expectEqual(@as(u10, 0b1101000101), s1.u10_a); | 180 | try expectEqual(0b1101000101, s1.u10_a); |
| 181 | try expectEqual(@as(u10, 0b0001001000), s1.u10_b); | 181 | try expectEqual(0b0001001000, s1.u10_b); |
| 182 | 182 | ||
| 183 | const s2 = @as(packed struct { x: u1, y: u7, z: u24 }, @bitCast(@as(u32, 0xd5c71ff4))); | 183 | const s2 = @as(packed struct { x: u1, y: u7, z: u24 }, @bitCast(@as(u32, 0xd5c71ff4))); |
| 184 | try expectEqual(@as(u1, 0), s2.x); | 184 | try expectEqual(0, s2.x); |
| 185 | try expectEqual(@as(u7, 0b1111010), s2.y); | 185 | try expectEqual(0b1111010, s2.y); |
| 186 | try expectEqual(@as(u24, 0xd5c71f), s2.z); | 186 | try expectEqual(0xd5c71f, s2.z); |
| 187 | } | 187 | } |
| 188 | } | 188 | } |
| 189 | 189 | ||
| ... | @@ -208,12 +208,12 @@ test "nested packed structs" { | ... | @@ -208,12 +208,12 @@ test "nested packed structs" { |
| 208 | 208 | ||
| 209 | if (native_endian == .little) { | 209 | if (native_endian == .little) { |
| 210 | const s3 = @as(S3Padded, @bitCast(@as(u64, 0xe952d5c71ff4))).s3; | 210 | const s3 = @as(S3Padded, @bitCast(@as(u64, 0xe952d5c71ff4))).s3; |
| 211 | try expectEqual(@as(u8, 0xf4), s3.x.a); | 211 | try expectEqual(0xf4, s3.x.a); |
| 212 | try expectEqual(@as(u8, 0x1f), s3.x.b); | 212 | try expectEqual(0x1f, s3.x.b); |
| 213 | try expectEqual(@as(u8, 0xc7), s3.x.c); | 213 | try expectEqual(0xc7, s3.x.c); |
| 214 | try expectEqual(@as(u8, 0xd5), s3.y.d); | 214 | try expectEqual(0xd5, s3.y.d); |
| 215 | try expectEqual(@as(u8, 0x52), s3.y.e); | 215 | try expectEqual(0x52, s3.y.e); |
| 216 | try expectEqual(@as(u8, 0xe9), s3.y.f); | 216 | try expectEqual(0xe9, s3.y.f); |
| 217 | } | 217 | } |
| 218 | 218 | ||
| 219 | const S4 = packed struct { a: i32, b: i8 }; | 219 | const S4 = packed struct { a: i32, b: i8 }; |
| ... | @@ -249,8 +249,8 @@ test "regular in irregular packed struct" { | ... | @@ -249,8 +249,8 @@ test "regular in irregular packed struct" { |
| 249 | foo.bar.a = 235; | 249 | foo.bar.a = 235; |
| 250 | foo.bar.b = 42; | 250 | foo.bar.b = 42; |
| 251 | 251 | ||
| 252 | try expectEqual(@as(u16, 235), foo.bar.a); | 252 | try expectEqual(235, foo.bar.a); |
| 253 | try expectEqual(@as(u8, 42), foo.bar.b); | 253 | try expectEqual(42, foo.bar.b); |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | test "nested packed struct unaligned" { | 256 | test "nested packed struct unaligned" { |
| ... | @@ -456,12 +456,12 @@ test "nested packed struct field pointers" { | ... | @@ -456,12 +456,12 @@ test "nested packed struct field pointers" { |
| 456 | const ptr_p0_c = &S2.s.p0.c; | 456 | const ptr_p0_c = &S2.s.p0.c; |
| 457 | const ptr_p1_a = &S2.s.p1.a; | 457 | const ptr_p1_a = &S2.s.p1.a; |
| 458 | const ptr_p1_b = &S2.s.p1.b; | 458 | const ptr_p1_b = &S2.s.p1.b; |
| 459 | try expectEqual(@as(u8, 1), ptr_base.*); | 459 | try expectEqual(1, ptr_base.*); |
| 460 | try expectEqual(@as(u4, 2), ptr_p0_a.*); | 460 | try expectEqual(2, ptr_p0_a.*); |
| 461 | try expectEqual(@as(u4, 3), ptr_p0_b.*); | 461 | try expectEqual(3, ptr_p0_b.*); |
| 462 | try expectEqual(@as(u8, 4), ptr_p0_c.*); | 462 | try expectEqual(4, ptr_p0_c.*); |
| 463 | try expectEqual(@as(u7, 5), ptr_p1_a.*); | 463 | try expectEqual(5, ptr_p1_a.*); |
| 464 | try expectEqual(@as(u8, 6), ptr_p1_b.*); | 464 | try expectEqual(6, ptr_p1_b.*); |
| 465 | } | 465 | } |
| 466 | 466 | ||
| 467 | test "load pointer from packed struct" { | 467 | test "load pointer from packed struct" { |
| ... | @@ -1033,12 +1033,12 @@ test "modify nested packed struct aligned field" { | ... | @@ -1033,12 +1033,12 @@ test "modify nested packed struct aligned field" { |
| 1033 | 1033 | ||
| 1034 | var opts = Options{}; | 1034 | var opts = Options{}; |
| 1035 | opts.pretty_print.indent += 1; | 1035 | opts.pretty_print.indent += 1; |
| 1036 | try std.testing.expectEqual(@as(u17, 0b00000000100100000), @bitCast(opts)); | 1036 | try std.testing.expectEqual(0b00000000100100000, @as(u17, @bitCast(opts))); |
| 1037 | try std.testing.expect(!opts.foo); | 1037 | try std.testing.expect(!opts.foo); |
| 1038 | try std.testing.expect(!opts.bar); | 1038 | try std.testing.expect(!opts.bar); |
| 1039 | try std.testing.expect(!opts.pretty_print.enabled); | 1039 | try std.testing.expect(!opts.pretty_print.enabled); |
| 1040 | try std.testing.expectEqual(@as(u4, 4), opts.pretty_print.num_spaces); | 1040 | try std.testing.expectEqual(4, opts.pretty_print.num_spaces); |
| 1041 | try std.testing.expectEqual(@as(u8, 1), opts.pretty_print.indent); | 1041 | try std.testing.expectEqual(1, opts.pretty_print.indent); |
| 1042 | try std.testing.expect(!opts.baz); | 1042 | try std.testing.expect(!opts.baz); |
| 1043 | } | 1043 | } |
| 1044 | 1044 |
test/behavior/type.zig+2-2| ... | @@ -438,9 +438,9 @@ test "Type.Union" { | ... | @@ -438,9 +438,9 @@ test "Type.Union" { |
| 438 | }, | 438 | }, |
| 439 | }); | 439 | }); |
| 440 | var tagged = Tagged{ .signed = -1 }; | 440 | var tagged = Tagged{ .signed = -1 }; |
| 441 | try testing.expectEqual(Tag.signed, tagged); | 441 | try testing.expectEqual(Tag.signed, @as(Tag, tagged)); |
| 442 | tagged = .{ .unsigned = 1 }; | 442 | tagged = .{ .unsigned = 1 }; |
| 443 | try testing.expectEqual(Tag.unsigned, tagged); | 443 | try testing.expectEqual(Tag.unsigned, @as(Tag, tagged)); |
| 444 | } | 444 | } |
| 445 | 445 | ||
| 446 | test "Type.Union from Type.Enum" { | 446 | test "Type.Union from Type.Enum" { |
test/c_abi/main.zig+3-3| ... | @@ -946,7 +946,7 @@ test "DC: C returns to Zig" { | ... | @@ -946,7 +946,7 @@ test "DC: C returns to Zig" { |
| 946 | if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest; | 946 | if (comptime builtin.cpu.arch.isRISCV()) return error.SkipZigTest; |
| 947 | if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; | 947 | if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; |
| 948 | if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest; | 948 | if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest; |
| 949 | try expectEqual(c_ret_DC(), .{ .v1 = -0.25, .v2 = 15 }); | 949 | try expectEqual(DC{ .v1 = -0.25, .v2 = 15 }, c_ret_DC()); |
| 950 | } | 950 | } |
| 951 | 951 | ||
| 952 | pub extern fn c_assert_DC(lv: DC) c_int; | 952 | pub extern fn c_assert_DC(lv: DC) c_int; |
| ... | @@ -998,7 +998,7 @@ test "CFF: C returns to Zig" { | ... | @@ -998,7 +998,7 @@ test "CFF: C returns to Zig" { |
| 998 | if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest; | 998 | if (comptime builtin.cpu.arch.isMIPS()) return error.SkipZigTest; |
| 999 | if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; | 999 | if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; |
| 1000 | if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest; | 1000 | if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest; |
| 1001 | try expectEqual(c_ret_CFF(), .{ .v1 = 39, .v2 = 0.875, .v3 = 1.0 }); | 1001 | try expectEqual(CFF{ .v1 = 39, .v2 = 0.875, .v3 = 1.0 }, c_ret_CFF()); |
| 1002 | } | 1002 | } |
| 1003 | pub extern fn c_assert_CFF(lv: CFF) c_int; | 1003 | pub extern fn c_assert_CFF(lv: CFF) c_int; |
| 1004 | pub extern fn c_assert_ret_CFF() c_int; | 1004 | pub extern fn c_assert_ret_CFF() c_int; |
| ... | @@ -1045,7 +1045,7 @@ test "PD: C returns to Zig" { | ... | @@ -1045,7 +1045,7 @@ test "PD: C returns to Zig" { |
| 1045 | if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest; | 1045 | if (comptime builtin.cpu.arch.isMIPS() and builtin.mode != .Debug) return error.SkipZigTest; |
| 1046 | if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; | 1046 | if (comptime builtin.cpu.arch.isPPC()) return error.SkipZigTest; |
| 1047 | if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest; | 1047 | if (comptime builtin.cpu.arch.isPPC64()) return error.SkipZigTest; |
| 1048 | try expectEqual(c_ret_PD(), .{ .v1 = null, .v2 = 0.5 }); | 1048 | try expectEqual(PD{ .v1 = null, .v2 = 0.5 }, c_ret_PD()); |
| 1049 | } | 1049 | } |
| 1050 | pub extern fn c_assert_PD(lv: PD) c_int; | 1050 | pub extern fn c_assert_PD(lv: PD) c_int; |
| 1051 | pub extern fn c_assert_ret_PD() c_int; | 1051 | pub extern fn c_assert_ret_PD() c_int; |