authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-19 22:10:27-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-07-20 10:40:26-07:00
log8bcc91c15e966e1661124a73e17cf446e21831e9
treed92dea7a390748bb40005f6a2b7ac9858bbcec13
parentb70f12fc40f8f2bf4cce1904cb15a6e365ec95c2

add std.testing.io


3 files changed, 27 insertions(+), 14 deletions(-)

lib/compiler/test_runner.zig+7-8
...@@ -120,6 +120,7 @@ fn mainServer() !void {...@@ -120,6 +120,7 @@ fn mainServer() !void {
120120
121 .run_test => {121 .run_test => {
122 testing.allocator_instance = .{};122 testing.allocator_instance = .{};
123 testing.io_instance = .init(fba.allocator());
123 log_err_count = 0;124 log_err_count = 0;
124 const index = try server.receiveBody_u32();125 const index = try server.receiveBody_u32();
125 const test_fn = builtin.test_functions[index];126 const test_fn = builtin.test_functions[index];
...@@ -135,6 +136,8 @@ fn mainServer() !void {...@@ -135,6 +136,8 @@ fn mainServer() !void {
135 }136 }
136 },137 },
137 };138 };
139 testing.io_instance.deinit();
140 fba.reset();
138 const leak = testing.allocator_instance.deinit() == .leak;141 const leak = testing.allocator_instance.deinit() == .leak;
139 try server.serveTestResults(.{142 try server.serveTestResults(.{
140 .index = index,143 .index = index,
...@@ -194,18 +197,14 @@ fn mainTerminal() void {...@@ -194,18 +197,14 @@ fn mainTerminal() void {
194 });197 });
195 const have_tty = std.fs.File.stderr().isTty();198 const have_tty = std.fs.File.stderr().isTty();
196199
197 var async_frame_buffer: []align(builtin.target.stackAlignment()) u8 = undefined;
198 // TODO this is on the next line (using `undefined` above) because otherwise zig incorrectly
199 // ignores the alignment of the slice.
200 async_frame_buffer = &[_]u8{};
201
202 var leaks: usize = 0;200 var leaks: usize = 0;
203 for (test_fn_list, 0..) |test_fn, i| {201 for (test_fn_list, 0..) |test_fn, i| {
204 testing.allocator_instance = .{};202 testing.allocator_instance = .{};
203 testing.io_instance = .init(fba.allocator());
205 defer {204 defer {
206 if (testing.allocator_instance.deinit() == .leak) {205 if (testing.allocator_instance.deinit() == .leak) leaks += 1;
207 leaks += 1;206 testing.io_instance.deinit();
208 }207 fba.reset();
209 }208 }
210 testing.log_level = .warn;209 testing.log_level = .warn;
211210
lib/std/Io/test.zig+17-6
...@@ -1,5 +1,5 @@...@@ -1,5 +1,5 @@
1const std = @import("std");1const std = @import("std");
2const io = std.io;2const Io = std.Io;
3const DefaultPrng = std.Random.DefaultPrng;3const DefaultPrng = std.Random.DefaultPrng;
4const expect = std.testing.expect;4const expect = std.testing.expect;
5const expectEqual = std.testing.expectEqual;5const expectEqual = std.testing.expectEqual;
...@@ -24,7 +24,7 @@ test "write a file, read it, then delete it" {...@@ -24,7 +24,7 @@ test "write a file, read it, then delete it" {
24 var file = try tmp.dir.createFile(tmp_file_name, .{});24 var file = try tmp.dir.createFile(tmp_file_name, .{});
25 defer file.close();25 defer file.close();
2626
27 var buf_stream = io.bufferedWriter(file.deprecatedWriter());27 var buf_stream = Io.bufferedWriter(file.deprecatedWriter());
28 const st = buf_stream.writer();28 const st = buf_stream.writer();
29 try st.print("begin", .{});29 try st.print("begin", .{});
30 try st.writeAll(data[0..]);30 try st.writeAll(data[0..]);
...@@ -45,7 +45,7 @@ test "write a file, read it, then delete it" {...@@ -45,7 +45,7 @@ test "write a file, read it, then delete it" {
45 const expected_file_size: u64 = "begin".len + data.len + "end".len;45 const expected_file_size: u64 = "begin".len + data.len + "end".len;
46 try expectEqual(expected_file_size, file_size);46 try expectEqual(expected_file_size, file_size);
4747
48 var buf_stream = io.bufferedReader(file.deprecatedReader());48 var buf_stream = Io.bufferedReader(file.deprecatedReader());
49 const st = buf_stream.reader();49 const st = buf_stream.reader();
50 const contents = try st.readAllAlloc(std.testing.allocator, 2 * 1024);50 const contents = try st.readAllAlloc(std.testing.allocator, 2 * 1024);
51 defer std.testing.allocator.free(contents);51 defer std.testing.allocator.free(contents);
...@@ -66,7 +66,7 @@ test "BitStreams with File Stream" {...@@ -66,7 +66,7 @@ test "BitStreams with File Stream" {
66 var file = try tmp.dir.createFile(tmp_file_name, .{});66 var file = try tmp.dir.createFile(tmp_file_name, .{});
67 defer file.close();67 defer file.close();
6868
69 var bit_stream = io.bitWriter(native_endian, file.deprecatedWriter());69 var bit_stream = Io.bitWriter(native_endian, file.deprecatedWriter());
7070
71 try bit_stream.writeBits(@as(u2, 1), 1);71 try bit_stream.writeBits(@as(u2, 1), 1);
72 try bit_stream.writeBits(@as(u5, 2), 2);72 try bit_stream.writeBits(@as(u5, 2), 2);
...@@ -80,7 +80,7 @@ test "BitStreams with File Stream" {...@@ -80,7 +80,7 @@ test "BitStreams with File Stream" {
80 var file = try tmp.dir.openFile(tmp_file_name, .{});80 var file = try tmp.dir.openFile(tmp_file_name, .{});
81 defer file.close();81 defer file.close();
8282
83 var bit_stream = io.bitReader(native_endian, file.deprecatedReader());83 var bit_stream = Io.bitReader(native_endian, file.deprecatedReader());
8484
85 var out_bits: u16 = undefined;85 var out_bits: u16 = undefined;
8686
...@@ -170,7 +170,7 @@ test "updateTimes" {...@@ -170,7 +170,7 @@ test "updateTimes" {
170170
171test "GenericReader methods can return error.EndOfStream" {171test "GenericReader methods can return error.EndOfStream" {
172 // https://github.com/ziglang/zig/issues/17733172 // https://github.com/ziglang/zig/issues/17733
173 var fbs = std.io.fixedBufferStream("");173 var fbs = std.Io.fixedBufferStream("");
174 try std.testing.expectError(174 try std.testing.expectError(
175 error.EndOfStream,175 error.EndOfStream,
176 fbs.reader().readEnum(enum(u8) { a, b }, .little),176 fbs.reader().readEnum(enum(u8) { a, b }, .little),
...@@ -180,3 +180,14 @@ test "GenericReader methods can return error.EndOfStream" {...@@ -180,3 +180,14 @@ test "GenericReader methods can return error.EndOfStream" {
180 fbs.reader().isBytes("foo"),180 fbs.reader().isBytes("foo"),
181 );181 );
182}182}
183
184test "Io instance provided by unit tester async/await" {
185 const io = std.testing.io;
186 var future1 = io.async(silly, .{1});
187 var future2 = io.async(silly, .{2});
188 try std.testing.expectEqual(3, future1.await(io) + future2.await(io));
189}
190
191fn silly(n: usize) usize {
192 return n;
193}
lib/std/testing.zig+3
...@@ -28,6 +28,9 @@ pub var allocator_instance: std.heap.GeneralPurposeAllocator(.{...@@ -28,6 +28,9 @@ pub var allocator_instance: std.heap.GeneralPurposeAllocator(.{
28 break :b .init;28 break :b .init;
29};29};
3030
31pub var io_instance: std.Io.ThreadPool = undefined;
32pub const io = io_instance.io();
33
31/// TODO https://github.com/ziglang/zig/issues/573834/// TODO https://github.com/ziglang/zig/issues/5738
32pub var log_level = std.log.Level.warn;35pub var log_level = std.log.Level.warn;
3336