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

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