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

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

Issue 1469863005: Add JSON protocol support for groups. (Closed) Base URL: git@github.com:dart-lang/test@master
Patch Set: Code review changes Created 5 years 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/engine.dart ('k') | lib/src/runner/vm/isolate_listener.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 library test.runner.reporter.json; 5 library test.runner.reporter.json;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:convert'; 8 import 'dart:convert';
9 9
10 import '../../backend/group.dart';
10 import '../../backend/live_test.dart'; 11 import '../../backend/live_test.dart';
12 import '../../backend/metadata.dart';
11 import '../../frontend/expect.dart'; 13 import '../../frontend/expect.dart';
12 import '../../utils.dart'; 14 import '../../utils.dart';
13 import '../engine.dart'; 15 import '../engine.dart';
16 import '../load_suite.dart';
14 import '../reporter.dart'; 17 import '../reporter.dart';
15 import '../version.dart'; 18 import '../version.dart';
16 19
17 /// A reporter that prints machine-readable JSON-formatted test results. 20 /// A reporter that prints machine-readable JSON-formatted test results.
18 class JsonReporter implements Reporter { 21 class JsonReporter implements Reporter {
19 /// Whether to use verbose stack traces. 22 /// Whether to use verbose stack traces.
20 final bool _verboseTrace; 23 final bool _verboseTrace;
21 24
22 /// The engine used to run the tests. 25 /// The engine used to run the tests.
23 final Engine _engine; 26 final Engine _engine;
24 27
25 /// A stopwatch that tracks the duration of the full run. 28 /// A stopwatch that tracks the duration of the full run.
26 final _stopwatch = new Stopwatch(); 29 final _stopwatch = new Stopwatch();
27 30
28 /// Whether we've started [_stopwatch]. 31 /// Whether we've started [_stopwatch].
29 /// 32 ///
30 /// We can't just use `_stopwatch.isRunning` because the stopwatch is stopped 33 /// We can't just use `_stopwatch.isRunning` because the stopwatch is stopped
31 /// when the reporter is paused. 34 /// when the reporter is paused.
32 var _stopwatchStarted = false; 35 var _stopwatchStarted = false;
33 36
34 /// Whether the reporter is paused. 37 /// Whether the reporter is paused.
35 var _paused = false; 38 var _paused = false;
36 39
37 /// The set of all subscriptions to various streams. 40 /// The set of all subscriptions to various streams.
38 final _subscriptions = new Set<StreamSubscription>(); 41 final _subscriptions = new Set<StreamSubscription>();
39 42
40 /// An expando that associates unique IDs with [LiveTest]s. 43 /// An expando that associates unique IDs with [LiveTest]s.
41 final _ids = new Map<LiveTest, int>(); 44 final _liveTestIDs = new Map<LiveTest, int>();
45
46 /// An expando that associates unique IDs with [Group]s.
47 final _groupIDs = new Map<Group, int>();
42 48
43 /// The next ID to associate with a [LiveTest]. 49 /// The next ID to associate with a [LiveTest].
44 var _nextID = 0; 50 var _nextID = 0;
45 51
46 /// Watches the tests run by [engine] and prints their results as JSON. 52 /// Watches the tests run by [engine] and prints their results as JSON.
47 /// 53 ///
48 /// If [verboseTrace] is `true`, this will print core library frames. 54 /// If [verboseTrace] is `true`, this will print core library frames.
49 static JsonReporter watch(Engine engine, {bool verboseTrace: false}) { 55 static JsonReporter watch(Engine engine, {bool verboseTrace: false}) {
50 return new JsonReporter._(engine, verboseTrace: verboseTrace); 56 return new JsonReporter._(engine, verboseTrace: verboseTrace);
51 } 57 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 _subscriptions.clear(); 99 _subscriptions.clear();
94 } 100 }
95 101
96 /// A callback called when the engine begins running [liveTest]. 102 /// A callback called when the engine begins running [liveTest].
97 void _onTestStarted(LiveTest liveTest) { 103 void _onTestStarted(LiveTest liveTest) {
98 if (!_stopwatchStarted) { 104 if (!_stopwatchStarted) {
99 _stopwatchStarted = true; 105 _stopwatchStarted = true;
100 _stopwatch.start(); 106 _stopwatch.start();
101 } 107 }
102 108
109 // Don't emit groups for load suites. They're always empty and they provide
110 // unnecessary clutter.
111 var groupIDs = liveTest.suite is LoadSuite
112 ? []
113 : _idsForGroups(liveTest.groups);
114
103 var id = _nextID++; 115 var id = _nextID++;
104 _ids[liveTest] = id; 116 _liveTestIDs[liveTest] = id;
105 _emit("testStart", { 117 _emit("testStart", {
106 "test": { 118 "test": {
107 "id": id, 119 "id": id,
108 "name": liveTest.test.name, 120 "name": liveTest.test.name,
109 "metadata": { 121 "groupIDs": groupIDs,
110 "skip": liveTest.test.metadata.skip, 122 "metadata": _serializeMetadata(liveTest.test.metadata)
111 "skipReason": liveTest.test.metadata.skipReason
112 }
113 } 123 }
114 }); 124 });
115 125
116 /// Convert the future to a stream so that the subscription can be paused or 126 /// Convert the future to a stream so that the subscription can be paused or
117 /// canceled. 127 /// canceled.
118 _subscriptions.add(liveTest.onComplete.asStream().listen((_) => 128 _subscriptions.add(liveTest.onComplete.asStream().listen((_) =>
119 _onComplete(liveTest))); 129 _onComplete(liveTest)));
120 130
121 _subscriptions.add(liveTest.onError.listen((error) => 131 _subscriptions.add(liveTest.onError.listen((error) =>
122 _onError(liveTest, error.error, error.stackTrace))); 132 _onError(liveTest, error.error, error.stackTrace)));
123 133
124 _subscriptions.add(liveTest.onPrint.listen((line) { 134 _subscriptions.add(liveTest.onPrint.listen((line) {
125 _emit("print", { 135 _emit("print", {
126 "testID": id, 136 "testID": id,
127 "message": line 137 "message": line
128 }); 138 });
129 })); 139 }));
130 } 140 }
131 141
142 /// Returns a list of the IDs for all the groups in [groups].
143 ///
144 /// If a group doesn't have an ID yet, this assigns one and emits a new event
145 /// for that group.
146 List<int> _idsForGroups(Iterable<Group> groups) {
147 var parentID;
148 return groups.map((group) {
149 if (_groupIDs.containsKey(group)) {
150 parentID = _groupIDs[group];
151 return parentID;
152 }
153
154 var id = _nextID++;
155 _groupIDs[group] = id;
156
157 _emit("group", {
158 "group": {
159 "id": id,
160 "parentID": parentID,
161 "name": group.name,
162 "metadata": _serializeMetadata(group.metadata)
163 }
164 });
165 parentID = id;
166 return id;
167 }).toList();
168 }
169
170 /// Serializes [metadata] into a JSON-protocol-compatible map.
171 Map _serializeMetadata(Metadata metadata) =>
172 {"skip": metadata.skip, "skipReason": metadata.skipReason};
173
132 /// A callback called when [liveTest] finishes running. 174 /// A callback called when [liveTest] finishes running.
133 void _onComplete(LiveTest liveTest) { 175 void _onComplete(LiveTest liveTest) {
134 _emit("testDone", { 176 _emit("testDone", {
135 "testID": _ids[liveTest], 177 "testID": _liveTestIDs[liveTest],
136 "result": liveTest.state.result.toString(), 178 "result": liveTest.state.result.toString(),
137 "hidden": !_engine.liveTests.contains(liveTest) 179 "hidden": !_engine.liveTests.contains(liveTest)
138 }); 180 });
139 } 181 }
140 182
141 /// A callback called when [liveTest] throws [error]. 183 /// A callback called when [liveTest] throws [error].
142 void _onError(LiveTest liveTest, error, StackTrace stackTrace) { 184 void _onError(LiveTest liveTest, error, StackTrace stackTrace) {
143 _emit("error", { 185 _emit("error", {
144 "testID": _ids[liveTest], 186 "testID": _liveTestIDs[liveTest],
145 "error": error.toString(), 187 "error": error.toString(),
146 "stackTrace": terseChain(stackTrace, verbose: _verboseTrace).toString(), 188 "stackTrace": terseChain(stackTrace, verbose: _verboseTrace).toString(),
147 "isFailure": error is TestFailure 189 "isFailure": error is TestFailure
148 }); 190 });
149 } 191 }
150 192
151 /// A callback called when the engine is finished running tests. 193 /// A callback called when the engine is finished running tests.
152 /// 194 ///
153 /// [success] will be `true` if all tests passed, `false` if some tests 195 /// [success] will be `true` if all tests passed, `false` if some tests
154 /// failed, and `null` if the engine was closed prematurely. 196 /// failed, and `null` if the engine was closed prematurely.
155 void _onDone(bool success) { 197 void _onDone(bool success) {
156 cancel(); 198 cancel();
157 _stopwatch.stop(); 199 _stopwatch.stop();
158 200
159 _emit("done", {"success": success}); 201 _emit("done", {"success": success});
160 } 202 }
161 203
162 /// Emits an event with the given type and attributes. 204 /// Emits an event with the given type and attributes.
163 void _emit(String type, Map attributes) { 205 void _emit(String type, Map attributes) {
164 attributes["type"] = type; 206 attributes["type"] = type;
165 attributes["time"] = _stopwatch.elapsed.inMilliseconds; 207 attributes["time"] = _stopwatch.elapsed.inMilliseconds;
166 print(JSON.encode(attributes)); 208 print(JSON.encode(attributes));
167 } 209 }
168 } 210 }
OLDNEW
« no previous file with comments | « lib/src/runner/engine.dart ('k') | lib/src/runner/vm/isolate_listener.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698