mirror of
https://github.com/flutter/flutter
synced 2024-10-06 00:09:53 +00:00
716f82763a
When print is used inside tests its content is added to the test report as a string of unicode \u0000 making the test reporting parser fail. This PR cleans removes non json content every line of the report. Bug: https://github.com/flutter/flutter/issues/145553
103 lines
3.5 KiB
Dart
103 lines
3.5 KiB
Dart
// Copyright 2014 The Flutter Authors. 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:convert';
|
|
import 'dart:io';
|
|
|
|
class TestSpecs {
|
|
|
|
TestSpecs({
|
|
required this.path,
|
|
required this.startTime,
|
|
});
|
|
|
|
final String path;
|
|
int startTime;
|
|
int? _endTime;
|
|
|
|
int get milliseconds => endTime - startTime;
|
|
|
|
set endTime(int value) {
|
|
_endTime = value;
|
|
}
|
|
|
|
int get endTime => _endTime ?? 0;
|
|
|
|
String toJson() {
|
|
return json.encode(
|
|
<String, String>{'path': path, 'runtime': milliseconds.toString()}
|
|
);
|
|
}
|
|
}
|
|
|
|
class TestFileReporterResults {
|
|
TestFileReporterResults._({
|
|
required this.allTestSpecs,
|
|
required this.hasFailedTests,
|
|
required this.errors,
|
|
});
|
|
|
|
/// Intended to parse the output file of `dart test --file-reporter json:file_name
|
|
factory TestFileReporterResults.fromFile(File metrics) {
|
|
if (!metrics.existsSync()) {
|
|
throw Exception('${metrics.path} does not exist');
|
|
}
|
|
|
|
final Map<int, TestSpecs> testSpecs = <int, TestSpecs>{};
|
|
bool hasFailedTests = true;
|
|
final List<String> errors = <String>[];
|
|
|
|
for (final String metric in metrics.readAsLinesSync()) {
|
|
/// Using print within a test adds the printed content to the json file report
|
|
/// as \u0000 making the file parsing step fail. The content of the json file
|
|
/// is expected to be a json dictionary per line and the following line removes
|
|
/// all the additional content at the beginning of the line until it finds the
|
|
/// first opening curly bracket.
|
|
// TODO(godofredoc): remove when https://github.com/flutter/flutter/issues/145553 is fixed.
|
|
final String sanitizedMetric = metric.replaceAll(RegExp(r'$.*{'), '{');
|
|
final Map<String, Object?> entry = json.decode(sanitizedMetric) as Map<String, Object?>;
|
|
if (entry.containsKey('suite')) {
|
|
final Map<String, Object?> suite = entry['suite']! as Map<String, Object?>;
|
|
addTestSpec(suite, entry['time']! as int, testSpecs);
|
|
} else if (isMetricDone(entry, testSpecs)) {
|
|
final Map<String, Object?> group = entry['group']! as Map<String, Object?>;
|
|
final int suiteID = group['suiteID']! as int;
|
|
addMetricDone(suiteID, entry['time']! as int, testSpecs);
|
|
} else if (entry.containsKey('error')) {
|
|
final String stackTrace = entry.containsKey('stackTrace') ? entry['stackTrace']! as String : '';
|
|
errors.add('${entry['error']}\n $stackTrace');
|
|
} else if (entry.containsKey('success') && entry['success'] == true) {
|
|
hasFailedTests = false;
|
|
}
|
|
}
|
|
|
|
return TestFileReporterResults._(allTestSpecs: testSpecs, hasFailedTests: hasFailedTests, errors: errors);
|
|
}
|
|
|
|
final Map<int, TestSpecs> allTestSpecs;
|
|
final bool hasFailedTests;
|
|
final List<String> errors;
|
|
|
|
|
|
static void addTestSpec(Map<String, Object?> suite, int time, Map<int, TestSpecs> allTestSpecs) {
|
|
allTestSpecs[suite['id']! as int] = TestSpecs(
|
|
path: suite['path']! as String,
|
|
startTime: time,
|
|
);
|
|
}
|
|
|
|
static void addMetricDone(int suiteID, int time, Map<int, TestSpecs> allTestSpecs) {
|
|
final TestSpecs testSpec = allTestSpecs[suiteID]!;
|
|
testSpec.endTime = time;
|
|
}
|
|
|
|
static bool isMetricDone(Map<String, Object?> entry, Map<int, TestSpecs> allTestSpecs) {
|
|
if (entry.containsKey('group') && entry['type']! as String == 'group') {
|
|
final Map<String, Object?> group = entry['group']! as Map<String, Object?>;
|
|
return allTestSpecs.containsKey(group['suiteID']! as int);
|
|
}
|
|
return false;
|
|
}
|
|
}
|