From 7a16a14c6db945f8d4caf5b716dc29a405fe4750 Mon Sep 17 00:00:00 2001 From: Danny Tuppeny Date: Wed, 16 Apr 2025 13:50:40 +0100 Subject: [PATCH 1/2] Supporting passing a filename that contains a list of arguments as the last argument Allows the final argument to be `@filename` where `filename` is a path (relative to `cwd`) to a file that contains arguments to replace it before parsing. This allows arguments longer than Windows supports to be provided (see https://github.com/Dart-Code/Dart-Code/issues/5473). --- pkgs/test/CHANGELOG.md | 3 +++ pkgs/test/test/runner/runner_test.dart | 37 ++++++++++++++++++++++++++ pkgs/test_core/lib/src/executable.dart | 23 ++++++++++++++++ 3 files changed, 63 insertions(+) diff --git a/pkgs/test/CHANGELOG.md b/pkgs/test/CHANGELOG.md index 8ca0f96ab..445de6982 100644 --- a/pkgs/test/CHANGELOG.md +++ b/pkgs/test/CHANGELOG.md @@ -1,5 +1,8 @@ ## 1.25.16-wip +* Allow the final argument to be a filename prefixed with `@` that contains a + list of arguments as if they had been provided on the command line directly. + ## 1.25.15 * Allow the latest version of `package:shelf_web_socket`. diff --git a/pkgs/test/test/runner/runner_test.dart b/pkgs/test/test/runner/runner_test.dart index 379e2a7f1..cf3c79478 100644 --- a/pkgs/test/test/runner/runner_test.dart +++ b/pkgs/test/test/runner/runner_test.dart @@ -868,4 +868,41 @@ void main() { await test.shouldExit(0); }, skip: 'https://github.com/dart-lang/test/issues/1803'); }); + + group('using @file as the final argument', () { + test('prints a suitable message if the file does not exist', () async { + var test = await runTest(['@mytestfile']); + expect( + test.stderr, + emitsThrough( + contains('Failed to read the file "mytestfile" for arguments'))); + await test.shouldExit(64); + }); + + test('runs test suites provided in the file', () async { + await d.file('test.dart', _success).create(); + await d.file('mytestargs.txt', 'test.dart').create(); + var test = await runTest(['@mytestargs.txt']); + expect(test.stdout, emitsThrough(contains('+1: All tests passed!'))); + await test.shouldExit(0); + }); + + test('handles empty lines in the file', () async { + await d.file('test.dart', _success).create(); + await d.file('mytestargs.txt', '\n\r\ntest.dart\r\n').create(); + var test = await runTest(['@mytestargs.txt']); + expect(test.stdout, emitsThrough(contains('+1: All tests passed!'))); + await test.shouldExit(0); + }); + + test('handles other arguments in the file', () async { + await d.file('mytestargs.txt', '--help').create(); + var test = await runTest(['@mytestargs.txt']); + expectStdoutEquals(test, ''' +Runs tests in this package. + +$_usage'''); + await test.shouldExit(0); + }); + }); } diff --git a/pkgs/test_core/lib/src/executable.dart b/pkgs/test_core/lib/src/executable.dart index eeefd161c..5b03a2f35 100644 --- a/pkgs/test_core/lib/src/executable.dart +++ b/pkgs/test_core/lib/src/executable.dart @@ -68,6 +68,29 @@ Future _execute(List args) async { : StreamGroup.merge( [ProcessSignal.sigterm.watch(), ProcessSignal.sigint.watch()]); + // The last arg can start with @ and is a file that contains a list + // of args that should replace the filename as if they were just provided + // inline. + // It is up to the calling code to clean up this file (if required) after + // the test process terminates. + if (args.isNotEmpty) { + args = args.toList(); // Ensure mutable + var lastArg = args.last; + if (lastArg.startsWith('@')) { + lastArg = lastArg.substring(1); // Strip @ + var argsFile = File(lastArg); // Path must be relative to cwd + try { + args.removeLast(); + args.addAll( + argsFile.readAsLinesSync().where((line) => line.trim().isNotEmpty)); + } catch (e) { + _printUsage('Failed to read the file "$lastArg" for arguments: $e'); + exitCode = exit_codes.usage; + return; + } + } + } + Configuration configuration; try { configuration = Configuration.parse(args); From 1bf04d456f10afd66e3685f3bff93a3a948697e9 Mon Sep 17 00:00:00 2001 From: Danny Tuppeny Date: Wed, 16 Apr 2025 15:41:37 +0100 Subject: [PATCH 2/2] Add to test_core changelog --- pkgs/test_core/CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkgs/test_core/CHANGELOG.md b/pkgs/test_core/CHANGELOG.md index 9935d9dc0..377ae43d9 100644 --- a/pkgs/test_core/CHANGELOG.md +++ b/pkgs/test_core/CHANGELOG.md @@ -1,6 +1,9 @@ ## 0.6.9-wip -- Add support for native assets for `dart test` in pub workspaces. +* Add support for native assets for `dart test` in pub workspaces. +* Allow the final argument provided to the executable `main` method to be a + filename prefixed with `@` that contains a list of arguments as if they had + been provided on the command line directly. ## 0.6.8