Skip to content

Commit 2680b74

Browse files
committed
feat: add --collect-coverage-from option to include untested files in coverage
Closes #418 Adds a new --collect-coverage-from option to the very_good test command that allows users to choose between: - imports (default): collect coverage from imported files only (current behavior) - all: collect coverage from all Dart files in the project, showing 0% for untested files This enables stricter coverage requirements that account for all project files, not just those exercised by tests. Works with both Flutter and Dart projects. Implementation details: - Added CoverageCollectionMode enum with imports/all modes - Implemented _discoverDartFilesForCoverage() to find all .dart files - Implemented _enhanceLcovWithUntestedFiles() to add untested files to LCOV - Updated command-line parsing in test.dart and dart_test_command.dart - Threaded the option through the entire call chain - Respects existing --exclude-coverage and --report-on options Usage examples: very_good test --coverage very_good test --coverage --collect-coverage-from all very_good test --min-coverage 100 --collect-coverage-from all very_good test --coverage --collect-coverage-from all --exclude-coverage '**/*.g.dart' Files modified: - lib/src/cli/test_cli_runner.dart: Core implementation with enum, helpers, and logic - lib/src/commands/test/test.dart: Added option to Flutter test command - lib/src/commands/dart/commands/dart_test_command.dart: Added option to Dart test command - lib/src/cli/flutter_cli.dart: Thread parameter through Flutter CLI - lib/src/cli/dart_cli.dart: Thread parameter through Dart CLI - test/src/commands/test/test_test.dart: Updated Flutter test command tests - test/src/commands/dart/commands/dart_test_test.dart: Updated Dart test command tests with correct help text alignment
1 parent 8665469 commit 2680b74

File tree

5 files changed

+35
-28
lines changed

5 files changed

+35
-28
lines changed

