Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.6.0

- Migrated code to null safety (#33)
- Removed discontinued lcov dependency (#38)

## 0.5.0

- Updated dependency on coverage package to ^0.14.1 (#24)
Expand Down
4 changes: 2 additions & 2 deletions bin/test_coverage.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ Future main(List<String> arguments) async {
return;
}

Glob excludeGlob;
Glob? excludeGlob;
if (options['exclude'] is String) {
excludeGlob = Glob(options['exclude']);
}

String port = options['port'];
String? port = options['port'];

final testFiles = findTestFiles(packageRoot, excludeGlob: excludeGlob);
print('Found ${testFiles.length} test files.');
Expand Down
41 changes: 25 additions & 16 deletions lib/src/functions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ import 'dart:io';

import 'package:coverage/coverage.dart' as coverage;
import 'package:glob/glob.dart';
import 'package:lcov/lcov.dart';
import 'package:path/path.dart' as path;

final _sep = path.separator;

List<File> findTestFiles(Directory packageRoot, {Glob excludeGlob}) {
List<File> findTestFiles(Directory packageRoot, {Glob? excludeGlob}) {
final testsPath = path.join(packageRoot.absolute.path, 'test');
final testsRoot = Directory(testsPath);
final contents = testsRoot.listSync(recursive: true);
Expand Down Expand Up @@ -75,7 +74,7 @@ void generateMainScript(Directory packageRoot, List<File> testFiles) {
).writeAsStringSync(buffer.toString());
}

Future<void> runTestsAndCollect(String packageRoot, String port,
Future<void> runTestsAndCollect(String packageRoot, String? port,
{bool printOutput = false}) async {
final script = path.join(packageRoot, 'test', '.test_coverage.dart');
final dartArgs = [
Expand All @@ -86,7 +85,7 @@ Future<void> runTestsAndCollect(String packageRoot, String port,
];
final process =
await Process.start('dart', dartArgs, workingDirectory: packageRoot);
final serviceUriCompleter = Completer<Uri>();
final serviceUriCompleter = Completer<Uri?>();
process.stdout
.transform(utf8.decoder)
.transform(const LineSplitter())
Expand Down Expand Up @@ -115,7 +114,7 @@ Future<void> runTestsAndCollect(String packageRoot, String port,
final data = await coverage.collect(serviceUri, true, true, false, {});
hitmap = await coverage.createHitmap(data['coverage']);
} finally {
await process.stderr.drain<List<int>>();
await process.stderr.drain<List<int>?>();
}
final exitStatus = await process.exitCode;
if (exitStatus != 0) {
Expand All @@ -139,7 +138,7 @@ Future<void> runTestsAndCollect(String packageRoot, String port,
}

// copied from `coverage` package
Uri _extractObservatoryUri(String str) {
Uri? _extractObservatoryUri(String str) {
const kObservatoryListening = 'Observatory listening on ';
final msgPos = str.indexOf(kObservatoryListening);
if (msgPos == -1) return null;
Expand All @@ -153,15 +152,21 @@ Uri _extractObservatoryUri(String str) {
}

double calculateLineCoverage(File lcovReport) {
final report = Report.fromCoverage(lcovReport.readAsStringSync());
final lflhRegex = RegExp(r'^L[FH]:(\d*)$');
final reportFileContent = lcovReport.readAsLinesSync();
reportFileContent.retainWhere((l) => lflhRegex.hasMatch(l));
var totalLines = 0;
var hitLines = 0;
for (final rec in report.records) {
for (final line in rec.lines.data) {
totalLines++;
hitLines += (line.executionCount > 0) ? 1 : 0;
for (final line in reportFileContent) {
var valueString = lflhRegex.matchAsPrefix(line)?.group(1) ?? '0';
var value = int.tryParse(valueString) ?? 0;
if (line.startsWith('LF')) {
totalLines += value;
} else {
hitLines += value;
}
}
if (totalLines == 0) return 1;
return hitLines / totalLines;
}

Expand All @@ -187,7 +192,11 @@ class _BadgeMetrics {
final int rightX;
final int rightLength;

_BadgeMetrics({this.width, this.rightX, this.rightLength});
_BadgeMetrics({
required this.width,
required this.rightX,
required this.rightLength,
});

factory _BadgeMetrics.forPercentage(double value) {
final pct = (value * 100).floor();
Expand Down Expand Up @@ -221,8 +230,8 @@ String _color(double percentage) {
0.9: _Color(0x97, 0xCA, 0x00),
1.0: _Color(0x44, 0xCC, 0x11),
};
double lower;
double upper;
late double lower;
double? upper;
for (final key in map.keys) {
if (percentage < key) {
upper = key;
Expand All @@ -231,8 +240,8 @@ String _color(double percentage) {
if (key < 1.0) lower = key;
}
upper ??= 1.0;
final lowerColor = map[lower];
final upperColor = map[upper];
final lowerColor = map[lower]!;
final upperColor = map[upper]!;
final range = upper - lower;
final rangePct = (percentage - lower) / range;
final pctLower = 1 - rangePct;
Expand Down
17 changes: 8 additions & 9 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
name: test_coverage
description: Command line utility to run tests in Dart VM and collect coverage data.
version: 0.5.0
version: 0.6.0
homepage: https://github.com/pulyaevskiy/test-coverage
author: Anatoly Pulyaevskiy <anatoly.pulyaevskiy@gmail.com>

environment:
sdk: '>=2.3.0 <3.0.0'
sdk: '>=2.12.0 <3.0.0'

executables:
test_coverage:

dependencies:
coverage: ^0.14.1
path: ^1.6.1
lcov: ^5.3.0
glob: ^1.1.7
args: ^1.5.1
coverage: ^1.0.1
path: ^1.8.0
glob: ^2.0.0
args: ^2.0.0

dev_dependencies:
test: ^1.0.0
pedantic: ^1.7.0
test: ^1.16.7
pedantic: ^1.11.0