LCOV - code coverage report
Current view: top level - test-0.12.24+8/lib/src/backend - declarer.dart (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 41 61 67.2 %
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             : 
       7             : import 'package:stack_trace/stack_trace.dart';
       8             : 
       9             : import '../frontend/timeout.dart';
      10             : import '../utils.dart';
      11             : import 'group.dart';
      12             : import 'group_entry.dart';
      13             : import 'invoker.dart';
      14             : import 'metadata.dart';
      15             : import 'test.dart';
      16             : 
      17             : /// A class that manages the state of tests as they're declared.
      18             : ///
      19             : /// A nested tree of Declarers tracks the current group, set-up, and tear-down
      20             : /// functions. Each Declarer in the tree corresponds to a group. This tree is
      21             : /// tracked by a zone-scoped "current" Declarer; the current declarer can be set
      22             : /// for a block using [Declarer.declare], and it can be accessed using
      23             : /// [Declarer.current].
      24             : class Declarer {
      25             :   /// The parent declarer, or `null` if this corresponds to the root group.
      26             :   final Declarer _parent;
      27             : 
      28             :   /// The name of the current test group, including the name of any parent
      29             :   /// groups.
      30             :   ///
      31             :   /// This is `null` if this is the root group.
      32             :   final String _name;
      33             : 
      34             :   /// The metadata for this group, including the metadata of any parent groups
      35             :   /// and of the test suite.
      36             :   final Metadata _metadata;
      37             : 
      38             :   /// The stack trace for this group.
      39             :   final Trace _trace;
      40             : 
      41             :   /// Whether to collect stack traces for [GroupEntry]s.
      42             :   final bool _collectTraces;
      43             : 
      44             :   /// Whether to disable retries of tests.
      45             :   final bool _noRetry;
      46             : 
      47             :   /// The set-up functions to run for each test in this group.
      48             :   final _setUps = new List<AsyncFunction>();
      49             : 
      50             :   /// The tear-down functions to run for each test in this group.
      51             :   final _tearDowns = new List<AsyncFunction>();
      52             : 
      53             :   /// The set-up functions to run once for this group.
      54             :   final _setUpAlls = new List<AsyncFunction>();
      55             : 
      56             :   /// The trace for the first call to [setUpAll].
      57             :   ///
      58             :   /// All [setUpAll]s are run in a single logical test, so they can only have
      59             :   /// one trace. The first trace is most often correct, since the first
      60             :   /// [setUpAll] is always run and the rest are only run if that one succeeds.
      61             :   Trace _setUpAllTrace;
      62             : 
      63             :   /// The tear-down functions to run once for this group.
      64             :   final _tearDownAlls = new List<AsyncFunction>();
      65             : 
      66             :   /// The trace for the first call to [tearDownAll].
      67             :   ///
      68             :   /// All [tearDownAll]s are run in a single logical test, so they can only have
      69             :   /// one trace. The first trace matches [_setUpAllTrace].
      70             :   Trace _tearDownAllTrace;
      71             : 
      72             :   /// The children of this group, either tests or sub-groups.
      73             :   final _entries = new List<GroupEntry>();
      74             : 
      75             :   /// Whether [build] has been called for this declarer.
      76             :   bool _built = false;
      77             : 
      78             :   /// The current zone-scoped declarer.
      79          10 :   static Declarer get current => Zone.current[#test.declarer];
      80             : 
      81             :   /// Creates a new declarer for the root group.
      82             :   ///
      83             :   /// This is the implicit group that exists outside of any calls to `group()`.
      84             :   /// If [metadata] is passed, it's used as the metadata for the implicit root
      85             :   /// group.
      86             :   ///
      87             :   /// If [collectTraces] is `true`, this will set [GroupEntry.trace] for all
      88             :   /// entries built by the declarer. Note that this can be noticeably slow when
      89             :   /// thousands of tests are being declared (see #457).
      90             :   ///
      91             :   /// If [noRetry] is `true` tests will be run at most once.
      92             :   Declarer({Metadata metadata, bool collectTraces: false, bool noRetry: false})
      93          10 :       : this._(null, null, metadata ?? new Metadata(), collectTraces, null,
      94             :             noRetry);
      95             : 
      96             :   Declarer._(this._parent, this._name, this._metadata, this._collectTraces,
      97           5 :       this._trace, this._noRetry);
      98             : 
      99             :   /// Runs [body] with this declarer as [Declarer.current].
     100             :   ///
     101             :   /// Returns the return value of [body].
     102          10 :   declare(body()) => runZoned(body, zoneValues: {#test.declarer: this});
     103             : 
     104             :   /// Defines a test case with the given name and body.
     105             :   void test(String name, body(),
     106             :       {String testOn,
     107             :       Timeout timeout,
     108             :       skip,
     109             :       Map<String, dynamic> onPlatform,
     110             :       tags,
     111             :       int retry}) {
     112           5 :     _checkNotBuilt("test");
     113             : 
     114          15 :     var metadata = _metadata.merge(new Metadata.parse(
     115             :         testOn: testOn,
     116             :         timeout: timeout,
     117             :         skip: skip,
     118             :         onPlatform: onPlatform,
     119             :         tags: tags,
     120           5 :         retry: _noRetry ? 0 : retry));
     121             : 
     122          20 :     _entries.add(new LocalTest(_prefix(name), metadata, () async {
     123           5 :       var parents = <Declarer>[];
     124           5 :       for (var declarer = this; declarer != null; declarer = declarer._parent) {
     125           5 :         parents.add(declarer);
     126             :       }
     127             : 
     128             :       // Register all tear-down functions in all declarers. Iterate through
     129             :       // parents outside-in so that the Invoker gets the functions in the order
     130             :       // they were declared in source.
     131          15 :       for (var declarer in parents.reversed) {
     132          10 :         for (var tearDown in declarer._tearDowns) {
     133           0 :           Invoker.current.addTearDown(tearDown);
     134             :         }
     135             :       }
     136             : 
     137          15 :       await Invoker.current.waitForOutstandingCallbacks(() async {
     138          10 :         await _runSetUps();
     139          10 :         await body();
     140           0 :       });
     141           5 :     }, trace: _collectTraces ? new Trace.current(2) : null));
     142             :   }
     143             : 
     144             :   /// Creates a group of tests.
     145             :   void group(String name, void body(),
     146             :       {String testOn,
     147             :       Timeout timeout,
     148             :       skip,
     149             :       Map<String, dynamic> onPlatform,
     150             :       tags,
     151             :       int retry}) {
     152           5 :     _checkNotBuilt("group");
     153             : 
     154          15 :     var metadata = _metadata.merge(new Metadata.parse(
     155             :         testOn: testOn,
     156             :         timeout: timeout,
     157             :         skip: skip,
     158             :         onPlatform: onPlatform,
     159             :         tags: tags,
     160             :         retry: retry));
     161           5 :     var trace = _collectTraces ? new Trace.current(2) : null;
     162             : 
     163           5 :     var declarer = new Declarer._(
     164          15 :         this, _prefix(name), metadata, _collectTraces, trace, _noRetry);
     165           5 :     declarer.declare(() {
     166             :       // Cast to dynamic to avoid the analyzer complaining about us using the
     167             :       // result of a void method.
     168           5 :       var result = (body as dynamic)();
     169           5 :       if (result is! Future) return;
     170           0 :       throw new ArgumentError("Groups may not be async.");
     171             :     });
     172          15 :     _entries.add(declarer.build());
     173             :   }
     174             : 
     175             :   /// Returns [name] prefixed with this declarer's group name.
     176          15 :   String _prefix(String name) => _name == null ? name : "$_name $name";
     177             : 
     178             :   /// Registers a function to be run before each test in this group.
     179             :   void setUp(callback()) {
     180           5 :     _checkNotBuilt("setUp");
     181          10 :     _setUps.add(callback);
     182             :   }
     183             : 
     184             :   /// Registers a function to be run after each test in this group.
     185             :   void tearDown(callback()) {
     186           0 :     _checkNotBuilt("tearDown");
     187           0 :     _tearDowns.add(callback);
     188             :   }
     189             : 
     190             :   /// Registers a function to be run once before all tests.
     191             :   void setUpAll(callback()) {
     192           0 :     _checkNotBuilt("setUpAll");
     193           0 :     if (_collectTraces) _setUpAllTrace ??= new Trace.current(2);
     194           0 :     _setUpAlls.add(callback);
     195             :   }
     196             : 
     197             :   /// Registers a function to be run once after all tests.
     198             :   void tearDownAll(callback()) {
     199           0 :     _checkNotBuilt("tearDownAll");
     200           0 :     if (_collectTraces) _tearDownAllTrace ??= new Trace.current(2);
     201           0 :     _tearDownAlls.add(callback);
     202             :   }
     203             : 
     204             :   /// Finalizes and returns the group being declared.
     205             :   Group build() {
     206           5 :     _checkNotBuilt("build");
     207             : 
     208           5 :     _built = true;
     209          20 :     return new Group(_name, _entries.toList(),
     210           5 :         metadata: _metadata,
     211           5 :         trace: _trace,
     212           5 :         setUpAll: _setUpAll,
     213           5 :         tearDownAll: _tearDownAll);
     214             :   }
     215             : 
     216             :   /// Throws a [StateError] if [build] has been called.
     217             :   ///
     218             :   /// [name] should be the name of the method being called.
     219             :   void _checkNotBuilt(String name) {
     220           5 :     if (!_built) return;
     221           0 :     throw new StateError("Can't call $name() once tests have begun running.");
     222             :   }
     223             : 
     224             :   /// Run the set-up functions for this and any parent groups.
     225             :   ///
     226             :   /// If no set-up functions are declared, this returns a [Future] that
     227             :   /// completes immediately.
     228             :   Future _runSetUps() async {
     229          20 :     if (_parent != null) await _parent._runSetUps();
     230          20 :     await Future.forEach(_setUps, (setUp) => setUp());
     231           0 :   }
     232             : 
     233             :   /// Returns a [Test] that runs the callbacks in [_setUpAll].
     234             :   Test get _setUpAll {
     235          10 :     if (_setUpAlls.isEmpty) return null;
     236             : 
     237           0 :     return new LocalTest(_prefix("(setUpAll)"), _metadata, () {
     238           0 :       return Future.forEach(_setUpAlls, (setUp) => setUp());
     239           0 :     }, trace: _setUpAllTrace);
     240             :   }
     241             : 
     242             :   /// Returns a [Test] that runs the callbacks in [_tearDownAll].
     243             :   Test get _tearDownAll {
     244          10 :     if (_tearDownAlls.isEmpty) return null;
     245             : 
     246           0 :     return new LocalTest(_prefix("(tearDownAll)"), _metadata, () {
     247           0 :       return Invoker.current.unclosable(() {
     248           0 :         return Future.forEach(_tearDownAlls.reversed, errorsDontStopTest);
     249             :       });
     250           0 :     }, trace: _tearDownAllTrace);
     251             :   }
     252             : }

Generated by: LCOV version 1.13