Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(710)

Side by Side Diff: pkg/scheduled_test/lib/scheduled_test.dart

Issue 12288061: Support nested tasks in scheduled_test. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 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 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 // TODO(nweiz): Add support for calling [schedule] while the schedule is already 5 // TODO(nweiz): Add support for calling [schedule] while the schedule is already
6 // running. 6 // running.
7 // TODO(nweiz): Port the non-Pub-specific scheduled test libraries from Pub. 7 // TODO(nweiz): Port the non-Pub-specific scheduled test libraries from Pub.
8 /// A package for writing readable tests of asynchronous behavior. 8 /// A package for writing readable tests of asynchronous behavior.
9 /// 9 ///
10 /// This package works by building up a queue of asynchronous tasks called a 10 /// This package works by building up a queue of asynchronous tasks called a
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
102 /// }); 102 /// });
103 /// }); 103 /// });
104 /// } 104 /// }
105 /// 105 ///
106 /// ## Out-of-Band Callbacks 106 /// ## Out-of-Band Callbacks
107 /// 107 ///
108 /// Sometimes your tests will have callbacks that don't fit into the schedule. 108 /// Sometimes your tests will have callbacks that don't fit into the schedule.
109 /// It's important that errors in these callbacks are still registered, though, 109 /// It's important that errors in these callbacks are still registered, though,
110 /// and that [Schedule.onException] and [Schedule.onComplete] still run after 110 /// and that [Schedule.onException] and [Schedule.onComplete] still run after
111 /// they finish. When using `unittest`, you wrap these callbacks with 111 /// they finish. When using `unittest`, you wrap these callbacks with
112 /// `expectAsyncN`; when using `scheduled_test`, you use [wrapAsync]. 112 /// `expectAsyncN`; when using `scheduled_test`, you use [wrapAsync] or
113 /// [wrapFuture].
113 /// 114 ///
114 /// [wrapAsync] has two important functions. First, any errors that occur in it 115 /// [wrapAsync] has two important functions. First, any errors that occur in it
115 /// will be passed into the [Schedule] instead of causing the whole test to 116 /// will be passed into the [Schedule] instead of causing the whole test to
116 /// crash. They can then be handled by [Schedule.onException] and 117 /// crash. They can then be handled by [Schedule.onException] and
117 /// [Schedule.onComplete]. Second, a task queue isn't considered finished until 118 /// [Schedule.onComplete]. Second, a task queue isn't considered finished until
118 /// all of its [wrapAsync]-wrapped functions have been called. This ensures that 119 /// all of its [wrapAsync]-wrapped functions have been called. This ensures that
119 /// [Schedule.onException] and [Schedule.onComplete] will always run after all 120 /// [Schedule.onException] and [Schedule.onComplete] will always run after all
120 /// the test code in the main queue. 121 /// the test code in the main queue.
121 /// 122 ///
122 /// Note that the [completes], [completion], and [throws] matchers use 123 /// Note that the [completes], [completion], and [throws] matchers use
123 /// [wrapAsync] internally, so they're safe to use in conjunction with scheduled 124 /// [wrapAsync] internally, so they're safe to use in conjunction with scheduled
124 /// tests. 125 /// tests.
125 /// 126 ///
126 /// Here's an example of a test using [wrapAsync] to catch errors thrown in the 127 /// Here's an example of a test using [wrapAsync] to catch errors thrown in the
127 /// callback of a fictional `startServer` function: 128 /// callback of a fictional `startServer` function:
128 /// 129 ///
129 /// import 'package:scheduled_test/scheduled_test.dart'; 130 /// import 'package:scheduled_test/scheduled_test.dart';
130 /// 131 ///
131 /// void main() { 132 /// void main() {
132 /// test('sendRequest sends a request', () { 133 /// test('sendRequest sends a request', () {
133 /// startServer(wrapAsync((request) { 134 /// startServer(wrapAsync((request) {
134 /// expect(request.body, equals('payload')); 135 /// expect(request.body, equals('payload'));
135 /// request.response.close(); 136 /// request.response.close();
136 /// })); 137 /// }));
137 /// 138 ///
138 /// schedule(() => sendRequest('payload')); 139 /// schedule(() => sendRequest('payload'));
139 /// }); 140 /// });
140 /// } 141 /// }
141 /// 142 ///
143 /// [wrapFuture] works similarly to [wrapAsync], but instead of wrapping a
144 /// single callback it wraps a whole [Future] chain. Like [wrapAsync], it
145 /// ensures that the task quque doesn't complete until the out-of-band chain has
Bob Nystrom 2013/02/19 23:15:04 "quque" -> "queue"
nweiz 2013/02/20 00:23:12 Done.
146 /// finished, and that any errors in the chain are piped back into the scheduled
147 /// test. For example:
148 ///
149 /// import 'package:scheduled_test/scheduled_test.dart';
150 ///
151 /// void main() {
152 /// test('sendRequest sends a request', () {
153 /// wrapFuture(server.nextRequest.then((request) {
154 /// expect(request.body, equals('payload'));
155 /// expect(request.headers['content-type'], equals('text/plain'));
156 /// }));
157 ///
158 /// schedule(() => sendRequest('payload'));
159 /// });
160 /// }
161 ///
142 /// ## Timeouts 162 /// ## Timeouts
143 /// 163 ///
144 /// `scheduled_test` has a built-in timeout of 30 seconds (configurable via 164 /// `scheduled_test` has a built-in timeout of 30 seconds (configurable via
145 /// [Schedule.timeout]). This timeout is aware of the structure of the schedule; 165 /// [Schedule.timeout]). This timeout is aware of the structure of the schedule;
146 /// this means that it will reset for each task in a queue, when moving between 166 /// this means that it will reset for each task in a queue, when moving between
147 /// queues, or almost any other sort of interaction with [currentSchedule]. As 167 /// queues, or almost any other sort of interaction with [currentSchedule]. As
148 /// long as the [Schedule] knows your test is making some sort of progress, it 168 /// long as the [Schedule] knows your test is making some sort of progress, it
149 /// won't time out. 169 /// won't time out.
150 /// 170 ///
151 /// If a single task might take a long time, you can also manually tell the 171 /// If a single task might take a long time, you can also manually tell the
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 /// [fn] returns a [Future], tasks after it won't be run until that [Future] 257 /// [fn] returns a [Future], tasks after it won't be run until that [Future]
238 /// completes. 258 /// completes.
239 /// 259 ///
240 /// The return value will be completed once the scheduled task has finished 260 /// The return value will be completed once the scheduled task has finished
241 /// running. Its return value is the same as the return value of [fn], or the 261 /// running. Its return value is the same as the return value of [fn], or the
242 /// value it completes to if it's a [Future]. 262 /// value it completes to if it's a [Future].
243 /// 263 ///
244 /// If [description] is passed, it's used to describe the task for debugging 264 /// If [description] is passed, it's used to describe the task for debugging
245 /// purposes when an error occurs. 265 /// purposes when an error occurs.
246 /// 266 ///
247 /// This function is identical to [currentSchedule.tasks.schedule]. 267 /// If this is called when a task queue is currently running, it will run [fn]
268 /// on the next event loop iteration rather than adding it to a queue. The
269 /// current task will not complete until [fn] (and any [Future] it returns) has
270 /// finished running. Any errors in [fn] will automatically be handled.
248 Future schedule(fn(), [String description]) => 271 Future schedule(fn(), [String description]) =>
249 currentSchedule.tasks.schedule(fn, description); 272 currentSchedule.tasks.schedule(fn, description);
250 273
251 /// Register a [setUp] function for a test [group]. This has the same semantics 274 /// Register a [setUp] function for a test [group]. This has the same semantics
252 /// as [unittest.setUp]. Tasks may be scheduled using [schedule] within 275 /// as [unittest.setUp]. Tasks may be scheduled using [schedule] within
253 /// [setUpFn], and [currentSchedule] may be accessed as well. 276 /// [setUpFn], and [currentSchedule] may be accessed as well.
254 /// 277 ///
255 /// Note that there is no associated [tearDown] function. Instead, tasks should 278 /// Note that there is no associated [tearDown] function. Instead, tasks should
256 /// be scheduled for [currentSchedule.onComplete] or 279 /// be scheduled for [currentSchedule.onComplete] or
257 /// [currentSchedule.onException]. These tasks will be run after each test's 280 /// [currentSchedule.onException]. These tasks will be run after each test's
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 unittest.ensureInitialized(); 318 unittest.ensureInitialized();
296 unittest.wrapAsync = (f) { 319 unittest.wrapAsync = (f) {
297 if (currentSchedule == null) { 320 if (currentSchedule == null) {
298 throw new StateError("Unexpected call to wrapAsync with no current " 321 throw new StateError("Unexpected call to wrapAsync with no current "
299 "schedule."); 322 "schedule.");
300 } 323 }
301 324
302 return currentSchedule.wrapAsync(f); 325 return currentSchedule.wrapAsync(f);
303 }; 326 };
304 } 327 }
328
329 /// Like [wrapAsync], this ensures that the current task queue waits for
330 /// out-of-band asynchronous code, and that errors raised in that code are
331 /// handled correctly. However, [wrapFuture] wraps a [Future] chain rather than
332 /// a single callback.
333 ///
334 /// The returned [Future] completes to the same value or error as [future].
335 Future wrapFuture(Future future) {
336 if (currentSchedule == null) {
337 throw new StateError("Unexpected call to wrapFuture with no current "
338 "schedule.");
339 }
340
341 return currentSchedule.wrapFuture(future);
342 }
OLDNEW
« no previous file with comments | « no previous file | pkg/scheduled_test/lib/src/future_group.dart » ('j') | pkg/scheduled_test/lib/src/future_group.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698