authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-03 19:14:48-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-07 22:43:53-07:00
logf4720e14072fc4aa45fd2c985a676d4140ecc06a
treef4c261f8a3b0feb19dd44bddd7647391f88c1d37
parent87a7568a4437ab4e98ad32573548886529c6b10d

std.testing: update to new std.io API


2 files changed, 41 insertions(+), 36 deletions(-)

lib/std/testing.zig+32-27
......@@ -360,9 +360,6 @@ test expectApproxEqRel {
360360/// The colorized output is optional and controlled by the return of `std.io.tty.detectConfig()`.
361361/// If your inputs are UTF-8 encoded strings, consider calling `expectEqualStrings` instead.
362362pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const T) !void {
363 if (expected.ptr == actual.ptr and expected.len == actual.len) {
364 return;
365 }
366363 const diff_index: usize = diff_index: {
367364 const shortest = @min(expected.len, actual.len);
368365 var index: usize = 0;
......@@ -371,12 +368,21 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const
371368 }
372369 break :diff_index if (expected.len == actual.len) return else shortest;
373370 };
371 if (!backend_can_print) return error.TestExpectedEqual;
372 const stderr_w = std.debug.lockStderrWriter(&.{});
373 defer std.debug.unlockStderrWriter();
374 failEqualSlices(T, expected, actual, diff_index, stderr_w) catch {};
375 return error.TestExpectedEqual;
376}
374377
375 if (!backend_can_print) {
376 return error.TestExpectedEqual;
377 }
378
379 print("slices differ. first difference occurs at index {d} (0x{X})\n", .{ diff_index, diff_index });
378fn failEqualSlices(
379 comptime T: type,
380 expected: []const T,
381 actual: []const T,
382 diff_index: usize,
383 w: *std.io.Writer,
384) !void {
385 try w.print("slices differ. first difference occurs at index {d} (0x{X})\n", .{ diff_index, diff_index });
380386
381387 // TODO: Should this be configurable by the caller?
382388 const max_lines: usize = 16;
......@@ -394,8 +400,7 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const
394400 const actual_window = actual[window_start..@min(actual.len, window_start + max_window_size)];
395401 const actual_truncated = window_start + actual_window.len < actual.len;
396402
397 const stderr: std.fs.File = .stderr();
398 const ttyconf = std.io.tty.detectConfig(stderr);
403 const ttyconf = std.io.tty.detectConfig(.stderr());
399404 var differ = if (T == u8) BytesDiffer{
400405 .expected = expected_window,
401406 .actual = actual_window,
......@@ -411,47 +416,47 @@ pub fn expectEqualSlices(comptime T: type, expected: []const T, actual: []const
411416 // that is usually useful.
412417 const index_fmt = if (T == u8) "0x{X}" else "{}";
413418
414 print("\n============ expected this output: ============= len: {} (0x{X})\n\n", .{ expected.len, expected.len });
419 try w.print("\n============ expected this output: ============= len: {} (0x{X})\n\n", .{ expected.len, expected.len });
415420 if (window_start > 0) {
416421 if (T == u8) {
417 print("... truncated, start index: " ++ index_fmt ++ " ...\n", .{window_start});
422 try w.print("... truncated, start index: " ++ index_fmt ++ " ...\n", .{window_start});
418423 } else {
419 print("... truncated ...\n", .{});
424 try w.print("... truncated ...\n", .{});
420425 }
421426 }
422 differ.write(stderr.deprecatedWriter()) catch {};
427 differ.write(w) catch {};
423428 if (expected_truncated) {
424429 const end_offset = window_start + expected_window.len;
425430 const num_missing_items = expected.len - (window_start + expected_window.len);
426431 if (T == u8) {
427 print("... truncated, indexes [" ++ index_fmt ++ "..] not shown, remaining bytes: " ++ index_fmt ++ " ...\n", .{ end_offset, num_missing_items });
432 try w.print("... truncated, indexes [" ++ index_fmt ++ "..] not shown, remaining bytes: " ++ index_fmt ++ " ...\n", .{ end_offset, num_missing_items });
428433 } else {
429 print("... truncated, remaining items: " ++ index_fmt ++ " ...\n", .{num_missing_items});
434 try w.print("... truncated, remaining items: " ++ index_fmt ++ " ...\n", .{num_missing_items});
430435 }
431436 }
432437
433438 // now reverse expected/actual and print again
434439 differ.expected = actual_window;
435440 differ.actual = expected_window;
436 print("\n============= instead found this: ============== len: {} (0x{X})\n\n", .{ actual.len, actual.len });
441 try w.print("\n============= instead found this: ============== len: {} (0x{X})\n\n", .{ actual.len, actual.len });
437442 if (window_start > 0) {
438443 if (T == u8) {
439 print("... truncated, start index: " ++ index_fmt ++ " ...\n", .{window_start});
444 try w.print("... truncated, start index: " ++ index_fmt ++ " ...\n", .{window_start});
440445 } else {
441 print("... truncated ...\n", .{});
446 try w.print("... truncated ...\n", .{});
442447 }
443448 }
444 differ.write(stderr.deprecatedWriter()) catch {};
449 differ.write(w) catch {};
445450 if (actual_truncated) {
446451 const end_offset = window_start + actual_window.len;
447452 const num_missing_items = actual.len - (window_start + actual_window.len);
448453 if (T == u8) {
449 print("... truncated, indexes [" ++ index_fmt ++ "..] not shown, remaining bytes: " ++ index_fmt ++ " ...\n", .{ end_offset, num_missing_items });
454 try w.print("... truncated, indexes [" ++ index_fmt ++ "..] not shown, remaining bytes: " ++ index_fmt ++ " ...\n", .{ end_offset, num_missing_items });
450455 } else {
451 print("... truncated, remaining items: " ++ index_fmt ++ " ...\n", .{num_missing_items});
456 try w.print("... truncated, remaining items: " ++ index_fmt ++ " ...\n", .{num_missing_items});
452457 }
453458 }
454 print("\n================================================\n\n", .{});
459 try w.print("\n================================================\n\n", .{});
455460
456461 return error.TestExpectedEqual;
457462}
......@@ -465,7 +470,7 @@ fn SliceDiffer(comptime T: type) type {
465470
466471 const Self = @This();
467472
468 pub fn write(self: Self, writer: anytype) !void {
473 pub fn write(self: Self, writer: *std.io.Writer) !void {
469474 for (self.expected, 0..) |value, i| {
470475 const full_index = self.start_index + i;
471476 const diff = if (i < self.actual.len) !std.meta.eql(self.actual[i], value) else true;
......@@ -486,7 +491,7 @@ const BytesDiffer = struct {
486491 actual: []const u8,
487492 ttyconf: std.io.tty.Config,
488493
489 pub fn write(self: BytesDiffer, writer: anytype) !void {
494 pub fn write(self: BytesDiffer, writer: *std.io.Writer) !void {
490495 var expected_iterator = std.mem.window(u8, self.expected, 16, 16);
491496 var row: usize = 0;
492497 while (expected_iterator.next()) |chunk| {
......@@ -503,7 +508,7 @@ const BytesDiffer = struct {
503508 if (chunk.len < 16) {
504509 var missing_columns = (16 - chunk.len) * 3;
505510 if (chunk.len < 8) missing_columns += 1;
506 try writer.writeByteNTimes(' ', missing_columns);
511 try writer.splatByteAll(' ', missing_columns);
507512 }
508513 for (chunk, 0..) |byte, col| {
509514 const diff = diffs.isSet(col);
......@@ -532,7 +537,7 @@ const BytesDiffer = struct {
532537 }
533538 }
534539
535 fn writeDiff(self: BytesDiffer, writer: anytype, comptime fmt: []const u8, args: anytype, diff: bool) !void {
540 fn writeDiff(self: BytesDiffer, writer: *std.io.Writer, comptime fmt: []const u8, args: anytype, diff: bool) !void {
536541 if (diff) try self.ttyconf.setColor(writer, .red);
537542 try writer.print(fmt, args);
538543 if (diff) try self.ttyconf.setColor(writer, .reset);
lib/std/zip.zig+9-9
......@@ -124,7 +124,7 @@ pub fn findEndRecord(seekable_stream: anytype, stream_len: u64) !EndRecord {
124124
125125 try seekable_stream.seekTo(stream_len - @as(u64, new_loaded_len));
126126 const read_buf: []u8 = buf[buf.len - new_loaded_len ..][0..read_len];
127 const len = try seekable_stream.context.deprecatedReader().readAll(read_buf);
127 const len = try seekable_stream.context.reader().readAll(read_buf);
128128 if (len != read_len)
129129 return error.ZipTruncated;
130130 loaded_len = new_loaded_len;
......@@ -295,7 +295,7 @@ pub fn Iterator(comptime SeekableStream: type) type {
295295 if (locator_end_offset > stream_len)
296296 return error.ZipTruncated;
297297 try stream.seekTo(stream_len - locator_end_offset);
298 const locator = try stream.context.deprecatedReader().readStructEndian(EndLocator64, .little);
298 const locator = try stream.context.reader().readStructEndian(EndLocator64, .little);
299299 if (!std.mem.eql(u8, &locator.signature, &end_locator64_sig))
300300 return error.ZipBadLocatorSig;
301301 if (locator.zip64_disk_count != 0)
......@@ -305,7 +305,7 @@ pub fn Iterator(comptime SeekableStream: type) type {
305305
306306 try stream.seekTo(locator.record_file_offset);
307307
308 const record64 = try stream.context.deprecatedReader().readStructEndian(EndRecord64, .little);
308 const record64 = try stream.context.reader().readStructEndian(EndRecord64, .little);
309309
310310 if (!std.mem.eql(u8, &record64.signature, &end_record64_sig))
311311 return error.ZipBadEndRecord64Sig;
......@@ -357,7 +357,7 @@ pub fn Iterator(comptime SeekableStream: type) type {
357357
358358 const header_zip_offset = self.cd_zip_offset + self.cd_record_offset;
359359 try self.stream.seekTo(header_zip_offset);
360 const header = try self.stream.context.deprecatedReader().readStructEndian(CentralDirectoryFileHeader, .little);
360 const header = try self.stream.context.reader().readStructEndian(CentralDirectoryFileHeader, .little);
361361 if (!std.mem.eql(u8, &header.signature, &central_file_header_sig))
362362 return error.ZipBadCdOffset;
363363
......@@ -386,7 +386,7 @@ pub fn Iterator(comptime SeekableStream: type) type {
386386
387387 {
388388 try self.stream.seekTo(header_zip_offset + @sizeOf(CentralDirectoryFileHeader) + header.filename_len);
389 const len = try self.stream.context.deprecatedReader().readAll(extra);
389 const len = try self.stream.context.reader().readAll(extra);
390390 if (len != extra.len)
391391 return error.ZipTruncated;
392392 }
......@@ -449,7 +449,7 @@ pub fn Iterator(comptime SeekableStream: type) type {
449449 try stream.seekTo(self.header_zip_offset + @sizeOf(CentralDirectoryFileHeader));
450450
451451 {
452 const len = try stream.context.deprecatedReader().readAll(filename);
452 const len = try stream.context.reader().readAll(filename);
453453 if (len != filename.len)
454454 return error.ZipBadFileOffset;
455455 }
......@@ -457,7 +457,7 @@ pub fn Iterator(comptime SeekableStream: type) type {
457457 const local_data_header_offset: u64 = local_data_header_offset: {
458458 const local_header = blk: {
459459 try stream.seekTo(self.file_offset);
460 break :blk try stream.context.deprecatedReader().readStructEndian(LocalFileHeader, .little);
460 break :blk try stream.context.reader().readStructEndian(LocalFileHeader, .little);
461461 };
462462 if (!std.mem.eql(u8, &local_header.signature, &local_file_header_sig))
463463 return error.ZipBadFileOffset;
......@@ -483,7 +483,7 @@ pub fn Iterator(comptime SeekableStream: type) type {
483483
484484 {
485485 try stream.seekTo(self.file_offset + @sizeOf(LocalFileHeader) + local_header.filename_len);
486 const len = try stream.context.deprecatedReader().readAll(extra);
486 const len = try stream.context.reader().readAll(extra);
487487 if (len != extra.len)
488488 return error.ZipTruncated;
489489 }
......@@ -552,7 +552,7 @@ pub fn Iterator(comptime SeekableStream: type) type {
552552 @as(u64, @sizeOf(LocalFileHeader)) +
553553 local_data_header_offset;
554554 try stream.seekTo(local_data_file_offset);
555 var limited_reader = std.io.limitedReader(stream.context.deprecatedReader(), self.compressed_size);
555 var limited_reader = std.io.limitedReader(stream.context.reader(), self.compressed_size);
556556 const crc = try decompress(
557557 self.compression_method,
558558 self.uncompressed_size,