Add expectAsync0,1,..6 to unittest (#520)

diff --git a/.gitignore b/.gitignore
index 388eff0..e2552ea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,9 @@
-# Don’t commit the following directories created by pub.
+# Don’t commit the following files and directories created by pub.
 .buildlog
 .pub/
 build/
 packages
+.packages
 
 # Or the files created by dart2js.
 *.dart.js
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 70a58ea..b60e66b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,9 @@
+##0.11.7
+
+* Add separate methods for `expectAysnc` based on number of callback arguments 
+  `expectAsync0`, `expectAsync1`, ... `expectAsync6`.
+* Fix all strong mode warnings.
+
 ##0.11.6+4
 
 * Fix some strong mode warnings we missed in the `vm_config.dart` and
diff --git a/lib/src/expected_function.dart b/lib/src/expected_function.dart
index 7373c75..5a92d14 100644
--- a/lib/src/expected_function.dart
+++ b/lib/src/expected_function.dart
@@ -30,7 +30,7 @@
 ///
 /// The wrapper function is accessible via [func]. It supports up to six
 /// optional and/or required positional arguments, but no named arguments.
-class ExpectedFunction {
+class ExpectedFunction<T> {
   /// The wrapped callback.
   final Function _callback;
 
@@ -125,43 +125,60 @@
   /// Returns a function that has the same number of positional arguments as the
   /// wrapped function (up to a total of 6).
   Function get func {
-    if (_callback is _Func6) return _max6;
-    if (_callback is _Func5) return _max5;
-    if (_callback is _Func4) return _max4;
-    if (_callback is _Func3) return _max3;
-    if (_callback is _Func2) return _max2;
-    if (_callback is _Func1) return _max1;
-    if (_callback is _Func0) return _max0;
+    if (_callback is _Func6) return max6;
+    if (_callback is _Func5) return max5;
+    if (_callback is _Func4) return max4;
+    if (_callback is _Func3) return max3;
+    if (_callback is _Func2) return max2;
+    if (_callback is _Func1) return max1;
+    if (_callback is _Func0) return max0;
 
     throw new ArgumentError(
         'The wrapped function has more than 6 required arguments');
   }
 
+  T max0() => max6();
+
   // This indirection is critical. It ensures the returned function has an
   // argument count of zero.
-  _max0() => _max6();
+  T max1([Object a0 = _PLACEHOLDER]) => max6(a0);
 
-  _max1([a0 = _PLACEHOLDER]) => _max6(a0);
+  T max2([Object a0 = _PLACEHOLDER, Object a1 = _PLACEHOLDER]) => max6(a0, a1);
 
-  _max2([a0 = _PLACEHOLDER, a1 = _PLACEHOLDER]) => _max6(a0, a1);
+  T max3(
+          [Object a0 = _PLACEHOLDER, 
+          Object a1 = _PLACEHOLDER, 
+          Object a2 = _PLACEHOLDER]) =>  
+      max6(a0, a1, a2);
 
-  _max3([a0 = _PLACEHOLDER, a1 = _PLACEHOLDER, a2 = _PLACEHOLDER]) =>
-      _max6(a0, a1, a2);
+  T max4(
+          [Object a0 = _PLACEHOLDER,
+          Object a1 = _PLACEHOLDER,
+          Object a2 = _PLACEHOLDER,
+          Object a3 = _PLACEHOLDER]) =>
+      max6(a0, a1, a2, a3);
 
-  _max4([a0 = _PLACEHOLDER, a1 = _PLACEHOLDER, a2 = _PLACEHOLDER,
-      a3 = _PLACEHOLDER]) => _max6(a0, a1, a2, a3);
+  T max5(
+          [Object a0 = _PLACEHOLDER,
+          Object a1 = _PLACEHOLDER,
+          Object a2 = _PLACEHOLDER,
+          Object a3 = _PLACEHOLDER,
+          Object a4 = _PLACEHOLDER]) =>
+      max6(a0, a1, a2, a3, a4);
 
-  _max5([a0 = _PLACEHOLDER, a1 = _PLACEHOLDER, a2 = _PLACEHOLDER,
-      a3 = _PLACEHOLDER, a4 = _PLACEHOLDER]) => _max6(a0, a1, a2, a3, a4);
-
-  _max6([a0 = _PLACEHOLDER, a1 = _PLACEHOLDER, a2 = _PLACEHOLDER,
-      a3 = _PLACEHOLDER, a4 = _PLACEHOLDER, a5 = _PLACEHOLDER]) =>
+  T max6(
+          [Object a0 = _PLACEHOLDER,
+          Object a1 = _PLACEHOLDER,
+          Object a2 = _PLACEHOLDER,
+          Object a3 = _PLACEHOLDER,
+          Object a4 = _PLACEHOLDER,
+          Object a5 = _PLACEHOLDER]) =>
       _run([a0, a1, a2, a3, a4, a5].where((a) => a != _PLACEHOLDER));
 
   /// Runs the wrapped function with [args] and returns its return value.
   ///
   /// This will pass any errors on to [_testCase] and return `null`.
-  _run(Iterable args) {
+  T _run(Iterable args) {
     try {
       _actualCalls++;
       if (_testCase.isComplete) {
@@ -177,10 +194,10 @@
         return null;
       } else if (_maxExpectedCalls >= 0 && _actualCalls > _maxExpectedCalls) {
         throw new TestFailure('Callback ${_id}called more times than expected '
-                              '($_maxExpectedCalls).$_reason');
+            '($_maxExpectedCalls).$_reason');
       }
 
-      return Function.apply(_callback, args.toList());
+      return Function.apply(_callback, args.toList()) as T;
     } catch (error, stackTrace) {
       _testCase.registerException(error, stackTrace);
       return null;
diff --git a/lib/unittest.dart b/lib/unittest.dart
index 8cf8719..852b60d 100644
--- a/lib/unittest.dart
+++ b/lib/unittest.dart
@@ -160,6 +160,246 @@
     {int count: 1, int max: 0, String id, String reason}) =>
         new ExpectedFunction(callback, count, max, id: id, reason: reason).func;
 
+// Functions used to check how many arguments a callback takes.
+typedef T Func0<T>();
+typedef T Func1<T, A>(A a);
+typedef T Func2<T, A, B>(A a, B b);
+typedef T Func3<T, A, B, C>(A a, B b, C c);
+typedef T Func4<T, A, B, C, D>(A a, B b, C c, D d);
+typedef T Func5<T, A, B, C, D, E>(A a, B b, C c, D d, E e);
+typedef T Func6<T, A, B, C, D, E, F>(A a, B b, C c, D d, E e, F f);
+
+/// Informs the framework that the given [callback] of arity 0 is expected to be
+/// called [count] number of times (by default 1).
+///
+/// Returns a wrapped function that should be used as a replacement of the
+/// original callback.
+///
+/// The test framework will wait for the callback to run the [count] times
+/// before it considers the current test to be complete.
+///
+/// [max] can be used to specify an upper bound on the number of calls; if this
+/// is exceeded the test will fail. If [max] is `0` (the default), the callback
+/// is expected to be called exactly [count] times. If [max] is `-1`, the
+/// callback is allowed to be called any number of times greater than [count].
+///
+/// Both [id] and [reason] are optional and provide extra information about the
+/// callback when debugging. [id] should be the name of the callback, while
+/// [reason] should be the reason the callback is expected to be called.
+///
+/// This method takes callbacks with zero arguments. See also
+/// [expectAsync1], [expectAsync2], [expectAsync3], [expectAsync4],
+/// [expectAsync5], and [expectAsync6] for callbacks with different arity.
+Func0<dynamic/*=T*/ > expectAsync0/*<T>*/(dynamic/*=T*/ callback(),
+    {int count: 1, int max: 0, String id, String reason}) {
+  return new ExpectedFunction/*<T>*/(callback, count, max,
+      id: id, reason: reason)
+      .max0;
+}
+
+/// Informs the framework that the given [callback] of arity 1 is expected to be
+/// called [count] number of times (by default 1).
+///
+/// Returns a wrapped function that should be used as a replacement of the
+/// original callback.
+///
+/// The test framework will wait for the callback to run the [count] times
+/// before it considers the current test to be complete.
+///
+/// [max] can be used to specify an upper bound on the number of calls; if this
+/// is exceeded the test will fail. If [max] is `0` (the default), the callback
+/// is expected to be called exactly [count] times. If [max] is `-1`, the
+/// callback is allowed to be called any number of times greater than [count].
+///
+/// Both [id] and [reason] are optional and provide extra information about the
+/// callback when debugging. [id] should be the name of the callback, while
+/// [reason] should be the reason the callback is expected to be called.
+///
+/// This method takes callbacks with one argument. See also
+/// [expectAsync0], [expectAsync2], [expectAsync3], [expectAsync4],
+/// [expectAsync5], and [expectAsync6] for callbacks with different arity.
+Func1<dynamic/*=T*/, dynamic/*=A*/ > expectAsync1/*<T, A>*/(
+    dynamic/*=T*/ callback(dynamic/*=A*/ a),
+    {int count: 1,
+    int max: 0,
+    String id,
+    String reason}) {
+  return new ExpectedFunction/*<T>*/(callback, count, max,
+      id: id, reason: reason)
+      .max1;
+}
+
+/// Informs the framework that the given [callback] of arity 2 is expected to be
+/// called [count] number of times (by default 1).
+///
+/// Returns a wrapped function that should be used as a replacement of the
+/// original callback.
+///
+/// The test framework will wait for the callback to run the [count] times
+/// before it considers the current test to be complete.
+///
+/// [max] can be used to specify an upper bound on the number of calls; if this
+/// is exceeded the test will fail. If [max] is `0` (the default), the callback
+/// is expected to be called exactly [count] times. If [max] is `-1`, the
+/// callback is allowed to be called any number of times greater than [count].
+///
+/// Both [id] and [reason] are optional and provide extra information about the
+/// callback when debugging. [id] should be the name of the callback, while
+/// [reason] should be the reason the callback is expected to be called.
+///
+/// This method takes callbacks with two arguments. See also
+/// [expectAsync0], [expectAsync1], [expectAsync3], [expectAsync4],
+/// [expectAsync5], and [expectAsync6] for callbacks with different arity.
+Func2<dynamic/*=T*/, dynamic/*=A*/, dynamic/*=B*/ > expectAsync2/*<T, A, B>*/(
+    dynamic/*=T*/ callback(dynamic/*=A*/ a, dynamic/*=B*/ b),
+    {int count: 1,
+    int max: 0,
+    String id,
+    String reason}) {
+  return new ExpectedFunction/*<T>*/(callback, count, max,
+      id: id, reason: reason)
+      .max2;
+}
+
+/// Informs the framework that the given [callback] of arity 3 is expected to be
+/// called [count] number of times (by default 1).
+///
+/// Returns a wrapped function that should be used as a replacement of the
+/// original callback.
+///
+/// The test framework will wait for the callback to run the [count] times
+/// before it considers the current test to be complete.
+///
+/// [max] can be used to specify an upper bound on the number of calls; if this
+/// is exceeded the test will fail. If [max] is `0` (the default), the callback
+/// is expected to be called exactly [count] times. If [max] is `-1`, the
+/// callback is allowed to be called any number of times greater than [count].
+///
+/// Both [id] and [reason] are optional and provide extra information about the
+/// callback when debugging. [id] should be the name of the callback, while
+/// [reason] should be the reason the callback is expected to be called.
+///
+/// This method takes callbacks with three arguments. See also
+/// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync4],
+/// [expectAsync5], and [expectAsync6] for callbacks with different arity.
+Func3<dynamic/*=T*/, dynamic/*=A*/, dynamic/*=B*/, dynamic/*=C*/ >
+expectAsync3/*<T, A, B, C>*/(
+    dynamic/*=T*/ callback(
+        dynamic/*=A*/ a, dynamic/*=B*/ b, dynamic/*=C*/ c),
+    {int count: 1,
+    int max: 0,
+    String id,
+    String reason}) {
+  return new ExpectedFunction/*<T>*/(callback, count, max,
+      id: id, reason: reason)
+      .max3;
+}
+
+/// Informs the framework that the given [callback] of arity 4 is expected to be
+/// called [count] number of times (by default 1).
+///
+/// Returns a wrapped function that should be used as a replacement of the
+/// original callback.
+///
+/// The test framework will wait for the callback to run the [count] times
+/// before it considers the current test to be complete.
+///
+/// [max] can be used to specify an upper bound on the number of calls; if this
+/// is exceeded the test will fail. If [max] is `0` (the default), the callback
+/// is expected to be called exactly [count] times. If [max] is `-1`, the
+/// callback is allowed to be called any number of times greater than [count].
+///
+/// Both [id] and [reason] are optional and provide extra information about the
+/// callback when debugging. [id] should be the name of the callback, while
+/// [reason] should be the reason the callback is expected to be called.
+///
+/// This method takes callbacks with four arguments. See also
+/// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync3],
+/// [expectAsync5], and [expectAsync6] for callbacks with different arity.
+Func4<dynamic/*=T*/, dynamic/*=A*/, dynamic/*=B*/, dynamic/*=C*/,
+    dynamic/*=D*/ >
+expectAsync4/*<T, A, B, C, D>*/(
+    dynamic/*=T*/ callback(
+        dynamic/*=A*/ a, dynamic/*=B*/ b, dynamic/*=C*/ c, dynamic/*=D*/ d),
+    {int count: 1,
+    int max: 0,
+    String id,
+    String reason}) {
+  return new ExpectedFunction/*<T>*/(callback, count, max,
+      id: id, reason: reason)
+      .max4;
+}
+
+/// Informs the framework that the given [callback] of arity 5 is expected to be
+/// called [count] number of times (by default 1).
+///
+/// Returns a wrapped function that should be used as a replacement of the
+/// original callback.
+///
+/// The test framework will wait for the callback to run the [count] times
+/// before it considers the current test to be complete.
+///
+/// [max] can be used to specify an upper bound on the number of calls; if this
+/// is exceeded the test will fail. If [max] is `0` (the default), the callback
+/// is expected to be called exactly [count] times. If [max] is `-1`, the
+/// callback is allowed to be called any number of times greater than [count].
+///
+/// Both [id] and [reason] are optional and provide extra information about the
+/// callback when debugging. [id] should be the name of the callback, while
+/// [reason] should be the reason the callback is expected to be called.
+///
+/// This method takes callbacks with five arguments. See also
+/// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync3],
+/// [expectAsync4], and [expectAsync6] for callbacks with different arity.
+Func5<dynamic/*=T*/, dynamic/*=A*/, dynamic/*=B*/, dynamic/*=C*/, dynamic/*=D*/,
+    dynamic/*=E*/ >
+expectAsync5/*<T, A, B, C, D, E>*/(
+    dynamic/*=T*/ callback(dynamic/*=A*/ a, dynamic/*=B*/ b,
+        dynamic/*=C*/ c, dynamic/*=D*/ d, dynamic/*=E*/ e),
+    {int count: 1,
+    int max: 0,
+    String id,
+    String reason}) {
+  return new ExpectedFunction/*<T>*/(callback, count, max,
+      id: id, reason: reason)
+      .max5;
+}
+
+/// Informs the framework that the given [callback] of arity 6 is expected to be
+/// called [count] number of times (by default 1).
+///
+/// Returns a wrapped function that should be used as a replacement of the
+/// original callback.
+///
+/// The test framework will wait for the callback to run the [count] times
+/// before it considers the current test to be complete.
+///
+/// [max] can be used to specify an upper bound on the number of calls; if this
+/// is exceeded the test will fail. If [max] is `0` (the default), the callback
+/// is expected to be called exactly [count] times. If [max] is `-1`, the
+/// callback is allowed to be called any number of times greater than [count].
+///
+/// Both [id] and [reason] are optional and provide extra information about the
+/// callback when debugging. [id] should be the name of the callback, while
+/// [reason] should be the reason the callback is expected to be called.
+///
+/// This method takes callbacks with six arguments. See also
+/// [expectAsync0], [expectAsync1], [expectAsync2], [expectAsync3],
+/// [expectAsync4], and [expectAsync5] for callbacks with different arity.
+Func6<dynamic/*=T*/, dynamic/*=A*/, dynamic/*=B*/, dynamic/*=C*/, dynamic/*=D*/,
+    dynamic/*=E*/, dynamic/*=F*/ >
+expectAsync6/*<T, A, B, C, D, E, F>*/(
+    dynamic/*=T*/ callback(dynamic/*=A*/ a, dynamic/*=B*/ b,
+        dynamic/*=C*/ c, dynamic/*=D*/ d, dynamic/*=E*/ e, dynamic/*=F*/ f),
+    {int count: 1,
+    int max: 0,
+    String id,
+    String reason}) {
+  return new ExpectedFunction/*<T>*/(callback, count, max,
+      id: id, reason: reason)
+      .max6;
+}
+
 /// Indicate that [callback] is expected to be called until [isDone] returns
 /// true.
 ///
diff --git a/pubspec.yaml b/pubspec.yaml
index e1f2d4d..bc94363 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,5 +1,5 @@
 name: unittest
-version: 0.11.6+4
+version: 0.11.7
 author: Dart Team <misc@dartlang.org>
 description: A library for writing dart unit tests.
 homepage: https://github.com/dart-lang/old_unittest
diff --git a/test/expect_async_args_test.dart b/test/expect_async_args_test.dart
index 8e814dc..682852a 100644
--- a/test/expect_async_args_test.dart
+++ b/test/expect_async_args_test.dart
@@ -17,7 +17,7 @@
     var count = 0;
     List<int> _getArgs([a = 0, b = 0, c = 0, d = 0, e = 0, f = 0]) {
       count++;
-      return [a, b, c, d, e, f];
+      return <int>[a, b, c, d, e, f];
     }
 
     test('expect async args', () {
diff --git a/test/pretty_print_test.dart b/test/pretty_print_test.dart
index 6717a56..682547d 100644
--- a/test/pretty_print_test.dart
+++ b/test/pretty_print_test.dart
@@ -105,7 +105,7 @@
     });
 
     test("that's recursive", () {
-      var list = [1, 2, 3];
+      var list = <Object>[1, 2, 3];
       list.add(list);
       expect(prettyPrint(list), equals("[1, 2, 3, (recursive)]"));
     });
diff --git a/test/test_common.dart b/test/test_common.dart
index 7d7d70b..4f9cd7c 100644
--- a/test/test_common.dart
+++ b/test/test_common.dart
@@ -22,7 +22,7 @@
 
   SimpleIterable(this.count);
 
-  bool contains(int val) => count < val ? false : true;
+  bool contains(Object val) => val is int && val <= count;
 
   bool any(bool f(element)) {
     for (var i = 0; i <= count; i++) {
@@ -33,7 +33,7 @@
 
   String toString() => "<[$count]>";
 
-  Iterator get iterator {
+  Iterator<int> get iterator {
     return new _SimpleIterator(count);
   }
 }
diff --git a/test/test_utils.dart b/test/test_utils.dart
index d0adda2..f36533b 100644
--- a/test/test_utils.dart
+++ b/test/test_utils.dart
@@ -41,7 +41,7 @@
   }
 
   if (isAsync) {
-    Timer.run(expectAsync(afterTest));
+    Timer.run(expectAsync0(afterTest));
   } else {
     afterTest();
   }
@@ -57,7 +57,7 @@
     expect(_errorCount, equals(0));
   }
   if (isAsync) {
-    Timer.run(expectAsync(afterTest));
+    Timer.run(expectAsync0(afterTest));
   } else {
     afterTest();
   }