Skip to content

Commit fb2654c

Browse files
committed
Support passing a file that contains a list of tests to run
If the final filename argument begins with an `@` it is a file (relative to cwd) that contains a list of test file/directories that should replace it in the arguments. See Dart-Code/Dart-Code#5473
1 parent 84eba11 commit fb2654c

File tree

3 files changed

+51
-1
lines changed

3 files changed

+51
-1
lines changed

pkgs/test/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
## 1.25.16-wip
22

3+
* Allow the final argument to be a filename prefixed with `@` that contains a
4+
list of test files/directories to run. The lines of this file simply replace
5+
the @file during argument parsing (ignoring blanks).
6+
37
## 1.25.15
48

59
* Allow the latest version of `package:shelf_web_socket`.

pkgs/test/test/runner/runner_test.dart

+25
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,15 @@ $_usage''');
324324
await test.shouldExit(1);
325325
});
326326

327+
test('a non-existent last @file is passed', () async {
328+
var test = await runTest(['@mytestfile']);
329+
expect(
330+
test.stderr,
331+
emitsThrough(contains(
332+
'Failed to read the file "mytestfile" to read test paths')));
333+
await test.shouldExit(64);
334+
});
335+
327336
// TODO(nweiz): test what happens when a test file is unreadable once issue
328337
// 15078 is fixed.
329338
});
@@ -407,6 +416,22 @@ $_usage''');
407416
expect(test.stdout, emitsThrough(contains('+1: All tests passed!')));
408417
await test.shouldExit(0);
409418
});
419+
420+
test('provided via a final @file argument', () async {
421+
await d.file('test.dart', _success).create();
422+
await d.file('mytestfiles.txt', 'test.dart').create();
423+
var test = await runTest(['@mytestfiles.txt']);
424+
expect(test.stdout, emitsThrough(contains('+1: All tests passed!')));
425+
await test.shouldExit(0);
426+
});
427+
428+
test('provided via a final @file argument ignoring empty lines', () async {
429+
await d.file('test.dart', _success).create();
430+
await d.file('mytestfiles.txt', '\n\r\ntest.dart\r\n').create();
431+
var test = await runTest(['@mytestfiles.txt']);
432+
expect(test.stdout, emitsThrough(contains('+1: All tests passed!')));
433+
await test.shouldExit(0);
434+
});
410435
});
411436

412437
group('runs successful tests with async setup', () {

pkgs/test_core/lib/src/runner/configuration/args.dart

+22-1
Original file line numberDiff line numberDiff line change
@@ -298,11 +298,32 @@ class _Parser {
298298
compilerSelections.add(CompilerSelection.parse('vm:source'));
299299
}
300300

301-
final paths = _options.rest.isEmpty ? null : _options.rest;
301+
var paths = _options.rest.isEmpty ? null : _options.rest;
302302

303303
Map<String, Set<TestSelection>>? selections;
304304
if (paths != null) {
305305
selections = {};
306+
307+
// The last path can start with @ and is a file that contains a list
308+
// of paths that should be appended as if they were just inlined into
309+
// the args. It is up to the calling code to clean up this file (if
310+
// required) after the test process terminates.
311+
var lastPath = paths.last;
312+
if (lastPath.startsWith('@')) {
313+
lastPath = lastPath.substring(1); // Strip @
314+
paths = paths.toList(); // Make modifyable.
315+
var argsFile = File(lastPath);
316+
try {
317+
paths.removeLast();
318+
paths.addAll(argsFile
319+
.readAsLinesSync()
320+
.where((line) => line.trim().isNotEmpty));
321+
} on FileSystemException catch (e) {
322+
throw FormatException(
323+
'Failed to read the file "$lastPath" to read test paths: $e');
324+
}
325+
}
326+
306327
for (final path in paths) {
307328
_parseTestSelection(path, selections);
308329
}

0 commit comments

Comments
 (0)