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

Side by Side Diff: lib/src/backend/declarer.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 | « json_reporter.schema.json ('k') | lib/src/backend/group.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 6
7 import 'package:stack_trace/stack_trace.dart';
8
7 import '../frontend/timeout.dart'; 9 import '../frontend/timeout.dart';
8 import '../utils.dart'; 10 import '../utils.dart';
9 import 'group.dart'; 11 import 'group.dart';
10 import 'group_entry.dart'; 12 import 'group_entry.dart';
11 import 'invoker.dart'; 13 import 'invoker.dart';
12 import 'metadata.dart'; 14 import 'metadata.dart';
13 import 'test.dart'; 15 import 'test.dart';
14 16
15 /// A class that manages the state of tests as they're declared. 17 /// A class that manages the state of tests as they're declared.
16 /// 18 ///
17 /// A nested tree of Declarers tracks the current group, set-up, and tear-down 19 /// A nested tree of Declarers tracks the current group, set-up, and tear-down
18 /// functions. Each Declarer in the tree corresponds to a group. This tree is 20 /// functions. Each Declarer in the tree corresponds to a group. This tree is
19 /// tracked by a zone-scoped "current" Declarer; the current declarer can be set 21 /// tracked by a zone-scoped "current" Declarer; the current declarer can be set
20 /// for a block using [Declarer.declare], and it can be accessed using 22 /// for a block using [Declarer.declare], and it can be accessed using
21 /// [Declarer.current]. 23 /// [Declarer.current].
22 class Declarer { 24 class Declarer {
23 /// The parent declarer, or `null` if this corresponds to the root group. 25 /// The parent declarer, or `null` if this corresponds to the root group.
24 final Declarer _parent; 26 final Declarer _parent;
25 27
26 /// The name of the current test group, including the name of any parent 28 /// The name of the current test group, including the name of any parent
27 /// groups. 29 /// groups.
28 /// 30 ///
29 /// This is `null` if this is the root group. 31 /// This is `null` if this is the root group.
30 final String _name; 32 final String _name;
31 33
32 /// The metadata for this group, including the metadata of any parent groups 34 /// The metadata for this group, including the metadata of any parent groups
33 /// and of the test suite. 35 /// and of the test suite.
34 final Metadata _metadata; 36 final Metadata _metadata;
35 37
38 /// The stack trace for this group.
39 final Trace _trace;
40
36 /// The set-up functions to run for each test in this group. 41 /// The set-up functions to run for each test in this group.
37 final _setUps = new List<AsyncFunction>(); 42 final _setUps = new List<AsyncFunction>();
38 43
39 /// The tear-down functions to run for each test in this group. 44 /// The tear-down functions to run for each test in this group.
40 final _tearDowns = new List<AsyncFunction>(); 45 final _tearDowns = new List<AsyncFunction>();
41 46
42 /// The set-up functions to run once for this group. 47 /// The set-up functions to run once for this group.
43 final _setUpAlls = new List<AsyncFunction>(); 48 final _setUpAlls = new List<AsyncFunction>();
44 49
50 /// The trace for the first call to [setUpAll].
51 ///
52 /// All [setUpAll]s are run in a single logical test, so they can only have
53 /// one trace. The first trace is most often correct, since the first
54 /// [setUpAll] is always run and the rest are only run if that one succeeds.
55 Trace _setUpAllTrace;
56
45 /// The tear-down functions to run once for this group. 57 /// The tear-down functions to run once for this group.
46 final _tearDownAlls = new List<AsyncFunction>(); 58 final _tearDownAlls = new List<AsyncFunction>();
47 59
60 /// The trace for the first call to [tearDownAll].
61 ///
62 /// All [tearDownAll]s are run in a single logical test, so they can only have
63 /// one trace. The first trace matches [_setUpAllTrace].
64 Trace _tearDownAllTrace;
65
48 /// The children of this group, either tests or sub-groups. 66 /// The children of this group, either tests or sub-groups.
49 final _entries = new List<GroupEntry>(); 67 final _entries = new List<GroupEntry>();
50 68
51 /// Whether [build] has been called for this declarer. 69 /// Whether [build] has been called for this declarer.
52 bool _built = false; 70 bool _built = false;
53 71
54 /// The current zone-scoped declarer. 72 /// The current zone-scoped declarer.
55 static Declarer get current => Zone.current[#test.declarer]; 73 static Declarer get current => Zone.current[#test.declarer];
56 74
57 /// Creates a new declarer for the root group. 75 /// Creates a new declarer for the root group.
58 /// 76 ///
59 /// This is the implicit group that exists outside of any calls to `group()`. 77 /// This is the implicit group that exists outside of any calls to `group()`.
60 /// If [metadata] is passed, it's used as the metadata for the implicit root 78 /// If [metadata] is passed, it's used as the metadata for the implicit root
61 /// group. 79 /// group.
62 Declarer([Metadata metadata]) 80 Declarer([Metadata metadata])
63 : this._(null, null, metadata == null ? new Metadata() : metadata); 81 : this._(null, null, metadata == null ? new Metadata() : metadata, null);
64 82
65 Declarer._(this._parent, this._name, this._metadata); 83 Declarer._(this._parent, this._name, this._metadata, this._trace);
66 84
67 /// Runs [body] with this declarer as [Declarer.current]. 85 /// Runs [body] with this declarer as [Declarer.current].
68 /// 86 ///
69 /// Returns the return value of [body]. 87 /// Returns the return value of [body].
70 declare(body()) => runZoned(body, zoneValues: {#test.declarer: this}); 88 declare(body()) => runZoned(body, zoneValues: {#test.declarer: this});
71 89
72 /// Defines a test case with the given name and body. 90 /// Defines a test case with the given name and body.
73 void test(String name, body(), {String testOn, Timeout timeout, skip, 91 void test(String name, body(), {String testOn, Timeout timeout, skip,
74 Map<String, dynamic> onPlatform, tags}) { 92 Map<String, dynamic> onPlatform, tags}) {
75 _checkNotBuilt("test"); 93 _checkNotBuilt("test");
76 94
77 var metadata = _metadata.merge(new Metadata.parse( 95 var metadata = _metadata.merge(new Metadata.parse(
78 testOn: testOn, timeout: timeout, skip: skip, onPlatform: onPlatform, 96 testOn: testOn, timeout: timeout, skip: skip, onPlatform: onPlatform,
79 tags: tags)); 97 tags: tags));
80 98
81 _entries.add(new LocalTest(_prefix(name), metadata, () async { 99 _entries.add(new LocalTest(_prefix(name), metadata, () async {
82 // TODO(nweiz): It might be useful to throw an error here if a test starts 100 // TODO(nweiz): It might be useful to throw an error here if a test starts
83 // running while other tests from the same declarer are also running, 101 // running while other tests from the same declarer are also running,
84 // since they might share closurized state. 102 // since they might share closurized state.
85 103
86 await Invoker.current.waitForOutstandingCallbacks(() async { 104 await Invoker.current.waitForOutstandingCallbacks(() async {
87 await _runSetUps(); 105 await _runSetUps();
88 await body(); 106 await body();
89 }); 107 });
90 await _runTearDowns(); 108 await _runTearDowns();
91 })); 109 }, trace: new Trace.current(2)));
92 } 110 }
93 111
94 /// Creates a group of tests. 112 /// Creates a group of tests.
95 void group(String name, void body(), {String testOn, Timeout timeout, skip, 113 void group(String name, void body(), {String testOn, Timeout timeout, skip,
96 Map<String, dynamic> onPlatform, tags}) { 114 Map<String, dynamic> onPlatform, tags}) {
97 _checkNotBuilt("group"); 115 _checkNotBuilt("group");
98 116
99 var metadata = _metadata.merge(new Metadata.parse( 117 var metadata = _metadata.merge(new Metadata.parse(
100 testOn: testOn, timeout: timeout, skip: skip, onPlatform: onPlatform, 118 testOn: testOn, timeout: timeout, skip: skip, onPlatform: onPlatform,
101 tags: tags)); 119 tags: tags));
120 var trace = new Trace.current(2);
102 121
103 // Don't load the tests for a skipped group. 122 // Don't load the tests for a skipped group.
104 if (metadata.skip) { 123 if (metadata.skip) {
105 _entries.add(new Group(name, [], metadata: metadata)); 124 _entries.add(new Group(name, [], metadata: metadata, trace: trace));
106 return; 125 return;
107 } 126 }
108 127
109 var declarer = new Declarer._(this, _prefix(name), metadata); 128 var declarer = new Declarer._(this, _prefix(name), metadata, trace);
110 declarer.declare(body); 129 declarer.declare(body);
111 _entries.add(declarer.build()); 130 _entries.add(declarer.build());
112 } 131 }
113 132
114 /// Returns [name] prefixed with this declarer's group name. 133 /// Returns [name] prefixed with this declarer's group name.
115 String _prefix(String name) => _name == null ? name : "$_name $name"; 134 String _prefix(String name) => _name == null ? name : "$_name $name";
116 135
117 /// Registers a function to be run before each test in this group. 136 /// Registers a function to be run before each test in this group.
118 void setUp(callback()) { 137 void setUp(callback()) {
119 _checkNotBuilt("setUp"); 138 _checkNotBuilt("setUp");
120 _setUps.add(callback); 139 _setUps.add(callback);
121 } 140 }
122 141
123 /// Registers a function to be run after each test in this group. 142 /// Registers a function to be run after each test in this group.
124 void tearDown(callback()) { 143 void tearDown(callback()) {
125 _checkNotBuilt("tearDown"); 144 _checkNotBuilt("tearDown");
126 _tearDowns.add(callback); 145 _tearDowns.add(callback);
127 } 146 }
128 147
129 /// Registers a function to be run once before all tests. 148 /// Registers a function to be run once before all tests.
130 void setUpAll(callback()) { 149 void setUpAll(callback()) {
131 _checkNotBuilt("setUpAll"); 150 _checkNotBuilt("setUpAll");
151 _setUpAllTrace ??= new Trace.current(2);
132 _setUpAlls.add(callback); 152 _setUpAlls.add(callback);
133 } 153 }
134 154
135 /// Registers a function to be run once after all tests. 155 /// Registers a function to be run once after all tests.
136 void tearDownAll(callback()) { 156 void tearDownAll(callback()) {
137 _checkNotBuilt("tearDownAll"); 157 _checkNotBuilt("tearDownAll");
158 _tearDownAllTrace ??= new Trace.current(2);
138 _tearDownAlls.add(callback); 159 _tearDownAlls.add(callback);
139 } 160 }
140 161
141 /// Finalizes and returns the group being declared. 162 /// Finalizes and returns the group being declared.
142 Group build() { 163 Group build() {
143 _checkNotBuilt("build"); 164 _checkNotBuilt("build");
144 165
145 _built = true; 166 _built = true;
146 return new Group(_name, _entries.toList(), 167 return new Group(_name, _entries.toList(),
147 metadata: _metadata, 168 metadata: _metadata,
169 trace: _trace,
148 setUpAll: _setUpAll, 170 setUpAll: _setUpAll,
149 tearDownAll: _tearDownAll); 171 tearDownAll: _tearDownAll);
150 } 172 }
151 173
152 /// Throws a [StateError] if [build] has been called. 174 /// Throws a [StateError] if [build] has been called.
153 /// 175 ///
154 /// [name] should be the name of the method being called. 176 /// [name] should be the name of the method being called.
155 void _checkNotBuilt(String name) { 177 void _checkNotBuilt(String name) {
156 if (!_built) return; 178 if (!_built) return;
157 throw new StateError("Can't call $name() once tests have begun running."); 179 throw new StateError("Can't call $name() once tests have begun running.");
(...skipping 24 matching lines...) Expand all
182 return Future.forEach(tearDowns, _errorsDontStopTest); 204 return Future.forEach(tearDowns, _errorsDontStopTest);
183 }); 205 });
184 } 206 }
185 207
186 /// Returns a [Test] that runs the callbacks in [_setUpAll]. 208 /// Returns a [Test] that runs the callbacks in [_setUpAll].
187 Test get _setUpAll { 209 Test get _setUpAll {
188 if (_setUpAlls.isEmpty) return null; 210 if (_setUpAlls.isEmpty) return null;
189 211
190 return new LocalTest(_prefix("(setUpAll)"), _metadata, () { 212 return new LocalTest(_prefix("(setUpAll)"), _metadata, () {
191 return Future.forEach(_setUpAlls, (setUp) => setUp()); 213 return Future.forEach(_setUpAlls, (setUp) => setUp());
192 }); 214 }, trace: _setUpAllTrace);
193 } 215 }
194 216
195 /// Returns a [Test] that runs the callbacks in [_tearDownAll]. 217 /// Returns a [Test] that runs the callbacks in [_tearDownAll].
196 Test get _tearDownAll { 218 Test get _tearDownAll {
197 if (_tearDownAlls.isEmpty) return null; 219 if (_tearDownAlls.isEmpty) return null;
198 220
199 return new LocalTest(_prefix("(tearDownAll)"), _metadata, () { 221 return new LocalTest(_prefix("(tearDownAll)"), _metadata, () {
200 return Invoker.current.unclosable(() { 222 return Invoker.current.unclosable(() {
201 return Future.forEach(_tearDownAlls.reversed, _errorsDontStopTest); 223 return Future.forEach(_tearDownAlls.reversed, _errorsDontStopTest);
202 }); 224 });
203 }); 225 }, trace: _tearDownAllTrace);
204 } 226 }
205 227
206 /// Runs [body] with special error-handling behavior. 228 /// Runs [body] with special error-handling behavior.
207 /// 229 ///
208 /// Errors emitted [body] will still cause the current test to fail, but they 230 /// Errors emitted [body] will still cause the current test to fail, but they
209 /// won't cause it to *stop*. In particular, they won't remove any outstanding 231 /// won't cause it to *stop*. In particular, they won't remove any outstanding
210 /// callbacks registered outside of [body]. 232 /// callbacks registered outside of [body].
211 Future _errorsDontStopTest(body()) { 233 Future _errorsDontStopTest(body()) {
212 var completer = new Completer(); 234 var completer = new Completer();
213 235
214 Invoker.current.addOutstandingCallback(); 236 Invoker.current.addOutstandingCallback();
215 Invoker.current.waitForOutstandingCallbacks(() { 237 Invoker.current.waitForOutstandingCallbacks(() {
216 new Future.sync(body).whenComplete(completer.complete); 238 new Future.sync(body).whenComplete(completer.complete);
217 }).then((_) => Invoker.current.removeOutstandingCallback()); 239 }).then((_) => Invoker.current.removeOutstandingCallback());
218 240
219 return completer.future; 241 return completer.future;
220 } 242 }
221 } 243 }
OLDNEW
« no previous file with comments | « json_reporter.schema.json ('k') | lib/src/backend/group.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698