| 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 library unittest; | 5 library unittest; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | 8 |
| 9 import 'package:path/path.dart' as p; |
| 9 | 10 |
| 10 import 'src/configuration.dart'; | 11 import 'src/configuration.dart'; |
| 11 import 'src/expected_function.dart'; | 12 import 'src/declarer.dart'; |
| 12 import 'src/group_context.dart'; | 13 import 'src/console_reporter.dart'; |
| 13 import 'src/internal_test_case.dart'; | 14 import 'src/invoker.dart'; |
| 15 import 'src/suite.dart'; |
| 14 import 'src/test_case.dart'; | 16 import 'src/test_case.dart'; |
| 15 import 'src/test_environment.dart'; | |
| 16 | 17 |
| 17 export 'package:matcher/matcher.dart' | 18 export 'package:matcher/matcher.dart' |
| 18 hide | 19 hide |
| 19 completes, | 20 completes, |
| 20 completion, | 21 completion, |
| 21 configureExpectFailureHandler, | 22 configureExpectFailureHandler, |
| 22 DefaultFailureHandler, | 23 DefaultFailureHandler, |
| 23 ErrorFormatter, | 24 ErrorFormatter, |
| 24 expect, | 25 expect, |
| 25 fail, | 26 fail, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 37 throwsFormatException, | 38 throwsFormatException, |
| 38 throwsNoSuchMethodError, | 39 throwsNoSuchMethodError, |
| 39 throwsNullThrownError, | 40 throwsNullThrownError, |
| 40 throwsRangeError, | 41 throwsRangeError, |
| 41 throwsStateError, | 42 throwsStateError, |
| 42 throwsUnimplementedError, | 43 throwsUnimplementedError, |
| 43 throwsUnsupportedError; | 44 throwsUnsupportedError; |
| 44 | 45 |
| 45 export 'src/configuration.dart'; | 46 export 'src/configuration.dart'; |
| 46 export 'src/expect.dart'; | 47 export 'src/expect.dart'; |
| 47 export 'src/simple_configuration.dart'; | 48 export 'src/expect_async.dart'; |
| 48 export 'src/future_matchers.dart'; | 49 export 'src/future_matchers.dart'; |
| 49 export 'src/prints_matcher.dart'; | 50 export 'src/prints_matcher.dart'; |
| 51 export 'src/simple_configuration.dart'; |
| 52 export 'src/test_case.dart'; |
| 50 export 'src/throws_matcher.dart'; | 53 export 'src/throws_matcher.dart'; |
| 51 export 'src/throws_matchers.dart'; | 54 export 'src/throws_matchers.dart'; |
| 52 export 'src/test_case.dart'; | |
| 53 | 55 |
| 54 /// The signature for a function passed to [test]. | 56 Declarer _globalDeclarer; |
| 55 typedef dynamic TestFunction(); | |
| 56 | 57 |
| 57 /// [Configuration] used by the unittest library. | 58 Declarer get _declarer { |
| 58 /// | 59 var declarer = Zone.current[#unittest.declarer]; |
| 59 /// Note that if a configuration has not been set, calling this getter will | 60 if (declarer != null) return declarer; |
| 60 /// create a default configuration. | 61 if (_globalDeclarer != null) return _globalDeclarer; |
| 61 Configuration get unittestConfiguration { | 62 |
| 62 if (config == null) environment.config = new Configuration(); | 63 _globalDeclarer = new Declarer(); |
| 63 return config; | 64 scheduleMicrotask(() { |
| 65 var suite = new Suite(p.prettyUri(Uri.base), _globalDeclarer.tests); |
| 66 // TODO(nweiz): Use a reporter that doesn't import dart:io here. |
| 67 // TODO(nweiz): Set the exit code on the VM when issue 6943 is fixed. |
| 68 new ConsoleReporter([suite]).run(); |
| 69 }); |
| 70 return _globalDeclarer; |
| 64 } | 71 } |
| 65 | 72 |
| 66 /// If `true`, stack traces are reformatted to be more readable. | 73 // TODO(nweiz): This and other top-level functions should throw exceptions if |
| 67 bool formatStacks = true; | 74 // they're called after the declarer has finished declaring. |
| 75 void test(String description, body()) => _declarer.test(description, body); |
| 68 | 76 |
| 69 /// If `true`, irrelevant frames are filtered from the stack trace. | 77 void group(String description, void body()) => |
| 70 /// | 78 _declarer.group(description, body); |
| 71 /// This does nothing if [formatStacks] is false. | |
| 72 bool filterStacks = true; | |
| 73 | 79 |
| 74 /// Separator used between group names and test names. | 80 void setUp(callback()) => _declarer.setUp(callback); |
| 75 String groupSep = ' '; | |
| 76 | 81 |
| 77 /// Sets the [Configuration] used by the unittest library. | 82 void tearDown(callback()) => _declarer.tearDown(callback); |
| 78 /// | |
| 79 /// Throws a [StateError] if there is an existing, incompatible value. | |
| 80 void set unittestConfiguration(Configuration value) { | |
| 81 if (identical(config, value)) return; | |
| 82 if (config != null) { | |
| 83 logMessage('Warning: The unittestConfiguration has already been set. New ' | |
| 84 'unittestConfiguration ignored.'); | |
| 85 } else { | |
| 86 environment.config = value; | |
| 87 } | |
| 88 } | |
| 89 | |
| 90 /// Logs [message] associated with the current test case. | |
| 91 /// | |
| 92 /// Tests should use this instead of [print]. | |
| 93 void logMessage(String message) => | |
| 94 config.onLogMessage(currentTestCase, message); | |
| 95 | |
| 96 /// The test cases that have been defined so far. | |
| 97 List<TestCase> get testCases => | |
| 98 new UnmodifiableListView<TestCase>(environment.testCases); | |
| 99 | |
| 100 /// The interval (in milliseconds) after which a non-microtask asynchronous | |
| 101 /// delay will be scheduled between tests. | |
| 102 /// | |
| 103 /// This is used to avoid starving the DOM or other non-microtask events. | |
| 104 const int BREATH_INTERVAL = 200; | |
| 105 | |
| 106 /// The [TestCase] currently being executed. | |
| 107 TestCase get currentTestCase => (environment.currentTestCaseIndex >= 0 && | |
| 108 environment.currentTestCaseIndex < testCases.length) | |
| 109 ? testCases[environment.currentTestCaseIndex] | |
| 110 : null; | |
| 111 | |
| 112 /// The same as [currentTestCase], but typed as an [InternalTestCase]. | |
| 113 InternalTestCase get _currentTestCase => currentTestCase as InternalTestCase; | |
| 114 | |
| 115 /// The result string for a passing test case. | |
| 116 const PASS = 'pass'; | |
| 117 | |
| 118 /// The result string for a failing test case. | |
| 119 const FAIL = 'fail'; | |
| 120 | |
| 121 /// The result string for an test case with an error. | |
| 122 const ERROR = 'error'; | |
| 123 | |
| 124 /// Creates a new test case with the given description and body. | |
| 125 /// | |
| 126 /// The description will be added to the descriptions of any surrounding | |
| 127 /// [group]s. | |
| 128 void test(String description, TestFunction body) { | |
| 129 _requireNotRunning(); | |
| 130 ensureInitialized(); | |
| 131 | |
| 132 if (environment.soloTestSeen && environment.soloNestingLevel == 0) return; | |
| 133 var testCase = new InternalTestCase( | |
| 134 testCases.length + 1, _fullDescription(description), body); | |
| 135 environment.testCases.add(testCase); | |
| 136 } | |
| 137 | |
| 138 /// Returns [description] with all of its group prefixes prepended. | |
| 139 String _fullDescription(String description) { | |
| 140 var group = environment.currentContext.fullName; | |
| 141 if (description == null) return group; | |
| 142 return group != '' ? '$group$groupSep$description' : description; | |
| 143 } | |
| 144 | |
| 145 /// A convenience function for skipping a test. | |
| 146 void skip_test(String spec, TestFunction body) {} | |
| 147 | |
| 148 /// Creates a new test case with the given description and body. | |
| 149 /// | |
| 150 /// If [solo_test] is used instead of [test], then all non-solo tests will be | |
| 151 /// disabled. Note that if [solo_group] is used as well, all tests in the group | |
| 152 /// will be enabled, regardless of whether they use [test] or [solo_test], or | |
| 153 /// whether they are in a nested [group] versus [solo_group]. Put another way, | |
| 154 /// if there are any calls to [solo_test] or [solo_group] in a test file, all | |
| 155 /// tests that are not inside a [solo_group] will be disabled unless they are | |
| 156 /// [solo_test]s. | |
| 157 void solo_test(String spec, TestFunction body) { | |
| 158 _requireNotRunning(); | |
| 159 ensureInitialized(); | |
| 160 if (!environment.soloTestSeen) { | |
| 161 environment.soloTestSeen = true; | |
| 162 // This is the first solo-ed test. Discard all tests up to now. | |
| 163 environment.testCases.clear(); | |
| 164 } | |
| 165 environment.soloNestingLevel++; | |
| 166 try { | |
| 167 test(spec, body); | |
| 168 } finally { | |
| 169 environment.soloNestingLevel--; | |
| 170 } | |
| 171 } | |
| 172 | |
| 173 /// Indicate that [callback] is expected to be called [count] number of times | |
| 174 /// (by default 1). | |
| 175 /// | |
| 176 /// The unittest framework will wait for the callback to run the [count] times | |
| 177 /// before it considers the current test to be complete. Using [expectAsync] | |
| 178 /// will also ensure that errors that occur within [callback] are tracked and | |
| 179 /// reported. [callback] may take up to six optional or required positional | |
| 180 /// arguments; named arguments are not supported. | |
| 181 /// | |
| 182 /// [max] can be used to specify an upper bound on the number of calls; if this | |
| 183 /// is exceeded the test will fail. If [max] is `0` (the default), the callback | |
| 184 /// is expected to be called exactly [count] times. If [max] is `-1`, the | |
| 185 /// callback is allowed to be called any number of times greater than [count]. | |
| 186 /// | |
| 187 /// Both [id] and [reason] are optional and provide extra information about the | |
| 188 /// callback when debugging. [id] should be the name of the callback, while | |
| 189 /// [reason] should be the reason the callback is expected to be called. | |
| 190 Function expectAsync(Function callback, | |
| 191 {int count: 1, int max: 0, String id, String reason}) => | |
| 192 new ExpectedFunction(callback, count, max, id: id, reason: reason).func; | |
| 193 | |
| 194 /// Indicate that [callback] is expected to be called until [isDone] returns | |
| 195 /// true. | |
| 196 /// | |
| 197 /// [isDone] is called after each time the function is run. Only when it returns | |
| 198 /// true will the callback be considered complete. Using [expectAsyncUntil] will | |
| 199 /// also ensure that errors that occur within [callback] are tracked and | |
| 200 /// reported. [callback] may take up to six optional or required positional | |
| 201 /// arguments; named arguments are not supported. | |
| 202 /// | |
| 203 /// Both [id] and [reason] are optional and provide extra information about the | |
| 204 /// callback when debugging. [id] should be the name of the callback, while | |
| 205 /// [reason] should be the reason the callback is expected to be called. | |
| 206 Function expectAsyncUntil(Function callback, bool isDone(), | |
| 207 {String id, String reason}) => new ExpectedFunction(callback, 0, -1, | |
| 208 id: id, reason: reason, isDone: isDone).func; | |
| 209 | |
| 210 /// Creates a group of tests. | |
| 211 /// | |
| 212 /// A group's description is included in the descriptions of any tests or | |
| 213 /// sub-groups it contains. [setUp] and [tearDown] are also scoped to the | |
| 214 /// containing group. | |
| 215 void group(String description, void body()) { | |
| 216 ensureInitialized(); | |
| 217 _requireNotRunning(); | |
| 218 environment.currentContext = | |
| 219 new GroupContext(environment.currentContext, description); | |
| 220 try { | |
| 221 body(); | |
| 222 } catch (e, trace) { | |
| 223 var stack = (trace == null) ? '' : ': ${trace.toString()}'; | |
| 224 environment.uncaughtErrorMessage = "${e.toString()}$stack"; | |
| 225 } finally { | |
| 226 // Now that the group is over, restore the previous one. | |
| 227 environment.currentContext = environment.currentContext.parent; | |
| 228 } | |
| 229 } | |
| 230 | |
| 231 /// A convenience function for skipping a group of tests. | |
| 232 void skip_group(String description, void body()) {} | |
| 233 | |
| 234 /// Creates a group of tests. | |
| 235 /// | |
| 236 /// If [solo_group] is used instead of [group], then all tests not declared with | |
| 237 /// [solo_test] or in a [solo_group] will be disabled. Note that all tests in a | |
| 238 /// [solo_group] will be run, regardless of whether they're declared with [test] | |
| 239 /// or [solo_test]. | |
| 240 /// | |
| 241 /// [skip_test] and [skip_group] take precedence over [solo_group]. | |
| 242 void solo_group(String description, void body()) { | |
| 243 _requireNotRunning(); | |
| 244 ensureInitialized(); | |
| 245 if (!environment.soloTestSeen) { | |
| 246 environment.soloTestSeen = true; | |
| 247 // This is the first solo-ed group. Discard all tests up to now. | |
| 248 environment.testCases.clear(); | |
| 249 } | |
| 250 ++environment.soloNestingLevel; | |
| 251 try { | |
| 252 group(description, body); | |
| 253 } finally { | |
| 254 --environment.soloNestingLevel; | |
| 255 } | |
| 256 } | |
| 257 | |
| 258 /// Registers a function to be run before tests. | |
| 259 /// | |
| 260 /// This function will be called before each test is run. [callback] may be | |
| 261 /// asynchronous; if so, it must return a [Future]. | |
| 262 /// | |
| 263 /// If this is called within a test group, it applies only to tests in that | |
| 264 /// group. [callback] will be run after any set-up callbacks in parent groups or | |
| 265 /// at the top level. | |
| 266 void setUp(Function callback) { | |
| 267 _requireNotRunning(); | |
| 268 environment.currentContext.testSetUp = callback; | |
| 269 } | |
| 270 | |
| 271 /// Registers a function to be run after tests. | |
| 272 /// | |
| 273 /// This function will be called after each test is run. [callback] may be | |
| 274 /// asynchronous; if so, it must return a [Future]. | |
| 275 /// | |
| 276 /// If this is called within a test group, it applies only to tests in that | |
| 277 /// group. [callback] will be run before any tear-down callbacks in parent group
s or | |
| 278 /// at the top level. | |
| 279 void tearDown(Function callback) { | |
| 280 _requireNotRunning(); | |
| 281 environment.currentContext.testTearDown = callback; | |
| 282 } | |
| 283 | |
| 284 /// Advance to the next test case. | |
| 285 void _nextTestCase() { | |
| 286 environment.currentTestCaseIndex++; | |
| 287 _runTest(); | |
| 288 } | |
| 289 | 83 |
| 290 /// Handle an error that occurs outside of any test. | 84 /// Handle an error that occurs outside of any test. |
| 291 void handleExternalError(e, String message, [stackTrace]) { | 85 void handleExternalError(error, String message, [stackTrace]) { |
| 292 var msg = '$message\nCaught $e'; | 86 // TODO(nweiz): handle this better. |
| 293 | 87 registerException(error, stackTrace); |
| 294 if (currentTestCase != null) { | |
| 295 _currentTestCase.error(msg, stackTrace); | |
| 296 } else { | |
| 297 environment.uncaughtErrorMessage = "$msg: $stackTrace"; | |
| 298 } | |
| 299 } | |
| 300 | |
| 301 /// Remove any tests that match [testFilter]. | |
| 302 /// | |
| 303 /// [testFilter] can be a predicate function, a [RegExp], or a [String]. If it's | |
| 304 /// a function, it's called with each [TestCase]. If it's a [String], it's | |
| 305 /// parsed as a [RegExp] and matched against each [TestCase.description]. | |
| 306 /// | |
| 307 /// This is different from enabling or disabling tests in that it removes the | |
| 308 /// tests completely. | |
| 309 void filterTests(testFilter) { | |
| 310 var filterFunction; | |
| 311 if (testFilter is String) { | |
| 312 var re = new RegExp(testFilter); | |
| 313 filterFunction = (t) => re.hasMatch(t.description); | |
| 314 } else if (testFilter is RegExp) { | |
| 315 filterFunction = (t) => testFilter.hasMatch(t.description); | |
| 316 } else if (testFilter is Function) { | |
| 317 filterFunction = testFilter; | |
| 318 } | |
| 319 environment.testCases.retainWhere(filterFunction); | |
| 320 } | |
| 321 | |
| 322 /// Runs all queued tests, one at a time. | |
| 323 void runTests() { | |
| 324 _requireNotRunning(); | |
| 325 _ensureInitialized(false); | |
| 326 environment.currentTestCaseIndex = 0; | |
| 327 config.onStart(); | |
| 328 _runTest(); | |
| 329 } | 88 } |
| 330 | 89 |
| 331 /// Registers an exception that was caught for the current test. | 90 /// Registers an exception that was caught for the current test. |
| 332 void registerException(error, [StackTrace stackTrace]) => | 91 void registerException(error, [StackTrace stackTrace]) => |
| 333 _currentTestCase.registerException(error, stackTrace); | 92 Invoker.current.handleError(error, stackTrace); |
| 334 | 93 |
| 335 /// Runs the next test. | 94 // What follows are stubs for various top-level names supported by unittest |
| 336 void _runTest() { | 95 // 0.11.*. These are preserved for the time being for ease of migration, but |
| 337 if (environment.currentTestCaseIndex >= testCases.length) { | 96 // should be removed before this is released as stable. |
| 338 assert(environment.currentTestCaseIndex == testCases.length); | |
| 339 _completeTests(); | |
| 340 return; | |
| 341 } | |
| 342 | 97 |
| 343 var testCase = _currentTestCase; | 98 @deprecated |
| 344 var f = runZoned(testCase.run, onError: (error, stack) { | 99 typedef dynamic TestFunction(); |
| 345 // TODO(kevmoo) Do a better job of flagging these are async errors. | |
| 346 // https://code.google.com/p/dart/issues/detail?id=16530 | |
| 347 testCase.registerException(error, stack); | |
| 348 }); | |
| 349 | 100 |
| 350 var timer; | 101 @deprecated |
| 351 var timeout = unittestConfiguration.timeout; | 102 Configuration unittestConfiguration = new Configuration(); |
| 352 if (timeout != null) { | |
| 353 try { | |
| 354 timer = new Timer(timeout, () { | |
| 355 testCase.error("Test timed out after ${timeout.inSeconds} seconds."); | |
| 356 _nextTestCase(); | |
| 357 }); | |
| 358 } on UnsupportedError catch (e) { | |
| 359 if (e.message != "Timer greater than 0.") rethrow; | |
| 360 // Support running on d8 and jsshell which don't support timers. | |
| 361 } | |
| 362 } | |
| 363 | 103 |
| 364 f.whenComplete(() { | 104 @deprecated |
| 365 if (timer != null) timer.cancel(); | 105 bool formatStacks = true; |
| 366 var now = new DateTime.now().millisecondsSinceEpoch; | |
| 367 if (now - environment.lastBreath >= BREATH_INTERVAL) { | |
| 368 environment.lastBreath = now; | |
| 369 Timer.run(_nextTestCase); | |
| 370 } else { | |
| 371 scheduleMicrotask(_nextTestCase); // Schedule the next test. | |
| 372 } | |
| 373 }); | |
| 374 } | |
| 375 | 106 |
| 376 /// Notify the configuration that the testing has finished. | 107 @deprecated |
| 377 void _completeTests() { | 108 bool filterStacks = true; |
| 378 if (!environment.initialized) return; | |
| 379 | 109 |
| 380 var passed = 0; | 110 @deprecated |
| 381 var failed = 0; | 111 String groupSep = ' '; |
| 382 var errors = 0; | |
| 383 for (var testCase in testCases) { | |
| 384 switch (testCase.result) { | |
| 385 case PASS: | |
| 386 passed++; | |
| 387 break; | |
| 388 case FAIL: | |
| 389 failed++; | |
| 390 break; | |
| 391 case ERROR: | |
| 392 errors++; | |
| 393 break; | |
| 394 } | |
| 395 } | |
| 396 | 112 |
| 397 config.onSummary( | 113 @deprecated |
| 398 passed, failed, errors, testCases, environment.uncaughtErrorMessage); | 114 void logMessage(String message) => print(message); |
| 399 config.onDone(passed > 0 && | |
| 400 failed == 0 && | |
| 401 errors == 0 && | |
| 402 environment.uncaughtErrorMessage == null); | |
| 403 environment.initialized = false; | |
| 404 environment.currentTestCaseIndex = -1; | |
| 405 } | |
| 406 | 115 |
| 407 /// Initializes the test environment if it hasn't already been initialized. | 116 @deprecated |
| 408 void ensureInitialized() { | 117 final testCases = []; |
| 409 _ensureInitialized(true); | |
| 410 } | |
| 411 | 118 |
| 412 /// Initializes the test environment. | 119 @deprecated |
| 413 /// | 120 const int BREATH_INTERVAL = 200; |
| 414 /// If [configAutoStart] is `true`, schedule a microtask to run the tests. This | |
| 415 /// microtask is expected to run after all the tests are defined. | |
| 416 void _ensureInitialized(bool configAutoStart) { | |
| 417 if (environment.initialized) return; | |
| 418 | 121 |
| 419 environment.initialized = true; | 122 @deprecated |
| 123 TestCase get currentTestCase => null; |
| 420 | 124 |
| 421 environment.uncaughtErrorMessage = null; | 125 @deprecated |
| 126 const PASS = 'pass'; |
| 422 | 127 |
| 423 unittestConfiguration.onInit(); | 128 @deprecated |
| 129 const FAIL = 'fail'; |
| 424 | 130 |
| 425 // Immediately queue the suite up. It will run after a timeout (i.e. after | 131 @deprecated |
| 426 // main() has returned). | 132 const ERROR = 'error'; |
| 427 if (configAutoStart && config.autoStart) scheduleMicrotask(runTests); | |
| 428 } | |
| 429 | 133 |
| 430 /// Remove all tests other than the one identified by [id]. | 134 @deprecated |
| 431 void setSoloTest(int id) => | 135 void skip_test(String spec, TestFunction body) {} |
| 432 environment.testCases.retainWhere((t) => t.id == id); | |
| 433 | 136 |
| 434 /// Enable the test identified by [id]. | 137 @deprecated |
| 435 void enableTest(int id) => _setTestEnabledState(id, enable: true); | 138 void solo_test(String spec, TestFunction body) => test(spec, body); |
| 436 | 139 |
| 437 /// Disable the test by [id]. | 140 @deprecated |
| 438 void disableTest(int id) => _setTestEnabledState(id, enable: false); | 141 void skip_group(String description, void body()) {} |
| 439 | 142 |
| 440 /// Enable or disable the test identified by [id]. | 143 @deprecated |
| 441 void _setTestEnabledState(int id, {bool enable: true}) { | 144 void solo_group(String description, void body()) => group(description, body); |
| 442 // Try fast path first. | |
| 443 if (testCases.length > id && testCases[id].id == id) { | |
| 444 environment.testCases[id].enabled = enable; | |
| 445 } else { | |
| 446 for (var i = 0; i < testCases.length; i++) { | |
| 447 if (testCases[i].id != id) continue; | |
| 448 environment.testCases[i].enabled = enable; | |
| 449 break; | |
| 450 } | |
| 451 } | |
| 452 } | |
| 453 | 145 |
| 454 /// Throws a [StateError] if tests are running. | 146 @deprecated |
| 455 void _requireNotRunning() { | 147 void filterTests(testFilter) {} |
| 456 if (environment.currentTestCaseIndex == -1) return; | |
| 457 throw new StateError('Not allowed when tests are running.'); | |
| 458 } | |
| 459 | 148 |
| 460 /// Creates a test environment running in its own zone scope. | 149 @deprecated |
| 461 /// | 150 void runTests() {} |
| 462 /// This allows for multiple invocations of the unittest library in the same | 151 |
| 463 /// application instance. This is useful when, for example, creating a test | 152 @deprecated |
| 464 /// runner application which needs to create a new pristine test environment on | 153 void ensureInitialized() {} |
| 465 /// each invocation to run a given set of tests. | 154 |
| 466 withTestEnvironment(callback()) { | 155 @deprecated |
| 467 return runZoned(callback, | 156 void setSoloTest(int id) {} |
| 468 zoneValues: {#unittest.environment: new TestEnvironment()}); | 157 |
| 469 } | 158 @deprecated |
| 159 void enableTest(int id) {} |
| 160 |
| 161 @deprecated |
| 162 void disableTest(int id) {} |
| 163 |
| 164 @deprecated |
| 165 withTestEnvironment(callback()) => callback(); |
| OLD | NEW |