LCOV - code coverage report
Current view: top level - test-0.12.24+8/lib/src/backend - live_test_controller.dart (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 24 41 58.5 %
Date: 2017-10-10 20:17:03 Functions: 0 0 -

          Line data    Source code
       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
       3             : // BSD-style license that can be found in the LICENSE file.
       4             : 
       5             : import 'dart:async';
       6             : import 'dart:collection';
       7             : 
       8             : import 'package:stack_trace/stack_trace.dart';
       9             : 
      10             : import 'group.dart';
      11             : import 'live_test.dart';
      12             : import 'message.dart';
      13             : import 'state.dart';
      14             : import 'suite.dart';
      15             : import 'test.dart';
      16             : 
      17             : /// An implementation of [LiveTest] that's controlled by a [LiveTestController].
      18             : class _LiveTest extends LiveTest {
      19             :   final LiveTestController _controller;
      20             : 
      21          10 :   Suite get suite => _controller._suite;
      22             : 
      23           0 :   List<Group> get groups => _controller._groups;
      24             : 
      25          10 :   Test get test => _controller._test;
      26             : 
      27          10 :   State get state => _controller._state;
      28             : 
      29             :   Stream<State> get onStateChange =>
      30          15 :       _controller._onStateChangeController.stream;
      31             : 
      32           0 :   List<AsyncError> get errors => new UnmodifiableListView(_controller._errors);
      33             : 
      34          15 :   Stream<AsyncError> get onError => _controller._onErrorController.stream;
      35             : 
      36          15 :   Stream<Message> get onMessage => _controller._onMessageController.stream;
      37             : 
      38          15 :   Future get onComplete => _controller.completer.future;
      39             : 
      40          10 :   Future run() => _controller._run();
      41             : 
      42           0 :   Future close() => _controller._close();
      43             : 
      44           5 :   _LiveTest(this._controller);
      45             : }
      46             : 
      47             : /// A controller that drives a [LiveTest].
      48             : ///
      49             : /// This is a utility class to make it easier for implementors of [Test] to
      50             : /// create the [LiveTest] returned by [Test.load]. The [LiveTest] is accessible
      51             : /// through [LiveTestController.liveTest].
      52             : ///
      53             : /// This automatically handles some of [LiveTest]'s guarantees, but for the most
      54             : /// part it's the caller's responsibility to make sure everything gets
      55             : /// dispatched in the correct order.
      56             : class LiveTestController {
      57             :   /// The [LiveTest] controlled by [this].
      58           5 :   LiveTest get liveTest => _liveTest;
      59             :   LiveTest _liveTest;
      60             : 
      61             :   /// The test suite that's running [this].
      62             :   final Suite _suite;
      63             : 
      64             :   /// The groups containing [this].
      65             :   final List<Group> _groups;
      66             : 
      67             :   /// The test that's being run.
      68             :   final Test _test;
      69             : 
      70             :   /// The function that will actually start the test running.
      71             :   final Function _onRun;
      72             : 
      73             :   /// A function to run when the test is closed.
      74             :   ///
      75             :   /// This may be `null`.
      76             :   final Function _onClose;
      77             : 
      78             :   /// The list of errors caught by the test.
      79             :   final _errors = new List<AsyncError>();
      80             : 
      81             :   /// The current state of the test.
      82             :   var _state = const State(Status.pending, Result.success);
      83             : 
      84             :   /// The controller for [LiveTest.onStateChange].
      85             :   ///
      86             :   /// This is synchronous to ensure that events are well-ordered across multiple
      87             :   /// streams.
      88             :   final _onStateChangeController =
      89             :       new StreamController<State>.broadcast(sync: true);
      90             : 
      91             :   /// The controller for [LiveTest.onError].
      92             :   ///
      93             :   /// This is synchronous to ensure that events are well-ordered across multiple
      94             :   /// streams.
      95             :   final _onErrorController =
      96             :       new StreamController<AsyncError>.broadcast(sync: true);
      97             : 
      98             :   /// The controller for [LiveTest.onMessage].
      99             :   ///
     100             :   /// This is synchronous to ensure that events are well-ordered across multiple
     101             :   /// streams.
     102             :   final _onMessageController =
     103             :       new StreamController<Message>.broadcast(sync: true);
     104             : 
     105             :   /// The completer for [LiveTest.onComplete];
     106             :   final completer = new Completer();
     107             : 
     108             :   /// Whether [run] has been called.
     109             :   var _runCalled = false;
     110             : 
     111             :   /// Whether [close] has been called.
     112          10 :   bool get _isClosed => _onErrorController.isClosed;
     113             : 
     114             :   /// Creates a new controller for a [LiveTest].
     115             :   ///
     116             :   /// [test] is the test being run; [suite] is the suite that contains it.
     117             :   ///
     118             :   /// [onRun] is a function that's called from [LiveTest.run]. It should start
     119             :   /// the test running. The controller takes care of ensuring that
     120             :   /// [LiveTest.run] isn't called more than once and that [LiveTest.onComplete]
     121             :   /// is returned.
     122             :   ///
     123             :   /// [onClose] is a function that's called the first time [LiveTest.close] is
     124             :   /// called. It should clean up any resources that have been allocated for the
     125             :   /// test and ensure that the test finishes quickly if it's still running. It
     126             :   /// will only be called if [onRun] has been called first.
     127             :   ///
     128             :   /// If [groups] is passed, it's used to populate the list of groups that
     129             :   /// contain this test. Otherwise, `suite.group` is used.
     130             :   LiveTestController(Suite suite, this._test, void onRun(), void onClose(),
     131             :       {Iterable<Group> groups})
     132             :       : _suite = suite,
     133             :         _onRun = onRun,
     134             :         _onClose = onClose,
     135             :         _groups =
     136          10 :             groups == null ? [suite.group] : new List.unmodifiable(groups) {
     137          10 :     _liveTest = new _LiveTest(this);
     138             :   }
     139             : 
     140             :   /// Adds an error to the [LiveTest].
     141             :   ///
     142             :   /// This both adds the error to [LiveTest.errors] and emits it via
     143             :   /// [LiveTest.onError]. [stackTrace] is automatically converted into a [Chain]
     144             :   /// if it's not one already.
     145             :   void addError(error, StackTrace stackTrace) {
     146           0 :     if (_isClosed) return;
     147             : 
     148           0 :     var asyncError = new AsyncError(error, new Chain.forTrace(stackTrace));
     149           0 :     _errors.add(asyncError);
     150           0 :     _onErrorController.add(asyncError);
     151             :   }
     152             : 
     153             :   /// Sets the current state of the [LiveTest] to [newState].
     154             :   ///
     155             :   /// If [newState] is different than the old state, this both sets
     156             :   /// [LiveTest.state] and emits the new state via [LiveTest.onStateChanged]. If
     157             :   /// it's not different, this does nothing.
     158             :   void setState(State newState) {
     159           5 :     if (_isClosed) return;
     160          10 :     if (_state == newState) return;
     161             : 
     162           5 :     _state = newState;
     163          10 :     _onStateChangeController.add(newState);
     164             :   }
     165             : 
     166             :   /// Emits message over [LiveTest.onMessage].
     167             :   void message(Message message) {
     168           2 :     if (_onMessageController.hasListener) {
     169           2 :       _onMessageController.add(message);
     170             :     } else {
     171             :       // Make sure all messages get surfaced one way or another to aid in
     172             :       // debugging.
     173           0 :       Zone.ROOT.print(message.text);
     174             :     }
     175             :   }
     176             : 
     177             :   /// A wrapper for [_onRun] that ensures that it follows the guarantees for
     178             :   /// [LiveTest.run].
     179             :   Future _run() {
     180           5 :     if (_runCalled) {
     181           0 :       throw new StateError("LiveTest.run() may not be called more than once.");
     182           5 :     } else if (_isClosed) {
     183           0 :       throw new StateError("LiveTest.run() may not be called for a closed "
     184             :           "test.");
     185             :     }
     186           5 :     _runCalled = true;
     187             : 
     188          10 :     _onRun();
     189          10 :     return liveTest.onComplete;
     190             :   }
     191             : 
     192             :   /// A wrapper for [_onClose] that ensures that all controllers are closed.
     193             :   Future _close() {
     194           0 :     if (_isClosed) return completer.future;
     195             : 
     196           0 :     _onStateChangeController.close();
     197           0 :     _onErrorController.close();
     198             : 
     199           0 :     if (_runCalled) {
     200           0 :       _onClose();
     201             :     } else {
     202           0 :       completer.complete();
     203             :     }
     204             : 
     205           0 :     return completer.future;
     206             :   }
     207             : }

Generated by: LCOV version 1.13