@@ -186,38 +186,32 @@ pub fn printInvalidUsageAlloc(
186186 return command .printInvalidUsage (io , exe_path , error_message );
187187}
188188
189+ pub const TestExecuteSettings = struct {
190+ stdin : ? std.io.AnyReader = null ,
191+ stdout : ? std.io.AnyWriter = null ,
192+ stderr : ? std.io.AnyWriter = null ,
193+ cwd : ? std.fs.Dir = null ,
194+ };
195+
189196pub fn testExecute (
190197 command : Command ,
191198 arguments : []const []const u8 ,
192- settings : anytype ,
199+ settings : TestExecuteSettings ,
193200) ExposedError ! void {
194201 std .debug .assert (builtin .is_test );
195202
196- const SettingsType = @TypeOf (settings );
197- const stdin = if (@hasField (SettingsType , "stdin" ))
198- settings .stdin
199- else
200- VoidReader .reader ();
201- const stdout = if (@hasField (SettingsType , "stdout" ))
202- settings .stdout
203- else
204- VoidWriter .writer ();
205- const stderr = if (@hasField (SettingsType , "stderr" ))
206- settings .stderr
207- else
208- VoidWriter .writer ();
209-
210- const cwd_provided = @hasField (SettingsType , "cwd" );
211- var tmp_dir = if (! cwd_provided ) std .testing .tmpDir (.{}) else {};
203+ const cwd_provided = settings .cwd != null ;
204+
205+ var tmp_dir : std.testing.TmpDir = if (! cwd_provided ) std .testing .tmpDir (.{}) else undefined ;
212206 defer if (! cwd_provided ) tmp_dir .cleanup ();
213- const cwd = if (cwd_provided ) settings .cwd else tmp_dir .dir ;
207+ const cwd = if (settings .cwd ) | c | c else tmp_dir .dir ;
214208
215209 var arg_iter : Arg.Iterator = .{ .slice = .{ .slice = arguments } };
216210
217211 const io : IO = .{
218- ._stderr = stderr .any (),
219- ._stdin = stdin .any (),
220- ._stdout = stdout .any (),
212+ ._stderr = if ( settings . stderr ) | s | s else VoidWriter . writer () .any (),
213+ ._stdin = if ( settings . stdin ) | s | s else VoidReader . reader () .any (),
214+ ._stdout = if ( settings . stdout ) | s | s else VoidWriter . writer () .any (),
221215 };
222216
223217 return command .execute (
@@ -232,42 +226,24 @@ pub fn testExecute(
232226pub fn testError (
233227 command : Command ,
234228 arguments : []const []const u8 ,
235- settings : anytype ,
229+ settings : TestExecuteSettings ,
236230 expected_error : []const u8 ,
237231) ! void {
238232 std .debug .assert (builtin .is_test );
239233
240- const SettingsType = @TypeOf (settings );
241-
242- if (@hasField (SettingsType , "stderr" )) {
243- @compileError ("`testError` does not support `stderr` on the settings type" );
234+ if (settings .stderr != null ) {
235+ @panic ("`stderr` cannot be provided with `testError`" );
244236 }
245237
246- const stdin = if (@hasField (SettingsType , "stdin" ))
247- settings .stdin
248- else
249- VoidReader .reader ();
250- const stdout = if (@hasField (SettingsType , "stdout" ))
251- settings .stdout
252- else
253- VoidWriter .writer ();
254-
255- const cwd_provided = @hasField (SettingsType , "cwd" );
256- var tmp_dir = if (! cwd_provided ) std .testing .tmpDir (.{}) else {};
257- defer if (! cwd_provided ) tmp_dir .cleanup ();
258- const cwd = if (cwd_provided ) settings .cwd else tmp_dir .dir ;
259-
260238 var stderr = std .ArrayList (u8 ).init (std .testing .allocator );
261239 defer stderr .deinit ();
262240
241+ var settings_copy = settings ;
242+ settings_copy .stderr = stderr .writer ().any ();
243+
263244 try std .testing .expectError (error .AlreadyHandled , command .testExecute (
264245 arguments ,
265- .{
266- .stderr = stderr .writer (),
267- .stdin = stdin ,
268- .stdout = stdout ,
269- .cwd = cwd ,
270- },
246+ settings_copy ,
271247 ));
272248
273249 std .testing .expect (std .mem .indexOf (u8 , stderr .items , expected_error ) != null ) catch | err | {
@@ -307,7 +283,7 @@ pub fn testHelp(command: Command, comptime include_shorthand: bool) !void {
307283
308284 try command .testExecute (
309285 &.{"--help" },
310- .{ .stdout = out .writer () },
286+ .{ .stdout = out .writer (). any () },
311287 );
312288
313289 try std .testing .expectEqualStrings (full_expected_help , out .items );
@@ -334,7 +310,7 @@ pub fn testHelp(command: Command, comptime include_shorthand: bool) !void {
334310 try testExecute (
335311 command ,
336312 &.{"-h" },
337- .{ .stdout = out .writer () },
313+ .{ .stdout = out .writer (). any () },
338314 );
339315
340316 try std .testing .expectEqualStrings (short_expected_help , out .items );
@@ -350,7 +326,7 @@ pub fn testVersion(command: Command) !void {
350326 try command .testExecute (
351327 &.{"--version" },
352328 .{
353- .stdout = out .writer (),
329+ .stdout = out .writer (). any () ,
354330 },
355331 );
356332
@@ -412,7 +388,7 @@ pub fn testFuzz(command: Command, options: TestFuzzOptions) !void {
412388
413389 context .inner_command .testExecute (
414390 arguments ,
415- .{ .stdout = stdout .writer (), .stderr = stderr .writer () },
391+ .{ .stdout = stdout .writer (). any () , .stderr = stderr .writer (). any () },
416392 ) catch | err | {
417393 switch (err ) {
418394 error .OutOfMemory = > {
0 commit comments