| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 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 | 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 test.backend.declarer; | 5 library test.backend.declarer; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import '../frontend/timeout.dart'; | 9 import '../frontend/timeout.dart'; |
| 10 import '../utils.dart'; | 10 import '../utils.dart'; |
| 11 import 'group.dart'; | 11 import 'group.dart'; |
| 12 import 'invoker.dart'; | 12 import 'invoker.dart'; |
| 13 import 'metadata.dart'; | 13 import 'metadata.dart'; |
| 14 import 'suite_entry.dart'; | 14 import 'group_entry.dart'; |
| 15 | 15 |
| 16 /// A class that manages the state of tests as they're declared. | 16 /// A class that manages the state of tests as they're declared. |
| 17 /// | 17 /// |
| 18 /// A nested tree of Declarers tracks the current group, set-up, and tear-down | 18 /// A nested tree of Declarers tracks the current group, set-up, and tear-down |
| 19 /// functions. Each Declarer in the tree corresponds to a group. This tree is | 19 /// functions. Each Declarer in the tree corresponds to a group. This tree is |
| 20 /// tracked by a zone-scoped "current" Declarer; the current declarer can be set | 20 /// tracked by a zone-scoped "current" Declarer; the current declarer can be set |
| 21 /// for a block using [Declarer.declare], and it can be accessed using | 21 /// for a block using [Declarer.declare], and it can be accessed using |
| 22 /// [Declarer.current]. | 22 /// [Declarer.current]. |
| 23 class Declarer { | 23 class Declarer { |
| 24 /// The parent declarer, or `null` if this corresponds to the root group. | 24 /// The parent declarer, or `null` if this corresponds to the root group. |
| 25 final Declarer _parent; | 25 final Declarer _parent; |
| 26 | 26 |
| 27 /// The name of the current test group, including the name of any parent | 27 /// The name of the current test group, including the name of any parent |
| 28 /// groups. | 28 /// groups. |
| 29 /// | 29 /// |
| 30 /// This is `null` if this is the root group. | 30 /// This is `null` if this is the root group. |
| 31 final String _name; | 31 final String _name; |
| 32 | 32 |
| 33 /// The metadata for this group, including the metadata of any parent groups | 33 /// The metadata for this group, including the metadata of any parent groups |
| 34 /// and of the test suite. | 34 /// and of the test suite. |
| 35 final Metadata _metadata; | 35 final Metadata _metadata; |
| 36 | 36 |
| 37 /// The set-up functions for this group. | 37 /// The set-up functions for this group. |
| 38 final _setUps = new List<AsyncFunction>(); | 38 final _setUps = new List<AsyncFunction>(); |
| 39 | 39 |
| 40 /// The tear-down functions for this group. | 40 /// The tear-down functions for this group. |
| 41 final _tearDowns = new List<AsyncFunction>(); | 41 final _tearDowns = new List<AsyncFunction>(); |
| 42 | 42 |
| 43 /// The children of this group, either tests or sub-groups. | 43 /// The children of this group, either tests or sub-groups. |
| 44 final _entries = new List<SuiteEntry>(); | 44 final _entries = new List<GroupEntry>(); |
| 45 | 45 |
| 46 /// Whether [build] has been called for this declarer. | 46 /// Whether [build] has been called for this declarer. |
| 47 bool _built = false; | 47 bool _built = false; |
| 48 | 48 |
| 49 /// The current zone-scoped declarer. | 49 /// The current zone-scoped declarer. |
| 50 static Declarer get current => Zone.current[#test.declarer]; | 50 static Declarer get current => Zone.current[#test.declarer]; |
| 51 | 51 |
| 52 /// Creates a new declarer for the root group. | 52 /// Creates a new declarer for the root group. |
| 53 /// | 53 /// |
| 54 /// This is the implicit group that exists outside of any calls to `group()`. | 54 /// This is the implicit group that exists outside of any calls to `group()`. |
| 55 /// [metadata] should be the suite's metadata, if available. | 55 /// If [metadata] is passed, it's used as the metadata for the implicit root |
| 56 /// group. |
| 56 Declarer([Metadata metadata]) | 57 Declarer([Metadata metadata]) |
| 57 : this._(null, null, metadata == null ? new Metadata() : metadata); | 58 : this._(null, null, metadata == null ? new Metadata() : metadata); |
| 58 | 59 |
| 59 Declarer._(this._parent, this._name, this._metadata); | 60 Declarer._(this._parent, this._name, this._metadata); |
| 60 | 61 |
| 61 /// Runs [body] with this declarer as [Declarer.current]. | 62 /// Runs [body] with this declarer as [Declarer.current]. |
| 62 /// | 63 /// |
| 63 /// Returns the return value of [body]. | 64 /// Returns the return value of [body]. |
| 64 declare(body()) => runZoned(body, zoneValues: {#test.declarer: this}); | 65 declare(body()) => runZoned(body, zoneValues: {#test.declarer: this}); |
| 65 | 66 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 91 Map<String, dynamic> onPlatform}) { | 92 Map<String, dynamic> onPlatform}) { |
| 92 if (_built) { | 93 if (_built) { |
| 93 throw new StateError("Can't call group() once tests have begun running."); | 94 throw new StateError("Can't call group() once tests have begun running."); |
| 94 } | 95 } |
| 95 | 96 |
| 96 var metadata = _metadata.merge(new Metadata.parse( | 97 var metadata = _metadata.merge(new Metadata.parse( |
| 97 testOn: testOn, timeout: timeout, skip: skip, onPlatform: onPlatform)); | 98 testOn: testOn, timeout: timeout, skip: skip, onPlatform: onPlatform)); |
| 98 | 99 |
| 99 // Don't load the tests for a skipped group. | 100 // Don't load the tests for a skipped group. |
| 100 if (metadata.skip) { | 101 if (metadata.skip) { |
| 101 _entries.add(new Group(name, metadata, [])); | 102 _entries.add(new Group(name, [], metadata: metadata)); |
| 102 return; | 103 return; |
| 103 } | 104 } |
| 104 | 105 |
| 105 var declarer = new Declarer._(this, _prefix(name), metadata); | 106 var declarer = new Declarer._(this, _prefix(name), metadata); |
| 106 declarer.declare(body); | 107 declarer.declare(body); |
| 107 _entries.add(new Group(declarer._name, metadata, declarer.build())); | 108 _entries.add(declarer.build()); |
| 108 } | 109 } |
| 109 | 110 |
| 110 /// Returns [name] prefixed with this declarer's group name. | 111 /// Returns [name] prefixed with this declarer's group name. |
| 111 String _prefix(String name) => _name == null ? name : "$_name $name"; | 112 String _prefix(String name) => _name == null ? name : "$_name $name"; |
| 112 | 113 |
| 113 /// Registers a function to be run before each test in this group. | 114 /// Registers a function to be run before each test in this group. |
| 114 void setUp(callback()) { | 115 void setUp(callback()) { |
| 115 if (_built) { | 116 if (_built) { |
| 116 throw new StateError("Can't call setUp() once tests have begun running."); | 117 throw new StateError("Can't call setUp() once tests have begun running."); |
| 117 } | 118 } |
| 118 | 119 |
| 119 _setUps.add(callback); | 120 _setUps.add(callback); |
| 120 } | 121 } |
| 121 | 122 |
| 122 /// Registers a function to be run after each test in this group. | 123 /// Registers a function to be run after each test in this group. |
| 123 void tearDown(callback()) { | 124 void tearDown(callback()) { |
| 124 if (_built) { | 125 if (_built) { |
| 125 throw new StateError( | 126 throw new StateError( |
| 126 "Can't call tearDown() once tests have begun running."); | 127 "Can't call tearDown() once tests have begun running."); |
| 127 } | 128 } |
| 128 | 129 |
| 129 _tearDowns.add(callback); | 130 _tearDowns.add(callback); |
| 130 } | 131 } |
| 131 | 132 |
| 132 /// Finalizes and returns the tests and groups being declared. | 133 /// Finalizes and returns the group being declared. |
| 133 List<SuiteEntry> build() { | 134 Group build() { |
| 134 if (_built) { | 135 if (_built) { |
| 135 throw new StateError("Can't call Declarer.build() more than once."); | 136 throw new StateError("Can't call Declarer.build() more than once."); |
| 136 } | 137 } |
| 137 | 138 |
| 138 _built = true; | 139 _built = true; |
| 139 return _entries.toList(); | 140 return new Group(_name, _entries.toList(), metadata: _metadata); |
| 140 } | 141 } |
| 141 | 142 |
| 142 /// Run the set-up functions for this and any parent groups. | 143 /// Run the set-up functions for this and any parent groups. |
| 143 /// | 144 /// |
| 144 /// If no set-up functions are declared, this returns a [Future] that | 145 /// If no set-up functions are declared, this returns a [Future] that |
| 145 /// completes immediately. | 146 /// completes immediately. |
| 146 Future _runSetUps() { | 147 Future _runSetUps() { |
| 147 // TODO(nweiz): Use async/await here once issue 23497 has been fixed in two | 148 // TODO(nweiz): Use async/await here once issue 23497 has been fixed in two |
| 148 // stable versions. | 149 // stable versions. |
| 149 if (_parent != null) { | 150 if (_parent != null) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 var completer = new Completer(); | 182 var completer = new Completer(); |
| 182 | 183 |
| 183 Invoker.current.addOutstandingCallback(); | 184 Invoker.current.addOutstandingCallback(); |
| 184 Invoker.current.waitForOutstandingCallbacks(() { | 185 Invoker.current.waitForOutstandingCallbacks(() { |
| 185 new Future.sync(body).whenComplete(completer.complete); | 186 new Future.sync(body).whenComplete(completer.complete); |
| 186 }).then((_) => Invoker.current.removeOutstandingCallback()); | 187 }).then((_) => Invoker.current.removeOutstandingCallback()); |
| 187 | 188 |
| 188 return completer.future; | 189 return completer.future; |
| 189 } | 190 } |
| 190 } | 191 } |
| OLD | NEW |