Support passing extra arguments to test via test_with_coverage
Fixes https://github.com/dart-lang/coverage/issues/403
Also cleaned up help text
diff --git a/pkgs/coverage/CHANGELOG.md b/pkgs/coverage/CHANGELOG.md
index 6d864fa..a3b7c6c 100644
--- a/pkgs/coverage/CHANGELOG.md
+++ b/pkgs/coverage/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 1.5.0
+
+* Support passing extra arguments to `test_with_coverage` which are then passed
+ to `package:test`.
+
+ Example: `dart run coverage:test_with_coverage -- --preset CI`
+
+
## 1.4.0 - 2022-6-16
* Added `HitMap.parseJsonSync` which takes a cache of ignored lines which can
diff --git a/pkgs/coverage/bin/test_with_coverage.dart b/pkgs/coverage/bin/test_with_coverage.dart
index 56be562..d234527 100644
--- a/pkgs/coverage/bin/test_with_coverage.dart
+++ b/pkgs/coverage/bin/test_with_coverage.dart
@@ -90,8 +90,9 @@
this.port,
this.testScript,
this.functionCoverage,
- this.branchCoverage,
- );
+ this.branchCoverage, {
+ required this.rest,
+ });
final String packageDir;
final String packageName;
@@ -100,6 +101,7 @@
final String testScript;
final bool functionCoverage;
final bool branchCoverage;
+ final List<String> rest;
}
Future<Flags> _parseArgs(List<String> arguments) async {
@@ -107,11 +109,16 @@
final args = parser.parse(arguments);
void printUsage() {
- print('Runs tests and collects coverage for a package. By default this '
- "script assumes it's being run from the root directory of a package, and "
- 'outputs a coverage.json and lcov.info to ./coverage/');
- print('Usage: dart test_with_coverage.dart [OPTIONS...]\n');
- print(parser.usage);
+ print('''
+Runs tests and collects coverage for a package.
+
+By default this script assumes it's being run from the root directory of a
+package, and outputs a coverage.json and lcov.info to ./coverage/
+
+Usage: test_with_coverage [OPTIONS...] [-- <test script OPTIONS>]
+
+${parser.usage}
+''');
}
Never fail(String msg) {
@@ -147,6 +154,7 @@
args['test'] as String,
args['function-coverage'] as bool,
args['branch-coverage'] as bool,
+ rest: args.rest,
);
}
@@ -166,21 +174,25 @@
}
final serviceUriCompleter = Completer<Uri>();
- final testProcess = _dartRun([
- if (flags.branchCoverage) '--branch-coverage',
- 'run',
- '--pause-isolates-on-exit',
- '--disable-service-auth-codes',
- '--enable-vm-service=${flags.port}',
- flags.testScript,
- ], onStdout: (line) {
- if (!serviceUriCompleter.isCompleted) {
- final uri = extractVMServiceUri(line);
- if (uri != null) {
- serviceUriCompleter.complete(uri);
+ final testProcess = _dartRun(
+ [
+ if (flags.branchCoverage) '--branch-coverage',
+ 'run',
+ '--pause-isolates-on-exit',
+ '--disable-service-auth-codes',
+ '--enable-vm-service=${flags.port}',
+ flags.testScript,
+ ...flags.rest,
+ ],
+ onStdout: (line) {
+ if (!serviceUriCompleter.isCompleted) {
+ final uri = extractVMServiceUri(line);
+ if (uri != null) {
+ serviceUriCompleter.complete(uri);
+ }
}
- }
- });
+ },
+ );
final serviceUri = await serviceUriCompleter.future;
await collect_coverage.main([
diff --git a/pkgs/coverage/pubspec.yaml b/pkgs/coverage/pubspec.yaml
index 41dd013..a60cc19 100644
--- a/pkgs/coverage/pubspec.yaml
+++ b/pkgs/coverage/pubspec.yaml
@@ -1,5 +1,5 @@
name: coverage
-version: 1.4.0
+version: 1.5.0
description: Coverage data manipulation and formatting
repository: https://github.com/dart-lang/coverage
diff --git a/pkgs/coverage/test/test_with_coverage_package/lib/validate_lib.dart b/pkgs/coverage/test/test_with_coverage_package/lib/validate_lib.dart
new file mode 100644
index 0000000..99e5200
--- /dev/null
+++ b/pkgs/coverage/test/test_with_coverage_package/lib/validate_lib.dart
@@ -0,0 +1,15 @@
+int sum(Iterable<int> values) {
+ var val = 0;
+ for (var value in values) {
+ val += value;
+ }
+ return val;
+}
+
+int product(Iterable<int> values) {
+ var val = 1;
+ for (var value in values) {
+ val *= value;
+ }
+ return val;
+}
diff --git a/pkgs/coverage/test/test_with_coverage_package/main.dart b/pkgs/coverage/test/test_with_coverage_package/main.dart
deleted file mode 100644
index ac94d3c..0000000
--- a/pkgs/coverage/test/test_with_coverage_package/main.dart
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-void main() {}
diff --git a/pkgs/coverage/test/test_with_coverage_package/pubspec.yaml b/pkgs/coverage/test/test_with_coverage_package/pubspec.yaml
index 7507f20..3fa7ee0 100644
--- a/pkgs/coverage/test/test_with_coverage_package/pubspec.yaml
+++ b/pkgs/coverage/test/test_with_coverage_package/pubspec.yaml
@@ -4,6 +4,9 @@
environment:
sdk: '>=2.15.0 <3.0.0'
-dependencies:
+dev_dependencies:
+ test: ^1.16.0
+
+dependency_overrides:
coverage:
path: ../../
diff --git a/pkgs/coverage/test/test_with_coverage_package/test/product_test.dart b/pkgs/coverage/test/test_with_coverage_package/test/product_test.dart
new file mode 100644
index 0000000..91eac53
--- /dev/null
+++ b/pkgs/coverage/test/test_with_coverage_package/test/product_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+
+// ignore: avoid_relative_lib_imports
+import '../lib/validate_lib.dart';
+
+void main() {
+ test('product', () {
+ expect(product([2, 3]), 6);
+ });
+}
diff --git a/pkgs/coverage/test/test_with_coverage_package/test/sum_test.dart b/pkgs/coverage/test/test_with_coverage_package/test/sum_test.dart
new file mode 100644
index 0000000..f5b1ea4
--- /dev/null
+++ b/pkgs/coverage/test/test_with_coverage_package/test/sum_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test/test.dart';
+
+// ignore: avoid_relative_lib_imports
+import '../lib/validate_lib.dart';
+
+void main() {
+ test('sum', () {
+ expect(sum([1, 2]), 3);
+ });
+}
diff --git a/pkgs/coverage/test/test_with_coverage_test.dart b/pkgs/coverage/test/test_with_coverage_test.dart
index c128f2d..5aab793 100644
--- a/pkgs/coverage/test/test_with_coverage_test.dart
+++ b/pkgs/coverage/test/test_with_coverage_test.dart
@@ -2,19 +2,22 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:convert';
import 'dart:io';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
+import 'package:test_descriptor/test_descriptor.dart' as d;
import 'package:test_process/test_process.dart';
+import 'test_util.dart';
+
// this package
final _pkgDir = p.absolute('');
final _testWithCoveragePath = p.join(_pkgDir, 'bin', 'test_with_coverage.dart');
// test package
final _testPkgDirPath = p.join(_pkgDir, 'test', 'test_with_coverage_package');
-final _testPkgExePath = p.join(_testPkgDirPath, 'main.dart');
/// Override PUB_CACHE
///
@@ -24,59 +27,128 @@
final _pubCachePathInTestPkgSubDir = p.join(_pkgDir, 'var', 'pub-cache');
final _env = {'PUB_CACHE': _pubCachePathInTestPkgSubDir};
+const _testPackageName = 'coverage_integration_test_for_test_with_coverage';
+
int _port = 9300;
+Iterable<File> _dartFiles(String dir) =>
+ Directory(p.join(_testPkgDirPath, dir)).listSync().whereType<File>();
+
+String _fixTestFile(String content) => content.replaceAll(
+ "import '../lib/",
+ "import 'package:$_testPackageName/",
+ );
+
void main() {
setUpAll(() async {
+ for (var dir in const ['lib', 'test']) {
+ await d.dir(dir, [
+ for (var dartFile in _dartFiles(dir))
+ d.file(
+ p.basename(dartFile.path),
+ _fixTestFile(dartFile.readAsStringSync()),
+ ),
+ ]).create();
+ }
+
+ var pubspecContent =
+ File(p.join(_testPkgDirPath, 'pubspec.yaml')).readAsStringSync();
+
+ expect(
+ pubspecContent.replaceAll('\r\n', '\n'),
+ contains(r'''
+dependency_overrides:
+ coverage:
+ path: ../../
+'''),
+ );
+
+ pubspecContent =
+ pubspecContent.replaceFirst('path: ../../', 'path: $_pkgDir');
+
+ await d.file('pubspec.yaml', pubspecContent).create();
+
final localPub = await _run(['pub', 'get']);
await localPub.shouldExit(0);
-
- final globalPub =
- await _run(['pub', 'global', 'activate', '-s', 'path', _pkgDir]);
- await globalPub.shouldExit(0);
});
- tearDownAll(() {
- for (final entry in [
- Directory(p.join(_testPkgDirPath, '.dart_tool')),
- Directory(p.join(_testPkgDirPath, 'coverage')),
- File(p.join(_testPkgDirPath, '.packages')),
- File(p.join(_testPkgDirPath, 'pubspec.lock')),
- ]) {
- if (entry.existsSync()) {
- entry.deleteSync(recursive: true);
- }
- }
+ test('dart run bin/test_with_coverage.dart -f', () async {
+ final list = await _runTest(['run', _testWithCoveragePath, '-f']);
+
+ final sources = list.sources();
+ final functionHits = functionInfoFromSources(sources);
+
+ expect(
+ functionHits['package:$_testPackageName/validate_lib.dart'],
+ {
+ 'product': 1,
+ 'sum': 1,
+ },
+ );
});
- test('dart run bin/test_with_coverage.dart', () async {
- final result = await _runTest(['run', _testWithCoveragePath]);
- await result.shouldExit(0);
+ test('dart run bin/test_with_coverage.dart -f -- -N sum', () async {
+ final list = await _runTest(
+ ['run', _testWithCoveragePath, '-f'],
+ extraArgs: ['--', '-N', 'sum'],
+ );
+
+ final sources = list.sources();
+ final functionHits = functionInfoFromSources(sources);
+
+ expect(
+ functionHits['package:$_testPackageName/validate_lib.dart'],
+ {
+ 'product': 0,
+ 'sum': 1,
+ },
+ reason: 'only `sum` tests should be run',
+ );
});
test('dart run coverage:test_with_coverage', () async {
- final result = await _runTest(['run', 'coverage:test_with_coverage']);
- await result.shouldExit(0);
+ await _runTest(['run', 'coverage:test_with_coverage']);
});
test('dart pub global run coverage:test_with_coverage', () async {
- final result =
- await _runTest(['pub', 'global', 'run', 'coverage:test_with_coverage']);
- await result.shouldExit(0);
+ final globalPub =
+ await _run(['pub', 'global', 'activate', '-s', 'path', _pkgDir]);
+ await globalPub.shouldExit(0);
+
+ await _runTest(
+ ['pub', 'global', 'run', 'coverage:test_with_coverage'],
+ );
});
}
Future<TestProcess> _run(List<String> args) => TestProcess.start(
Platform.executable,
args,
- workingDirectory: _testPkgDirPath,
+ workingDirectory: d.sandbox,
environment: _env,
);
-Future<TestProcess> _runTest(List<String> invokeArgs) => _run([
- ...invokeArgs,
- '--port',
- '${_port++}',
- '--test',
- _testPkgExePath,
- ]);
+Future<List<Map<String, dynamic>>> _runTest(
+ List<String> invokeArgs, {
+ List<String>? extraArgs,
+}) async {
+ final process = await _run([
+ ...invokeArgs,
+ '--port',
+ '${_port++}',
+ ...?extraArgs,
+ ]);
+
+ await process.shouldExit(0);
+
+ await d.dir(
+ 'coverage',
+ [d.file('coverage.json', isNotEmpty), d.file('lcov.info', isNotEmpty)],
+ ).validate();
+
+ final coverageDataFile = File(p.join(d.sandbox, 'coverage', 'coverage.json'));
+
+ final json = jsonDecode(coverageDataFile.readAsStringSync());
+
+ return coverageDataFromJson(json as Map<String, dynamic>);
+}