[coverage] Partial workspace support (#2095)
diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml
index 98e1bb4..997e33f 100644
--- a/.github/workflows/coverage.yaml
+++ b/.github/workflows/coverage.yaml
@@ -56,12 +56,7 @@
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
- sdk: [3.4, dev]
- exclude:
- # VM service times out on windows before Dart 3.5
- # https://github.com/dart-lang/coverage/issues/490
- - os: windows-latest
- sdk: 3.4
+ sdk: [3.6, dev]
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: dart-lang/setup-dart@e51d8e571e22473a2ddebf0ef8a2123f0ab2c02c
@@ -89,7 +84,7 @@
name: Install dependencies
run: dart pub get
- name: Collect and report coverage
- run: dart run bin/test_with_coverage.dart --port=9292
+ run: dart run bin/test_with_coverage.dart
- name: Upload coverage
uses: coverallsapp/github-action@648a8eb78e6d50909eff900e4ec85cab4524a45b
with:
diff --git a/pkgs/coverage/CHANGELOG.md b/pkgs/coverage/CHANGELOG.md
index 6dc80a5..2a680ad 100644
--- a/pkgs/coverage/CHANGELOG.md
+++ b/pkgs/coverage/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 1.14.0
+
+- Require Dart ^3.6.0
+- Partial support for workspace packages in `test_wth_coverage`.
+- Deprecate `test_wth_coverage`'s `--package-name` flag, because it doesn't make
+ sense for workspaces.
+- Change the default `--port` to 0, allowing the VM to choose a free port.
+
## 1.13.1
- Fix a bug where the VM service can be shut down while some coverage
diff --git a/pkgs/coverage/README.md b/pkgs/coverage/README.md
index 2963c6a..7a90c8e 100644
--- a/pkgs/coverage/README.md
+++ b/pkgs/coverage/README.md
@@ -43,6 +43,30 @@
For more complicated use cases, where you want to control each of these stages,
see the sections below.
+#### Workspaces
+
+package:coverage has partial support for
+[workspaces](https://dart.dev/tools/pub/workspaces). You can run
+`test_with_coverage` from the root of the workspace to collect coverage for all
+the tests in all the subpackages, but you must specify the test directories to
+run.
+
+For example, in a workspace with subpackages `pkgs/foo` and `pkgs/bar`, you
+could run the following command from the root directory of the workspace:
+
+```
+dart run coverage:test_with_coverage -- pkgs/foo/test pkgs/bar/test
+```
+
+This would output coverage to ./coverage/ as normal. An important caveat is that
+the working directory of the tests will be the workspace's root directory. So
+this approach won't work if your tests assume that they are being run from the
+subpackage directory.
+
+[Full support](https://github.com/dart-lang/tools/issues/2083) for workspaces
+will likely be added in a future version. This will mean you won't need to
+explicitly specify the test directories: `dart run coverage:test_with_coverage`
+
#### Collecting coverage from the VM
```
diff --git a/pkgs/coverage/bin/test_with_coverage.dart b/pkgs/coverage/bin/test_with_coverage.dart
index c22e9b8..9f4884d 100644
--- a/pkgs/coverage/bin/test_with_coverage.dart
+++ b/pkgs/coverage/bin/test_with_coverage.dart
@@ -7,10 +7,8 @@
import 'package:args/args.dart';
import 'package:coverage/src/coverage_options.dart';
-import 'package:coverage/src/util.dart'
- show StandardOutExtension, extractVMServiceUri;
+import 'package:coverage/src/util.dart';
import 'package:meta/meta.dart';
-import 'package:package_config/package_config.dart';
import 'package:path/path.dart' as path;
import 'collect_coverage.dart' as collect_coverage;
@@ -19,37 +17,36 @@
final _allProcesses = <Process>[];
Future<void> _dartRun(List<String> args,
- {void Function(String)? onStdout, String? workingDir}) async {
- final process = await Process.start(
- Platform.executable,
- args,
- workingDirectory: workingDir,
- );
+ {required void Function(String) onStdout,
+ required void Function(String) onStderr}) async {
+ final process = await Process.start(Platform.executable, args);
_allProcesses.add(process);
- final broadStdout = process.stdout.asBroadcastStream();
- broadStdout.listen(stdout.add);
- if (onStdout != null) {
- broadStdout.lines().listen(onStdout);
+
+ void listen(
+ Stream<List<int>> stream, IOSink sink, void Function(String) onLine) {
+ final broadStream = stream.asBroadcastStream();
+ broadStream.listen(sink.add);
+ broadStream.lines().listen(onLine);
}
- process.stderr.listen(stderr.add);
+
+ listen(process.stdout, stdout, onStdout);
+ listen(process.stderr, stderr, onStderr);
+
final result = await process.exitCode;
if (result != 0) {
throw ProcessException(Platform.executable, args, '', result);
}
}
-Future<String?> _packageNameFromConfig(String packageDir) async {
- final config = await findPackageConfig(Directory(packageDir));
- return config?.packageOf(Uri.directory(packageDir))?.name;
+void _killSubprocessesAndExit(ProcessSignal signal) {
+ for (final process in _allProcesses) {
+ process.kill(signal);
+ }
+ exit(1);
}
void _watchExitSignal(ProcessSignal signal) {
- signal.watch().listen((sig) {
- for (final process in _allProcesses) {
- process.kill(sig);
- }
- exit(1);
- });
+ signal.watch().listen(_killSubprocessesAndExit);
}
ArgParser _createArgParser(CoverageOptions defaultOptions) => ArgParser()
@@ -61,10 +58,10 @@
..addOption(
'package-name',
help: 'Name of the package to test. '
- 'Deduced from --package if not provided.',
- defaultsTo: defaultOptions.packageName,
+ 'Deduced from --package if not provided. '
+ 'DEPRECATED: use --scope-output',
)
- ..addOption('port', help: 'VM service port.', defaultsTo: '8181')
+ ..addOption('port', help: 'VM service port. Defaults to using any free port.')
..addOption(
'out',
defaultsTo: defaultOptions.outputDirectory,
@@ -93,13 +90,13 @@
defaultsTo: defaultOptions.scopeOutput,
help: 'restrict coverage results so that only scripts that start with '
'the provided package path are considered. Defaults to the name of '
- 'the package under test.')
+ 'the current package (including all subpackages, if this is a '
+ 'workspace).')
..addFlag('help', abbr: 'h', negatable: false, help: 'Show this help.');
class Flags {
Flags(
this.packageDir,
- this.packageName,
this.outDir,
this.port,
this.testScript,
@@ -111,7 +108,6 @@
});
final String packageDir;
- final String packageName;
final String outDir;
final String port;
final String testScript;
@@ -157,25 +153,23 @@
fail('--package is not a valid directory.');
}
- final packageName = (args['package-name'] as String?) ??
- await _packageNameFromConfig(packageDir);
- if (packageName == null) {
+ final pubspecPath = getPubspecPath(packageDir);
+ if (!File(pubspecPath).existsSync()) {
fail(
- "Couldn't figure out package name from --package. Make sure this is a "
- 'package directory, or try passing --package-name explicitly.',
+ "Couldn't find $pubspecPath. Make sure this command is run in a "
+ 'package directory, or pass --package to explicitly set the directory.',
);
}
return Flags(
packageDir,
- packageName,
- (args['out'] as String?) ?? path.join(packageDir, 'coverage'),
- args['port'] as String,
- args['test'] as String,
- args['function-coverage'] as bool,
- args['branch-coverage'] as bool,
- args['scope-output'] as List<String>,
- args['fail-under'] as String?,
+ args.option('out') ?? path.join(packageDir, 'coverage'),
+ args.option('port') ?? '0',
+ args.option('test')!,
+ args.flag('function-coverage'),
+ args.flag('branch-coverage'),
+ args.multiOption('scope-output'),
+ args.option('fail-under'),
rest: args.rest,
);
}
@@ -215,11 +209,19 @@
}
}
},
+ onStderr: (line) {
+ if (!serviceUriCompleter.isCompleted) {
+ if (line.contains('Could not start the VM service')) {
+ _killSubprocessesAndExit(ProcessSignal.sigkill);
+ }
+ }
+ },
);
final serviceUri = await serviceUriCompleter.future;
- final scopes =
- flags.scopeOutput.isEmpty ? [flags.packageName] : flags.scopeOutput;
+ final scopes = flags.scopeOutput.isEmpty
+ ? getAllWorkspaceNames(flags.packageDir)
+ : flags.scopeOutput;
await collect_coverage.main([
'--wait-paused',
'--resume-isolates',
diff --git a/pkgs/coverage/dart_test.yaml b/pkgs/coverage/dart_test.yaml
new file mode 100644
index 0000000..f982167
--- /dev/null
+++ b/pkgs/coverage/dart_test.yaml
@@ -0,0 +1,5 @@
+tags:
+ # Tests that start subprocesses, so are slower and can be a bit flaky.
+ integration:
+ timeout: 2x
+ retry: 3
diff --git a/pkgs/coverage/lib/src/collect.dart b/pkgs/coverage/lib/src/collect.dart
index 76227ba..1bed28d 100644
--- a/pkgs/coverage/lib/src/collect.dart
+++ b/pkgs/coverage/lib/src/collect.dart
@@ -170,6 +170,7 @@
isolateReport,
includeDart,
functionCoverage,
+ branchCoverage,
coverableLineCache,
scopedOutput);
allCoverage.addAll(coverage);
@@ -244,6 +245,7 @@
SourceReport report,
bool includeDart,
bool functionCoverage,
+ bool branchCoverage,
Map<String, Set<int>>? coverableLineCache,
Set<String> scopedOutput) async {
final hitMaps = <Uri, HitMap>{};
@@ -262,7 +264,10 @@
return scripts[scriptRef];
}
- HitMap getHitMap(Uri scriptUri) => hitMaps.putIfAbsent(scriptUri, HitMap.new);
+ HitMap getHitMap(Uri scriptUri) => hitMaps.putIfAbsent(
+ scriptUri,
+ () => HitMap.empty(
+ functionCoverage: functionCoverage, branchCoverage: branchCoverage));
Future<void> processFunction(FuncRef funcRef) async {
final func = await service.getObject(isolateRef.id!, funcRef.id!) as Func;
@@ -290,8 +295,7 @@
return;
}
final hits = getHitMap(Uri.parse(script.uri!));
- hits.funcHits ??= <int, int>{};
- (hits.funcNames ??= <int, String>{})[line] = funcName;
+ hits.funcNames![line] = funcName;
}
for (var range in report.ranges!) {
@@ -385,13 +389,12 @@
hits.funcHits?.putIfAbsent(line, () => 0);
});
- final branchCoverage = range.branchCoverage;
- if (branchCoverage != null) {
- hits.branchHits ??= <int, int>{};
- forEachLine(branchCoverage.hits, (line) {
+ final branches = range.branchCoverage;
+ if (branchCoverage && branches != null) {
+ forEachLine(branches.hits, (line) {
hits.branchHits!.increment(line);
});
- forEachLine(branchCoverage.misses, (line) {
+ forEachLine(branches.misses, (line) {
hits.branchHits!.putIfAbsent(line, () => 0);
});
}
diff --git a/pkgs/coverage/lib/src/coverage_options.dart b/pkgs/coverage/lib/src/coverage_options.dart
index a15c31d..87790df 100644
--- a/pkgs/coverage/lib/src/coverage_options.dart
+++ b/pkgs/coverage/lib/src/coverage_options.dart
@@ -9,7 +9,6 @@
required this.functionCoverage,
required this.branchCoverage,
required this.packageDirectory,
- this.packageName,
required this.testScript,
});
@@ -40,8 +39,6 @@
branchCoverage: options.optionalBool('branch_coverage') ??
defaultOptions.branchCoverage,
packageDirectory: packageDirectory,
- packageName:
- options.optionalString('package_name') ?? defaultOptions.packageName,
testScript:
options.optionalString('test_script') ?? defaultOptions.testScript,
);
@@ -52,7 +49,6 @@
final bool functionCoverage;
final bool branchCoverage;
final String packageDirectory;
- final String? packageName;
final String testScript;
}
@@ -119,7 +115,6 @@
functionCoverage: false,
branchCoverage: false,
packageDirectory: '.',
- packageName: null,
testScript: 'test',
);
}
diff --git a/pkgs/coverage/lib/src/formatter.dart b/pkgs/coverage/lib/src/formatter.dart
index a37df73..2680607 100644
--- a/pkgs/coverage/lib/src/formatter.dart
+++ b/pkgs/coverage/lib/src/formatter.dart
@@ -151,6 +151,20 @@
);
final buf = StringBuffer();
for (final entry in entries) {
+ final source = resolver.resolve(entry.key);
+ if (source == null) {
+ continue;
+ }
+
+ if (!pathFilter(source)) {
+ continue;
+ }
+
+ final lines = await loader.load(source);
+ if (lines == null) {
+ continue;
+ }
+
final v = entry.value;
if (reportFuncs && v.funcHits == null) {
throw StateError(
@@ -165,24 +179,12 @@
'missing branch coverage information. Did you run '
'collect_coverage with the --branch-coverage flag?');
}
+
final hits = reportFuncs
? v.funcHits!
: reportBranches
? v.branchHits!
: v.lineHits;
- final source = resolver.resolve(entry.key);
- if (source == null) {
- continue;
- }
-
- if (!pathFilter(source)) {
- continue;
- }
-
- final lines = await loader.load(source);
- if (lines == null) {
- continue;
- }
buf.writeln(source);
for (var line = 1; line <= lines.length; line++) {
var prefix = _prefix;
diff --git a/pkgs/coverage/lib/src/hitmap.dart b/pkgs/coverage/lib/src/hitmap.dart
index 4c3b468..133c24b 100644
--- a/pkgs/coverage/lib/src/hitmap.dart
+++ b/pkgs/coverage/lib/src/hitmap.dart
@@ -18,6 +18,15 @@
this.branchHits,
]) : lineHits = lineHits ?? {};
+ /// Constructs an empty hitmap, optionally with function and branch coverage
+ /// tables.
+ HitMap.empty({bool functionCoverage = false, bool branchCoverage = false})
+ : this(
+ null,
+ functionCoverage ? <int, int>{} : null,
+ functionCoverage ? <int, String>{} : null,
+ branchCoverage ? <int, int>{} : null);
+
/// Map from line to hit count for that line.
final Map<int, int> lineHits;
diff --git a/pkgs/coverage/lib/src/util.dart b/pkgs/coverage/lib/src/util.dart
index cc7f584..74a1697 100644
--- a/pkgs/coverage/lib/src/util.dart
+++ b/pkgs/coverage/lib/src/util.dart
@@ -6,6 +6,8 @@
import 'dart:convert';
import 'dart:io';
+import 'package:path/path.dart' as path;
+import 'package:pubspec_parse/pubspec_parse.dart';
import 'package:vm_service/vm_service.dart';
// TODO(cbracken) make generic
@@ -57,25 +59,6 @@
return null;
}
-/// Returns an open port by creating a temporary Socket
-Future<int> getOpenPort() async {
- ServerSocket socket;
-
- try {
- socket = await ServerSocket.bind(InternetAddress.loopbackIPv4, 0);
- } catch (_) {
- // try again v/ V6 only. Slight possibility that V4 is disabled
- socket =
- await ServerSocket.bind(InternetAddress.loopbackIPv6, 0, v6Only: true);
- }
-
- try {
- return socket.port;
- } finally {
- await socket.close();
- }
-}
-
final muliLineIgnoreStart = RegExp(r'//\s*coverage:ignore-start[\w\d\s]*$');
final muliLineIgnoreEnd = RegExp(r'//\s*coverage:ignore-end[\w\d\s]*$');
final singleLineIgnore = RegExp(r'//\s*coverage:ignore-line[\w\d\s]*$');
@@ -184,3 +167,19 @@
Future<List<IsolateRef>> getAllIsolates(VmService service) async =>
(await service.getVM()).isolates ?? [];
+
+String getPubspecPath(String root) => path.join(root, 'pubspec.yaml');
+
+List<String> getAllWorkspaceNames(String packageRoot) =>
+ _getAllWorkspaceNames(packageRoot, <String>[]);
+
+List<String> _getAllWorkspaceNames(String packageRoot, List<String> results) {
+ final pubspecPath = getPubspecPath(packageRoot);
+ final yaml = File(pubspecPath).readAsStringSync();
+ final pubspec = Pubspec.parse(yaml, sourceUrl: Uri.file(pubspecPath));
+ results.add(pubspec.name);
+ for (final workspace in pubspec.workspace ?? <String>[]) {
+ _getAllWorkspaceNames(path.join(packageRoot, workspace), results);
+ }
+ return results;
+}
diff --git a/pkgs/coverage/pubspec.yaml b/pkgs/coverage/pubspec.yaml
index 46307b8..e4a229e 100644
--- a/pkgs/coverage/pubspec.yaml
+++ b/pkgs/coverage/pubspec.yaml
@@ -1,5 +1,5 @@
name: coverage
-version: 1.13.1
+version: 1.14.0
description: Coverage data manipulation and formatting
repository: https://github.com/dart-lang/tools/tree/main/pkgs/coverage
issue_tracker: https://github.com/dart-lang/tools/issues?q=is%3Aissue+is%3Aopen+label%3Apackage%3Acoverage
@@ -15,6 +15,7 @@
meta: ^1.0.2
package_config: ^2.0.0
path: ^1.8.0
+ pubspec_parse: ^1.5.0
source_maps: ^0.10.10
stack_trace: ^1.10.0
vm_service: '>=12.0.0 <16.0.0'
diff --git a/pkgs/coverage/test/collect_coverage_api_test.dart b/pkgs/coverage/test/collect_coverage_api_test.dart
index fd3de43..5ccedd8 100644
--- a/pkgs/coverage/test/collect_coverage_api_test.dart
+++ b/pkgs/coverage/test/collect_coverage_api_test.dart
@@ -2,6 +2,9 @@
// 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.
+@Tags(['integration'])
+library;
+
import 'dart:async';
import 'package:coverage/coverage.dart';
@@ -140,10 +143,8 @@
bool functionCoverage = false,
bool branchCoverage = false,
Map<String, Set<int>>? coverableLineCache}) async {
- final openPort = await getOpenPort();
-
// run the sample app, with the right flags
- final sampleProcess = await runTestApp(openPort);
+ final sampleProcess = await runTestApp();
final serviceUri = await serviceUriFromProcess(sampleProcess.stdoutStream());
final isolateIdSet = isolateIds ? <String>{} : null;
diff --git a/pkgs/coverage/test/collect_coverage_config_test.dart b/pkgs/coverage/test/collect_coverage_config_test.dart
index 5f6c460..d2b6b58 100644
--- a/pkgs/coverage/test/collect_coverage_config_test.dart
+++ b/pkgs/coverage/test/collect_coverage_config_test.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2025, 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:coverage/src/coverage_options.dart';
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
@@ -35,7 +39,6 @@
expect(path.canonicalize(testCoverage.packageDir),
path.canonicalize(defaults.packageDirectory));
- expect(testCoverage.packageName, 'coverage');
expect(path.canonicalize(testCoverage.outDir),
path.canonicalize('coverage'));
expect(testCoverage.testScript, defaults.testScript);
@@ -73,7 +76,6 @@
// Verify test with coverage yaml values
expect(path.canonicalize(testCoverage.packageDir),
path.canonicalize('test/test_files'));
- expect(testCoverage.packageName, 'My Dart Package');
expect(path.canonicalize(testCoverage.outDir),
path.canonicalize('var/coverage_data'));
expect(testCoverage.testScript, 'test1');
@@ -102,7 +104,6 @@
expect(collectedCoverage.functionCoverage, isFalse);
expect(path.canonicalize(formattedCoverage.output!),
path.canonicalize('var/coverage_data/custom_coverage/lcov.info'));
- expect(testCoverage.packageName, 'Custom Dart Package');
expect(testCoverage.scopeOutput, ['lib', 'test']);
});
@@ -133,7 +134,6 @@
path.canonicalize('test/test_coverage_options'));
// Verify test with coverage yaml values
- expect(testCoverage.packageName, 'coverage');
expect(path.canonicalize(testCoverage.outDir),
path.canonicalize('var/coverage_data/custom_lcov'));
expect(testCoverage.testScript, 'custom_test');
@@ -178,7 +178,6 @@
expect(formattedCoverage.packagePath, '../code_builder');
// Verify test with coverage command line args
- expect(testCoverage.packageName, 'test');
expect(testCoverage.outDir, 'test_coverage.json');
expect(testCoverage.testScript, 'test_test.dart');
expect(testCoverage.functionCoverage, isTrue);
@@ -218,7 +217,6 @@
expect(formattedCoverage.packagePath, '../cli_config');
// Verify test with coverage command line args
- expect(testCoverage.packageName, 'cli_config');
expect(testCoverage.outDir, 'cli_config_coverage.json');
expect(testCoverage.testScript, 'cli_config_test.dart');
expect(testCoverage.functionCoverage, isTrue);
diff --git a/pkgs/coverage/test/collect_coverage_test.dart b/pkgs/coverage/test/collect_coverage_test.dart
index 476fee1..5758b5e 100644
--- a/pkgs/coverage/test/collect_coverage_test.dart
+++ b/pkgs/coverage/test/collect_coverage_test.dart
@@ -2,7 +2,7 @@
// 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.
-@Retry(3)
+@Tags(['integration'])
library;
import 'dart:async';
@@ -294,10 +294,8 @@
bool functionCoverage, bool branchCoverage) async {
expect(FileSystemEntity.isFileSync(testAppPath), isTrue);
- final openPort = await getOpenPort();
-
// Run the sample app with the right flags.
- final sampleProcess = await runTestApp(openPort);
+ final sampleProcess = await runTestApp();
// Capture the VM service URI.
final serviceUri = await serviceUriFromProcess(sampleProcess.stdoutStream());
diff --git a/pkgs/coverage/test/config_file_locator_test.dart b/pkgs/coverage/test/config_file_locator_test.dart
index d46fc86..db131e8 100644
--- a/pkgs/coverage/test/config_file_locator_test.dart
+++ b/pkgs/coverage/test/config_file_locator_test.dart
@@ -1,3 +1,7 @@
+// Copyright (c) 2025, 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 'dart:io';
import 'package:coverage/src/coverage_options.dart';
import 'package:path/path.dart' as path;
diff --git a/pkgs/coverage/test/function_coverage_test.dart b/pkgs/coverage/test/function_coverage_test.dart
index 965d0d0..d8aaa74 100644
--- a/pkgs/coverage/test/function_coverage_test.dart
+++ b/pkgs/coverage/test/function_coverage_test.dart
@@ -2,6 +2,9 @@
// 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.
+@Tags(['integration'])
+library;
+
import 'dart:async';
import 'dart:convert' show json;
import 'dart:io';
@@ -74,14 +77,9 @@
Future<String> _collectCoverage() async {
expect(FileSystemEntity.isFileSync(_funcCovApp), isTrue);
- final openPort = await getOpenPort();
-
// Run the sample app with the right flags.
- final sampleProcess = await TestProcess.start(Platform.resolvedExecutable, [
- '--enable-vm-service=$openPort',
- '--pause_isolates_on_exit',
- _funcCovApp
- ]);
+ final sampleProcess = await TestProcess.start(Platform.resolvedExecutable,
+ ['--enable-vm-service=0', '--pause_isolates_on_exit', _funcCovApp]);
final serviceUri = await serviceUriFromProcess(sampleProcess.stdoutStream());
diff --git a/pkgs/coverage/test/lcov_test.dart b/pkgs/coverage/test/lcov_test.dart
index ca62117..a03612c 100644
--- a/pkgs/coverage/test/lcov_test.dart
+++ b/pkgs/coverage/test/lcov_test.dart
@@ -2,6 +2,9 @@
// 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.
+@Tags(['integration'])
+library;
+
import 'dart:async';
import 'dart:io';
@@ -337,13 +340,10 @@
Future<Map<String, HitMap>> _getHitMap() async {
expect(FileSystemEntity.isFileSync(_sampleAppPath), isTrue);
- // select service port.
- final port = await getOpenPort();
-
// start sample app.
final sampleAppArgs = [
'--pause-isolates-on-exit',
- '--enable-vm-service=$port',
+ '--enable-vm-service=0',
'--branch-coverage',
_sampleAppPath
];
diff --git a/pkgs/coverage/test/run_and_collect_test.dart b/pkgs/coverage/test/run_and_collect_test.dart
index a538a88..0a45a44 100644
--- a/pkgs/coverage/test/run_and_collect_test.dart
+++ b/pkgs/coverage/test/run_and_collect_test.dart
@@ -2,6 +2,9 @@
// 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.
+@Tags(['integration'])
+library;
+
import 'package:coverage/coverage.dart';
import 'package:path/path.dart' as p;
import 'package:test/test.dart';
diff --git a/pkgs/coverage/test/test_coverage_options/pubspec.yaml b/pkgs/coverage/test/test_coverage_options/pubspec.yaml
new file mode 100644
index 0000000..9d55a4f
--- /dev/null
+++ b/pkgs/coverage/test/test_coverage_options/pubspec.yaml
@@ -0,0 +1 @@
+name: test_coverage_options
diff --git a/pkgs/coverage/test/test_files/pubspec.yaml b/pkgs/coverage/test/test_files/pubspec.yaml
new file mode 100644
index 0000000..ab2a25b
--- /dev/null
+++ b/pkgs/coverage/test/test_files/pubspec.yaml
@@ -0,0 +1,5 @@
+name: coverage_test_files
+
+dev_dependencies:
+ coverage:
+ path: ../../
diff --git a/pkgs/coverage/test/test_util.dart b/pkgs/coverage/test/test_util.dart
index e0a3edb..6fe89d3 100644
--- a/pkgs/coverage/test/test_util.dart
+++ b/pkgs/coverage/test/test_util.dart
@@ -11,12 +11,12 @@
final String testAppPath = p.join('test', 'test_files', 'test_app.dart');
-const Duration timeout = Duration(seconds: 20);
+const Duration timeout = Duration(seconds: 30);
-Future<TestProcess> runTestApp(int openPort) => TestProcess.start(
+Future<TestProcess> runTestApp() => TestProcess.start(
Platform.resolvedExecutable,
[
- '--enable-vm-service=$openPort',
+ '--enable-vm-service=0',
'--pause_isolates_on_exit',
'--branch-coverage',
testAppPath
diff --git a/pkgs/coverage/test/test_with_coverage_test.dart b/pkgs/coverage/test/test_with_coverage_test.dart
index 53e2253..364510b 100644
--- a/pkgs/coverage/test/test_with_coverage_test.dart
+++ b/pkgs/coverage/test/test_with_coverage_test.dart
@@ -2,7 +2,7 @@
// 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.
-@Timeout(Duration(seconds: 60))
+@Tags(['integration'])
library;
import 'dart:convert';
diff --git a/pkgs/coverage/test/util_test.dart b/pkgs/coverage/test/util_test.dart
index 6a4e556..75405ba 100644
--- a/pkgs/coverage/test/util_test.dart
+++ b/pkgs/coverage/test/util_test.dart
@@ -355,4 +355,22 @@
]);
});
});
+
+ test('getAllWorkspaceNames', () {
+ // Uses the workspace_names directory:
+ // workspace_names
+ // └── pkgs
+ // ├── foo
+ // │ └── foo_example // Not part of foo's workspace.
+ // └── bar
+ // └── bar_example // Part of bar's workspace.
+ expect(
+ getAllWorkspaceNames('test/workspace_names'),
+ unorderedEquals([
+ 'workspace_names',
+ 'foo',
+ 'bar',
+ 'bar_example',
+ ]));
+ });
}
diff --git a/pkgs/coverage/test/workspace_names/pkgs/bar/bar_example/pubspec.yaml b/pkgs/coverage/test/workspace_names/pkgs/bar/bar_example/pubspec.yaml
new file mode 100644
index 0000000..e59be7d
--- /dev/null
+++ b/pkgs/coverage/test/workspace_names/pkgs/bar/bar_example/pubspec.yaml
@@ -0,0 +1,2 @@
+name: bar_example
+resolution: workspace
diff --git a/pkgs/coverage/test/workspace_names/pkgs/bar/pubspec.yaml b/pkgs/coverage/test/workspace_names/pkgs/bar/pubspec.yaml
new file mode 100644
index 0000000..a003681
--- /dev/null
+++ b/pkgs/coverage/test/workspace_names/pkgs/bar/pubspec.yaml
@@ -0,0 +1,4 @@
+name: bar
+resolution: workspace
+workspace:
+- bar_example
diff --git a/pkgs/coverage/test/workspace_names/pkgs/foo/foo_example/pubspec.yaml b/pkgs/coverage/test/workspace_names/pkgs/foo/foo_example/pubspec.yaml
new file mode 100644
index 0000000..92033a9
--- /dev/null
+++ b/pkgs/coverage/test/workspace_names/pkgs/foo/foo_example/pubspec.yaml
@@ -0,0 +1 @@
+name: foo_example
diff --git a/pkgs/coverage/test/workspace_names/pkgs/foo/pubspec.yaml b/pkgs/coverage/test/workspace_names/pkgs/foo/pubspec.yaml
new file mode 100644
index 0000000..e6ffc83
--- /dev/null
+++ b/pkgs/coverage/test/workspace_names/pkgs/foo/pubspec.yaml
@@ -0,0 +1,2 @@
+name: foo
+resolution: workspace
diff --git a/pkgs/coverage/test/workspace_names/pubspec.yaml b/pkgs/coverage/test/workspace_names/pubspec.yaml
new file mode 100644
index 0000000..90e1fbc
--- /dev/null
+++ b/pkgs/coverage/test/workspace_names/pubspec.yaml
@@ -0,0 +1,4 @@
+name: workspace_names
+workspace:
+- pkgs/bar
+- pkgs/foo