From 7fc79c30ee351ff46642cc2595fffbaa68b24209 Mon Sep 17 00:00:00 2001 From: Abdullah <89297042+AzazelSensei@users.noreply.github.com> Date: Thu, 13 Aug 2026 12:24:30 +0300 Subject: [PATCH] fix: resolve dart coverage package_config in pub workspaces Pub workspaces only write .dart_tool/package_config.json at the workspace root. Pass the package directory as packagePath so the coverage resolver walks up the same way dart does. --- lib/src/cli/test_cli_runner.dart | 12 +++--- test/src/cli/test_cli_runner_test.dart | 53 ++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/lib/src/cli/test_cli_runner.dart b/lib/src/cli/test_cli_runner.dart index e3a748319..d6453a240 100644 --- a/lib/src/cli/test_cli_runner.dart +++ b/lib/src/cli/test_cli_runner.dart @@ -199,19 +199,17 @@ class TestCLIRunner { p.join(cwd, 'coverage'), ); - final packagesPath = p.join( - '.dart_tool', - 'package_config.json', - ); + // Resolve package_config.json the way dart does: start at + // the package cwd and walk up. In a pub workspace the file + // lives at the workspace root, not in the member package. final hitmap = await coverage.HitMap.parseFiles( files, - packagePath: packagesPath, + packagePath: cwd, checkIgnoredLines: checkIgnore, ); final resolver = await coverage.Resolver.create( - packagesPath: packagesPath, - packagePath: packagesPath, + packagePath: cwd, ); final output = hitmap.formatLcov( diff --git a/test/src/cli/test_cli_runner_test.dart b/test/src/cli/test_cli_runner_test.dart index 0b92b446a..2dcdbcc6f 100644 --- a/test/src/cli/test_cli_runner_test.dart +++ b/test/src/cli/test_cli_runner_test.dart @@ -778,6 +778,59 @@ void main() { expect(testRunnerArgs, equals(['--coverage=coverage'])); }); + test( + 'resolves dart coverage package_config from the pub workspace root', + () async { + final workspaceRoot = Directory.systemTemp.createTempSync(); + addTearDown(() => workspaceRoot.deleteSync(recursive: true)); + + final member = Directory( + p.join(workspaceRoot.path, 'packages', 'foo'), + )..createSync(recursive: true); + File(p.join(member.path, 'pubspec.yaml')).createSync(); + Directory(p.join(member.path, 'test')).createSync(); + + // Pub workspaces only write package_config.json at the root. + File(p.join(workspaceRoot.path, '.dart_tool', 'package_config.json')) + ..createSync(recursive: true) + ..writeAsStringSync('{"configVersion":2,"packages":[]}'); + + final lcovFile = File(p.join(member.path, 'coverage', 'lcov.info')); + + final originalCwd = Directory.current; + addTearDown(() => Directory.current = originalCwd); + Directory.current = member; + + await expectLater( + TestCLIRunner.test( + testType: TestRunType.dart, + cwd: member.path, + collectCoverage: true, + stdout: stdoutLogs.add, + stderr: stderrLogs.add, + overrideTestRunner: testRunner( + Stream.fromIterable([ + const DoneTestEvent(success: true, time: 0), + const ExitTestEvent(exitCode: 0, time: 0), + ]), + onStart: () { + expect(lcovFile.existsSync(), isFalse); + lcovFile.createSync(recursive: true); + }, + ), + logger: logger, + ), + completion(equals([ExitCode.success.code])), + ); + expect( + File( + p.join(member.path, '.dart_tool', 'package_config.json'), + ).existsSync(), + isFalse, + ); + }, + ); + test('runs dart tests w/coverage and checkIgnore', () async { final tempDirectory = Directory.systemTemp.createTempSync(); addTearDown(() => tempDirectory.deleteSync(recursive: true));