Expose isMethodCall matcher in flutter_test (#12942)

diff --git a/packages/flutter/test/services/haptic_feedback_test.dart b/packages/flutter/test/services/haptic_feedback_test.dart
index 71c8d8b..b73a4b0 100644
--- a/packages/flutter/test/services/haptic_feedback_test.dart
+++ b/packages/flutter/test/services/haptic_feedback_test.dart
@@ -3,9 +3,7 @@
 // found in the LICENSE file.
 
 import 'package:flutter/services.dart';
-import 'package:test/test.dart';
-
-import 'message_codecs_utils.dart';
+import 'package:flutter_test/flutter_test.dart';
 
 void main() {
   test('Haptic feedback control test', () async {
diff --git a/packages/flutter/test/services/message_codecs_utils.dart b/packages/flutter/test/services/message_codecs_utils.dart
deleted file mode 100644
index 0687b54..0000000
--- a/packages/flutter/test/services/message_codecs_utils.dart
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'package:flutter/services.dart' show MethodCall;
-import 'package:meta/meta.dart';
-import 'package:test/test.dart';
-
-class _IsMethodCall extends Matcher {
-  const _IsMethodCall(this.name, this.arguments);
-
-  final String name;
-  final dynamic arguments;
-
-  @override
-  bool matches(dynamic item, Map<dynamic, dynamic> matchState) {
-    if (item is! MethodCall)
-      return false;
-    if (item.method != name)
-      return false;
-    return _deepEquals(item.arguments, arguments);
-  }
-
-  bool _deepEquals(dynamic a, dynamic b) {
-    if (a == b)
-      return true;
-    if (a is List)
-      return b is List && _deepEqualsList(a, b);
-    if (a is Map)
-      return b is Map && _deepEqualsMap(a, b);
-    return false;
-  }
-
-  bool _deepEqualsList(List<dynamic> a, List<dynamic> b) {
-    if (a.length != b.length)
-      return false;
-    for (int i = 0; i < a.length; i++) {
-      if (!_deepEquals(a[i], b[i]))
-        return false;
-    }
-    return true;
-  }
-
-  bool _deepEqualsMap(Map<dynamic, dynamic> a, Map<dynamic, dynamic> b) {
-    if (a.length != b.length)
-      return false;
-    for (dynamic key in a.keys) {
-      if (!b.containsKey(key) || !_deepEquals(a[key], b[key]))
-        return false;
-    }
-    return true;
-  }
-
-  @override
-  Description describe(Description description) {
-    return description
-      .add('has method name: ').addDescriptionOf(name)
-      .add(' with arguments: ').addDescriptionOf(arguments);
-  }
-}
-
-/// Returns a matcher that matches [MethodCall] instances with the specified
-/// method name and arguments.
-///
-/// Arguments checking implements deep equality for [List] and [Map] types.
-Matcher isMethodCall(String name, {@required dynamic arguments}) {
-  return new _IsMethodCall(name, arguments);
-}
diff --git a/packages/flutter/test/services/system_chrome_test.dart b/packages/flutter/test/services/system_chrome_test.dart
index 65b0bb6..abeb5dc 100644
--- a/packages/flutter/test/services/system_chrome_test.dart
+++ b/packages/flutter/test/services/system_chrome_test.dart
@@ -7,8 +7,6 @@
 import 'package:flutter/services.dart';
 import 'package:flutter_test/flutter_test.dart';
 
-import 'message_codecs_utils.dart';
-
 void main() {
   testWidgets('SystemChrome overlay style test', (WidgetTester tester) async {
     // The first call is a cache miss and will queue a microtask
diff --git a/packages/flutter/test/services/system_navigator_test.dart b/packages/flutter/test/services/system_navigator_test.dart
index 753d37d..f3e28fa 100644
--- a/packages/flutter/test/services/system_navigator_test.dart
+++ b/packages/flutter/test/services/system_navigator_test.dart
@@ -3,9 +3,7 @@
 // found in the LICENSE file.
 
 import 'package:flutter/services.dart';
-import 'package:test/test.dart';
-
-import 'message_codecs_utils.dart';
+import 'package:flutter_test/flutter_test.dart';
 
 void main() {
   test('System navigator control test', () async {
diff --git a/packages/flutter/test/services/system_sound_test.dart b/packages/flutter/test/services/system_sound_test.dart
index 9abb15a..c9fcf54 100644
--- a/packages/flutter/test/services/system_sound_test.dart
+++ b/packages/flutter/test/services/system_sound_test.dart
@@ -3,9 +3,7 @@
 // found in the LICENSE file.
 
 import 'package:flutter/services.dart';
-import 'package:test/test.dart';
-
-import 'message_codecs_utils.dart';
+import 'package:flutter_test/flutter_test.dart';
 
 void main() {
   test('System sound control test', () async {
diff --git a/packages/flutter/test/widgets/editable_text_test.dart b/packages/flutter/test/widgets/editable_text_test.dart
index c535ecb..a80f75d 100644
--- a/packages/flutter/test/widgets/editable_text_test.dart
+++ b/packages/flutter/test/widgets/editable_text_test.dart
@@ -10,7 +10,6 @@
 import 'package:flutter/widgets.dart';
 import 'package:flutter/services.dart';
 
-import '../services/message_codecs_utils.dart';
 import 'semantics_tester.dart';
 
 void main() {
diff --git a/packages/flutter/test/widgets/title_test.dart b/packages/flutter/test/widgets/title_test.dart
index bc17354..09696e2 100644
--- a/packages/flutter/test/widgets/title_test.dart
+++ b/packages/flutter/test/widgets/title_test.dart
@@ -6,8 +6,6 @@
 import 'package:flutter/widgets.dart';
 import 'package:flutter/services.dart';
 
-import '../services/message_codecs_utils.dart';
-
 void main() {
   testWidgets('toString control test', (WidgetTester tester) async {
     final Widget widget = new Title(
diff --git a/packages/flutter_test/lib/src/matchers.dart b/packages/flutter_test/lib/src/matchers.dart
index a78ae1e..369c589 100644
--- a/packages/flutter_test/lib/src/matchers.dart
+++ b/packages/flutter_test/lib/src/matchers.dart
@@ -5,6 +5,7 @@
 import 'dart:math' as math;
 
 import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
 import 'package:meta/meta.dart';
 import 'package:test/test.dart';
 
@@ -216,6 +217,14 @@
   return new _EqualsIgnoringHashCodes(value);
 }
 
+/// A matcher for [MethodCall]s, asserting that it has the specified
+/// method [name] and [arguments].
+///
+/// Arguments checking implements deep equality for [List] and [Map] types.
+Matcher isMethodCall(String name, {@required dynamic arguments}) {
+  return new _IsMethodCall(name, arguments);
+}
+
 class _FindsWidgetMatcher extends Matcher {
   const _FindsWidgetMatcher(this.min, this.max);
 
@@ -686,3 +695,57 @@
   @override
   Description describe(Description description) => description.add('$value (±$epsilon)');
 }
+
+class _IsMethodCall extends Matcher {
+  const _IsMethodCall(this.name, this.arguments);
+
+  final String name;
+  final dynamic arguments;
+
+  @override
+  bool matches(dynamic item, Map<dynamic, dynamic> matchState) {
+    if (item is! MethodCall)
+      return false;
+    if (item.method != name)
+      return false;
+    return _deepEquals(item.arguments, arguments);
+  }
+
+  bool _deepEquals(dynamic a, dynamic b) {
+    if (a == b)
+      return true;
+    if (a is List)
+      return b is List && _deepEqualsList(a, b);
+    if (a is Map)
+      return b is Map && _deepEqualsMap(a, b);
+    return false;
+  }
+
+  bool _deepEqualsList(List<dynamic> a, List<dynamic> b) {
+    if (a.length != b.length)
+      return false;
+    for (int i = 0; i < a.length; i++) {
+      if (!_deepEquals(a[i], b[i]))
+        return false;
+    }
+    return true;
+  }
+
+  bool _deepEqualsMap(Map<dynamic, dynamic> a, Map<dynamic, dynamic> b) {
+    if (a.length != b.length)
+      return false;
+    for (dynamic key in a.keys) {
+      if (!b.containsKey(key) || !_deepEquals(a[key], b[key]))
+        return false;
+    }
+    return true;
+  }
+
+  @override
+  Description describe(Description description) {
+    return description
+        .add('has method name: ').addDescriptionOf(name)
+        .add(' with arguments: ').addDescriptionOf(arguments);
+  }
+}
+