| Index: lib/src/test_case.dart
|
| diff --git a/lib/src/test_case.dart b/lib/src/test_case.dart
|
| index fc84ed7e7d03326f40604371ea788b3abc569808..37596ff599c434d206980fc2d7b0d661ace52e6b 100644
|
| --- a/lib/src/test_case.dart
|
| +++ b/lib/src/test_case.dart
|
| @@ -2,190 +2,54 @@
|
| // for details. All rights reserved. Use of this source code is governed by a
|
| // BSD-style license that can be found in the LICENSE file.
|
|
|
| -part of unittest;
|
| +library unittest.test_case;
|
|
|
| -/// Represents the state for an individual unit test.
|
| -///
|
| -/// Create by calling [test] or [solo_test].
|
| -class TestCase {
|
| - /// Identifier for this test.
|
| - final int id;
|
| +import '../unittest.dart';
|
|
|
| - /// A description of what the test is specifying.
|
| - final String description;
|
| -
|
| - /// The setup function to call before the test, if any.
|
| - Function _setUp;
|
| -
|
| - /// The teardown function to call after the test, if any.
|
| - Function _tearDown;
|
| +/// An individual unit test.
|
| +abstract class TestCase {
|
| + /// A unique numeric identifier for this test case.
|
| + int get id;
|
|
|
| - /// The body of the test case.
|
| - TestFunction _testFunction;
|
| -
|
| - /// Remaining number of callbacks functions that must reach a 'done' state
|
| - /// to wait for before the test completes.
|
| - int _callbackFunctionsOutstanding = 0;
|
| + /// A description of what the test is specifying.
|
| + String get description;
|
|
|
| - String _message = '';
|
| - /// Error or failure message.
|
| - String get message => _message;
|
| + /// The error or failure message for the tests.
|
| + ///
|
| + /// Initially an empty string.
|
| + String get message;
|
|
|
| - String _result;
|
| - /// One of [PASS], [FAIL], [ERROR], or [:null:] if the test hasn't run yet.
|
| - String get result => _result;
|
| + /// The result of the test case.
|
| + ///
|
| + /// If the test case has is completed, this will be one of [PASS], [FAIL], or
|
| + /// [ERROR]. Otherwise, it will be `null`.
|
| + String get result;
|
|
|
| /// Returns whether this test case passed.
|
| - bool get passed => _result == PASS;
|
| + bool get passed;
|
|
|
| - StackTrace _stackTrace;
|
| - /// Stack trace associated with this test, or [:null:] if it succeeded.
|
| - StackTrace get stackTrace => _stackTrace;
|
| + /// The stack trace for the error that caused this test case to fail, or
|
| + /// `null` if it succeeded.
|
| + StackTrace get stackTrace;
|
|
|
| - /// The group (or groups) under which this test is running.
|
| - final String currentGroup;
|
| + /// The name of the group within which this test is running.
|
| + String get currentGroup;
|
|
|
| - DateTime _startTime;
|
| - DateTime get startTime => _startTime;
|
| + /// The time the test case started running.
|
| + ///
|
| + /// `null` if the test hasn't yet begun running.
|
| + DateTime get startTime;
|
|
|
| - Duration _runningTime;
|
| - Duration get runningTime => _runningTime;
|
| + /// The amount of time the test case took.
|
| + ///
|
| + /// `null` if the test hasn't finished running.
|
| + Duration get runningTime;
|
|
|
| - bool _enabled = true;
|
| -
|
| - bool get enabled => _enabled;
|
| -
|
| - bool _doneTeardown = false;
|
| -
|
| - Completer _testComplete;
|
| -
|
| - TestCase._internal(this.id, this.description, this._testFunction)
|
| - : currentGroup = _environment.currentContext.fullName,
|
| - _setUp = _environment.currentContext.testSetup,
|
| - _tearDown = _environment.currentContext.testTeardown;
|
| + /// Whether this test is enabled.
|
| + ///
|
| + /// Disabled tests won't be run.
|
| + bool get enabled;
|
|
|
| + /// Whether this test case has finished running.
|
| bool get isComplete => !enabled || result != null;
|
| -
|
| - Function _errorHandler(String stage) => (e, stack) {
|
| - if (stack == null && e is Error) {
|
| - stack = e.stackTrace;
|
| - }
|
| - if (result == null || result == PASS) {
|
| - if (e is TestFailure) {
|
| - _fail("$e", stack);
|
| - } else {
|
| - _error("$stage failed: Caught $e", stack);
|
| - }
|
| - }
|
| - };
|
| -
|
| - /// Perform any associated [_setUp] function and run the test. Returns
|
| - /// a [Future] that can be used to schedule the next test. If the test runs
|
| - /// to completion synchronously, or is disabled, null is returned, to
|
| - /// tell unittest to schedule the next test immediately.
|
| - Future _run() {
|
| - if (!enabled) return new Future.value();
|
| -
|
| - _result = _stackTrace = null;
|
| - _message = '';
|
| -
|
| - // Avoid calling [new Future] to avoid issue 11911.
|
| - return new Future.value().then((_) {
|
| - if (_setUp != null) return _setUp();
|
| - }).catchError(_errorHandler('Setup')).then((_) {
|
| - // Skip the test if setup failed.
|
| - if (result != null) return new Future.value();
|
| - _config.onTestStart(this);
|
| - _startTime = new DateTime.now();
|
| - _runningTime = null;
|
| - ++_callbackFunctionsOutstanding;
|
| - var testReturn = _testFunction();
|
| - // If _testFunction() returned a future, we want to wait for it like we
|
| - // would a callback, so if a failure occurs while waiting, we can abort.
|
| - if (testReturn is Future) {
|
| - ++_callbackFunctionsOutstanding;
|
| - testReturn.catchError(_errorHandler('Test'))
|
| - .whenComplete(_markCallbackComplete);
|
| - }
|
| - }).catchError(_errorHandler('Test')).then((_) {
|
| - _markCallbackComplete();
|
| - if (result == null) {
|
| - // Outstanding callbacks exist; we need to return a Future.
|
| - _testComplete = new Completer();
|
| - return _testComplete.future.whenComplete(() {
|
| - if (_tearDown != null) {
|
| - return _tearDown();
|
| - }
|
| - }).catchError(_errorHandler('Teardown'));
|
| - } else if (_tearDown != null) {
|
| - return _tearDown();
|
| - }
|
| - }).catchError(_errorHandler('Teardown')).whenComplete(() {
|
| - _setUp = null;
|
| - _tearDown = null;
|
| - _testFunction = null;
|
| - });
|
| - }
|
| -
|
| - // Set the results, notify the config, and return true if this
|
| - // is the first time the result is being set.
|
| - void _setResult(String testResult, String messageText, StackTrace stack) {
|
| - _message = messageText;
|
| - _stackTrace = getTrace(stack, formatStacks, filterStacks);
|
| - if (_stackTrace == null) _stackTrace = stack;
|
| - if (result == null) {
|
| - _result = testResult;
|
| - _config.onTestResult(this);
|
| - } else {
|
| - _result = testResult;
|
| - _config.onTestResultChanged(this);
|
| - }
|
| - }
|
| -
|
| - void _complete(String testResult, [String messageText = '',
|
| - StackTrace stack]) {
|
| - if (runningTime == null) {
|
| - // The startTime can be `null` if an error happened during setup. In this
|
| - // case we simply report a running time of 0.
|
| - if (startTime != null) {
|
| - _runningTime = new DateTime.now().difference(startTime);
|
| - } else {
|
| - _runningTime = const Duration(seconds: 0);
|
| - }
|
| - }
|
| - _setResult(testResult, messageText, stack);
|
| - if (_testComplete != null) {
|
| - var t = _testComplete;
|
| - _testComplete = null;
|
| - t.complete(this);
|
| - }
|
| - }
|
| -
|
| - void _pass() {
|
| - _complete(PASS);
|
| - }
|
| -
|
| - void _fail(String messageText, [StackTrace stack]) {
|
| - if (result != null) {
|
| - String newMessage = (result == PASS)
|
| - ? 'Test failed after initially passing: $messageText'
|
| - : 'Test failed more than once: $messageText';
|
| - // TODO(gram): Should we combine the stack with the old one?
|
| - _complete(ERROR, newMessage, stack);
|
| - } else {
|
| - _complete(FAIL, messageText, stack);
|
| - }
|
| - }
|
| -
|
| - void _error(String messageText, [StackTrace stack]) {
|
| - _complete(ERROR, messageText, stack);
|
| - }
|
| -
|
| - void _markCallbackComplete() {
|
| - if (--_callbackFunctionsOutstanding == 0 && !isComplete) {
|
| - _pass();
|
| - }
|
| - }
|
| -
|
| - String toString() => _result != null ? "$description: $result" : description;
|
| }
|
|
|