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

Side by Side Diff: pkg/unittest/lib/unittest.dart

Issue 709903004: Enhance the Dart unittest library to support multiple invocations in the same application run. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « pkg/unittest/lib/src/test_environment.dart ('k') | no next file » | 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) 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 /// Support for writing Dart unit tests. 5 /// Support for writing Dart unit tests.
6 /// 6 ///
7 /// For information on installing and importing this library, see the 7 /// For information on installing and importing this library, see the
8 /// [unittest package on pub.dartlang.org] 8 /// [unittest package on pub.dartlang.org]
9 /// (http://pub.dartlang.org/packages/unittest). 9 /// (http://pub.dartlang.org/packages/unittest).
10 /// 10 ///
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 144
145 import 'src/utils.dart'; 145 import 'src/utils.dart';
146 146
147 import 'src/configuration.dart'; 147 import 'src/configuration.dart';
148 export 'src/configuration.dart'; 148 export 'src/configuration.dart';
149 149
150 part 'src/simple_configuration.dart'; 150 part 'src/simple_configuration.dart';
151 part 'src/group_context.dart'; 151 part 'src/group_context.dart';
152 part 'src/spread_args_helper.dart'; 152 part 'src/spread_args_helper.dart';
153 part 'src/test_case.dart'; 153 part 'src/test_case.dart';
154 part 'src/test_environment.dart';
154 155
155 Configuration _config; 156 const Symbol _TEST_ENVIRONMENT = #test_environment;
157
158 TestEnvironment _defaultEnvironment = new TestEnvironment();
kustermann 2014/11/10 11:37:37 Make this final.
wibling 2014/11/11 12:18:54 Done.
159
160 /**
161 * Internal getter for the current unittest config.
162 */
163 TestEnvironment get _environment {
164 var environment = Zone.current[_TEST_ENVIRONMENT];
165 if (environment == null) {
166 return _defaultEnvironment;
167 }
168 return environment;
169 }
170
171 // Convenience getter/setter for the current environment's config.
172 Configuration get _config => _environment.config;
173 void set _config(var config) { _environment.config = config; }
174
175 // Convenience getter for the current environment's test cases.
176 List<TestCase> get _testCases => _environment.testCases;
156 177
157 /// [Configuration] used by the unittest library. Note that if a 178 /// [Configuration] used by the unittest library. Note that if a
158 /// configuration has not been set, calling this getter will create 179 /// configuration has not been set, calling this getter will create
159 /// a default configuration. 180 /// a default configuration.
160 Configuration get unittestConfiguration { 181 Configuration get unittestConfiguration {
161 if (_config == null) { 182 if (_config == null) {
162 _config = new Configuration(); 183 _config = new Configuration();
163 } 184 }
164 return _config; 185 return _config;
165 } 186 }
(...skipping 11 matching lines...) Expand all
177 } 198 }
178 199
179 /// Can be called by tests to log status. Tests should use this 200 /// Can be called by tests to log status. Tests should use this
180 /// instead of [print]. 201 /// instead of [print].
181 void logMessage(String message) => 202 void logMessage(String message) =>
182 _config.onLogMessage(currentTestCase, message); 203 _config.onLogMessage(currentTestCase, message);
183 204
184 /// Separator used between group names and test names. 205 /// Separator used between group names and test names.
185 String groupSep = ' '; 206 String groupSep = ' ';
186 207
187 final List<TestCase> _testCases = new List<TestCase>();
188
189 /// Tests executed in this suite. 208 /// Tests executed in this suite.
190 final List<TestCase> testCases = new UnmodifiableListView<TestCase>(_testCases); 209 List<TestCase> get testCases => new UnmodifiableListView<TestCase>(_testCases);
191 210
192 /// Interval (in msecs) after which synchronous tests will insert an async 211 /// Interval (in msecs) after which synchronous tests will insert an async
193 /// delay to allow DOM or other updates. 212 /// delay to allow DOM or other updates.
194 const int BREATH_INTERVAL = 200; 213 const int BREATH_INTERVAL = 200;
195 214
196 /// The set of tests to run can be restricted by using [solo_test] and
197 /// [solo_group].
198 /// As groups can be nested we use a counter to keep track of the nest level
199 /// of soloing, and a flag to tell if we have seen any solo tests.
200 int _soloNestingLevel = 0;
201 bool _soloTestSeen = false;
202
203 // We use a 'dummy' context for the top level to eliminate null
204 // checks when querying the context. This allows us to easily
205 // support top-level setUp/tearDown functions as well.
206 final _rootContext = new _GroupContext();
207 _GroupContext _currentContext = _rootContext;
208
209 /// Represents the index of the currently running test case
210 /// == -1 implies the test system is not running
211 /// == [number of test cases] is a short-lived state flagging that the last test
212 /// has completed
213 int _currentTestCaseIndex = -1;
214
215 /// [TestCase] currently being executed. 215 /// [TestCase] currently being executed.
216 TestCase get currentTestCase => 216 TestCase get currentTestCase =>
217 (_currentTestCaseIndex >= 0 && _currentTestCaseIndex < testCases.length) 217 (_environment.currentTestCaseIndex >= 0 && _environment.currentTestCaseIndex < testCases.length)
kustermann 2014/11/10 11:37:37 long line
wibling 2014/11/11 12:18:54 Done.
218 ? testCases[_currentTestCaseIndex] 218 ? testCases[_environment.currentTestCaseIndex]
219 : null; 219 : null;
220 220
221 /// Whether the framework is in an initialized state.
222 bool _initialized = false;
223
224 String _uncaughtErrorMessage = null;
225
226 /// Time since we last gave non-sync code a chance to be scheduled.
227 int _lastBreath = new DateTime.now().millisecondsSinceEpoch;
228
229 /* Test case result strings. */ 221 /* Test case result strings. */
230 // TODO(gram) we should change these constants to use a different string 222 // TODO(gram) we should change these constants to use a different string
231 // (so that writing 'FAIL' in the middle of a test doesn't 223 // (so that writing 'FAIL' in the middle of a test doesn't
232 // imply that the test fails). We can't do it without also changing 224 // imply that the test fails). We can't do it without also changing
233 // the testrunner and test.dart though. 225 // the testrunner and test.dart though.
234 /// Result string for a passing test case. 226 /// Result string for a passing test case.
235 const PASS = 'pass'; 227 const PASS = 'pass';
236 /// Result string for a failing test case. 228 /// Result string for a failing test case.
237 const FAIL = 'fail'; 229 const FAIL = 'fail';
238 /// Result string for an test case with an error. 230 /// Result string for an test case with an error.
239 const ERROR = 'error'; 231 const ERROR = 'error';
240 232
241 /// Creates a new test case with the given description and body. The 233 /// Creates a new test case with the given description and body. The
242 /// description will include the descriptions of any surrounding group() 234 /// description will include the descriptions of any surrounding group()
243 /// calls. 235 /// calls.
244 void test(String spec, TestFunction body) { 236 void test(String spec, TestFunction body) {
245 _requireNotRunning(); 237 _requireNotRunning();
246 ensureInitialized(); 238 ensureInitialized();
247 if (!_soloTestSeen || _soloNestingLevel > 0) { 239 if (!_environment.soloTestSeen || _environment.soloNestingLevel > 0) {
248 var testcase = new TestCase._internal(testCases.length + 1, _fullSpec(spec), 240 var testcase = new TestCase._internal(testCases.length + 1, _fullSpec(spec),
249 body); 241 body);
250 _testCases.add(testcase); 242 _testCases.add(testcase);
251 } 243 }
252 } 244 }
253 245
254 /// Convenience function for skipping a test. 246 /// Convenience function for skipping a test.
255 void skip_test(String spec, TestFunction body) {} 247 void skip_test(String spec, TestFunction body) {}
256 248
257 /// Creates a new test case with the given description and body. The 249 /// Creates a new test case with the given description and body. The
258 /// description will include the descriptions of any surrounding group() 250 /// description will include the descriptions of any surrounding group()
259 /// calls. 251 /// calls.
260 /// 252 ///
261 /// If we use [solo_test] (or [solo_group]) instead of test, then all non-solo 253 /// If we use [solo_test] (or [solo_group]) instead of test, then all non-solo
262 /// tests will be disabled. Note that if we use [solo_group], all tests in 254 /// tests will be disabled. Note that if we use [solo_group], all tests in
263 /// the group will be enabled, regardless of whether they use [test] or 255 /// the group will be enabled, regardless of whether they use [test] or
264 /// [solo_test], or whether they are in a nested [group] vs [solo_group]. Put 256 /// [solo_test], or whether they are in a nested [group] vs [solo_group]. Put
265 /// another way, if there are any calls to [solo_test] or [solo_group] in a test 257 /// another way, if there are any calls to [solo_test] or [solo_group] in a test
266 /// file, all tests that are not inside a [solo_group] will be disabled unless 258 /// file, all tests that are not inside a [solo_group] will be disabled unless
267 /// they are [solo_test]s. 259 /// they are [solo_test]s.
268 /// 260 ///
269 /// [skip_test] and [skip_group] take precedence over soloing, by virtue of the 261 /// [skip_test] and [skip_group] take precedence over soloing, by virtue of the
270 /// fact that they are effectively no-ops. 262 /// fact that they are effectively no-ops.
271 void solo_test(String spec, TestFunction body) { 263 void solo_test(String spec, TestFunction body) {
272 _requireNotRunning(); 264 _requireNotRunning();
273 ensureInitialized(); 265 ensureInitialized();
274 if (!_soloTestSeen) { 266 if (!_environment.soloTestSeen) {
275 _soloTestSeen = true; 267 _environment.soloTestSeen = true;
276 // This is the first solo-ed test. Discard all tests up to now. 268 // This is the first solo-ed test. Discard all tests up to now.
277 _testCases.clear(); 269 _testCases.clear();
278 } 270 }
279 ++_soloNestingLevel; 271 ++_environment.soloNestingLevel;
280 try { 272 try {
281 test(spec, body); 273 test(spec, body);
282 } finally { 274 } finally {
283 --_soloNestingLevel; 275 --_environment.soloNestingLevel;
284 } 276 }
285 } 277 }
286 278
287 /// Indicate that [callback] is expected to be called a [count] number of times 279 /// Indicate that [callback] is expected to be called a [count] number of times
288 /// (by default 1). The unittest framework will wait for the callback to run the 280 /// (by default 1). The unittest framework will wait for the callback to run the
289 /// specified [count] times before it continues with the following test. Using 281 /// specified [count] times before it continues with the following test. Using
290 /// [expectAsync] will also ensure that errors that occur within [callback] are 282 /// [expectAsync] will also ensure that errors that occur within [callback] are
291 /// tracked and reported. [callback] should take 0 positional arguments (named 283 /// tracked and reported. [callback] should take 0 positional arguments (named
292 /// arguments are not supported). [id] can be used to provide more 284 /// arguments are not supported). [id] can be used to provide more
293 /// descriptive error messages if the callback is called more often than 285 /// descriptive error messages if the callback is called more often than
(...skipping 16 matching lines...) Expand all
310 /// identify the callback in error messages (for example if it is called 302 /// identify the callback in error messages (for example if it is called
311 /// after the test case is complete). 303 /// after the test case is complete).
312 Function expectAsyncUntil(Function callback, bool isDone(), {String id}) => 304 Function expectAsyncUntil(Function callback, bool isDone(), {String id}) =>
313 new _SpreadArgsHelper(callback, 0, -1, id, isDone: isDone).func; 305 new _SpreadArgsHelper(callback, 0, -1, id, isDone: isDone).func;
314 306
315 /// Creates a new named group of tests. Calls to group() or test() within the 307 /// Creates a new named group of tests. Calls to group() or test() within the
316 /// body of the function passed to this will inherit this group's description. 308 /// body of the function passed to this will inherit this group's description.
317 void group(String description, void body()) { 309 void group(String description, void body()) {
318 ensureInitialized(); 310 ensureInitialized();
319 _requireNotRunning(); 311 _requireNotRunning();
320 _currentContext = new _GroupContext(_currentContext, description); 312 _environment.currentContext = new _GroupContext(_environment.currentContext, d escription);
321 try { 313 try {
322 body(); 314 body();
323 } catch (e, trace) { 315 } catch (e, trace) {
324 var stack = (trace == null) ? '' : ': ${trace.toString()}'; 316 var stack = (trace == null) ? '' : ': ${trace.toString()}';
325 _uncaughtErrorMessage = "${e.toString()}$stack"; 317 _environment.uncaughtErrorMessage = "${e.toString()}$stack";
326 } finally { 318 } finally {
327 // Now that the group is over, restore the previous one. 319 // Now that the group is over, restore the previous one.
328 _currentContext = _currentContext.parent; 320 _environment.currentContext = _environment.currentContext.parent;
329 } 321 }
330 } 322 }
331 323
332 /// Like [skip_test], but for groups. 324 /// Like [skip_test], but for groups.
333 void skip_group(String description, void body()) {} 325 void skip_group(String description, void body()) {}
334 326
335 /// Like [solo_test], but for groups. 327 /// Like [solo_test], but for groups.
336 void solo_group(String description, void body()) { 328 void solo_group(String description, void body()) {
337 _requireNotRunning(); 329 _requireNotRunning();
338 ensureInitialized(); 330 ensureInitialized();
339 if (!_soloTestSeen) { 331 if (!_environment.soloTestSeen) {
340 _soloTestSeen = true; 332 _environment.soloTestSeen = true;
341 // This is the first solo-ed group. Discard all tests up to now. 333 // This is the first solo-ed group. Discard all tests up to now.
342 _testCases.clear(); 334 _testCases.clear();
343 } 335 }
344 ++_soloNestingLevel; 336 ++_environment.soloNestingLevel;
345 try { 337 try {
346 group(description, body); 338 group(description, body);
347 } finally { 339 } finally {
348 --_soloNestingLevel; 340 --_environment.soloNestingLevel;
349 } 341 }
350 } 342 }
351 343
352 /// Register a [setUp] function for a test [group]. This function will 344 /// Register a [setUp] function for a test [group]. This function will
353 /// be called before each test in the group is run. 345 /// be called before each test in the group is run.
354 /// [setUp] and [tearDown] should be called within the [group] before any 346 /// [setUp] and [tearDown] should be called within the [group] before any
355 /// calls to [test]. The [setupTest] function can be asynchronous; in this 347 /// calls to [test]. The [setupTest] function can be asynchronous; in this
356 /// case it must return a [Future]. 348 /// case it must return a [Future].
357 void setUp(Function setupTest) { 349 void setUp(Function setupTest) {
358 _requireNotRunning(); 350 _requireNotRunning();
359 _currentContext.testSetup = setupTest; 351 _environment.currentContext.testSetup = setupTest;
360 } 352 }
361 353
362 /// Register a [tearDown] function for a test [group]. This function will 354 /// Register a [tearDown] function for a test [group]. This function will
363 /// be called after each test in the group is run. Note that if groups 355 /// be called after each test in the group is run. Note that if groups
364 /// are nested only the most locally scoped [teardownTest] function will be run. 356 /// are nested only the most locally scoped [teardownTest] function will be run.
365 /// [setUp] and [tearDown] should be called within the [group] before any 357 /// [setUp] and [tearDown] should be called within the [group] before any
366 /// calls to [test]. The [teardownTest] function can be asynchronous; in this 358 /// calls to [test]. The [teardownTest] function can be asynchronous; in this
367 /// case it must return a [Future]. 359 /// case it must return a [Future].
368 void tearDown(Function teardownTest) { 360 void tearDown(Function teardownTest) {
369 _requireNotRunning(); 361 _requireNotRunning();
370 _currentContext.testTeardown = teardownTest; 362 _environment.currentContext.testTeardown = teardownTest;
371 } 363 }
372 364
373 /// Advance to the next test case. 365 /// Advance to the next test case.
374 void _nextTestCase() { 366 void _nextTestCase() {
375 _currentTestCaseIndex++; 367 _environment.currentTestCaseIndex++;
376 _runTest(); 368 _runTest();
377 } 369 }
378 370
379 /// Handle errors that happen outside the tests. 371 /// Handle errors that happen outside the tests.
380 // TODO(vsm): figure out how to expose the stack trace here 372 // TODO(vsm): figure out how to expose the stack trace here
381 // Currently e.message works in dartium, but not in dartc. 373 // Currently e.message works in dartium, but not in dartc.
382 void handleExternalError(e, String message, [stack]) { 374 void handleExternalError(e, String message, [stack]) {
383 var msg = '$message\nCaught $e'; 375 var msg = '$message\nCaught $e';
384 376
385 if (currentTestCase != null) { 377 if (currentTestCase != null) {
386 currentTestCase._error(msg, stack); 378 currentTestCase._error(msg, stack);
387 } else { 379 } else {
388 _uncaughtErrorMessage = "$msg: $stack"; 380 _environment.uncaughtErrorMessage = "$msg: $stack";
389 } 381 }
390 } 382 }
391 383
392 /// Filter the tests. [testFilter] can be a [RegExp], a [String] or a 384 /// Filter the tests. [testFilter] can be a [RegExp], a [String] or a
393 /// predicate function. This is different to enabling/disabling tests 385 /// predicate function. This is different to enabling/disabling tests
394 /// in that it removes the tests completely. 386 /// in that it removes the tests completely.
395 void filterTests(testFilter) { 387 void filterTests(testFilter) {
396 var filterFunction; 388 var filterFunction;
397 if (testFilter is String) { 389 if (testFilter is String) {
398 RegExp re = new RegExp(testFilter); 390 RegExp re = new RegExp(testFilter);
399 filterFunction = (t) => re.hasMatch(t.description); 391 filterFunction = (t) => re.hasMatch(t.description);
400 } else if (testFilter is RegExp) { 392 } else if (testFilter is RegExp) {
401 filterFunction = (t) => testFilter.hasMatch(t.description); 393 filterFunction = (t) => testFilter.hasMatch(t.description);
402 } else if (testFilter is Function) { 394 } else if (testFilter is Function) {
403 filterFunction = testFilter; 395 filterFunction = testFilter;
404 } 396 }
405 _testCases.retainWhere(filterFunction); 397 _testCases.retainWhere(filterFunction);
406 } 398 }
407 399
408 /// Runs all queued tests, one at a time. 400 /// Runs all queued tests, one at a time.
409 void runTests() { 401 void runTests() {
410 _requireNotRunning(); 402 _requireNotRunning();
411 _ensureInitialized(false); 403 _ensureInitialized(false);
412 _currentTestCaseIndex = 0; 404 _environment.currentTestCaseIndex = 0;
413 _config.onStart(); 405 _config.onStart();
414 _runTest(); 406 _runTest();
415 } 407 }
416 408
417 /// Registers that an exception was caught for the current test. 409 /// Registers that an exception was caught for the current test.
418 void registerException(e, [trace]) { 410 void registerException(e, [trace]) {
419 _registerException(currentTestCase, e, trace); 411 _registerException(currentTestCase, e, trace);
420 } 412 }
421 413
422 /// Registers that an exception was caught for the current test. 414 /// Registers that an exception was caught for the current test.
423 void _registerException(TestCase testCase, e, [trace]) { 415 void _registerException(TestCase testCase, e, [trace]) {
424 String message = (e is TestFailure) ? e.message : 'Caught $e'; 416 String message = (e is TestFailure) ? e.message : 'Caught $e';
425 if (testCase.result == null) { 417 if (testCase.result == null) {
426 testCase._fail(message, trace); 418 testCase._fail(message, trace);
427 } else { 419 } else {
428 testCase._error(message, trace); 420 testCase._error(message, trace);
429 } 421 }
430 } 422 }
431 423
432 /// Runs the next test. 424 /// Runs the next test.
433 void _runTest() { 425 void _runTest() {
434 if (_currentTestCaseIndex >= testCases.length) { 426 if (_environment.currentTestCaseIndex >= testCases.length) {
435 assert(_currentTestCaseIndex == testCases.length); 427 assert(_environment.currentTestCaseIndex == testCases.length);
436 _completeTests(); 428 _completeTests();
437 } else { 429 } else {
438 var testCase = testCases[_currentTestCaseIndex]; 430 var testCase = testCases[_environment.currentTestCaseIndex];
439 Future f = runZoned(testCase._run, onError: (error, stack) { 431 Future f = runZoned(testCase._run, onError: (error, stack) {
440 // TODO(kevmoo) Do a better job of flagging these are async errors. 432 // TODO(kevmoo) Do a better job of flagging these are async errors.
441 // https://code.google.com/p/dart/issues/detail?id=16530 433 // https://code.google.com/p/dart/issues/detail?id=16530
442 _registerException(testCase, error, stack); 434 _registerException(testCase, error, stack);
443 }); 435 });
444 436
445 var timeout = unittestConfiguration.timeout; 437 var timeout = unittestConfiguration.timeout;
446 438
447 Timer timer; 439 Timer timer;
448 if (timeout != null) { 440 if (timeout != null) {
449 try { 441 try {
450 timer = new Timer(timeout, () { 442 timer = new Timer(timeout, () {
451 testCase._error("Test timed out after ${timeout.inSeconds} seconds."); 443 testCase._error("Test timed out after ${timeout.inSeconds} seconds.");
452 _nextTestCase(); 444 _nextTestCase();
453 }); 445 });
454 } on UnsupportedError catch (e) { 446 } on UnsupportedError catch (e) {
455 if (e.message != "Timer greater than 0.") rethrow; 447 if (e.message != "Timer greater than 0.") rethrow;
456 // Support running on d8 and jsshell which don't support timers. 448 // Support running on d8 and jsshell which don't support timers.
457 } 449 }
458 } 450 }
459 f.whenComplete(() { 451 f.whenComplete(() {
460 if (timer != null) timer.cancel(); 452 if (timer != null) timer.cancel();
461 var now = new DateTime.now().millisecondsSinceEpoch; 453 var now = new DateTime.now().millisecondsSinceEpoch;
462 if ((now - _lastBreath) >= BREATH_INTERVAL) { 454 if ((now - _environment.lastBreath) >= BREATH_INTERVAL) {
463 _lastBreath = now; 455 _environment.lastBreath = now;
464 Timer.run(_nextTestCase); 456 Timer.run(_nextTestCase);
465 } else { 457 } else {
466 scheduleMicrotask(_nextTestCase); // Schedule the next test. 458 scheduleMicrotask(_nextTestCase); // Schedule the next test.
467 } 459 }
468 }); 460 });
469 } 461 }
470 } 462 }
471 463
472 /// Publish results on the page and notify controller. 464 /// Publish results on the page and notify controller.
473 void _completeTests() { 465 void _completeTests() {
474 if (!_initialized) return; 466 if (!_environment.initialized) return;
475 int passed = 0; 467 int passed = 0;
476 int failed = 0; 468 int failed = 0;
477 int errors = 0; 469 int errors = 0;
478 470
479 for (TestCase t in testCases) { 471 for (TestCase t in testCases) {
480 switch (t.result) { 472 switch (t.result) {
481 case PASS: passed++; break; 473 case PASS: passed++; break;
482 case FAIL: failed++; break; 474 case FAIL: failed++; break;
483 case ERROR: errors++; break; 475 case ERROR: errors++; break;
484 } 476 }
485 } 477 }
486 _config.onSummary(passed, failed, errors, testCases, _uncaughtErrorMessage); 478 _config.onSummary(passed, failed, errors, testCases, _environment.uncaughtErro rMessage);
kustermann 2014/11/10 11:37:37 long line
wibling 2014/11/11 12:18:54 Done.
487 _config.onDone(passed > 0 && failed == 0 && errors == 0 && 479 _config.onDone(passed > 0 && failed == 0 && errors == 0 &&
488 _uncaughtErrorMessage == null); 480 _environment.uncaughtErrorMessage == null);
489 _initialized = false; 481 _environment.initialized = false;
490 _currentTestCaseIndex = -1; 482 _environment.currentTestCaseIndex = -1;
491 } 483 }
492 484
493 String _fullSpec(String spec) { 485 String _fullSpec(String spec) {
494 var group = '${_currentContext.fullName}'; 486 var group = '${_environment.currentContext.fullName}';
495 if (spec == null) return group; 487 if (spec == null) return group;
496 return group != '' ? '$group$groupSep$spec' : spec; 488 return group != '' ? '$group$groupSep$spec' : spec;
497 } 489 }
498 490
499 /// Lazily initializes the test library if not already initialized. 491 /// Lazily initializes the test library if not already initialized.
500 void ensureInitialized() { 492 void ensureInitialized() {
501 _ensureInitialized(true); 493 _ensureInitialized(true);
502 } 494 }
503 495
504 void _ensureInitialized(bool configAutoStart) { 496 void _ensureInitialized(bool configAutoStart) {
505 if (_initialized) { 497 if (_environment.initialized) {
506 return; 498 return;
507 } 499 }
508 _initialized = true; 500 _environment.initialized = true;
509 // Hook our async guard into the matcher library. 501 // Hook our async guard into the matcher library.
510 wrapAsync = (f, [id]) => expectAsync(f, id: id); 502 wrapAsync = (f, [id]) => expectAsync(f, id: id);
511 503
512 _uncaughtErrorMessage = null; 504 _environment.uncaughtErrorMessage = null;
513 505
514 unittestConfiguration.onInit(); 506 unittestConfiguration.onInit();
515 507
516 if (configAutoStart && _config.autoStart) { 508 if (configAutoStart && _config.autoStart) {
517 // Immediately queue the suite up. It will run after a timeout (i.e. after 509 // Immediately queue the suite up. It will run after a timeout (i.e. after
518 // main() has returned). 510 // main() has returned).
519 scheduleMicrotask(runTests); 511 scheduleMicrotask(runTests);
520 } 512 }
521 } 513 }
522 514
(...skipping 28 matching lines...) Expand all
551 /// exception stacks. 543 /// exception stacks.
552 /// 544 ///
553 /// Useful to disable when debugging unittest or matcher customizations. 545 /// Useful to disable when debugging unittest or matcher customizations.
554 bool formatStacks = true; 546 bool formatStacks = true;
555 547
556 /// A flag that controls whether we try to filter out irrelevant frames from 548 /// A flag that controls whether we try to filter out irrelevant frames from
557 /// the stack trace. Requires formatStacks to be set. 549 /// the stack trace. Requires formatStacks to be set.
558 bool filterStacks = true; 550 bool filterStacks = true;
559 551
560 void _requireNotRunning() { 552 void _requireNotRunning() {
561 if (_currentTestCaseIndex != -1) { 553 if (_environment.currentTestCaseIndex != -1) {
562 throw new StateError('Not allowed when tests are running.'); 554 throw new StateError('Not allowed when tests are running.');
563 } 555 }
564 } 556 }
557
558 /// Method to support multiple invocations of the unittest library in the same
559 /// application instance.
560 dynamic withTestEnvironment(callback()) {
561 print("Creating new test env!");
kustermann 2014/11/10 11:37:37 left-over print?
wibling 2014/11/11 12:18:54 Indeed:) Removed.
562 return runZoned(callback,
563 zoneValues: <Symbol, Object>{_TEST_ENVIRONMENT: new TestEnvironment()},
564 onError: (error, stack) => print("$error\nStack:\n$stack"));
kustermann 2014/11/10 11:37:37 Maybe there is a better way then printing the erro
wibling 2014/11/11 12:18:54 I removed the onError handler and used the default
565 }
OLDNEW
« no previous file with comments | « pkg/unittest/lib/src/test_environment.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698