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 '../backend/invoker.dart';
8 : import 'expect.dart';
9 :
10 : /// An object used to detect unpassed arguments.
11 : const _PLACEHOLDER = const Object();
12 :
13 : // Function types returned by expectAsync# methods.
14 :
15 : typedef T Func0<T>();
16 : typedef T Func1<T, A>([A a]);
17 : typedef T Func2<T, A, B>([A a, B b]);
18 : typedef T Func3<T, A, B, C>([A a, B b, C c]);
19 : typedef T Func4<T, A, B, C, D>([A a, B b, C c, D d]);
20 : typedef T Func5<T, A, B, C, D, E>([A a, B b, C c, D d, E e]);
21 : typedef T Func6<T, A, B, C, D, E, F>([A a, B b, C c, D d, E e, F f]);
22 :
23 : // Functions used to check how many arguments a callback takes. We can't use the
24 : // previous functions for this, because (a) {} is not a subtype of
25 : // ([dynamic]) -> dynamic.
26 :
27 : typedef _Func0();
28 : typedef _Func1(Null a);
29 : typedef _Func2(Null a, Null b);
30 : typedef _Func3(Null a, Null b, Null c);
31 : typedef _Func4(Null a, Null b, Null c, Null d);
32 : typedef _Func5(Null a, Null b, Null c, Null d, Null e);
33 : typedef _Func6(Null a, Null b, Null c, Null d, Null e, Null f);
34 :
35 : typedef bool _IsDoneCallback();
36 :
37 : /// A wrapper for a function that ensures that it's called the appropriate
38 : /// number of times.
39 : ///
40 : /// The containing test won't be considered to have completed successfully until
41 : /// this function has been called the appropriate number of times.
42 : ///
43 : /// The wrapper function is accessible via [func]. It supports up to six
44 : /// optional and/or required positional arguments, but no named arguments.
45 : class _ExpectedFunction<T> {
46 : /// The wrapped callback.
47 : final Function _callback;
48 :
49 : /// The minimum number of calls that are expected to be made to the function.
50 : ///
51 : /// If fewer calls than this are made, the test will fail.
52 : final int _minExpectedCalls;
53 :
54 : /// The maximum number of calls that are expected to be made to the function.
55 : ///
56 : /// If more calls than this are made, the test will fail.
57 : final int _maxExpectedCalls;
58 :
59 : /// A callback that should return whether the function is not expected to have
60 : /// any more calls.
61 : ///
62 : /// This will be called after every time the function is run. The test case
63 : /// won't be allowed to terminate until it returns `true`.
64 : ///
65 : /// This may be `null`. If so, the function is considered to be done after
66 : /// it's been run once.
67 : final _IsDoneCallback _isDone;
68 :
69 : /// A descriptive name for the function.
70 : final String _id;
71 :
72 : /// An optional description of why the function is expected to be called.
73 : ///
74 : /// If not passed, this will be an empty string.
75 : final String _reason;
76 :
77 : /// The number of times the function has been called.
78 : int _actualCalls = 0;
79 :
80 : /// The test invoker in which this function was wrapped.
81 0 : Invoker get _invoker => _zone[#test.invoker];
82 :
83 : /// The zone in which this function was wrapped.
84 : final Zone _zone;
85 :
86 : /// Whether this function has been called the requisite number of times.
87 : bool _complete;
88 :
89 : /// Wraps [callback] in a function that asserts that it's called at least
90 : /// [minExpected] times and no more than [maxExpected] times.
91 : ///
92 : /// If passed, [id] is used as a descriptive name fo the function and [reason]
93 : /// as a reason it's expected to be called. If [isDone] is passed, the test
94 : /// won't be allowed to complete until it returns `true`.
95 : _ExpectedFunction(Function callback, int minExpected, int maxExpected,
96 : {String id, String reason, bool isDone()})
97 : : this._callback = callback,
98 : _minExpectedCalls = minExpected,
99 : _maxExpectedCalls =
100 0 : (maxExpected == 0 && minExpected > 0) ? minExpected : maxExpected,
101 : this._isDone = isDone,
102 0 : this._reason = reason == null ? '' : '\n$reason',
103 0 : this._zone = Zone.current,
104 0 : this._id = _makeCallbackId(id, callback) {
105 0 : if (_invoker == null) {
106 0 : throw new StateError("[expectAsync] was called outside of a test.");
107 0 : } else if (maxExpected > 0 && minExpected > maxExpected) {
108 0 : throw new ArgumentError("max ($maxExpected) may not be less than count "
109 0 : "($minExpected).");
110 : }
111 :
112 0 : if (isDone != null || minExpected > 0) {
113 0 : _invoker.addOutstandingCallback();
114 0 : _complete = false;
115 : } else {
116 0 : _complete = true;
117 : }
118 : }
119 :
120 : /// Tries to find a reasonable name for [callback].
121 : ///
122 : /// If [id] is passed, uses that. Otherwise, tries to determine a name from
123 : /// calling `toString`. If no name can be found, returns the empty string.
124 : static String _makeCallbackId(String id, Function callback) {
125 0 : if (id != null) return "$id ";
126 :
127 : // If the callback is not an anonymous closure, try to get the
128 : // name.
129 0 : var toString = callback.toString();
130 : var prefix = "Function '";
131 0 : var start = toString.indexOf(prefix);
132 0 : if (start == -1) return '';
133 :
134 0 : start += prefix.length;
135 0 : var end = toString.indexOf("'", start);
136 0 : if (end == -1) return '';
137 0 : return "${toString.substring(start, end)} ";
138 : }
139 :
140 : /// Returns a function that has the same number of positional arguments as the
141 : /// wrapped function (up to a total of 6).
142 : Function get func {
143 0 : if (_callback is _Func6) return max6;
144 0 : if (_callback is _Func5) return max5;
145 0 : if (_callback is _Func4) return max4;
146 0 : if (_callback is _Func3) return max3;
147 0 : if (_callback is _Func2) return max2;
148 0 : if (_callback is _Func1) return max1;
149 0 : if (_callback is _Func0) return max0;
150 :
151 0 : _invoker.removeOutstandingCallback();
152 0 : throw new ArgumentError(
153 : 'The wrapped function has more than 6 required arguments');
154 : }
155 :
156 : // This indirection is critical. It ensures the returned function has an
157 : // argument count of zero.
158 0 : T max0() => max6();
159 :
160 0 : T max1([Object a0 = _PLACEHOLDER]) => max6(a0);
161 :
162 0 : T max2([Object a0 = _PLACEHOLDER, Object a1 = _PLACEHOLDER]) => max6(a0, a1);
163 :
164 : T max3(
165 : [Object a0 = _PLACEHOLDER,
166 : Object a1 = _PLACEHOLDER,
167 : Object a2 = _PLACEHOLDER]) =>
168 0 : max6(a0, a1, a2);
169 :
170 : T max4(
171 : [Object a0 = _PLACEHOLDER,
172 : Object a1 = _PLACEHOLDER,
173 : Object a2 = _PLACEHOLDER,
174 : Object a3 = _PLACEHOLDER]) =>
175 0 : max6(a0, a1, a2, a3);
176 :
177 : T max5(
178 : [Object a0 = _PLACEHOLDER,
179 : Object a1 = _PLACEHOLDER,
180 : Object a2 = _PLACEHOLDER,
181 : Object a3 = _PLACEHOLDER,
182 : Object a4 = _PLACEHOLDER]) =>
183 0 : max6(a0, a1, a2, a3, a4);
184 :
185 : T max6(
186 : [Object a0 = _PLACEHOLDER,
187 : Object a1 = _PLACEHOLDER,
188 : Object a2 = _PLACEHOLDER,
189 : Object a3 = _PLACEHOLDER,
190 : Object a4 = _PLACEHOLDER,
191 : Object a5 = _PLACEHOLDER]) =>
192 0 : _run([a0, a1, a2, a3, a4, a5].where((a) => a != _PLACEHOLDER));
193 :
194 : /// Runs the wrapped function with [args] and returns its return value.
195 : T _run(Iterable args) {
196 : // Note that in the old test, this returned `null` if it encountered an
197 : // error, where now it just re-throws that error because Zone machinery will
198 : // pass it to the invoker anyway.
199 : try {
200 0 : _actualCalls++;
201 0 : if (_invoker.liveTest.state.shouldBeDone) {
202 0 : throw 'Callback ${_id}called ($_actualCalls) after test case '
203 0 : '${_invoker.liveTest.test.name} had already completed.$_reason';
204 0 : } else if (_maxExpectedCalls >= 0 && _actualCalls > _maxExpectedCalls) {
205 0 : throw new TestFailure('Callback ${_id}called more times than expected '
206 0 : '($_maxExpectedCalls).$_reason');
207 : }
208 :
209 0 : return Function.apply(_callback, args.toList()) as T;
210 : } catch (error, stackTrace) {
211 0 : _zone.handleUncaughtError(error, stackTrace);
212 : return null;
213 : } finally {
214 0 : _afterRun();
215 : }
216 : }
217 :
218 : /// After each time the function is run, check to see if it's complete.
219 : void _afterRun() {
220 0 : if (_complete) return;
221 0 : if (_minExpectedCalls > 0 && _actualCalls < _minExpectedCalls) return;
222 0 : if (_isDone != null && !_isDone()) return;
223 :
224 : // Mark this callback as complete and remove it from the test case's
225 : // oustanding callback count; if that hits zero the test is done.
226 0 : _complete = true;
227 0 : _invoker.removeOutstandingCallback();
228 : }
229 : }
230 :
231 : /// This function is deprecated because it doesn't work well with strong mode.
232 : /// Use [expectAsync0], [expectAsync1],
233 : /// [expectAsync2], [expectAsync3], [expectAsync4], [expectAsync5], or
234 : /// [expectAsync6] instead.
235 : @Deprecated("Will be removed in 0.13.0")
236 : Function expectAsync(Function callback,
237 : {int count: 1, int max: 0, String id, String reason}) {
238 0 : if (Invoker.current == null) {
239 0 : throw new StateError("expectAsync() may only be called within a test.");
240 : }
241 :
242 0 : return new _ExpectedFunction(callback, count, max, id: id, reason: reason)
243 0 : .func;
244 : }
245 :
246 : /// Informs the framework that the given [callback] of arity 0 is expected to be
247 : /// called [count] number of times (by default 1).
248 : ///
249 : /// Returns a wrapped function that should be used as a replacement of the
250 : /// original callback.
251 : ///
252 : /// The test framework will wait for the callback to run the [count] times
253 : /// before it considers the current test to be complete.
254 : ///
255 : /// [max] can be used to specify an upper bound on the number of calls; if this
256 : /// is exceeded the test will fail. If [max] is `0` (the default), the callback
257 : /// is expected to be called exactly [count] times. If [max] is `-1`, the
258 : /// callback is allowed to be called any number of times greater than [count].
259 : ///
260 : /// Both [id] and [reason] are optional and provide extra information about the
261 : /// callback when debugging. [id] should be the name of the callback, while
262 : /// [reason] should be the reason the callback is expected to be called.
263 : ///
264 : /// This method takes callbacks with zero arguments. See also
265 : /// [expectAsync1], [expectAsync2], [expectAsync3], [expectAsync4],
266 : /// [expectAsync5], and [expectAsync6] for callbacks with different arity.
267 : Func0<T> expectAsync0<T>(T callback(),
268 : {int count: 1, int max: 0, String id, String reason}) {
269 0 : if (Invoker.current == null) {
270 0 : throw new StateError("expectAsync0() may only be called within a test.");
271 : }
272 :
273 0 : return new _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
274 0 : .max0;
275 : }
276 :
277 : /// Informs the framework that the given [callback] of arity 1 is expected to be
278 : /// called [count] number of times (by default 1).
279 : ///
280 : /// Returns a wrapped function that should be used as a replacement of the
281 : /// original callback.
282 : ///
283 : /// The test framework will wait for the callback to run the [count] times
284 : /// before it considers the current test to be complete.
285 : ///
286 : /// [max] can be used to specify an upper bound on the number of calls; if this
287 : /// is exceeded the test will fail. If [max] is `0` (the default), the callback
288 : /// is expected to be called exactly [count] times. If [max] is `-1`, the
289 : /// callback is allowed to be called any number of times greater than [count].
290 : ///
291 : /// Both [id] and [reason] are optional and provide extra information about the
292 : /// callback when debugging. [id] should be the name of the callback, while
293 : /// [reason] should be the reason the callback is expected to be called.
294 : ///
295 : /// This method takes callbacks with one argument. See also
296 : /// [expectAsync0], [expectAsync2], [expectAsync3], [expectAsync4],
297 : /// [expectAsync5], and [expectAsync6] for callbacks with different arity.
298 : Func1<T, A> expectAsync1<T, A>(T callback(A a),
299 : {int count: 1, int max: 0, String id, String reason}) {
300 0 : if (Invoker.current == null) {
301 0 : throw new StateError("expectAsync1() may only be called within a test.");
302 : }
303 :
304 0 : return new _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
305 0 : .max1;
306 : }
307 :
308 : /// Informs the framework that the given [callback] of arity 2 is expected to be
309 : /// called [count] number of times (by default 1).
310 : ///
311 : /// Returns a wrapped function that should be used as a replacement of the
312 : /// original callback.
313 : ///
314 : /// The test framework will wait for the callback to run the [count] times
315 : /// before it considers the current test to be complete.
316 : ///
317 : /// [max] can be used to specify an upper bound on the number of calls; if this
318 : /// is exceeded the test will fail. If [max] is `0` (the default), the callback
319 : /// is expected to be called exactly [count] times. If [max] is `-1`, the
320 : /// callback is allowed to be called any number of times greater than [count].
321 : ///
322 : /// Both [id] and [reason] are optional and provide extra information about the
323 : /// callback when debugging. [id] should be the name of the callback, while
324 : /// [reason] should be the reason the callback is expected to be called.
325 : ///
326 : /// This method takes callbacks with two arguments. See also
327 : /// [expectAsync0], [expectAsync1], [expectAsync3], [expectAsync4],
328 : /// [expectAsync5], and [expectAsync6] for callbacks with different arity.
329 : Func2<T, A, B> expectAsync2<T, A, B>(T callback(A a, B b),
330 : {int count: 1, int max: 0, String id, String reason}) {
331 0 : if (Invoker.current == null) {
332 0 : throw new StateError("expectAsync2() may only be called within a test.");
333 : }
334 :
335 0 : return new _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
336 0 : .max2;
337 : }
338 :
339 : /// Informs the framework that the given [callback] of arity 3 is expected to be
340 : /// called [count] number of times (by default 1).
341 : ///
342 : /// Returns a wrapped function that should be used as a replacement of the
343 : /// original callback.
344 : ///
345 : /// The test framework will wait for the callback to run the [count] times
346 : /// before it considers the current test to be complete.
347 : ///
348 : /// [max] can be used to specify an upper bound on the number of calls; if this
349 : /// is exceeded the test will fail. If [max] is `0` (the default), the callback
350 : /// is expected to be called exactly [count] times. If [max] is `-1`, the
351 : /// callback is allowed to be called any number of times greater than [count].
352 : ///
353 : /// Both [id] and [reason] are optional and provide extra information about the
354 : /// callback when debugging. [id] should be the name of the callback, while
355 : /// [reason] should be the reason the callback is expected to be called.
356 : ///
357 : /// This method takes callbacks with three arguments. See also
358 : /// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync4],
359 : /// [expectAsync5], and [expectAsync6] for callbacks with different arity.
360 : Func3<T, A, B, C> expectAsync3<T, A, B, C>(T callback(A a, B b, C c),
361 : {int count: 1, int max: 0, String id, String reason}) {
362 0 : if (Invoker.current == null) {
363 0 : throw new StateError("expectAsync3() may only be called within a test.");
364 : }
365 :
366 0 : return new _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
367 0 : .max3;
368 : }
369 :
370 : /// Informs the framework that the given [callback] of arity 4 is expected to be
371 : /// called [count] number of times (by default 1).
372 : ///
373 : /// Returns a wrapped function that should be used as a replacement of the
374 : /// original callback.
375 : ///
376 : /// The test framework will wait for the callback to run the [count] times
377 : /// before it considers the current test to be complete.
378 : ///
379 : /// [max] can be used to specify an upper bound on the number of calls; if this
380 : /// is exceeded the test will fail. If [max] is `0` (the default), the callback
381 : /// is expected to be called exactly [count] times. If [max] is `-1`, the
382 : /// callback is allowed to be called any number of times greater than [count].
383 : ///
384 : /// Both [id] and [reason] are optional and provide extra information about the
385 : /// callback when debugging. [id] should be the name of the callback, while
386 : /// [reason] should be the reason the callback is expected to be called.
387 : ///
388 : /// This method takes callbacks with four arguments. See also
389 : /// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync3],
390 : /// [expectAsync5], and [expectAsync6] for callbacks with different arity.
391 : Func4<T, A, B, C, D> expectAsync4<T, A, B, C, D>(T callback(A a, B b, C c, D d),
392 : {int count: 1, int max: 0, String id, String reason}) {
393 0 : if (Invoker.current == null) {
394 0 : throw new StateError("expectAsync4() may only be called within a test.");
395 : }
396 :
397 0 : return new _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
398 0 : .max4;
399 : }
400 :
401 : /// Informs the framework that the given [callback] of arity 5 is expected to be
402 : /// called [count] number of times (by default 1).
403 : ///
404 : /// Returns a wrapped function that should be used as a replacement of the
405 : /// original callback.
406 : ///
407 : /// The test framework will wait for the callback to run the [count] times
408 : /// before it considers the current test to be complete.
409 : ///
410 : /// [max] can be used to specify an upper bound on the number of calls; if this
411 : /// is exceeded the test will fail. If [max] is `0` (the default), the callback
412 : /// is expected to be called exactly [count] times. If [max] is `-1`, the
413 : /// callback is allowed to be called any number of times greater than [count].
414 : ///
415 : /// Both [id] and [reason] are optional and provide extra information about the
416 : /// callback when debugging. [id] should be the name of the callback, while
417 : /// [reason] should be the reason the callback is expected to be called.
418 : ///
419 : /// This method takes callbacks with five arguments. See also
420 : /// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync3],
421 : /// [expectAsync4], and [expectAsync6] for callbacks with different arity.
422 : Func5<T, A, B, C, D, E> expectAsync5<T, A, B, C, D, E>(
423 : T callback(A a, B b, C c, D d, E e),
424 : {int count: 1,
425 : int max: 0,
426 : String id,
427 : String reason}) {
428 0 : if (Invoker.current == null) {
429 0 : throw new StateError("expectAsync5() may only be called within a test.");
430 : }
431 :
432 0 : return new _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
433 0 : .max5;
434 : }
435 :
436 : /// Informs the framework that the given [callback] of arity 6 is expected to be
437 : /// called [count] number of times (by default 1).
438 : ///
439 : /// Returns a wrapped function that should be used as a replacement of the
440 : /// original callback.
441 : ///
442 : /// The test framework will wait for the callback to run the [count] times
443 : /// before it considers the current test to be complete.
444 : ///
445 : /// [max] can be used to specify an upper bound on the number of calls; if this
446 : /// is exceeded the test will fail. If [max] is `0` (the default), the callback
447 : /// is expected to be called exactly [count] times. If [max] is `-1`, the
448 : /// callback is allowed to be called any number of times greater than [count].
449 : ///
450 : /// Both [id] and [reason] are optional and provide extra information about the
451 : /// callback when debugging. [id] should be the name of the callback, while
452 : /// [reason] should be the reason the callback is expected to be called.
453 : ///
454 : /// This method takes callbacks with six arguments. See also
455 : /// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync3],
456 : /// [expectAsync4], and [expectAsync5] for callbacks with different arity.
457 : Func6<T, A, B, C, D, E, F> expectAsync6<T, A, B, C, D, E, F>(
458 : T callback(A a, B b, C c, D d, E e, F f),
459 : {int count: 1,
460 : int max: 0,
461 : String id,
462 : String reason}) {
463 0 : if (Invoker.current == null) {
464 0 : throw new StateError("expectAsync6() may only be called within a test.");
465 : }
466 :
467 0 : return new _ExpectedFunction<T>(callback, count, max, id: id, reason: reason)
468 0 : .max6;
469 : }
470 :
471 : /// This function is deprecated because it doesn't work well with strong mode.
472 : /// Use [expectAsyncUntil0], [expectAsyncUntil1],
473 : /// [expectAsyncUntil2], [expectAsyncUntil3], [expectAsyncUntil4],
474 : /// [expectAsyncUntil5], or [expectAsyncUntil6] instead.
475 : @Deprecated("Will be removed in 0.13.0")
476 : Function expectAsyncUntil(Function callback, bool isDone(),
477 : {String id, String reason}) {
478 0 : if (Invoker.current == null) {
479 0 : throw new StateError(
480 : "expectAsyncUntil() may only be called within a test.");
481 : }
482 :
483 0 : return new _ExpectedFunction(callback, 0, -1,
484 : id: id, reason: reason, isDone: isDone)
485 0 : .func;
486 : }
487 :
488 : /// Informs the framework that the given [callback] of arity 0 is expected to be
489 : /// called until [isDone] returns true.
490 : ///
491 : /// Returns a wrapped function that should be used as a replacement of the
492 : /// original callback.
493 : ///
494 : /// [isDone] is called after each time the function is run. Only when it returns
495 : /// true will the callback be considered complete.
496 : ///
497 : /// Both [id] and [reason] are optional and provide extra information about the
498 : /// callback when debugging. [id] should be the name of the callback, while
499 : /// [reason] should be the reason the callback is expected to be called.
500 : ///
501 : /// This method takes callbacks with zero arguments. See also
502 : /// [expectAsyncUntil1], [expectAsyncUntil2], [expectAsyncUntil3],
503 : /// [expectAsyncUntil4], [expectAsyncUntil5], and [expectAsyncUntil6] for
504 : /// callbacks with different arity.
505 : Func0<T> expectAsyncUntil0<T>(T callback(), bool isDone(),
506 : {String id, String reason}) {
507 0 : if (Invoker.current == null) {
508 0 : throw new StateError(
509 : "expectAsyncUntil0() may only be called within a test.");
510 : }
511 :
512 0 : return new _ExpectedFunction<T>(callback, 0, -1,
513 : id: id, reason: reason, isDone: isDone)
514 0 : .max0;
515 : }
516 :
517 : /// Informs the framework that the given [callback] of arity 1 is expected to be
518 : /// called until [isDone] returns true.
519 : ///
520 : /// Returns a wrapped function that should be used as a replacement of the
521 : /// original callback.
522 : ///
523 : /// [isDone] is called after each time the function is run. Only when it returns
524 : /// true will the callback be considered complete.
525 : ///
526 : /// Both [id] and [reason] are optional and provide extra information about the
527 : /// callback when debugging. [id] should be the name of the callback, while
528 : /// [reason] should be the reason the callback is expected to be called.
529 : ///
530 : /// This method takes callbacks with one argument. See also
531 : /// [expectAsyncUntil0], [expectAsyncUntil2], [expectAsyncUntil3],
532 : /// [expectAsyncUntil4], [expectAsyncUntil5], and [expectAsyncUntil6] for
533 : /// callbacks with different arity.
534 : Func1<T, A> expectAsyncUntil1<T, A>(T callback(A a), bool isDone(),
535 : {String id, String reason}) {
536 0 : if (Invoker.current == null) {
537 0 : throw new StateError(
538 : "expectAsyncUntil1() may only be called within a test.");
539 : }
540 :
541 0 : return new _ExpectedFunction<T>(callback, 0, -1,
542 : id: id, reason: reason, isDone: isDone)
543 0 : .max1;
544 : }
545 :
546 : /// Informs the framework that the given [callback] of arity 2 is expected to be
547 : /// called until [isDone] returns true.
548 : ///
549 : /// Returns a wrapped function that should be used as a replacement of the
550 : /// original callback.
551 : ///
552 : /// [isDone] is called after each time the function is run. Only when it returns
553 : /// true will the callback be considered complete.
554 : ///
555 : /// Both [id] and [reason] are optional and provide extra information about the
556 : /// callback when debugging. [id] should be the name of the callback, while
557 : /// [reason] should be the reason the callback is expected to be called.
558 : ///
559 : /// This method takes callbacks with two arguments. See also
560 : /// [expectAsyncUntil0], [expectAsyncUntil1], [expectAsyncUntil3],
561 : /// [expectAsyncUntil4], [expectAsyncUntil5], and [expectAsyncUntil6] for
562 : /// callbacks with different arity.
563 : Func2<T, A, B> expectAsyncUntil2<T, A, B>(T callback(A a, B b), bool isDone(),
564 : {String id, String reason}) {
565 0 : if (Invoker.current == null) {
566 0 : throw new StateError(
567 : "expectAsyncUntil2() may only be called within a test.");
568 : }
569 :
570 0 : return new _ExpectedFunction<T>(callback, 0, -1,
571 : id: id, reason: reason, isDone: isDone)
572 0 : .max2;
573 : }
574 :
575 : /// Informs the framework that the given [callback] of arity 3 is expected to be
576 : /// called until [isDone] returns true.
577 : ///
578 : /// Returns a wrapped function that should be used as a replacement of the
579 : /// original callback.
580 : ///
581 : /// [isDone] is called after each time the function is run. Only when it returns
582 : /// true will the callback be considered complete.
583 : ///
584 : /// Both [id] and [reason] are optional and provide extra information about the
585 : /// callback when debugging. [id] should be the name of the callback, while
586 : /// [reason] should be the reason the callback is expected to be called.
587 : ///
588 : /// This method takes callbacks with three arguments. See also
589 : /// [expectAsyncUntil0], [expectAsyncUntil1], [expectAsyncUntil2],
590 : /// [expectAsyncUntil4], [expectAsyncUntil5], and [expectAsyncUntil6] for
591 : /// callbacks with different arity.
592 : Func3<T, A, B, C> expectAsyncUntil3<T, A, B, C>(
593 : T callback(A a, B b, C c), bool isDone(),
594 : {String id, String reason}) {
595 0 : if (Invoker.current == null) {
596 0 : throw new StateError(
597 : "expectAsyncUntil3() may only be called within a test.");
598 : }
599 :
600 0 : return new _ExpectedFunction<T>(callback, 0, -1,
601 : id: id, reason: reason, isDone: isDone)
602 0 : .max3;
603 : }
604 :
605 : /// Informs the framework that the given [callback] of arity 4 is expected to be
606 : /// called until [isDone] returns true.
607 : ///
608 : /// Returns a wrapped function that should be used as a replacement of the
609 : /// original callback.
610 : ///
611 : /// [isDone] is called after each time the function is run. Only when it returns
612 : /// true will the callback be considered complete.
613 : ///
614 : /// Both [id] and [reason] are optional and provide extra information about the
615 : /// callback when debugging. [id] should be the name of the callback, while
616 : /// [reason] should be the reason the callback is expected to be called.
617 : ///
618 : /// This method takes callbacks with four arguments. See also
619 : /// [expectAsyncUntil0], [expectAsyncUntil1], [expectAsyncUntil2],
620 : /// [expectAsyncUntil3], [expectAsyncUntil5], and [expectAsyncUntil6] for
621 : /// callbacks with different arity.
622 : Func4<T, A, B, C, D> expectAsyncUntil4<T, A, B, C, D>(
623 : T callback(A a, B b, C c, D d), bool isDone(),
624 : {String id, String reason}) {
625 0 : if (Invoker.current == null) {
626 0 : throw new StateError(
627 : "expectAsyncUntil4() may only be called within a test.");
628 : }
629 :
630 0 : return new _ExpectedFunction<T>(callback, 0, -1,
631 : id: id, reason: reason, isDone: isDone)
632 0 : .max4;
633 : }
634 :
635 : /// Informs the framework that the given [callback] of arity 5 is expected to be
636 : /// called until [isDone] returns true.
637 : ///
638 : /// Returns a wrapped function that should be used as a replacement of the
639 : /// original callback.
640 : ///
641 : /// [isDone] is called after each time the function is run. Only when it returns
642 : /// true will the callback be considered complete.
643 : ///
644 : /// Both [id] and [reason] are optional and provide extra information about the
645 : /// callback when debugging. [id] should be the name of the callback, while
646 : /// [reason] should be the reason the callback is expected to be called.
647 : ///
648 : /// This method takes callbacks with five arguments. See also
649 : /// [expectAsyncUntil0], [expectAsyncUntil1], [expectAsyncUntil2],
650 : /// [expectAsyncUntil3], [expectAsyncUntil4], and [expectAsyncUntil6] for
651 : /// callbacks with different arity.
652 : Func5<T, A, B, C, D, E> expectAsyncUntil5<T, A, B, C, D, E>(
653 : T callback(A a, B b, C c, D d, E e), bool isDone(),
654 : {String id, String reason}) {
655 0 : if (Invoker.current == null) {
656 0 : throw new StateError(
657 : "expectAsyncUntil5() may only be called within a test.");
658 : }
659 :
660 0 : return new _ExpectedFunction<T>(callback, 0, -1,
661 : id: id, reason: reason, isDone: isDone)
662 0 : .max5;
663 : }
664 :
665 : /// Informs the framework that the given [callback] of arity 6 is expected to be
666 : /// called until [isDone] returns true.
667 : ///
668 : /// Returns a wrapped function that should be used as a replacement of the
669 : /// original callback.
670 : ///
671 : /// [isDone] is called after each time the function is run. Only when it returns
672 : /// true will the callback be considered complete.
673 : ///
674 : /// Both [id] and [reason] are optional and provide extra information about the
675 : /// callback when debugging. [id] should be the name of the callback, while
676 : /// [reason] should be the reason the callback is expected to be called.
677 : ///
678 : /// This method takes callbacks with six arguments. See also
679 : /// [expectAsyncUntil0], [expectAsyncUntil1], [expectAsyncUntil2],
680 : /// [expectAsyncUntil3], [expectAsyncUntil4], and [expectAsyncUntil5] for
681 : /// callbacks with different arity.
682 : Func6<T, A, B, C, D, E, F> expectAsyncUntil6<T, A, B, C, D, E, F>(
683 : T callback(A a, B b, C c, D d, E e, F f), bool isDone(),
684 : {String id, String reason}) {
685 0 : if (Invoker.current == null) {
686 0 : throw new StateError(
687 : "expectAsyncUntil() may only be called within a test.");
688 : }
689 :
690 0 : return new _ExpectedFunction<T>(callback, 0, -1,
691 : id: id, reason: reason, isDone: isDone)
692 0 : .max6;
693 : }
|