Use collection expansion to add frame info (#1441)
Expand a map with the frame info into the full message with `...`. This
keeps the structure more clear and makes it obvious that no other side
effects happen.
Refactor the method finding the frame info. Use `firstWhereOrNull` over
a for loop to find the frame matching the suite path. Separate out two
returns to make it clear that there are always `null` values for some
keys in the map, but not others.
diff --git a/pkgs/test_core/lib/src/runner/reporter/json.dart b/pkgs/test_core/lib/src/runner/reporter/json.dart
index 11710da..f31f185 100644
--- a/pkgs/test_core/lib/src/runner/reporter/json.dart
+++ b/pkgs/test_core/lib/src/runner/reporter/json.dart
@@ -8,24 +8,23 @@
import 'dart:convert';
import 'dart:io' show pid;
+import 'package:collection/collection.dart';
import 'package:path/path.dart' as p;
-
import 'package:stack_trace/stack_trace.dart';
import 'package:test_api/src/backend/group.dart'; // ignore: implementation_imports
-import 'package:test_api/src/backend/group_entry.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/live_test.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/metadata.dart'; // ignore: implementation_imports
+import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/state.dart'; // ignore: implementation_imports
import 'package:test_api/src/backend/suite.dart'; // ignore: implementation_imports
-import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
import 'package:test_api/src/frontend/expect.dart'; // ignore: implementation_imports
-import '../runner_suite.dart';
-import '../suite.dart';
import '../configuration.dart';
import '../engine.dart';
import '../load_suite.dart';
import '../reporter.dart';
+import '../runner_suite.dart';
+import '../suite.dart';
import '../version.dart';
/// A reporter that prints machine-readable JSON-formatted test results.
@@ -134,18 +133,15 @@
var id = _nextID++;
_liveTestIDs[liveTest] = id;
_emit('testStart', {
- 'test': _addFrameInfo(
- suiteConfig,
- {
- 'id': id,
- 'name': liveTest.test.name,
- 'suiteID': suiteID,
- 'groupIDs': groupIDs,
- 'metadata': _serializeMetadata(suiteConfig, liveTest.test.metadata)
- },
- liveTest.test,
- liveTest.suite.platform.runtime,
- liveTest.suite.path)
+ 'test': {
+ 'id': id,
+ 'name': liveTest.test.name,
+ 'suiteID': suiteID,
+ 'groupIDs': groupIDs,
+ 'metadata': _serializeMetadata(suiteConfig, liveTest.test.metadata),
+ ..._frameInfo(suiteConfig, liveTest.test.trace,
+ liveTest.suite.platform.runtime, liveTest.suite.path),
+ }
});
// Convert the future to a stream so that the subscription can be paused or
@@ -222,19 +218,16 @@
var suiteConfig = _configFor(suite);
_emit('group', {
- 'group': _addFrameInfo(
- suiteConfig,
- {
- 'id': id,
- 'suiteID': _idForSuite(suite),
- 'parentID': parentID,
- 'name': group.name,
- 'metadata': _serializeMetadata(suiteConfig, group.metadata),
- 'testCount': group.testCount
- },
- group,
- suite.platform.runtime,
- suite.path)
+ 'group': {
+ 'id': id,
+ 'suiteID': _idForSuite(suite),
+ 'parentID': parentID,
+ 'name': group.name,
+ 'metadata': _serializeMetadata(suiteConfig, group.metadata),
+ 'testCount': group.testCount,
+ ..._frameInfo(
+ suiteConfig, group.trace, suite.platform.runtime, suite.path)
+ }
});
parentID = id;
return id;
@@ -295,39 +288,32 @@
_sink.writeln(jsonEncode(attributes));
}
- /// Modifies [map] to include line, column, and URL information from the first
- /// frame of [entry.trace], as well as the first line in the original file.
+ /// Returns a map with the line, column, and URL information for the first
+ /// frame of [trace], as well as the first line in the original file.
///
- /// Returns [map].
- Map<String, dynamic> _addFrameInfo(
- SuiteConfiguration suiteConfig,
- Map<String, dynamic> map,
- GroupEntry entry,
- Runtime runtime,
- String suitePath) {
- var frame = entry.trace?.frames?.first;
- Frame /*?*/ rootFrame;
- for (var frame in entry.trace?.frames ?? <Frame>[]) {
- if (frame.uri.scheme == 'file' &&
- frame.uri.toFilePath() == p.absolute(suitePath)) {
- rootFrame = frame;
- break;
+ /// If javascript traces are enabled and the test is on a javascript platform,
+ /// or if the [trace] is null or empty, then the line, column, and url will
+ /// all be `null`.
+ Map<String, dynamic> _frameInfo(SuiteConfiguration suiteConfig,
+ Trace /*?*/ trace, Runtime runtime, String suitePath) {
+ var absoluteSuitePath = p.absolute(suitePath);
+ var frame = trace?.frames?.first;
+ if (frame == null || (suiteConfig.jsTrace && runtime.isJS)) {
+ return {'line': null, 'column': null, 'url': null};
+ }
+
+ var rootFrame = trace?.frames?.firstWhereOrNull((frame) =>
+ frame.uri.scheme == 'file' &&
+ frame.uri.toFilePath() == absoluteSuitePath);
+ return {
+ 'line': frame.line,
+ 'column': frame.column,
+ 'url': frame.uri.toString(),
+ if (rootFrame != null && rootFrame != frame) ...{
+ 'root_line': rootFrame.line,
+ 'root_column': rootFrame.column,
+ 'root_url': rootFrame.uri.toString(),
}
- }
-
- if (suiteConfig.jsTrace && runtime.isJS) {
- frame = null;
- rootFrame = null;
- }
-
- map['line'] = frame?.line;
- map['column'] = frame?.column;
- map['url'] = frame?.uri?.toString();
- if (rootFrame != null && rootFrame != frame) {
- map['root_line'] = rootFrame.line;
- map['root_column'] = rootFrame.column;
- map['root_url'] = rootFrame.uri.toString();
- }
- return map;
+ };
}
}