Skip to content

Commit 462b474

Browse files
authored
[coverage] Support workspaces in coverage filters (#2574)
1 parent 30aa541 commit 462b474

File tree

5 files changed

+96
-2
lines changed

5 files changed

+96
-2
lines changed

pkgs/test/test/runner/coverage_test.dart

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ end_of_record
179179
''');
180180
});
181181

182-
test('gathers coverage for tests in multiple pacakges', () async {
182+
test('gathers coverage for tests in multiple packages', () async {
183183
final clientPkgDir = p.join(d.sandbox, 'fake_client');
184184
await (await runPub([
185185
'get',
@@ -214,6 +214,75 @@ end_of_record
214214
''');
215215
});
216216

217+
test('gathers coverage for package in a workspace', () async {
218+
await d.dir(d.sandbox, [
219+
d.dir('fake_workspace', [
220+
d.file('pubspec.yaml', '''
221+
name: fake_workspace
222+
version: 1.0.0
223+
environment:
224+
sdk: ^3.5.0
225+
workspace:
226+
- workspace_package
227+
'''),
228+
d.dir('workspace_package', [
229+
d.file('pubspec.yaml', '''
230+
name: workspace_package
231+
version: 1.0.0
232+
environment:
233+
sdk: ^3.5.0
234+
resolution: workspace
235+
dev_dependencies:
236+
test: ^1.26.2
237+
'''),
238+
d.dir('lib', [
239+
d.file('calculate.dart', '''
240+
int calculate(int x) {
241+
if (x % 2 == 0) {
242+
return x * 2;
243+
} else {
244+
return x * 3;
245+
}
246+
}
247+
'''),
248+
]),
249+
d.dir('test', [
250+
d.file('test.dart', '''
251+
import 'package:workspace_package/calculate.dart';
252+
import 'package:test/test.dart';
253+
254+
void main() {
255+
test('test 1', () {
256+
expect(calculate(6), 12);
257+
});
258+
}
259+
'''),
260+
]),
261+
]),
262+
]),
263+
]).create();
264+
265+
final pkgDir = p.join(d.sandbox, 'fake_workspace', 'workspace_package');
266+
await (await runPub(['get'], workingDirectory: pkgDir)).shouldExit(0);
267+
final lcovFile = p.join(coverageDirectory.path, 'lcov.info');
268+
var test = await runTest(
269+
['--coverage-path', lcovFile, 'test/test.dart'],
270+
packageConfig: p.join(pkgDir, '../.dart_tool/package_config.json'),
271+
workingDirectory: pkgDir,
272+
);
273+
await validateTest(test);
274+
expect(File(lcovFile).readAsStringSync(), '''
275+
SF:${p.join(pkgDir, 'lib', 'calculate.dart')}
276+
DA:1,1
277+
DA:2,2
278+
DA:3,1
279+
DA:5,0
280+
LF:4
281+
LH:3
282+
end_of_record
283+
''');
284+
});
285+
217286
test('gathers coverage for Chrome tests', () async {
218287
await (await runPub(['get'], workingDirectory: pkgDir)).shouldExit(0);
219288
var test = await runTest(

pkgs/test_core/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
packages using RegExps.
55
* Require a function definition named `main` directly in a test suite and
66
provide a more direct error message than a failing compiler output.
7+
* Fix default coverage filter when running in a workspace package. Default
8+
filter now includes all the workspace's package.
79

810
## 0.6.14
911

pkgs/test_core/lib/src/runner/vm/platform.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ Future<Set<String>> _filterCoveragePackages(
458458
List<RegExp>? coveragePackages,
459459
) async {
460460
if (coveragePackages == null || coveragePackages.isEmpty) {
461-
return {(await currentPackage).name};
461+
return workspacePackageNames(await currentPackage);
462462
} else {
463463
return (await currentPackageConfig).packages
464464
.map((package) => package.name)

pkgs/test_core/lib/src/util/package_config.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'dart:isolate';
77

88
import 'package:package_config/package_config.dart';
99
import 'package:path/path.dart' as p;
10+
import 'package:pubspec_parse/pubspec_parse.dart';
1011

1112
/// The [PackageConfig] parsed from the current isolates package config file.
1213
final Future<PackageConfig> currentPackageConfig = () async {
@@ -42,3 +43,24 @@ Future<Uri> absoluteUri(String path) async {
4243
final Future<Package> currentPackage = () async {
4344
return (await currentPackageConfig).packageOf(await packageConfigUri)!;
4445
}();
46+
47+
/// Returns the names of all the packages in the workspace.
48+
///
49+
/// The returned set includes the package's own name (if the package is not a
50+
/// workspace, that will be the only name in the set).
51+
Set<String> workspacePackageNames(Package package) =>
52+
_allWorkspaceNames(package.root, <String>{});
53+
54+
Set<String> _allWorkspaceNames(Uri packageRoot, Set<String> results) {
55+
final pubspecUri = packageRoot.resolve('pubspec.yaml');
56+
final pubspecFile = File(pubspecUri.toFilePath());
57+
if (pubspecFile.existsSync()) {
58+
final yaml = pubspecFile.readAsStringSync();
59+
final pubspec = Pubspec.parse(yaml, sourceUrl: pubspecUri);
60+
results.add(pubspec.name);
61+
for (final package in pubspec.workspace ?? const <String>[]) {
62+
_allWorkspaceNames(packageRoot.resolve('$package/'), results);
63+
}
64+
}
65+
return results;
66+
}

pkgs/test_core/pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ dependencies:
2222
package_config: ^2.0.0
2323
path: ^1.8.0
2424
pool: ^1.5.0
25+
pubspec_parse: ^1.5.0
2526
source_map_stack_trace: ^2.1.0
2627
source_maps: ^0.10.10
2728
source_span: ^1.8.0

0 commit comments

Comments
 (0)