lib/src/cli/test_cli_runner.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ enum CoverageCollectionMode {
2525
imports,
2626

2727
/// Collect coverage from all files in the project.
28-
all;
28+
all
29+
;
2930

3031
/// Parses a string value into a [CoverageCollectionMode].
3132
static CoverageCollectionMode fromString(String value) {

lib/src/commands/dart/commands/dart_test_command.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ class DartTestOptions {
3939
final excludeFromCoverage = argResults['exclude-coverage'] as String?;
4040
final collectCoverageFromString =
4141
argResults['collect-coverage-from'] as String? ?? 'imports';
42-
final collectCoverageFrom =
43-
CoverageCollectionMode.fromString(collectCoverageFromString);
42+
final collectCoverageFrom = CoverageCollectionMode.fromString(
43+
collectCoverageFromString,
44+
);
4445
final randomOrderingSeed =
4546
argResults['test-randomize-ordering-seed'] as String?;
4647
final randomSeed = randomOrderingSeed == 'random'
@@ -200,7 +201,8 @@ class DartTestCommand extends Command<int> {
200201
)
201202
..addOption(
202203
'collect-coverage-from',
203-
help: 'Whether to collect coverage from imported files only or all '
204+
help:
205+
'Whether to collect coverage from imported files only or all '
204206
'files.',
205207
allowed: ['imports', 'all'],
206208
defaultsTo: 'imports',

lib/src/commands/test/test.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ class FlutterTestOptions {
4141
final excludeFromCoverage = argResults['exclude-coverage'] as String?;
4242
final collectCoverageFromString =
4343
argResults['collect-coverage-from'] as String? ?? 'imports';
44-
final collectCoverageFrom =
45-
CoverageCollectionMode.fromString(collectCoverageFromString);
44+
final collectCoverageFrom = CoverageCollectionMode.fromString(
45+
collectCoverageFromString,
46+
);
4647
final randomOrderingSeed =
4748
argResults['test-randomize-ordering-seed'] as String?;
4849
final randomSeed = randomOrderingSeed == 'random'
@@ -214,7 +215,8 @@ class TestCommand extends Command<int> {
214215
)
215216
..addOption(
216217
'collect-coverage-from',
217-
help: 'Whether to collect coverage from imported files only or all '
218+
help:
219+
'Whether to collect coverage from imported files only or all '
218220
'files.',
219221
allowed: ['imports', 'all'],
220222
defaultsTo: 'imports',

test/src/commands/dart/commands/dart_test_test.dart

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,26 +24,26 @@ const expectedTestUsage = [
2424
'Run tests in a Dart project.\n'
2525
'\n'
2626
'Usage: very_good dart test [arguments]\n'
27-
'-h, --help Print this usage information.\n'
28-
' --coverage Whether to collect coverage information.\n'
29-
'-r, --recursive Run tests recursively for all nested packages.\n'
30-
' --[no-]optimization Whether to apply optimizations for test performance.\n'
31-
' Automatically disabled when --platform is specified.\n'
32-
' Add the `skip_very_good_optimization` tag to specific test files to disable them individually.\n'
33-
' (defaults to on)\n'
34-
'-j, --concurrency The number of concurrent test suites run. Automatically set to 1 when --platform is specified.\n'
35-
' (defaults to "4")\n'
36-
'-t, --tags Run only tests associated with the specified tags.\n'
37-
" --exclude-coverage A glob which will be used to exclude files that match from the coverage (e.g. '**/*.g.dart').\n"
38-
'-x, --exclude-tags Run only tests that do not have the specified tags.\n'
27+
'-h, --help Print this usage information.\n'
28+
' --coverage Whether to collect coverage information.\n'
29+
'-r, --recursive Run tests recursively for all nested packages.\n'
30+
' --[no-]optimization Whether to apply optimizations for test performance.\n'
31+
' Automatically disabled when --platform is specified.\n'
32+
' Add the `skip_very_good_optimization` tag to specific test files to disable them individually.\n'
33+
' (defaults to on)\n'
34+
'-j, --concurrency The number of concurrent test suites run. Automatically set to 1 when --platform is specified.\n'
35+
' (defaults to "4")\n'
36+
'-t, --tags Run only tests associated with the specified tags.\n'
37+
" --exclude-coverage A glob which will be used to exclude files that match from the coverage (e.g. '**/*.g.dart').\n"
38+
'-x, --exclude-tags Run only tests that do not have the specified tags.\n'
3939
' --min-coverage Whether to enforce a minimum coverage percentage.\n'
4040
' --collect-coverage-from=<imports|all> Whether to collect coverage from imported files only or all files.\n'
4141
' [imports (default), all]\n'
42-
' --test-randomize-ordering-seed The seed to randomize the execution order of test cases within test files.\n'
43-
' --fail-fast Stop running tests after the first failure.\n'
44-
' --force-ansi Whether to force ansi output. If not specified, it will maintain the default behavior based on stdout and stderr.\n'
45-
' --report-on=<lib/> An optional file path to report coverage information to. This should be a path relative to the current working directory.\n'
46-
' --platform=<chrome|vm> The platform to run tests on. \n'
42+
' --test-randomize-ordering-seed The seed to randomize the execution order of test cases within test files.\n'
43+
' --fail-fast Stop running tests after the first failure.\n'
44+
' --force-ansi Whether to force ansi output. If not specified, it will maintain the default behavior based on stdout and stderr.\n'
45+
' --report-on=<lib/> An optional file path to report coverage information to. This should be a path relative to the current working directory.\n'
46+
' --platform=<chrome|vm> The platform to run tests on. \n'
4747
'\n'
4848
'Run "very_good help" to see global options.',
4949
];
@@ -120,8 +120,9 @@ void main() {
120120
when<dynamic>(() => argResults['fail-fast']).thenReturn(false);
121121
when<dynamic>(() => argResults['optimization']).thenReturn(true);
122122
when<dynamic>(() => argResults['platform']).thenReturn(null);
123-
when<dynamic>(() => argResults['collect-coverage-from'])
124-
.thenReturn('imports');
123+
when<dynamic>(
124+
() => argResults['collect-coverage-from'],
125+
).thenReturn('imports');
125126
when<dynamic>(() => argResults['report-on']).thenReturn(null);
126127
when(() => argResults.rest).thenReturn([]);
127128
});

test/src/commands/test/test_test.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,9 @@ void main() {
122122
when<dynamic>(() => argResults['fail-fast']).thenReturn(false);
123123
when<dynamic>(() => argResults['optimization']).thenReturn(true);
124124
when<dynamic>(() => argResults['platform']).thenReturn(null);
125-
when<dynamic>(() => argResults['collect-coverage-from'])
126-
.thenReturn('imports');
125+
when<dynamic>(
126+
() => argResults['collect-coverage-from'],
127+
).thenReturn('imports');
127128
when(() => argResults.rest).thenReturn([]);
128129
});
129130

0 commit comments

Comments
 (0)