OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 /** | 5 /** |
6 * This configuration can be used to rerun selected tests, as well | 6 * This configuration can be used to rerun selected tests, as well |
7 * as see diagnostic output from tests. It runs each test in its own | 7 * as see diagnostic output from tests. It runs each test in its own |
8 * IFrame, so the configuration consists of two parts - a 'parent' | 8 * IFrame, so the configuration consists of two parts - a 'parent' |
9 * config that manages all the tests, and a 'child' config for the | 9 * config that manages all the tests, and a 'child' config for the |
10 * IFrame that runs the individual tests. | 10 * IFrame that runs the individual tests. |
11 * | 11 * |
12 * Note: this unit test configuration will not work with the debugger (the tests | 12 * Note: this unit test configuration will not work with the debugger (the tests |
13 * are executed in a separate IFrame). | 13 * are executed in a separate IFrame). |
14 */ | 14 */ |
15 library unittest_interactive_html_config; | 15 library unittest_interactive_html_config; |
16 | 16 |
17 // TODO(gram) - add options for: remove IFrame on done/keep | 17 // TODO(gram) - add options for: remove IFrame on done/keep |
18 // IFrame for failed tests/keep IFrame for all tests. | 18 // IFrame for failed tests/keep IFrame for all tests. |
19 | 19 |
20 import 'dart:html'; | 20 import 'dart:html'; |
21 import 'dart:async'; | 21 import 'dart:async'; |
22 import 'dart:math'; | 22 import 'dart:math'; |
23 | |
24 import 'package:stack_trace/stack_trace.dart'; | |
25 | |
26 import 'unittest.dart'; | 23 import 'unittest.dart'; |
27 | 24 |
28 /** The messages exchanged between parent and child. */ | 25 /** The messages exchanged between parent and child. */ |
29 | 26 |
30 class _Message { | 27 class _Message { |
31 static const START = 'start'; | 28 static const START = 'start'; |
32 static const LOG = 'log'; | 29 static const LOG = 'log'; |
33 static const STACK = 'stack'; | 30 static const STACK = 'stack'; |
34 static const PASS = 'pass'; | 31 static const PASS = 'pass'; |
35 static const FAIL = 'fail'; | 32 static const FAIL = 'fail'; |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 elapsed = -1; | 140 elapsed = -1; |
144 } else { | 141 } else { |
145 DateTime end = new DateTime.now(); | 142 DateTime end = new DateTime.now(); |
146 elapsed = end.difference(_testStarts[testCase.id]).inMilliseconds; | 143 elapsed = end.difference(_testStarts[testCase.id]).inMilliseconds; |
147 } | 144 } |
148 parentWindow.postMessage( | 145 parentWindow.postMessage( |
149 _Message.text(_Message.LOG, elapsed, message).toString(), '*'); | 146 _Message.text(_Message.LOG, elapsed, message).toString(), '*'); |
150 } | 147 } |
151 | 148 |
152 /** | 149 /** |
153 * Get the elapsed time for the test, and post the test result back to the | 150 * Get the elapsed time for the test, anbd post the test result |
154 * parent window. If the test failed due to an exception the stack is posted | 151 * back to the parent window. If the test failed due to an exception |
155 * back too (before the test result). | 152 * the stack is posted back too (before the test result). |
156 */ | 153 */ |
157 void onTestResult(TestCase testCase) { | 154 void onTestResult(TestCase testCase) { |
158 super.onTestResult(testCase); | 155 super.onTestResult(testCase); |
159 DateTime end = new DateTime.now(); | 156 DateTime end = new DateTime.now(); |
160 int elapsed = end.difference(_testStarts[testCase.id]).inMilliseconds; | 157 int elapsed = end.difference(_testStarts[testCase.id]).inMilliseconds; |
161 if (testCase.stackTrace != null) { | 158 if (testCase.stackTrace != null) { |
162 var message = json.stringify(testCase.stackTrace.frames.map((frame) { | |
163 return <String>{ | |
164 "uri": frame.uri.toString(), | |
165 "line": frame.line, | |
166 "column": frame.column, | |
167 "member": frame.member | |
168 }; | |
169 }).toList()); | |
170 parentWindow.postMessage( | 159 parentWindow.postMessage( |
171 _Message.text(_Message.STACK, elapsed, message), '*'); | 160 _Message.text(_Message.STACK, elapsed, testCase.stackTrace), '*'); |
172 } | 161 } |
173 parentWindow.postMessage( | 162 parentWindow.postMessage( |
174 _Message.text(testCase.result, elapsed, testCase.message), '*'); | 163 _Message.text(testCase.result, elapsed, testCase.message), '*'); |
175 } | 164 } |
176 void onSummary(int passed, int failed, int errors, List<TestCase> results, | 165 void onSummary(int passed, int failed, int errors, List<TestCase> results, |
177 String uncaughtError) { | 166 String uncaughtError) { |
178 } | 167 } |
179 | 168 |
180 void onDone(bool success) { | 169 void onDone(bool success) { |
181 _uninstallErrorHandler(); | 170 _uninstallErrorHandler(); |
182 } | 171 } |
183 } | 172 } |
184 | 173 |
185 /** | 174 /** |
186 * The parent configuration runs in the top-level window; it wraps the tests | 175 * The parent configuration runs in the top-level window; it wraps the tests |
187 * in new functions that create child IFrames and run the real tests. | 176 * in new functions that create child IFrames and run the real tests. |
188 */ | 177 */ |
189 class ParentInteractiveHtmlConfiguration extends HtmlConfiguration { | 178 class ParentInteractiveHtmlConfiguration extends HtmlConfiguration { |
190 Map<int,DateTime> _testStarts; | 179 Map<int,DateTime> _testStarts; |
191 | 180 |
192 | 181 |
193 /** The stack that was posted back from the child, if any. */ | 182 /** The stack that was posted back from the child, if any. */ |
194 Trace _stack; | 183 String _stack; |
195 | 184 |
196 int _testTime; | 185 int _testTime; |
197 /** | 186 /** |
198 * Whether or not we have already wrapped the TestCase test functions | 187 * Whether or not we have already wrapped the TestCase test functions |
199 * in new closures that instead create an IFrame and get it to run the | 188 * in new closures that instead create an IFrame and get it to run the |
200 * test. | 189 * test. |
201 */ | 190 */ |
202 bool _doneWrap = false; | 191 bool _doneWrap = false; |
203 | 192 |
204 StreamSubscription _messageSubscription; | 193 StreamSubscription _messageSubscription; |
(...skipping 23 matching lines...) Expand all Loading... |
228 }); | 217 }); |
229 }; | 218 }; |
230 } | 219 } |
231 | 220 |
232 void _handleMessage(MessageEvent e) { | 221 void _handleMessage(MessageEvent e) { |
233 // Get the result, do any logging, then do a pass/fail. | 222 // Get the result, do any logging, then do a pass/fail. |
234 var msg = new _Message.fromString(e.data); | 223 var msg = new _Message.fromString(e.data); |
235 if (msg.messageType == _Message.LOG) { | 224 if (msg.messageType == _Message.LOG) { |
236 logMessage(e.data); | 225 logMessage(e.data); |
237 } else if (msg.messageType == _Message.STACK) { | 226 } else if (msg.messageType == _Message.STACK) { |
238 _stack = new Trace(json.parse(msg.body).map((frame) { | 227 _stack = msg.body; |
239 return new Frame( | |
240 Uri.parse(frame['uri']), | |
241 frame['line'], | |
242 frame['column'], | |
243 frame['member']); | |
244 })); | |
245 } else { | 228 } else { |
246 _testTime = msg.elapsed; | 229 _testTime = msg.elapsed; |
247 logMessage(_Message.text(_Message.LOG, _testTime, 'Complete')); | 230 logMessage(_Message.text(_Message.LOG, _testTime, 'Complete')); |
248 if (msg.messageType == _Message.PASS) { | 231 if (msg.messageType == _Message.PASS) { |
249 currentTestCase.pass(); | 232 currentTestCase.pass(); |
250 } else if (msg.messageType == _Message.FAIL) { | 233 } else if (msg.messageType == _Message.FAIL) { |
251 currentTestCase.fail(msg.body, _stack); | 234 currentTestCase.fail(msg.body, _stack); |
252 } else if (msg.messageType == _Message.ERROR) { | 235 } else if (msg.messageType == _Message.ERROR) { |
253 currentTestCase.error(msg.body, _stack); | 236 currentTestCase.error(msg.body, _stack); |
254 } | 237 } |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
692 display: block; | 675 display: block; |
693 list-style-type: disc; | 676 list-style-type: disc; |
694 -webkit-margin-before: 1em; | 677 -webkit-margin-before: 1em; |
695 -webkit-margin-after: 1em; | 678 -webkit-margin-after: 1em; |
696 -webkit-margin-start: 0px; | 679 -webkit-margin-start: 0px; |
697 -webkit-margin-end: 0px; | 680 -webkit-margin-end: 0px; |
698 -webkit-padding-start: 40px; | 681 -webkit-padding-start: 40px; |
699 } | 682 } |
700 | 683 |
701 """; | 684 """; |
OLD | NEW |