Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Side by Side Diff: lib/src/runner/reporter/json.dart

Issue 2066113002: Add location information to the JSON reporter. (Closed) Base URL: git@github.com:dart-lang/test@master
Patch Set: cr Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/src/runner/remote_listener.dart ('k') | lib/src/runner/runner_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import 'dart:async'; 5 import 'dart:async';
6 import 'dart:convert'; 6 import 'dart:convert';
7 7
8 import '../../backend/group.dart'; 8 import '../../backend/group.dart';
9 import '../../backend/group_entry.dart';
9 import '../../backend/live_test.dart'; 10 import '../../backend/live_test.dart';
10 import '../../backend/metadata.dart'; 11 import '../../backend/metadata.dart';
11 import '../../backend/suite.dart'; 12 import '../../backend/suite.dart';
13 import '../../backend/test_platform.dart';
12 import '../../frontend/expect.dart'; 14 import '../../frontend/expect.dart';
13 import '../../utils.dart'; 15 import '../../utils.dart';
14 import '../engine.dart'; 16 import '../engine.dart';
15 import '../load_suite.dart'; 17 import '../load_suite.dart';
16 import '../reporter.dart'; 18 import '../reporter.dart';
17 import '../version.dart'; 19 import '../version.dart';
18 20
19 /// A reporter that prints machine-readable JSON-formatted test results. 21 /// A reporter that prints machine-readable JSON-formatted test results.
20 class JsonReporter implements Reporter { 22 class JsonReporter implements Reporter {
21 /// Whether to use verbose stack traces. 23 /// Whether to use verbose stack traces.
22 final bool _verboseTrace; 24 final bool _verboseTrace;
23 25
26 /// Whether to emit location information for JS tests.
27 final bool _jsLocations;
28
24 /// The engine used to run the tests. 29 /// The engine used to run the tests.
25 final Engine _engine; 30 final Engine _engine;
26 31
27 /// A stopwatch that tracks the duration of the full run. 32 /// A stopwatch that tracks the duration of the full run.
28 final _stopwatch = new Stopwatch(); 33 final _stopwatch = new Stopwatch();
29 34
30 /// Whether we've started [_stopwatch]. 35 /// Whether we've started [_stopwatch].
31 /// 36 ///
32 /// We can't just use `_stopwatch.isRunning` because the stopwatch is stopped 37 /// We can't just use `_stopwatch.isRunning` because the stopwatch is stopped
33 /// when the reporter is paused. 38 /// when the reporter is paused.
(...skipping 12 matching lines...) Expand all
46 final _suiteIDs = new Map<Suite, int>(); 51 final _suiteIDs = new Map<Suite, int>();
47 52
48 /// An expando that associates unique IDs with [Group]s. 53 /// An expando that associates unique IDs with [Group]s.
49 final _groupIDs = new Map<Group, int>(); 54 final _groupIDs = new Map<Group, int>();
50 55
51 /// The next ID to associate with a [LiveTest]. 56 /// The next ID to associate with a [LiveTest].
52 var _nextID = 0; 57 var _nextID = 0;
53 58
54 /// Watches the tests run by [engine] and prints their results as JSON. 59 /// Watches the tests run by [engine] and prints their results as JSON.
55 /// 60 ///
56 /// If [verboseTrace] is `true`, this will print core library frames. 61 /// If [verboseTrace] is `true`, this will print core library frames. If
57 static JsonReporter watch(Engine engine, {bool verboseTrace: false}) { 62 /// [jsLocations] is `false`, this will not emit location information for JS
58 return new JsonReporter._(engine, verboseTrace: verboseTrace); 63 /// tests.
64 static JsonReporter watch(Engine engine, {bool verboseTrace: false,
65 bool jsLocations: true}) {
66 return new JsonReporter._(engine,
67 verboseTrace: verboseTrace, jsLocations: jsLocations);
59 } 68 }
60 69
61 JsonReporter._(this._engine, {bool verboseTrace: false}) 70 JsonReporter._(this._engine, {bool verboseTrace: false,
62 : _verboseTrace = verboseTrace { 71 bool jsLocations: true})
72 : _verboseTrace = verboseTrace,
73 _jsLocations = jsLocations {
63 _subscriptions.add(_engine.onTestStarted.listen(_onTestStarted)); 74 _subscriptions.add(_engine.onTestStarted.listen(_onTestStarted));
64 75
65 /// Convert the future to a stream so that the subscription can be paused or 76 /// Convert the future to a stream so that the subscription can be paused or
66 /// canceled. 77 /// canceled.
67 _subscriptions.add(_engine.success.asStream().listen(_onDone)); 78 _subscriptions.add(_engine.success.asStream().listen(_onDone));
68 79
69 _subscriptions.add(_engine.onSuiteAdded.listen(null, onDone: () { 80 _subscriptions.add(_engine.onSuiteAdded.listen(null, onDone: () {
70 _emit("allSuites", { 81 _emit("allSuites", {
71 "count": _engine.addedSuites.length 82 "count": _engine.addedSuites.length
72 }); 83 });
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 _stopwatchStarted = true; 124 _stopwatchStarted = true;
114 _stopwatch.start(); 125 _stopwatch.start();
115 } 126 }
116 127
117 var suiteID = _idForSuite(liveTest.suite); 128 var suiteID = _idForSuite(liveTest.suite);
118 129
119 // Don't emit groups for load suites. They're always empty and they provide 130 // Don't emit groups for load suites. They're always empty and they provide
120 // unnecessary clutter. 131 // unnecessary clutter.
121 var groupIDs = liveTest.suite is LoadSuite 132 var groupIDs = liveTest.suite is LoadSuite
122 ? [] 133 ? []
123 : _idsForGroups(liveTest.groups, suiteID); 134 : _idsForGroups(liveTest.groups, liveTest.suite);
124 135
125 var id = _nextID++; 136 var id = _nextID++;
126 _liveTestIDs[liveTest] = id; 137 _liveTestIDs[liveTest] = id;
127 _emit("testStart", { 138 _emit("testStart", {
128 "test": { 139 "test": _addFrameInfo({
129 "id": id, 140 "id": id,
130 "name": liveTest.test.name, 141 "name": liveTest.test.name,
131 "suiteID": suiteID, 142 "suiteID": suiteID,
132 "groupIDs": groupIDs, 143 "groupIDs": groupIDs,
133 "metadata": _serializeMetadata(liveTest.test.metadata) 144 "metadata": _serializeMetadata(liveTest.test.metadata)
134 } 145 }, liveTest.test, liveTest.suite.platform)
135 }); 146 });
136 147
137 /// Convert the future to a stream so that the subscription can be paused or 148 /// Convert the future to a stream so that the subscription can be paused or
138 /// canceled. 149 /// canceled.
139 _subscriptions.add(liveTest.onComplete.asStream().listen((_) => 150 _subscriptions.add(liveTest.onComplete.asStream().listen((_) =>
140 _onComplete(liveTest))); 151 _onComplete(liveTest)));
141 152
142 _subscriptions.add(liveTest.onError.listen((error) => 153 _subscriptions.add(liveTest.onError.listen((error) =>
143 _onError(liveTest, error.error, error.stackTrace))); 154 _onError(liveTest, error.error, error.stackTrace)));
144 155
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 } 187 }
177 }); 188 });
178 return id; 189 return id;
179 } 190 }
180 191
181 /// Returns a list of the IDs for all the groups in [groups], which are 192 /// Returns a list of the IDs for all the groups in [groups], which are
182 /// contained in the suite identified by [suiteID]. 193 /// contained in the suite identified by [suiteID].
183 /// 194 ///
184 /// If a group doesn't have an ID yet, this assigns one and emits a new event 195 /// If a group doesn't have an ID yet, this assigns one and emits a new event
185 /// for that group. 196 /// for that group.
186 List<int> _idsForGroups(Iterable<Group> groups, int suiteID) { 197 List<int> _idsForGroups(Iterable<Group> groups, Suite suite) {
187 int parentID; 198 int parentID;
188 return groups.map((group) { 199 return groups.map((group) {
189 if (_groupIDs.containsKey(group)) { 200 if (_groupIDs.containsKey(group)) {
190 parentID = _groupIDs[group]; 201 parentID = _groupIDs[group];
191 return parentID; 202 return parentID;
192 } 203 }
193 204
194 var id = _nextID++; 205 var id = _nextID++;
195 _groupIDs[group] = id; 206 _groupIDs[group] = id;
196 207
197 _emit("group", { 208 _emit("group", {
198 "group": { 209 "group": _addFrameInfo({
199 "id": id, 210 "id": id,
200 "suiteID": suiteID, 211 "suiteID": _idForSuite(suite),
201 "parentID": parentID, 212 "parentID": parentID,
202 "name": group.name, 213 "name": group.name,
203 "metadata": _serializeMetadata(group.metadata), 214 "metadata": _serializeMetadata(group.metadata),
204 "testCount": group.testCount 215 "testCount": group.testCount
205 } 216 }, group, suite.platform)
206 }); 217 });
207 parentID = id; 218 parentID = id;
208 return id; 219 return id;
209 }).toList(); 220 }).toList();
210 } 221 }
211 222
212 /// Serializes [metadata] into a JSON-protocol-compatible map. 223 /// Serializes [metadata] into a JSON-protocol-compatible map.
213 Map _serializeMetadata(Metadata metadata) => 224 Map _serializeMetadata(Metadata metadata) =>
214 {"skip": metadata.skip, "skipReason": metadata.skipReason}; 225 {"skip": metadata.skip, "skipReason": metadata.skipReason};
215 226
(...skipping 26 matching lines...) Expand all
242 253
243 _emit("done", {"success": success}); 254 _emit("done", {"success": success});
244 } 255 }
245 256
246 /// Emits an event with the given type and attributes. 257 /// Emits an event with the given type and attributes.
247 void _emit(String type, Map attributes) { 258 void _emit(String type, Map attributes) {
248 attributes["type"] = type; 259 attributes["type"] = type;
249 attributes["time"] = _stopwatch.elapsed.inMilliseconds; 260 attributes["time"] = _stopwatch.elapsed.inMilliseconds;
250 print(JSON.encode(attributes)); 261 print(JSON.encode(attributes));
251 } 262 }
263
264 /// Modifies [map] to include line, column, and URL information from the first
265 /// frame of [entry.trace].
266 ///
267 /// Returns [map].
268 Map<String, dynamic> _addFrameInfo(Map<String, dynamic> map,
269 GroupEntry entry, TestPlatform platform) {
270 var frame = entry.trace?.frames?.first;
271 if (!_jsLocations && platform.isJS) frame = null;
272
273 map["line"] = frame?.line;
274 map["column"] = frame?.column;
275 map["url"] = frame?.uri?.toString();
276 return map;
277 }
252 } 278 }
OLDNEW
« no previous file with comments | « lib/src/runner/remote_listener.dart ('k') | lib/src/runner/runner_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698