Line data Source code
1 : // Copyright (c) 2021, 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:meta/meta.dart';
8 :
9 : import '../backend/configuration/timeout.dart';
10 : import '../backend/declarer.dart';
11 : import '../backend/invoker.dart';
12 :
13 : // test_core does not support running tests directly, so the Declarer should
14 : // always be on the Zone.
15 0 : Declarer get _declarer => Zone.current[#test.declarer] as Declarer;
16 :
17 : // TODO(nweiz): This and other top-level functions should throw exceptions if
18 : // they're called after the declarer has finished declaring.
19 : /// Creates a new test case with the given description (converted to a string)
20 : /// and body.
21 : ///
22 : /// The description will be added to the descriptions of any surrounding
23 : /// [group]s. If [testOn] is passed, it's parsed as a [platform selector][]; the
24 : /// test will only be run on matching platforms.
25 : ///
26 : /// [platform selector]: https://github.com/dart-lang/test/tree/master/pkgs/test#platform-selectors
27 : ///
28 : /// If [timeout] is passed, it's used to modify or replace the default timeout
29 : /// of 30 seconds. Timeout modifications take precedence in suite-group-test
30 : /// order, so [timeout] will also modify any timeouts set on the group or suite.
31 : ///
32 : /// If [skip] is a String or `true`, the test is skipped. If it's a String, it
33 : /// should explain why the test is skipped; this reason will be printed instead
34 : /// of running the test.
35 : ///
36 : /// If [tags] is passed, it declares user-defined tags that are applied to the
37 : /// test. These tags can be used to select or skip the test on the command line,
38 : /// or to do bulk test configuration. All tags should be declared in the
39 : /// [package configuration file][configuring tags]. The parameter can be an
40 : /// [Iterable] of tag names, or a [String] representing a single tag.
41 : ///
42 : /// If [retry] is passed, the test will be retried the provided number of times
43 : /// before being marked as a failure.
44 : ///
45 : /// [configuring tags]: https://github.com/dart-lang/test/blob/master/pkgs/test/doc/configuration.md#configuring-tags
46 : ///
47 : /// [onPlatform] allows tests to be configured on a platform-by-platform
48 : /// basis. It's a map from strings that are parsed as [PlatformSelector]s to
49 : /// annotation classes: [Timeout], [Skip], or lists of those. These
50 : /// annotations apply only on the given platforms. For example:
51 : ///
52 : /// test('potentially slow test', () {
53 : /// // ...
54 : /// }, onPlatform: {
55 : /// // This test is especially slow on Windows.
56 : /// 'windows': Timeout.factor(2),
57 : /// 'browser': [
58 : /// Skip('TODO: add browser support'),
59 : /// // This will be slow on browsers once it works on them.
60 : /// Timeout.factor(2)
61 : /// ]
62 : /// });
63 : ///
64 : /// If multiple platforms match, the annotations apply in order as through
65 : /// they were in nested groups.
66 : ///
67 : /// If the `solo` flag is `true`, only tests and groups marked as
68 : /// "solo" will be be run. This only restricts tests *within this test
69 : /// suite*—tests in other suites will run as normal. We recommend that users
70 : /// avoid this flag if possible and instead use the test runner flag `-n` to
71 : /// filter tests by name.
72 0 : @isTest
73 : void test(description, dynamic Function() body,
74 : {String? testOn,
75 : Timeout? timeout,
76 : skip,
77 : tags,
78 : Map<String, dynamic>? onPlatform,
79 : int? retry,
80 : @Deprecated('Debug only') bool solo = false}) {
81 0 : _declarer.test(description.toString(), body,
82 : testOn: testOn,
83 : timeout: timeout,
84 : skip: skip,
85 : onPlatform: onPlatform,
86 : tags: tags,
87 : retry: retry,
88 : solo: solo);
89 :
90 : // Force dart2js not to inline this function. We need it to be separate from
91 : // `main()` in JS stack traces in order to properly determine the line and
92 : // column where the test was defined. See sdk#26705.
93 : return;
94 : return; // ignore: dead_code
95 : }
96 :
97 : /// Creates a group of tests.
98 : ///
99 : /// A group's description (converted to a string) is included in the descriptions
100 : /// of any tests or sub-groups it contains. [setUp] and [tearDown] are also scoped
101 : /// to the containing group.
102 : ///
103 : /// If [testOn] is passed, it's parsed as a [platform selector][]; the test will
104 : /// only be run on matching platforms.
105 : ///
106 : /// [platform selector]: https://github.com/dart-lang/test/tree/master/pkgs/test#platform-selectors
107 : ///
108 : /// If [timeout] is passed, it's used to modify or replace the default timeout
109 : /// of 30 seconds. Timeout modifications take precedence in suite-group-test
110 : /// order, so [timeout] will also modify any timeouts set on the suite, and will
111 : /// be modified by any timeouts set on individual tests.
112 : ///
113 : /// If [skip] is a String or `true`, the group is skipped. If it's a String, it
114 : /// should explain why the group is skipped; this reason will be printed instead
115 : /// of running the group's tests.
116 : ///
117 : /// If [tags] is passed, it declares user-defined tags that are applied to the
118 : /// test. These tags can be used to select or skip the test on the command line,
119 : /// or to do bulk test configuration. All tags should be declared in the
120 : /// [package configuration file][configuring tags]. The parameter can be an
121 : /// [Iterable] of tag names, or a [String] representing a single tag.
122 : ///
123 : /// [configuring tags]: https://github.com/dart-lang/test/blob/master/pkgs/test/doc/configuration.md#configuring-tags
124 : ///
125 : /// [onPlatform] allows groups to be configured on a platform-by-platform
126 : /// basis. It's a map from strings that are parsed as [PlatformSelector]s to
127 : /// annotation classes: [Timeout], [Skip], or lists of those. These
128 : /// annotations apply only on the given platforms. For example:
129 : ///
130 : /// group('potentially slow tests', () {
131 : /// // ...
132 : /// }, onPlatform: {
133 : /// // These tests are especially slow on Windows.
134 : /// 'windows': Timeout.factor(2),
135 : /// 'browser': [
136 : /// Skip('TODO: add browser support'),
137 : /// // They'll be slow on browsers once it works on them.
138 : /// Timeout.factor(2)
139 : /// ]
140 : /// });
141 : ///
142 : /// If multiple platforms match, the annotations apply in order as through
143 : /// they were in nested groups.
144 : ///
145 : /// If the `solo` flag is `true`, only tests and groups marked as
146 : /// "solo" will be be run. This only restricts tests *within this test
147 : /// suite*—tests in other suites will run as normal. We recommend that users
148 : /// avoid this flag if possible, and instead use the test runner flag `-n` to
149 : /// filter tests by name.
150 0 : @isTestGroup
151 : void group(description, dynamic Function() body,
152 : {String? testOn,
153 : Timeout? timeout,
154 : skip,
155 : tags,
156 : Map<String, dynamic>? onPlatform,
157 : int? retry,
158 : @Deprecated('Debug only') bool solo = false}) {
159 0 : _declarer.group(description.toString(), body,
160 : testOn: testOn,
161 : timeout: timeout,
162 : skip: skip,
163 : tags: tags,
164 : onPlatform: onPlatform,
165 : retry: retry,
166 : solo: solo);
167 :
168 : // Force dart2js not to inline this function. We need it to be separate from
169 : // `main()` in JS stack traces in order to properly determine the line and
170 : // column where the test was defined. See sdk#26705.
171 : return;
172 : return; // ignore: dead_code
173 : }
174 :
175 : /// Registers a function to be run before tests.
176 : ///
177 : /// This function will be called before each test is run. [callback] may be
178 : /// asynchronous; if so, it must return a [Future].
179 : ///
180 : /// If this is called within a test group, it applies only to tests in that
181 : /// group. [callback] will be run after any set-up callbacks in parent groups or
182 : /// at the top level.
183 : ///
184 : /// Each callback at the top level or in a given group will be run in the order
185 : /// they were declared.
186 0 : void setUp(dynamic Function() callback) => _declarer.setUp(callback);
187 :
188 : /// Registers a function to be run after tests.
189 : ///
190 : /// This function will be called after each test is run. [callback] may be
191 : /// asynchronous; if so, it must return a [Future].
192 : ///
193 : /// If this is called within a test group, it applies only to tests in that
194 : /// group. [callback] will be run before any tear-down callbacks in parent
195 : /// groups or at the top level.
196 : ///
197 : /// Each callback at the top level or in a given group will be run in the
198 : /// reverse of the order they were declared.
199 : ///
200 : /// See also [addTearDown], which adds tear-downs to a running test.
201 0 : void tearDown(dynamic Function() callback) => _declarer.tearDown(callback);
202 :
203 : /// Registers a function to be run after the current test.
204 : ///
205 : /// This is called within a running test, and adds a tear-down only for the
206 : /// current test. It allows testing libraries to add cleanup logic as soon as
207 : /// there's something to clean up.
208 : ///
209 : /// The [callback] is run before any callbacks registered with [tearDown]. Like
210 : /// [tearDown], the most recently registered callback is run first.
211 : ///
212 : /// If this is called from within a [setUpAll] or [tearDownAll] callback, it
213 : /// instead runs the function after *all* tests in the current test suite.
214 0 : void addTearDown(dynamic Function() callback) {
215 0 : if (Invoker.current == null) {
216 0 : throw StateError('addTearDown() may only be called within a test.');
217 : }
218 :
219 0 : Invoker.current!.addTearDown(callback);
220 : }
221 :
222 : /// Registers a function to be run once before all tests.
223 : ///
224 : /// [callback] may be asynchronous; if so, it must return a [Future].
225 : ///
226 : /// If this is called within a test group, [callback] will run before all tests
227 : /// in that group. It will be run after any [setUpAll] callbacks in parent
228 : /// groups or at the top level. It won't be run if none of the tests in the
229 : /// group are run.
230 : ///
231 : /// **Note**: This function makes it very easy to accidentally introduce hidden
232 : /// dependencies between tests that should be isolated. In general, you should
233 : /// prefer [setUp], and only use [setUpAll] if the callback is prohibitively
234 : /// slow.
235 0 : void setUpAll(dynamic Function() callback) => _declarer.setUpAll(callback);
236 :
237 : /// Registers a function to be run once after all tests.
238 : ///
239 : /// If this is called within a test group, [callback] will run after all tests
240 : /// in that group. It will be run before any [tearDownAll] callbacks in parent
241 : /// groups or at the top level. It won't be run if none of the tests in the
242 : /// group are run.
243 : ///
244 : /// **Note**: This function makes it very easy to accidentally introduce hidden
245 : /// dependencies between tests that should be isolated. In general, you should
246 : /// prefer [tearDown], and only use [tearDownAll] if the callback is
247 : /// prohibitively slow.
248 0 : void tearDownAll(dynamic Function() callback) =>
249 0 : _declarer.tearDownAll(callback);
|