| ... | ... | @@ -2,7 +2,6 @@ const std = @import("std.zig"); |
| 2 | 2 | const builtin = @import("builtin"); |
| 3 | 3 | |
| 4 | 4 | const math = std.math; |
| 5 | | const print = std.debug.print; |
| 6 | 5 | |
| 7 | 6 | pub const FailingAllocator = @import("testing/failing_allocator.zig").FailingAllocator; |
| 8 | 7 | |
| ... | ... | @@ -22,15 +21,22 @@ pub var base_allocator_instance = std.heap.FixedBufferAllocator.init(""); |
| 22 | 21 | /// TODO https://github.com/ziglang/zig/issues/5738 |
| 23 | 22 | pub var log_level = std.log.Level.warn; |
| 24 | 23 | |
| 24 | fn print(comptime fmt: []const u8, args: anytype) void { |
| 25 | // Disable printing in tests for simple backends. |
| 26 | if (builtin.zig_backend == .stage2_spirv64) return; |
| 27 | |
| 28 | std.debug.print(fmt, args); |
| 29 | } |
| 30 | |
| 25 | 31 | /// This function is intended to be used only in tests. It prints diagnostics to stderr |
| 26 | 32 | /// and then returns a test failure error when actual_error_union is not expected_error. |
| 27 | 33 | pub fn expectError(expected_error: anyerror, actual_error_union: anytype) !void { |
| 28 | 34 | if (actual_error_union) |actual_payload| { |
| 29 | | std.debug.print("expected error.{s}, found {any}\n", .{ @errorName(expected_error), actual_payload }); |
| 35 | print("expected error.{s}, found {any}\n", .{ @errorName(expected_error), actual_payload }); |
| 30 | 36 | return error.TestUnexpectedError; |
| 31 | 37 | } else |actual_error| { |
| 32 | 38 | if (expected_error != actual_error) { |
| 33 | | std.debug.print("expected error.{s}, found error.{s}\n", .{ |
| 39 | print("expected error.{s}, found error.{s}\n", .{ |
| 34 | 40 | @errorName(expected_error), |
| 35 | 41 | @errorName(actual_error), |
| 36 | 42 | }); |
| ... | ... | @@ -58,7 +64,7 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) !void { |
| 58 | 64 | |
| 59 | 65 | .Type => { |
| 60 | 66 | if (actual != expected) { |
| 61 | | std.debug.print("expected type {s}, found type {s}\n", .{ @typeName(expected), @typeName(actual) }); |
| 67 | print("expected type {s}, found type {s}\n", .{ @typeName(expected), @typeName(actual) }); |
| 62 | 68 | return error.TestExpectedEqual; |
| 63 | 69 | } |
| 64 | 70 | }, |
| ... | ... | @@ -74,7 +80,7 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) !void { |
| 74 | 80 | .ErrorSet, |
| 75 | 81 | => { |
| 76 | 82 | if (actual != expected) { |
| 77 | | std.debug.print("expected {}, found {}\n", .{ expected, actual }); |
| 83 | print("expected {}, found {}\n", .{ expected, actual }); |
| 78 | 84 | return error.TestExpectedEqual; |
| 79 | 85 | } |
| 80 | 86 | }, |
| ... | ... | @@ -83,17 +89,17 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) !void { |
| 83 | 89 | switch (pointer.size) { |
| 84 | 90 | .One, .Many, .C => { |
| 85 | 91 | if (actual != expected) { |
| 86 | | std.debug.print("expected {*}, found {*}\n", .{ expected, actual }); |
| 92 | print("expected {*}, found {*}\n", .{ expected, actual }); |
| 87 | 93 | return error.TestExpectedEqual; |
| 88 | 94 | } |
| 89 | 95 | }, |
| 90 | 96 | .Slice => { |
| 91 | 97 | if (actual.ptr != expected.ptr) { |
| 92 | | std.debug.print("expected slice ptr {*}, found {*}\n", .{ expected.ptr, actual.ptr }); |
| 98 | print("expected slice ptr {*}, found {*}\n", .{ expected.ptr, actual.ptr }); |
| 93 | 99 | return error.TestExpectedEqual; |
| 94 | 100 | } |
| 95 | 101 | if (actual.len != expected.len) { |
| 96 | | std.debug.print("expected slice len {}, found {}\n", .{ expected.len, actual.len }); |
| 102 | print("expected slice len {}, found {}\n", .{ expected.len, actual.len }); |
| 97 | 103 | return error.TestExpectedEqual; |
| 98 | 104 | } |
| 99 | 105 | }, |
| ... | ... | @@ -106,7 +112,7 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) !void { |
| 106 | 112 | var i: usize = 0; |
| 107 | 113 | while (i < info.len) : (i += 1) { |
| 108 | 114 | if (!std.meta.eql(expected[i], actual[i])) { |
| 109 | | std.debug.print("index {} incorrect. expected {}, found {}\n", .{ |
| 115 | print("index {} incorrect. expected {}, found {}\n", .{ |
| 110 | 116 | i, expected[i], actual[i], |
| 111 | 117 | }); |
| 112 | 118 | return error.TestExpectedEqual; |
| ... | ... | @@ -151,12 +157,12 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) !void { |
| 151 | 157 | if (actual) |actual_payload| { |
| 152 | 158 | try expectEqual(expected_payload, actual_payload); |
| 153 | 159 | } else { |
| 154 | | std.debug.print("expected {any}, found null\n", .{expected_payload}); |
| 160 | print("expected {any}, found null\n", .{expected_payload}); |
| 155 | 161 | return error.TestExpectedEqual; |
| 156 | 162 | } |
| 157 | 163 | } else { |
| 158 | 164 | if (actual) |actual_payload| { |
| 159 | | std.debug.print("expected null, found {any}\n", .{actual_payload}); |
| 165 | print("expected null, found {any}\n", .{actual_payload}); |
| 160 | 166 | return error.TestExpectedEqual; |
| 161 | 167 | } |
| 162 | 168 | } |
| ... | ... | @@ -167,12 +173,12 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) !void { |
| 167 | 173 | if (actual) |actual_payload| { |
| 168 | 174 | try expectEqual(expected_payload, actual_payload); |
| 169 | 175 | } else |actual_err| { |
| 170 | | std.debug.print("expected {any}, found {}\n", .{ expected_payload, actual_err }); |
| 176 | print("expected {any}, found {}\n", .{ expected_payload, actual_err }); |
| 171 | 177 | return error.TestExpectedEqual; |
| 172 | 178 | } |
| 173 | 179 | } else |expected_err| { |
| 174 | 180 | if (actual) |actual_payload| { |
| 175 | | std.debug.print("expected {}, found {any}\n", .{ expected_err, actual_payload }); |
| 181 | print("expected {}, found {any}\n", .{ expected_err, actual_payload }); |
| 176 | 182 | return error.TestExpectedEqual; |
| 177 | 183 | } else |actual_err| { |
| 178 | 184 | try expectEqual(expected_err, actual_err); |
| ... | ... | @@ -219,7 +225,7 @@ pub fn expectApproxEqAbs(expected: anytype, actual: @TypeOf(expected), tolerance |
| 219 | 225 | |
| 220 | 226 | switch (@typeInfo(T)) { |
| 221 | 227 | .Float => if (!math.approxEqAbs(T, expected, actual, tolerance)) { |
| 222 | | std.debug.print("actual {}, not within absolute tolerance {} of expected {}\n", .{ actual, tolerance, expected }); |
| 228 | print("actual {}, not within absolute tolerance {} of expected {}\n", .{ actual, tolerance, expected }); |
| 223 | 229 | return error.TestExpectedApproxEqAbs; |
| 224 | 230 | }, |
| 225 | 231 | |
| ... | ... | @@ -251,7 +257,7 @@ pub fn expectApproxEqRel(expected: anytype, actual: @TypeOf(expected), tolerance |
| 251 | 257 | |
| 252 | 258 | switch (@typeInfo(T)) { |
| 253 | 259 | .Float => if (!math.approxEqRel(T, expected, actual, tolerance)) { |
| 254 | | std.debug.print("actual {}, not within relative tolerance {} of expected {}\n", .{ actual, tolerance, expected }); |
| 260 | print("actual {}, not within relative tolerance {} of expected {}\n", .{ actual, tolerance, expected }); |
| 255 | 261 | return error.TestExpectedApproxEqRel; |
| 256 | 262 | }, |
| 257 | 263 | |
| ... | ... | @@ -294,7 +300,7 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const |
| 294 | 300 | break :diff_index if (expected.len == actual.len) return else shortest; |
| 295 | 301 | }; |
| 296 | 302 | |
| 297 | | std.debug.print("slices differ. first difference occurs at index {d} (0x{X})\n", .{ diff_index, diff_index }); |
| 303 | print("slices differ. first difference occurs at index {d} (0x{X})\n", .{ diff_index, diff_index }); |
| 298 | 304 | |
| 299 | 305 | // TODO: Should this be configurable by the caller? |
| 300 | 306 | const max_lines: usize = 16; |
| ... | ... | @@ -329,12 +335,12 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const |
| 329 | 335 | // that is usually useful. |
| 330 | 336 | const index_fmt = if (T == u8) "0x{X}" else "{}"; |
| 331 | 337 | |
| 332 | | std.debug.print("\n============ expected this output: ============= len: {} (0x{X})\n\n", .{ expected.len, expected.len }); |
| 338 | print("\n============ expected this output: ============= len: {} (0x{X})\n\n", .{ expected.len, expected.len }); |
| 333 | 339 | if (window_start > 0) { |
| 334 | 340 | if (T == u8) { |
| 335 | | std.debug.print("... truncated, start index: " ++ index_fmt ++ " ...\n", .{window_start}); |
| 341 | print("... truncated, start index: " ++ index_fmt ++ " ...\n", .{window_start}); |
| 336 | 342 | } else { |
| 337 | | std.debug.print("... truncated ...\n", .{}); |
| 343 | print("... truncated ...\n", .{}); |
| 338 | 344 | } |
| 339 | 345 | } |
| 340 | 346 | differ.write(stderr.writer()) catch {}; |
| ... | ... | @@ -342,21 +348,21 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const |
| 342 | 348 | const end_offset = window_start + expected_window.len; |
| 343 | 349 | const num_missing_items = expected.len - (window_start + expected_window.len); |
| 344 | 350 | if (T == u8) { |
| 345 | | std.debug.print("... truncated, indexes [" ++ index_fmt ++ "..] not shown, remaining bytes: " ++ index_fmt ++ " ...\n", .{ end_offset, num_missing_items }); |
| 351 | print("... truncated, indexes [" ++ index_fmt ++ "..] not shown, remaining bytes: " ++ index_fmt ++ " ...\n", .{ end_offset, num_missing_items }); |
| 346 | 352 | } else { |
| 347 | | std.debug.print("... truncated, remaining items: " ++ index_fmt ++ " ...\n", .{num_missing_items}); |
| 353 | print("... truncated, remaining items: " ++ index_fmt ++ " ...\n", .{num_missing_items}); |
| 348 | 354 | } |
| 349 | 355 | } |
| 350 | 356 | |
| 351 | 357 | // now reverse expected/actual and print again |
| 352 | 358 | differ.expected = actual_window; |
| 353 | 359 | differ.actual = expected_window; |
| 354 | | std.debug.print("\n============= instead found this: ============== len: {} (0x{X})\n\n", .{ actual.len, actual.len }); |
| 360 | print("\n============= instead found this: ============== len: {} (0x{X})\n\n", .{ actual.len, actual.len }); |
| 355 | 361 | if (window_start > 0) { |
| 356 | 362 | if (T == u8) { |
| 357 | | std.debug.print("... truncated, start index: " ++ index_fmt ++ " ...\n", .{window_start}); |
| 363 | print("... truncated, start index: " ++ index_fmt ++ " ...\n", .{window_start}); |
| 358 | 364 | } else { |
| 359 | | std.debug.print("... truncated ...\n", .{}); |
| 365 | print("... truncated ...\n", .{}); |
| 360 | 366 | } |
| 361 | 367 | } |
| 362 | 368 | differ.write(stderr.writer()) catch {}; |
| ... | ... | @@ -364,12 +370,12 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const |
| 364 | 370 | const end_offset = window_start + actual_window.len; |
| 365 | 371 | const num_missing_items = actual.len - (window_start + actual_window.len); |
| 366 | 372 | if (T == u8) { |
| 367 | | std.debug.print("... truncated, indexes [" ++ index_fmt ++ "..] not shown, remaining bytes: " ++ index_fmt ++ " ...\n", .{ end_offset, num_missing_items }); |
| 373 | print("... truncated, indexes [" ++ index_fmt ++ "..] not shown, remaining bytes: " ++ index_fmt ++ " ...\n", .{ end_offset, num_missing_items }); |
| 368 | 374 | } else { |
| 369 | | std.debug.print("... truncated, remaining items: " ++ index_fmt ++ " ...\n", .{num_missing_items}); |
| 375 | print("... truncated, remaining items: " ++ index_fmt ++ " ...\n", .{num_missing_items}); |
| 370 | 376 | } |
| 371 | 377 | } |
| 372 | | std.debug.print("\n================================================\n\n", .{}); |
| 378 | print("\n================================================\n\n", .{}); |
| 373 | 379 | |
| 374 | 380 | return error.TestExpectedEqual; |
| 375 | 381 | } |
| ... | ... | @@ -493,12 +499,12 @@ pub fn expectEqualSentinel(comptime T: type, comptime sentinel: T, expected: [:s |
| 493 | 499 | }; |
| 494 | 500 | |
| 495 | 501 | if (!std.meta.eql(sentinel, expected_value_sentinel)) { |
| 496 | | std.debug.print("expectEqualSentinel: 'expected' sentinel in memory is different from its type sentinel. type sentinel {}, in memory sentinel {}\n", .{ sentinel, expected_value_sentinel }); |
| 502 | print("expectEqualSentinel: 'expected' sentinel in memory is different from its type sentinel. type sentinel {}, in memory sentinel {}\n", .{ sentinel, expected_value_sentinel }); |
| 497 | 503 | return error.TestExpectedEqual; |
| 498 | 504 | } |
| 499 | 505 | |
| 500 | 506 | if (!std.meta.eql(sentinel, actual_value_sentinel)) { |
| 501 | | std.debug.print("expectEqualSentinel: 'actual' sentinel in memory is different from its type sentinel. type sentinel {}, in memory sentinel {}\n", .{ sentinel, actual_value_sentinel }); |
| 507 | print("expectEqualSentinel: 'actual' sentinel in memory is different from its type sentinel. type sentinel {}, in memory sentinel {}\n", .{ sentinel, actual_value_sentinel }); |
| 502 | 508 | return error.TestExpectedEqual; |
| 503 | 509 | } |
| 504 | 510 | } |
| ... | ... | @@ -697,7 +703,7 @@ pub fn expectEqualDeep(expected: anytype, actual: @TypeOf(expected)) !void { |
| 697 | 703 | |
| 698 | 704 | .Type => { |
| 699 | 705 | if (actual != expected) { |
| 700 | | std.debug.print("expected type {s}, found type {s}\n", .{ @typeName(expected), @typeName(actual) }); |
| 706 | print("expected type {s}, found type {s}\n", .{ @typeName(expected), @typeName(actual) }); |
| 701 | 707 | return error.TestExpectedEqual; |
| 702 | 708 | } |
| 703 | 709 | }, |
| ... | ... | @@ -713,7 +719,7 @@ pub fn expectEqualDeep(expected: anytype, actual: @TypeOf(expected)) !void { |
| 713 | 719 | .ErrorSet, |
| 714 | 720 | => { |
| 715 | 721 | if (actual != expected) { |
| 716 | | std.debug.print("expected {}, found {}\n", .{ expected, actual }); |
| 722 | print("expected {}, found {}\n", .{ expected, actual }); |
| 717 | 723 | return error.TestExpectedEqual; |
| 718 | 724 | } |
| 719 | 725 | }, |
| ... | ... | @@ -723,7 +729,7 @@ pub fn expectEqualDeep(expected: anytype, actual: @TypeOf(expected)) !void { |
| 723 | 729 | // We have no idea what is behind those pointers, so the best we can do is `==` check. |
| 724 | 730 | .C, .Many => { |
| 725 | 731 | if (actual != expected) { |
| 726 | | std.debug.print("expected {*}, found {*}\n", .{ expected, actual }); |
| 732 | print("expected {*}, found {*}\n", .{ expected, actual }); |
| 727 | 733 | return error.TestExpectedEqual; |
| 728 | 734 | } |
| 729 | 735 | }, |
| ... | ... | @@ -732,7 +738,7 @@ pub fn expectEqualDeep(expected: anytype, actual: @TypeOf(expected)) !void { |
| 732 | 738 | switch (@typeInfo(pointer.child)) { |
| 733 | 739 | .Fn, .Opaque => { |
| 734 | 740 | if (actual != expected) { |
| 735 | | std.debug.print("expected {*}, found {*}\n", .{ expected, actual }); |
| 741 | print("expected {*}, found {*}\n", .{ expected, actual }); |
| 736 | 742 | return error.TestExpectedEqual; |
| 737 | 743 | } |
| 738 | 744 | }, |
| ... | ... | @@ -741,13 +747,13 @@ pub fn expectEqualDeep(expected: anytype, actual: @TypeOf(expected)) !void { |
| 741 | 747 | }, |
| 742 | 748 | .Slice => { |
| 743 | 749 | if (expected.len != actual.len) { |
| 744 | | std.debug.print("Slice len not the same, expected {d}, found {d}\n", .{ expected.len, actual.len }); |
| 750 | print("Slice len not the same, expected {d}, found {d}\n", .{ expected.len, actual.len }); |
| 745 | 751 | return error.TestExpectedEqual; |
| 746 | 752 | } |
| 747 | 753 | var i: usize = 0; |
| 748 | 754 | while (i < expected.len) : (i += 1) { |
| 749 | 755 | expectEqualDeep(expected[i], actual[i]) catch |e| { |
| 750 | | std.debug.print("index {d} incorrect. expected {any}, found {any}\n", .{ |
| 756 | print("index {d} incorrect. expected {any}, found {any}\n", .{ |
| 751 | 757 | i, expected[i], actual[i], |
| 752 | 758 | }); |
| 753 | 759 | return e; |
| ... | ... | @@ -759,13 +765,13 @@ pub fn expectEqualDeep(expected: anytype, actual: @TypeOf(expected)) !void { |
| 759 | 765 | |
| 760 | 766 | .Array => |_| { |
| 761 | 767 | if (expected.len != actual.len) { |
| 762 | | std.debug.print("Array len not the same, expected {d}, found {d}\n", .{ expected.len, actual.len }); |
| 768 | print("Array len not the same, expected {d}, found {d}\n", .{ expected.len, actual.len }); |
| 763 | 769 | return error.TestExpectedEqual; |
| 764 | 770 | } |
| 765 | 771 | var i: usize = 0; |
| 766 | 772 | while (i < expected.len) : (i += 1) { |
| 767 | 773 | expectEqualDeep(expected[i], actual[i]) catch |e| { |
| 768 | | std.debug.print("index {d} incorrect. expected {any}, found {any}\n", .{ |
| 774 | print("index {d} incorrect. expected {any}, found {any}\n", .{ |
| 769 | 775 | i, expected[i], actual[i], |
| 770 | 776 | }); |
| 771 | 777 | return e; |
| ... | ... | @@ -775,13 +781,13 @@ pub fn expectEqualDeep(expected: anytype, actual: @TypeOf(expected)) !void { |
| 775 | 781 | |
| 776 | 782 | .Vector => |info| { |
| 777 | 783 | if (info.len != @typeInfo(@TypeOf(actual)).Vector.len) { |
| 778 | | std.debug.print("Vector len not the same, expected {d}, found {d}\n", .{ info.len, @typeInfo(@TypeOf(actual)).Vector.len }); |
| 784 | print("Vector len not the same, expected {d}, found {d}\n", .{ info.len, @typeInfo(@TypeOf(actual)).Vector.len }); |
| 779 | 785 | return error.TestExpectedEqual; |
| 780 | 786 | } |
| 781 | 787 | var i: usize = 0; |
| 782 | 788 | while (i < info.len) : (i += 1) { |
| 783 | 789 | expectEqualDeep(expected[i], actual[i]) catch |e| { |
| 784 | | std.debug.print("index {d} incorrect. expected {any}, found {any}\n", .{ |
| 790 | print("index {d} incorrect. expected {any}, found {any}\n", .{ |
| 785 | 791 | i, expected[i], actual[i], |
| 786 | 792 | }); |
| 787 | 793 | return e; |
| ... | ... | @@ -792,7 +798,7 @@ pub fn expectEqualDeep(expected: anytype, actual: @TypeOf(expected)) !void { |
| 792 | 798 | .Struct => |structType| { |
| 793 | 799 | inline for (structType.fields) |field| { |
| 794 | 800 | expectEqualDeep(@field(expected, field.name), @field(actual, field.name)) catch |e| { |
| 795 | | std.debug.print("Field {s} incorrect. expected {any}, found {any}\n", .{ field.name, @field(expected, field.name), @field(actual, field.name) }); |
| 801 | print("Field {s} incorrect. expected {any}, found {any}\n", .{ field.name, @field(expected, field.name), @field(actual, field.name) }); |
| 796 | 802 | return e; |
| 797 | 803 | }; |
| 798 | 804 | } |
| ... | ... | @@ -823,12 +829,12 @@ pub fn expectEqualDeep(expected: anytype, actual: @TypeOf(expected)) !void { |
| 823 | 829 | if (actual) |actual_payload| { |
| 824 | 830 | try expectEqualDeep(expected_payload, actual_payload); |
| 825 | 831 | } else { |
| 826 | | std.debug.print("expected {any}, found null\n", .{expected_payload}); |
| 832 | print("expected {any}, found null\n", .{expected_payload}); |
| 827 | 833 | return error.TestExpectedEqual; |
| 828 | 834 | } |
| 829 | 835 | } else { |
| 830 | 836 | if (actual) |actual_payload| { |
| 831 | | std.debug.print("expected null, found {any}\n", .{actual_payload}); |
| 837 | print("expected null, found {any}\n", .{actual_payload}); |
| 832 | 838 | return error.TestExpectedEqual; |
| 833 | 839 | } |
| 834 | 840 | } |
| ... | ... | @@ -839,12 +845,12 @@ pub fn expectEqualDeep(expected: anytype, actual: @TypeOf(expected)) !void { |
| 839 | 845 | if (actual) |actual_payload| { |
| 840 | 846 | try expectEqualDeep(expected_payload, actual_payload); |
| 841 | 847 | } else |actual_err| { |
| 842 | | std.debug.print("expected {any}, found {any}\n", .{ expected_payload, actual_err }); |
| 848 | print("expected {any}, found {any}\n", .{ expected_payload, actual_err }); |
| 843 | 849 | return error.TestExpectedEqual; |
| 844 | 850 | } |
| 845 | 851 | } else |expected_err| { |
| 846 | 852 | if (actual) |actual_payload| { |
| 847 | | std.debug.print("expected {any}, found {any}\n", .{ expected_err, actual_payload }); |
| 853 | print("expected {any}, found {any}\n", .{ expected_err, actual_payload }); |
| 848 | 854 | return error.TestExpectedEqual; |
| 849 | 855 | } else |actual_err| { |
| 850 | 856 | try expectEqualDeep(expected_err, actual_err); |