OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2013, 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 library test; |
| 6 |
| 7 import 'dart:async'; |
| 8 |
| 9 import 'package:path/path.dart' as p; |
| 10 |
| 11 import 'src/backend/declarer.dart'; |
| 12 import 'src/backend/test_platform.dart'; |
| 13 import 'src/frontend/timeout.dart'; |
| 14 import 'src/runner/engine.dart'; |
| 15 import 'src/runner/reporter/expanded.dart'; |
| 16 import 'src/runner/runner_suite.dart'; |
| 17 import 'src/runner/vm/environment.dart'; |
| 18 import 'src/utils.dart'; |
| 19 |
| 20 export 'package:matcher/matcher.dart'; |
| 21 |
| 22 export 'src/frontend/expect.dart'; |
| 23 export 'src/frontend/expect_async.dart'; |
| 24 export 'src/frontend/future_matchers.dart'; |
| 25 export 'src/frontend/on_platform.dart'; |
| 26 export 'src/frontend/prints_matcher.dart'; |
| 27 export 'src/frontend/skip.dart'; |
| 28 export 'src/frontend/test_on.dart'; |
| 29 export 'src/frontend/throws_matcher.dart'; |
| 30 export 'src/frontend/throws_matchers.dart'; |
| 31 export 'src/frontend/timeout.dart'; |
| 32 |
| 33 /// The global declarer. |
| 34 /// |
| 35 /// This is used if a test file is run directly, rather than through the runner. |
| 36 Declarer _globalDeclarer; |
| 37 |
| 38 /// Gets the declarer for the current scope. |
| 39 /// |
| 40 /// When using the runner, this returns the [Zone]-scoped declarer that's set by |
| 41 /// [IsolateListener] or [IframeListener]. If the test file is run directly, |
| 42 /// this returns [_globalDeclarer] (and sets it up on the first call). |
| 43 Declarer get _declarer { |
| 44 var declarer = Zone.current[#test.declarer]; |
| 45 if (declarer != null) return declarer; |
| 46 if (_globalDeclarer != null) return _globalDeclarer; |
| 47 |
| 48 // Since there's no Zone-scoped declarer, the test file is being run directly. |
| 49 // In order to run the tests, we set up our own Declarer via |
| 50 // [_globalDeclarer], and schedule a microtask to run the tests once they're |
| 51 // finished being defined. |
| 52 _globalDeclarer = new Declarer(); |
| 53 scheduleMicrotask(() async { |
| 54 var suite = new RunnerSuite( |
| 55 // TODO(nweiz): Use a different environment if VM environment starts |
| 56 // import dart:io before cross-platform libraries exist. |
| 57 const VMEnvironment(), |
| 58 _globalDeclarer.tests, |
| 59 path: p.prettyUri(Uri.base), |
| 60 platform: TestPlatform.vm, |
| 61 os: currentOSGuess); |
| 62 |
| 63 var engine = new Engine(); |
| 64 engine.suiteSink.add(suite); |
| 65 engine.suiteSink.close(); |
| 66 ExpandedReporter.watch(engine, |
| 67 color: true, printPath: false, printPlatform: false); |
| 68 |
| 69 var success = await engine.run(); |
| 70 // TODO(nweiz): Set the exit code on the VM when issue 6943 is fixed. |
| 71 if (success) return; |
| 72 print(''); |
| 73 new Future.error("Dummy exception to set exit code."); |
| 74 }); |
| 75 return _globalDeclarer; |
| 76 } |
| 77 |
| 78 // TODO(nweiz): This and other top-level functions should throw exceptions if |
| 79 // they're called after the declarer has finished declaring. |
| 80 /// Creates a new test case with the given description and body. |
| 81 /// |
| 82 /// The description will be added to the descriptions of any surrounding |
| 83 /// [group]s. If [testOn] is passed, it's parsed as a [platform selector][]; the |
| 84 /// test will only be run on matching platforms. |
| 85 /// |
| 86 /// [platform selector]: https://github.com/dart-lang/test/#platform-selector-sy
ntax |
| 87 /// |
| 88 /// If [timeout] is passed, it's used to modify or replace the default timeout |
| 89 /// of 30 seconds. Timeout modifications take precedence in suite-group-test |
| 90 /// order, so [timeout] will also modify any timeouts set on the group or suite. |
| 91 /// |
| 92 /// If [skip] is a String or `true`, the test is skipped. If it's a String, it |
| 93 /// should explain why the test is skipped; this reason will be printed instead |
| 94 /// of running the test. |
| 95 /// |
| 96 /// [onPlatform] allows tests to be configured on a platform-by-platform |
| 97 /// basis. It's a map from strings that are parsed as [PlatformSelector]s to |
| 98 /// annotation classes: [Timeout], [Skip], or lists of those. These |
| 99 /// annotations apply only on the given platforms. For example: |
| 100 /// |
| 101 /// test("potentially slow test", () { |
| 102 /// // ... |
| 103 /// }, onPlatform: { |
| 104 /// // This test is especially slow on Windows. |
| 105 /// "windows": new Timeout.factor(2), |
| 106 /// "browser": [ |
| 107 /// new Skip("TODO: add browser support"), |
| 108 /// // This will be slow on browsers once it works on them. |
| 109 /// new Timeout.factor(2) |
| 110 /// ] |
| 111 /// }); |
| 112 /// |
| 113 /// If multiple platforms match, the annotations apply in order as through |
| 114 /// they were in nested groups. |
| 115 void test(String description, body(), {String testOn, Timeout timeout, |
| 116 skip, Map<String, dynamic> onPlatform}) => |
| 117 _declarer.test(description, body, |
| 118 testOn: testOn, timeout: timeout, skip: skip, onPlatform: onPlatform); |
| 119 |
| 120 /// Creates a group of tests. |
| 121 /// |
| 122 /// A group's description is included in the descriptions of any tests or |
| 123 /// sub-groups it contains. [setUp] and [tearDown] are also scoped to the |
| 124 /// containing group. |
| 125 /// |
| 126 /// If [testOn] is passed, it's parsed as a [platform selector][]; the test will |
| 127 /// only be run on matching platforms. |
| 128 /// |
| 129 /// [platform selector]: https://github.com/dart-lang/test/#platform-selector-sy
ntax |
| 130 /// |
| 131 /// If [timeout] is passed, it's used to modify or replace the default timeout |
| 132 /// of 30 seconds. Timeout modifications take precedence in suite-group-test |
| 133 /// order, so [timeout] will also modify any timeouts set on the suite, and will |
| 134 /// be modified by any timeouts set on individual tests. |
| 135 /// |
| 136 /// If [skip] is a String or `true`, the group is skipped. If it's a String, it |
| 137 /// should explain why the group is skipped; this reason will be printed instead |
| 138 /// of running the group's tests. |
| 139 /// |
| 140 /// [onPlatform] allows groups to be configured on a platform-by-platform |
| 141 /// basis. It's a map from strings that are parsed as [PlatformSelector]s to |
| 142 /// annotation classes: [Timeout], [Skip], or lists of those. These |
| 143 /// annotations apply only on the given platforms. For example: |
| 144 /// |
| 145 /// group("potentially slow tests", () { |
| 146 /// // ... |
| 147 /// }, onPlatform: { |
| 148 /// // These tests are especially slow on Windows. |
| 149 /// "windows": new Timeout.factor(2), |
| 150 /// "browser": [ |
| 151 /// new Skip("TODO: add browser support"), |
| 152 /// // They'll be slow on browsers once it works on them. |
| 153 /// new Timeout.factor(2) |
| 154 /// ] |
| 155 /// }); |
| 156 /// |
| 157 /// If multiple platforms match, the annotations apply in order as through |
| 158 /// they were in nested groups. |
| 159 void group(String description, void body(), {String testOn, Timeout timeout, |
| 160 skip, Map<String, dynamic> onPlatform}) => |
| 161 _declarer.group(description, body, |
| 162 testOn: testOn, timeout: timeout, skip: skip); |
| 163 |
| 164 /// Registers a function to be run before tests. |
| 165 /// |
| 166 /// This function will be called before each test is run. [callback] may be |
| 167 /// asynchronous; if so, it must return a [Future]. |
| 168 /// |
| 169 /// If this is called within a test group, it applies only to tests in that |
| 170 /// group. [callback] will be run after any set-up callbacks in parent groups or |
| 171 /// at the top level. |
| 172 void setUp(callback()) => _declarer.setUp(callback); |
| 173 |
| 174 /// Registers a function to be run after tests. |
| 175 /// |
| 176 /// This function will be called after each test is run. [callback] may be |
| 177 /// asynchronous; if so, it must return a [Future]. |
| 178 /// |
| 179 /// If this is called within a test group, it applies only to tests in that |
| 180 /// group. [callback] will be run before any tear-down callbacks in parent |
| 181 /// groups or at the top level. |
| 182 void tearDown(callback()) => _declarer.tearDown(callback); |
| 183 |
| 184 /// Registers an exception that was caught for the current test. |
| 185 void registerException(error, [StackTrace stackTrace]) { |
| 186 // This will usually forward directly to [Invoker.current.handleError], but |
| 187 // going through the zone API allows other zones to consistently see errors. |
| 188 Zone.current.handleUncaughtError(error, stackTrace); |
| 189 } |
OLD | NEW |