mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 14:25:16 +00:00
std.testing: Improve expectEqualBytes for large inputs and make expectEqualSlices use it
`expectEqualBytes` will now truncate the hexdump of each input to a maximum window of 256 bytes, which makes it safe to use for arbitrarily large inputs. Therefore, it can be used in `expectEqualSlices` when the type is u8.
This commit is contained in:
parent
a943422672
commit
c37afa2811
@ -281,8 +281,12 @@ test "expectApproxEqRel" {
|
||||
/// equal, prints diagnostics to stderr to show exactly how they are not equal,
|
||||
/// then returns a test failure error.
|
||||
/// If your inputs are UTF-8 encoded strings, consider calling `expectEqualStrings` instead.
|
||||
/// If your inputs are slices of bytes, consider calling `expectEqualBytes` instead.
|
||||
/// If your inputs are slices of bytes, consider calling `expectEqualBytes` instead (this
|
||||
/// function calls `expectEqualBytes` implicitly when `T` is `u8`).
|
||||
pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const T) !void {
|
||||
if (T == u8) {
|
||||
return expectEqualBytes(expected, actual);
|
||||
}
|
||||
// TODO better printing of the difference
|
||||
// If the arrays are small enough we could print the whole thing
|
||||
// If the child type is u8 and no weird bytes, we could print it as strings
|
||||
@ -556,26 +560,58 @@ test {
|
||||
/// then returns a test failure error. The colorized output is optional and controlled
|
||||
/// by the return of `std.debug.detectTTYConfig()`.
|
||||
pub fn expectEqualBytes(expected: []const u8, actual: []const u8) !void {
|
||||
std.testing.expectEqualSlices(u8, expected, actual) catch |err| {
|
||||
if (std.mem.indexOfDiff(u8, actual, expected)) |diff_index| {
|
||||
std.debug.print("byte slices differ. first difference occurs at offset {d} (0x{X})\n", .{ diff_index, diff_index });
|
||||
|
||||
// TODO: Should this be configurable by the caller?
|
||||
const max_window_size: usize = 256;
|
||||
|
||||
// Print a maximum of max_window_size bytes of each input, starting just before the
|
||||
// first difference.
|
||||
var window_start: usize = 0;
|
||||
if (@max(actual.len, expected.len) > max_window_size) {
|
||||
window_start = std.mem.alignBackward(diff_index - @min(diff_index, 16), 16);
|
||||
}
|
||||
const expected_window = expected[window_start..@min(expected.len, window_start + max_window_size)];
|
||||
const expected_truncated = window_start + expected_window.len < expected.len;
|
||||
const actual_window = actual[window_start..@min(actual.len, window_start + max_window_size)];
|
||||
const actual_truncated = window_start + actual_window.len < actual.len;
|
||||
|
||||
var differ = BytesDiffer{
|
||||
.expected = expected,
|
||||
.actual = actual,
|
||||
.expected = expected_window,
|
||||
.actual = actual_window,
|
||||
.ttyconf = std.debug.detectTTYConfig(),
|
||||
};
|
||||
const stderr = std.io.getStdErr();
|
||||
|
||||
std.debug.print("\n============ expected this output: =============\n\n", .{});
|
||||
std.debug.print("\n============ expected this output: ============= len: {} (0x{X})\n\n", .{ expected.len, expected.len });
|
||||
if (window_start > 0) {
|
||||
std.debug.print("... truncated, start offset: 0x{X} ...\n", .{window_start});
|
||||
}
|
||||
differ.write(stderr.writer()) catch {};
|
||||
if (expected_truncated) {
|
||||
const end_offset = window_start + expected_window.len;
|
||||
const num_missing_bytes = expected.len - (window_start + expected_window.len);
|
||||
std.debug.print("... truncated, end offset: 0x{X}, remaining bytes: 0x{X} ...\n", .{ end_offset, num_missing_bytes });
|
||||
}
|
||||
|
||||
// now reverse expected/actual and print again
|
||||
differ.expected = actual;
|
||||
differ.actual = expected;
|
||||
std.debug.print("\n============= instead found this: ==============\n\n", .{});
|
||||
differ.expected = actual_window;
|
||||
differ.actual = expected_window;
|
||||
std.debug.print("\n============= instead found this: ============== len: {} (0x{X})\n\n", .{ actual.len, actual.len });
|
||||
if (window_start > 0) {
|
||||
std.debug.print("... truncated, start offset: 0x{X} ...\n", .{window_start});
|
||||
}
|
||||
differ.write(stderr.writer()) catch {};
|
||||
if (actual_truncated) {
|
||||
const end_offset = window_start + actual_window.len;
|
||||
const num_missing_bytes = actual.len - (window_start + actual_window.len);
|
||||
std.debug.print("... truncated, end offset: 0x{X}, remaining bytes: 0x{X} ...\n", .{ end_offset, num_missing_bytes });
|
||||
}
|
||||
std.debug.print("\n================================================\n\n", .{});
|
||||
|
||||
return err;
|
||||
};
|
||||
return error.TestExpectedEqual;
|
||||
}
|
||||
}
|
||||
|
||||
const BytesDiffer = struct {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user