Revert "Migrate to ChannelBuffers.push (#81235)" (#81829)
This reverts commit 35ad43f20caa71ec051a97bc8bc8fec552fb4452.
diff --git a/dev/automated_tests/flutter_test/ticker_test.dart b/dev/automated_tests/flutter_test/ticker_test.dart
index 6881468..48d53f5 100644
--- a/dev/automated_tests/flutter_test/ticker_test.dart
+++ b/dev/automated_tests/flutter_test/ticker_test.dart
@@ -11,6 +11,6 @@
Ticker((Duration duration) { }).start();
final ByteData? message = const StringCodec().encodeMessage('AppLifecycleState.paused');
- await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) {});
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) {});
});
}
diff --git a/dev/integration_tests/web_e2e_tests/test_driver/text_editing_integration.dart b/dev/integration_tests/web_e2e_tests/test_driver/text_editing_integration.dart
index 36e5753..ef84b1b 100644
--- a/dev/integration_tests/web_e2e_tests/test_driver/text_editing_integration.dart
+++ b/dev/integration_tests/web_e2e_tests/test_driver/text_editing_integration.dart
@@ -20,6 +20,9 @@
app.main();
await tester.pumpAndSettle();
+ // TODO(nurhan): https://github.com/flutter/flutter/issues/51885
+ SystemChannels.textInput.setMockMethodCallHandler(null);
+
// Focus on a TextFormField.
final Finder finder = find.byKey(const Key('input'));
expect(finder, findsOneWidget);
@@ -45,6 +48,9 @@
app.main();
await tester.pumpAndSettle();
+ // TODO(nurhan): https://github.com/flutter/flutter/issues/51885
+ SystemChannels.textInput.setMockMethodCallHandler(null);
+
// Focus on a TextFormField.
final Finder finder = find.byKey(const Key('empty-input'));
expect(finder, findsOneWidget);
@@ -70,6 +76,9 @@
app.main();
await tester.pumpAndSettle();
+ // TODO(nurhan): https://github.com/flutter/flutter/issues/51885
+ SystemChannels.textInput.setMockMethodCallHandler(null);
+
// This text will show no-enter initially. It will have 'enter-pressed'
// after `onFieldSubmitted` of TextField is triggered.
final Finder textFinder = find.byKey(const Key('text'));
@@ -103,6 +112,9 @@
app.main();
await tester.pumpAndSettle();
+ // TODO(nurhan): https://github.com/flutter/flutter/issues/51885
+ SystemChannels.textInput.setMockMethodCallHandler(null);
+
// Focus on a TextFormField.
final Finder finder = find.byKey(const Key('input'));
expect(finder, findsOneWidget);
@@ -135,6 +147,9 @@
app.main();
await tester.pumpAndSettle();
+ // TODO(nurhan): https://github.com/flutter/flutter/issues/51885
+ SystemChannels.textInput.setMockMethodCallHandler(null);
+
// Focus on a TextFormField.
final Finder finder = find.byKey(const Key('input'));
expect(finder, findsOneWidget);
@@ -182,6 +197,9 @@
app.main();
await tester.pumpAndSettle();
+ // TODO(nurhan): https://github.com/flutter/flutter/issues/51885
+ SystemChannels.textInput.setMockMethodCallHandler(null);
+
// Select something from the selectable text.
final Finder finder = find.byKey(const Key('selectable'));
expect(finder, findsOneWidget);
diff --git a/examples/hello_world/test_driver/smoke_web_engine_test.dart b/examples/hello_world/test_driver/smoke_web_engine_test.dart
index b289222..2ca900c 100644
--- a/examples/hello_world/test_driver/smoke_web_engine_test.dart
+++ b/examples/hello_world/test_driver/smoke_web_engine_test.dart
@@ -5,7 +5,7 @@
import 'dart:async';
import 'package:flutter_driver/flutter_driver.dart';
-import 'package:test/test.dart';
+import 'package:test/test.dart' hide TypeMatcher, isInstanceOf;
import 'package:webdriver/async_io.dart';
/// The following test is used as a simple smoke test for verifying Flutter
@@ -33,7 +33,6 @@
test('enable accessibility', () async {
await driver.enableAccessibility();
- // TODO(ianh): this delay violates our style guide. We should instead wait for a triggering event.
await Future<void>.delayed(const Duration(seconds: 2));
// Elements with tag "flt-semantics" would show up after enabling
diff --git a/packages/flutter/lib/src/foundation/binding.dart b/packages/flutter/lib/src/foundation/binding.dart
index 71fe7cd..97a9237 100644
--- a/packages/flutter/lib/src/foundation/binding.dart
+++ b/packages/flutter/lib/src/foundation/binding.dart
@@ -104,8 +104,8 @@
/// A number of additional bindings are defined as extensions of
/// [BindingBase], e.g., [ServicesBinding], [RendererBinding], and
/// [WidgetsBinding]. Each of these bindings define behaviors that interact
- /// with a [ui.PlatformDispatcher], e.g., [ServicesBinding] registers
- /// listeners with the [ChannelBuffers], and [RendererBinding]
+ /// with a [ui.PlatformDispatcher], e.g., [ServicesBinding] registers a
+ /// [ui.PlatformDispatcher.onPlatformMessage] handler, and [RendererBinding]
/// registers [ui.PlatformDispatcher.onMetricsChanged],
/// [ui.PlatformDispatcher.onTextScaleFactorChanged],
/// [ui.PlatformDispatcher.onSemanticsEnabledChanged], and
diff --git a/packages/flutter/lib/src/services/binary_messenger.dart b/packages/flutter/lib/src/services/binary_messenger.dart
index 1acf6f5..39ac547 100644
--- a/packages/flutter/lib/src/services/binary_messenger.dart
+++ b/packages/flutter/lib/src/services/binary_messenger.dart
@@ -2,9 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+
import 'dart:typed_data';
import 'dart:ui' as ui;
+import 'binding.dart';
+
/// A function which takes a platform message and asynchronously returns an encoded response.
typedef MessageHandler = Future<ByteData?>? Function(ByteData? message);
@@ -16,39 +19,12 @@
/// const constructors so that they can be used in const expressions.
const BinaryMessenger();
- /// Queues a message.
+ /// Calls the handler registered for the given channel.
///
- /// The returned future completes immediately.
- ///
- /// This method adds the provided message to the given channel (named by the
- /// `channel` argument) of the [ChannelBuffers] object. This simulates what
- /// happens when a plugin on the platform thread (e.g. Kotlin or Swift code)
- /// sends a message to the plugin package on the Dart thread.
- ///
- /// The `data` argument contains the message as encoded bytes. (The format
- /// used for the message depends on the channel.)
- ///
- /// The `callback` argument, if non-null, is eventually invoked with the
- /// response that would have been sent to the platform thread.
- ///
- /// In production code, it is more efficient to call
- /// `ServicesBinding.instance.channelBuffers.push` directly.
- ///
- /// In tests, consider using
- /// `tester.binding.defaultBinaryMessenger.handlePlatformMessage` (see
- /// [WidgetTester], [TestWidgetsFlutterBinding], [TestDefaultBinaryMessenger],
- /// and [TestDefaultBinaryMessenger.handlePlatformMessage] respectively).
+ /// Typically called by [ServicesBinding] to handle platform messages received
+ /// from [dart:ui.PlatformDispatcher.onPlatformMessage].
///
/// To register a handler for a given message channel, see [setMessageHandler].
- ///
- /// To send a message _to_ a plugin on the platform thread, see [send].
- // TODO(ianh): deprecate this method once cocoon and other customer_tests are migrated:
- // @NotYetDeprecated(
- // 'Instead of calling this method, use ServicesBinding.instance.channelBuffers.push. '
- // 'In tests, consider using tester.binding.defaultBinaryMessenger.handlePlatformMessage '
- // 'or TestDefaultBinaryMessenger.instance.defaultBinaryMessenger.handlePlatformMessage. '
- // 'This feature was deprecated after v2.1.0-10.0.pre.'
- // )
Future<void> handlePlatformMessage(String channel, ByteData? data, ui.PlatformMessageResponseCallback? callback);
/// Send a binary message to the platform plugins on the given channel.
@@ -67,6 +43,37 @@
/// The handler's return value, if non-null, is sent as a response, unencoded.
void setMessageHandler(String channel, MessageHandler? handler);
- // Looking for setMockMessageHandler or checkMockMessageHandler?
- // See this shim package: packages/flutter_test/lib/src/deprecated.dart
+ /// Returns true if the `handler` argument matches the `handler` previously
+ /// passed to [setMessageHandler].
+ ///
+ /// This method is useful for tests or test harnesses that want to assert the
+ /// handler for the specified channel has not been altered by a previous test.
+ ///
+ /// Passing null for the `handler` returns true if the handler for the
+ /// `channel` is not set.
+ bool checkMessageHandler(String channel, MessageHandler? handler);
+
+ /// Set a mock callback for intercepting messages from the [send] method on
+ /// this class, on the given channel, without decoding them.
+ ///
+ /// The given callback will replace the currently registered mock callback for
+ /// that channel, if any. To remove the mock handler, pass null as the
+ /// `handler` argument.
+ ///
+ /// The handler's return value, if non-null, is used as a response, unencoded.
+ ///
+ /// This is intended for testing. Messages intercepted in this manner are not
+ /// sent to platform plugins.
+ void setMockMessageHandler(String channel, MessageHandler? handler);
+
+ /// Returns true if the `handler` argument matches the `handler` previously
+ /// passed to [setMockMessageHandler].
+ ///
+ /// This method is useful for tests or test harnesses that want to assert the
+ /// mock handler for the specified channel has not been altered by a previous
+ /// test.
+ ///
+ /// Passing null for the `handler` returns true if the handler for the
+ /// `channel` is not set.
+ bool checkMockMessageHandler(String channel, MessageHandler? handler);
}
diff --git a/packages/flutter/lib/src/services/binding.dart b/packages/flutter/lib/src/services/binding.dart
index d0e6bca..9ddca8a 100644
--- a/packages/flutter/lib/src/services/binding.dart
+++ b/packages/flutter/lib/src/services/binding.dart
@@ -30,6 +30,7 @@
_instance = this;
_defaultBinaryMessenger = createBinaryMessenger();
_restorationManager = createRestorationManager();
+ window.onPlatformMessage = defaultBinaryMessenger.handlePlatformMessage;
initLicenses();
SystemChannels.system.setMessageHandler((dynamic message) => handleSystemMessage(message as Object));
SystemChannels.lifecycle.setMessageHandler(_handleLifecycleMessage);
@@ -48,28 +49,6 @@
BinaryMessenger get defaultBinaryMessenger => _defaultBinaryMessenger;
late BinaryMessenger _defaultBinaryMessenger;
- /// The low level buffering and dispatch mechanism for messages sent by
- /// plugins on the engine side to their corresponding plugin code on
- /// the framework side.
- ///
- /// This exposes the [dart:ui.channelBuffers] object. Bindings can override
- /// this getter to intercept calls to the [ChannelBuffers] mechanism (for
- /// example, for tests).
- ///
- /// In production, direct access to this object should not be necessary.
- /// Messages are received and dispatched by the [defaultBinaryMessenger]. This
- /// object is primarily used to send mock messages in tests, via the
- /// [ChannelBuffers.push] method (simulating a plugin sending a message to the
- /// framework).
- ///
- /// See also:
- ///
- /// * [PlatformDispatcher.sendPlatformMessage], which is used for sending
- /// messages to plugins from the framework (the opposite of
- /// [channelBuffers]).
- /// * [platformDispatcher], the [PlatformDispatcher] singleton.
- ui.ChannelBuffers get channelBuffers => ui.channelBuffers;
-
/// Creates a default [BinaryMessenger] instance that can be used for sending
/// platform messages.
@protected
@@ -77,6 +56,7 @@
return const _DefaultBinaryMessenger._();
}
+
/// Called when the operating system notifies the application of a memory
/// pressure situation.
///
@@ -273,20 +253,17 @@
class _DefaultBinaryMessenger extends BinaryMessenger {
const _DefaultBinaryMessenger._();
- @override
- Future<void> handlePlatformMessage(
- String channel,
- ByteData? message,
- ui.PlatformMessageResponseCallback? callback,
- ) async {
- ui.channelBuffers.push(channel, message, (ByteData? data) {
- if (callback != null)
- callback(data);
- });
- }
+ // Handlers for incoming messages from platform plugins.
+ // This is static so that this class can have a const constructor.
+ static final Map<String, MessageHandler> _handlers =
+ <String, MessageHandler>{};
- @override
- Future<ByteData?> send(String channel, ByteData? message) {
+ // Mock handlers that intercept and respond to outgoing messages.
+ // This is static so that this class can have a const constructor.
+ static final Map<String, MessageHandler> _mockHandlers =
+ <String, MessageHandler>{};
+
+ Future<ByteData?> _sendPlatformMessage(String channel, ByteData? message) {
final Completer<ByteData?> completer = Completer<ByteData?>();
// ui.PlatformDispatcher.instance is accessed directly instead of using
// ServicesBinding.instance.platformDispatcher because this method might be
@@ -295,8 +272,6 @@
// ui.PlatformDispatcher.instance because the PlatformDispatcher may be
// dependency injected elsewhere with a different instance. However, static
// access at this location seems to be the least bad option.
- // TODO(ianh): Use ServicesBinding.instance once we have better diagnostics
- // on that getter.
ui.PlatformDispatcher.instance.sendPlatformMessage(channel, message, (ByteData? reply) {
try {
completer.complete(reply);
@@ -313,26 +288,69 @@
}
@override
+ // TODO(goderbauer): Add pragma (and enable test in
+ // break_on_framework_exceptions_test.dart) when it works on async methods,
+ // https://github.com/dart-lang/sdk/issues/45673
+ // @pragma('vm:notify-debugger-on-exception')
+ Future<void> handlePlatformMessage(
+ String channel,
+ ByteData? data,
+ ui.PlatformMessageResponseCallback? callback,
+ ) async {
+ ByteData? response;
+ try {
+ final MessageHandler? handler = _handlers[channel];
+ if (handler != null) {
+ response = await handler(data);
+ } else {
+ ui.channelBuffers.push(channel, data, callback!);
+ callback = null;
+ }
+ } catch (exception, stack) {
+ FlutterError.reportError(FlutterErrorDetails(
+ exception: exception,
+ stack: stack,
+ library: 'services library',
+ context: ErrorDescription('during a platform message callback'),
+ ));
+ } finally {
+ if (callback != null) {
+ callback(response);
+ }
+ }
+ }
+
+ @override
+ Future<ByteData?>? send(String channel, ByteData? message) {
+ final MessageHandler? handler = _mockHandlers[channel];
+ if (handler != null)
+ return handler(message);
+ return _sendPlatformMessage(channel, message);
+ }
+
+ @override
void setMessageHandler(String channel, MessageHandler? handler) {
if (handler == null) {
- ui.channelBuffers.clearListener(channel);
+ _handlers.remove(channel);
} else {
- ui.channelBuffers.setListener(channel, (ByteData? data, ui.PlatformMessageResponseCallback callback) async {
- ByteData? response;
- try {
- response = await handler(data);
- } catch (exception, stack) {
-
- FlutterError.reportError(FlutterErrorDetails(
- exception: exception,
- stack: stack,
- library: 'services library',
- context: ErrorDescription('during a platform message callback'),
- ));
- } finally {
- callback(response);
- }
+ _handlers[channel] = handler;
+ ui.channelBuffers.drain(channel, (ByteData? data, ui.PlatformMessageResponseCallback callback) async {
+ await handlePlatformMessage(channel, data, callback);
});
}
}
+
+ @override
+ bool checkMessageHandler(String channel, MessageHandler? handler) => _handlers[channel] == handler;
+
+ @override
+ void setMockMessageHandler(String channel, MessageHandler? handler) {
+ if (handler == null)
+ _mockHandlers.remove(channel);
+ else
+ _mockHandlers[channel] = handler;
+ }
+
+ @override
+ bool checkMockMessageHandler(String channel, MessageHandler? handler) => _mockHandlers[channel] == handler;
}
diff --git a/packages/flutter/lib/src/services/message_codec.dart b/packages/flutter/lib/src/services/message_codec.dart
index ba99134..c312972 100644
--- a/packages/flutter/lib/src/services/message_codec.dart
+++ b/packages/flutter/lib/src/services/message_codec.dart
@@ -95,6 +95,7 @@
ByteData encodeErrorEnvelope({ required String code, String? message, Object? details});
}
+
/// Thrown to indicate that a platform interaction failed in the platform
/// plugin.
///
diff --git a/packages/flutter/lib/src/services/platform_channel.dart b/packages/flutter/lib/src/services/platform_channel.dart
index c93c445..c9bad0e 100644
--- a/packages/flutter/lib/src/services/platform_channel.dart
+++ b/packages/flutter/lib/src/services/platform_channel.dart
@@ -75,10 +75,31 @@
}
}
- // Looking for setMockMessageHandler?
- // See this shim package: packages/flutter_test/lib/src/deprecated.dart
+ /// Sets a mock callback for intercepting messages sent on this channel.
+ /// Messages may be null.
+ ///
+ /// The given callback will replace the currently registered mock callback for
+ /// this channel, if any. To remove the mock handler, pass null as the
+ /// `handler` argument.
+ ///
+ /// The handler's return value is used as a message reply. It may be null.
+ ///
+ /// This is intended for testing. Messages intercepted in this manner are not
+ /// sent to platform plugins.
+ void setMockMessageHandler(Future<T> Function(T? message)? handler) {
+ if (handler == null) {
+ binaryMessenger.setMockMessageHandler(name, null);
+ } else {
+ binaryMessenger.setMockMessageHandler(name, (ByteData? message) async {
+ return codec.encodeMessage(await handler(codec.decodeMessage(message)));
+ });
+ }
+ }
}
+Expando<Object> _methodChannelHandlers = Expando<Object>();
+Expando<Object> _methodChannelMockHandlers = Expando<Object>();
+
/// A named channel for communicating with platform plugins using asynchronous
/// method calls.
///
@@ -353,6 +374,7 @@
/// similarly to what happens if no method call handler has been set.
/// Any other exception results in an error envelope being sent.
void setMethodCallHandler(Future<dynamic> Function(MethodCall call)? handler) {
+ _methodChannelHandlers[this] = handler;
binaryMessenger.setMessageHandler(
name,
handler == null
@@ -361,7 +383,53 @@
);
}
- Future<ByteData?> _handleAsMethodCall(ByteData? message, Future<dynamic> Function(MethodCall call) handler) async {
+ /// Returns true if the `handler` argument matches the `handler` previously
+ /// passed to [setMethodCallHandler].
+ ///
+ /// This method is useful for tests or test harnesses that want to assert the
+ /// handler for the specified channel has not been altered by a previous test.
+ ///
+ /// Passing null for the `handler` returns true if the handler for the channel
+ /// is not set.
+ bool checkMethodCallHandler(Future<dynamic> Function(MethodCall call)? handler) => _methodChannelHandlers[this] == handler;
+
+ /// Sets a mock callback for intercepting method invocations on this channel.
+ ///
+ /// The given callback will replace the currently registered mock callback for
+ /// this channel, if any. To remove the mock handler, pass null as the
+ /// `handler` argument.
+ ///
+ /// Later calls to [invokeMethod] will result in a successful result,
+ /// a [PlatformException] or a [MissingPluginException], determined by how
+ /// the future returned by the mock callback completes. The [codec] of this
+ /// channel is used to encode and decode values and errors.
+ ///
+ /// This is intended for testing. Method calls intercepted in this manner are
+ /// not sent to platform plugins.
+ ///
+ /// The provided `handler` must return a `Future` that completes with the
+ /// return value of the call. The value will be encoded using
+ /// [MethodCodec.encodeSuccessEnvelope], to act as if platform plugin had
+ /// returned that value.
+ void setMockMethodCallHandler(Future<dynamic>? Function(MethodCall call)? handler) {
+ _methodChannelMockHandlers[this] = handler;
+ binaryMessenger.setMockMessageHandler(
+ name,
+ handler == null ? null : (ByteData? message) => _handleAsMethodCall(message, handler),
+ );
+ }
+
+ /// Returns true if the `handler` argument matches the `handler` previously
+ /// passed to [setMockMethodCallHandler].
+ ///
+ /// This method is useful for tests or test harnesses that want to assert the
+ /// handler for the specified channel has not been altered by a previous test.
+ ///
+ /// Passing null for the `handler` returns true if the handler for the channel
+ /// is not set.
+ bool checkMockMethodCallHandler(Future<dynamic> Function(MethodCall call)? handler) => _methodChannelMockHandlers[this] == handler;
+
+ Future<ByteData?> _handleAsMethodCall(ByteData? message, Future<dynamic>? Function(MethodCall call) handler) async {
final MethodCall call = codec.decodeMethodCall(message);
try {
return codec.encodeSuccessEnvelope(await handler(call));
@@ -377,9 +445,6 @@
return codec.encodeErrorEnvelope(code: 'error', message: e.toString(), details: null);
}
}
-
- // Looking for setMockMethodCallHandler or checkMethodCallHandler?
- // See this shim package: packages/flutter_test/lib/src/deprecated.dart
}
/// A [MethodChannel] that ignores missing platform plugins.
@@ -407,6 +472,7 @@
final Map<dynamic, dynamic>? result = await invokeMethod<Map<dynamic, dynamic>>(method, arguments);
return result?.cast<K, V>();
}
+
}
/// A named channel for communicating with platform plugins using event streams.
diff --git a/packages/flutter/lib/src/services/restoration.dart b/packages/flutter/lib/src/services/restoration.dart
index 4395699..ab42efa 100644
--- a/packages/flutter/lib/src/services/restoration.dart
+++ b/packages/flutter/lib/src/services/restoration.dart
@@ -166,6 +166,7 @@
/// that communications channel, or to set it up differently, as necessary.
@protected
void initChannels() {
+ assert(!SystemChannels.restoration.checkMethodCallHandler(_methodHandler));
SystemChannels.restoration.setMethodCallHandler(_methodHandler);
}
diff --git a/packages/flutter/lib/src/services/system_channels.dart b/packages/flutter/lib/src/services/system_channels.dart
index 4ab2b27..43e6bf2 100644
--- a/packages/flutter/lib/src/services/system_channels.dart
+++ b/packages/flutter/lib/src/services/system_channels.dart
@@ -120,11 +120,6 @@
/// they apply, so that stale messages referencing past transactions can be
/// ignored.
///
- /// In debug builds, messages sent with a client ID of -1 are always accepted.
- /// This allows tests to smuggle messages without having to mock the engine's
- /// text handling (for example, allowing the engine to still handle the text
- /// input messages in an integration test).
- ///
/// The methods described below are wrapped in a more convenient form by the
/// [TextInput] and [TextInputConnection] class.
///
@@ -157,15 +152,9 @@
/// is a transaction identifier. Calls for stale transactions should be ignored.
///
/// * `TextInputClient.updateEditingState`: The user has changed the contents
- /// of the text control. The second argument is an object with seven keys,
- /// in the form expected by [TextEditingValue.fromJSON].
- ///
- /// * `TextInputClient.updateEditingStateWithTag`: One or more text controls
- /// were autofilled by the platform's autofill service. The first argument
- /// (the client ID) is ignored, the second argument is a map of tags to
- /// objects in the form expected by [TextEditingValue.fromJSON]. See
- /// [AutofillScope.getAutofillClient] for details on the interpretation of
- /// the tag.
+ /// of the text control. The second argument is a [String] containing a
+ /// JSON-encoded object with seven keys, in the form expected by
+ /// [TextEditingValue.fromJSON].
///
/// * `TextInputClient.performAction`: The user has triggered an action. The
/// second argument is a [String] consisting of the stringification of one
@@ -176,8 +165,7 @@
/// one. The framework should call `TextInput.setClient` and
/// `TextInput.setEditingState` again with its most recent information. If
/// there is no existing state on the framework side, the call should
- /// fizzle. (This call is made without a client ID; indeed, without any
- /// arguments at all.)
+ /// fizzle.
///
/// * `TextInputClient.onConnectionClosed`: The text input connection closed
/// on the platform side. For example the application is moved to
diff --git a/packages/flutter/lib/src/services/text_input.dart b/packages/flutter/lib/src/services/text_input.dart
index 0e0c637..bac572f 100644
--- a/packages/flutter/lib/src/services/text_input.dart
+++ b/packages/flutter/lib/src/services/text_input.dart
@@ -1327,11 +1327,9 @@
final List<dynamic> args = methodCall.arguments as List<dynamic>;
- // The updateEditingStateWithTag request (autofill) can come up even to a
- // text field that doesn't have a connection.
if (method == 'TextInputClient.updateEditingStateWithTag') {
- assert(_currentConnection!._client != null);
final TextInputClient client = _currentConnection!._client;
+ assert(client != null);
final AutofillScope? scope = client.currentAutofillScope;
final Map<String, dynamic> editingValue = args[1] as Map<String, dynamic>;
for (final String tag in editingValue.keys) {
@@ -1345,22 +1343,9 @@
}
final int client = args[0] as int;
- if (client != _currentConnection!._id) {
- // If the client IDs don't match, the incoming message was for a different
- // client.
- bool debugAllowAnyway = false;
- assert(() {
- // In debug builds we allow "-1" as a magical client ID that ignores
- // this verification step so that tests can always get through, even
- // when they are not mocking the engine side of text input.
- if (client == -1)
- debugAllowAnyway = true;
- return true;
- }());
- if (!debugAllowAnyway)
- return;
- }
-
+ // The incoming message was for a different client.
+ if (client != _currentConnection!._id)
+ return;
switch (method) {
case 'TextInputClient.updateEditingState':
_currentConnection!._client.updateEditingValue(TextEditingValue.fromJSON(args[1] as Map<String, dynamic>));
@@ -1517,7 +1502,7 @@
assert(shouldSave != null);
TextInput._instance._channel.invokeMethod<void>(
'TextInput.finishAutofillContext',
- shouldSave,
+ shouldSave ,
);
}
}
diff --git a/packages/flutter/lib/src/widgets/editable_text.dart b/packages/flutter/lib/src/widgets/editable_text.dart
index 4b1fbdb..498550e 100644
--- a/packages/flutter/lib/src/widgets/editable_text.dart
+++ b/packages/flutter/lib/src/widgets/editable_text.dart
@@ -2112,7 +2112,7 @@
if (_hasFocus) {
_openInputConnection();
} else {
- widget.focusNode.requestFocus(); // This eventually calls _openInputConnection also, see _handleFocusChanged.
+ widget.focusNode.requestFocus();
}
}
@@ -2360,13 +2360,11 @@
void _cursorWaitForStart(Timer timer) {
assert(_kCursorBlinkHalfPeriod > _fadeDuration);
- assert(!EditableText.debugDeterministicCursor);
_cursorTimer?.cancel();
_cursorTimer = Timer.periodic(_kCursorBlinkHalfPeriod, _cursorTick);
}
void _startCursorTimer() {
- assert(_cursorTimer == null);
_targetCursorVisibility = true;
_cursorBlinkOpacityController.value = 1.0;
if (EditableText.debugDeterministicCursor)
diff --git a/packages/flutter/test/cupertino/picker_test.dart b/packages/flutter/test/cupertino/picker_test.dart
index 6e5f655..df0fd15 100644
--- a/packages/flutter/test/cupertino/picker_test.dart
+++ b/packages/flutter/test/cupertino/picker_test.dart
@@ -201,7 +201,7 @@
final List<int> selectedItems = <int>[];
final List<MethodCall> systemCalls = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
systemCalls.add(methodCall);
});
@@ -254,7 +254,7 @@
final List<int> selectedItems = <int>[];
final List<MethodCall> systemCalls = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
systemCalls.add(methodCall);
});
diff --git a/packages/flutter/test/cupertino/refresh_test.dart b/packages/flutter/test/cupertino/refresh_test.dart
index 02b41cc..e01e24c 100644
--- a/packages/flutter/test/cupertino/refresh_test.dart
+++ b/packages/flutter/test/cupertino/refresh_test.dart
@@ -175,7 +175,7 @@
testWidgets('drag past threshold triggers refresh task', (WidgetTester tester) async {
final List<MethodCall> platformCallLog = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
platformCallLog.add(methodCall);
});
diff --git a/packages/flutter/test/cupertino/scrollbar_test.dart b/packages/flutter/test/cupertino/scrollbar_test.dart
index ba14bae..8977e2a 100644
--- a/packages/flutter/test/cupertino/scrollbar_test.dart
+++ b/packages/flutter/test/cupertino/scrollbar_test.dart
@@ -132,9 +132,9 @@
await tester.pump();
int hapticFeedbackCalls = 0;
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'HapticFeedback.vibrate') {
- hapticFeedbackCalls += 1;
+ hapticFeedbackCalls++;
}
});
@@ -692,9 +692,9 @@
await tester.pump();
int hapticFeedbackCalls = 0;
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'HapticFeedback.vibrate') {
- hapticFeedbackCalls += 1;
+ hapticFeedbackCalls++;
}
});
diff --git a/packages/flutter/test/cupertino/switch_test.dart b/packages/flutter/test/cupertino/switch_test.dart
index 6cd48bf..9c475b4 100644
--- a/packages/flutter/test/cupertino/switch_test.dart
+++ b/packages/flutter/test/cupertino/switch_test.dart
@@ -47,7 +47,7 @@
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -87,7 +87,7 @@
bool value2 = false;
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -154,7 +154,7 @@
bool value = false;
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -192,7 +192,7 @@
bool value = false;
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
diff --git a/packages/flutter/test/cupertino/text_field_test.dart b/packages/flutter/test/cupertino/text_field_test.dart
index ca6edb2..86da35a 100644
--- a/packages/flutter/test/cupertino/text_field_test.dart
+++ b/packages/flutter/test/cupertino/text_field_test.dart
@@ -162,7 +162,7 @@
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final MockClipboard mockClipboard = MockClipboard();
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
+ SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
// Returns the first RenderEditable.
RenderEditable findRenderEditable(WidgetTester tester) {
@@ -3228,7 +3228,7 @@
testWidgets('text field respects keyboardAppearance from theme', (WidgetTester tester) async {
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
+ SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -3251,7 +3251,7 @@
testWidgets('text field can override keyboardAppearance from theme', (WidgetTester tester) async {
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
+ SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
diff --git a/packages/flutter/test/cupertino/text_selection_test.dart b/packages/flutter/test/cupertino/text_selection_test.dart
index 3f27490..b67d27e 100644
--- a/packages/flutter/test/cupertino/text_selection_test.dart
+++ b/packages/flutter/test/cupertino/text_selection_test.dart
@@ -66,7 +66,7 @@
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final MockClipboard mockClipboard = MockClipboard();
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
+ SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
// Returns true iff the button is visually enabled.
bool appearsEnabled(WidgetTester tester, String text) {
diff --git a/packages/flutter/test/foundation/service_extensions_test.dart b/packages/flutter/test/foundation/service_extensions_test.dart
index a36f5bc..dd7ae1a 100644
--- a/packages/flutter/test/foundation/service_extensions_test.dart
+++ b/packages/flutter/test/foundation/service_extensions_test.dart
@@ -21,8 +21,7 @@
PaintingBinding,
SemanticsBinding,
RendererBinding,
- WidgetsBinding,
- TestDefaultBinaryMessengerBinding {
+ WidgetsBinding {
final Map<String, ServiceExtensionCallback> extensions = <String, ServiceExtensionCallback>{};
@@ -468,7 +467,7 @@
bool completed;
completed = false;
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (ByteData? message) async {
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (ByteData? message) async {
expect(utf8.decode(message!.buffer.asUint8List()), 'test');
completed = true;
return ByteData(5); // 0x0000000000
@@ -495,7 +494,7 @@
});
expect(data, isFalse);
expect(completed, isTrue);
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', null);
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', null);
});
test('Service extensions - exit', () async {
diff --git a/packages/flutter/test/gestures/gesture_binding_resample_event_on_widget_test.dart b/packages/flutter/test/gestures/gesture_binding_resample_event_on_widget_test.dart
index 65d8f76..3c3e397 100644
--- a/packages/flutter/test/gestures/gesture_binding_resample_event_on_widget_test.dart
+++ b/packages/flutter/test/gestures/gesture_binding_resample_event_on_widget_test.dart
@@ -2,6 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// Logically this file should be part of `gesture_binding_test.dart` but is here
+// due to conflict of `flutter_test` and `package:test`.
+// See https://github.com/dart-lang/matcher/issues/98
+// TODO(CareF): Consider combine this file back to `gesture_binding_test.dart`
+// after #98 is fixed.
+
import 'dart:ui' as ui;
import 'package:clock/clock.dart';
diff --git a/packages/flutter/test/material/checkbox_test.dart b/packages/flutter/test/material/checkbox_test.dart
index 6c03f41..d477588 100644
--- a/packages/flutter/test/material/checkbox_test.dart
+++ b/packages/flutter/test/material/checkbox_test.dart
@@ -267,7 +267,7 @@
testWidgets('has semantic events', (WidgetTester tester) async {
dynamic semanticEvent;
bool? checkboxValue = false;
- tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
+ SystemChannels.accessibility.setMockMessageHandler((dynamic message) async {
semanticEvent = message;
});
final SemanticsTester semanticsTester = SemanticsTester(tester);
@@ -300,7 +300,7 @@
});
expect(object.debugSemantics!.getSemanticsData().hasAction(SemanticsAction.tap), true);
- tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
+ SystemChannels.accessibility.setMockMessageHandler(null);
semanticsTester.dispose();
});
diff --git a/packages/flutter/test/material/feedback_test.dart b/packages/flutter/test/material/feedback_test.dart
index 3f80ff8..06a016c 100644
--- a/packages/flutter/test/material/feedback_test.dart
+++ b/packages/flutter/test/material/feedback_test.dart
@@ -27,14 +27,14 @@
setUp(() {
semanticEvents = <Map<String, Object>>[];
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
+ SystemChannels.accessibility.setMockMessageHandler((dynamic message) async {
final Map<dynamic, dynamic> typedMessage = message as Map<dynamic, dynamic>;
semanticEvents.add(typedMessage.cast<String, Object>());
});
});
tearDown(() {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
+ SystemChannels.accessibility.setMockMessageHandler(null);
});
testWidgets('forTap', (WidgetTester tester) async {
diff --git a/packages/flutter/test/material/feedback_tester.dart b/packages/flutter/test/material/feedback_tester.dart
index c65d994..5f1c469 100644
--- a/packages/flutter/test/material/feedback_tester.dart
+++ b/packages/flutter/test/material/feedback_tester.dart
@@ -3,7 +3,6 @@
// found in the LICENSE file.
import 'package:flutter/services.dart';
-import 'package:flutter_test/flutter_test.dart';
/// Tracks how often feedback has been requested since its instantiation.
///
@@ -11,7 +10,13 @@
/// cannot be used in combination with other classes that do the same.
class FeedbackTester {
FeedbackTester() {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, _handler);
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
+ if (methodCall.method == 'HapticFeedback.vibrate')
+ _hapticCount++;
+ if (methodCall.method == 'SystemSound.play' &&
+ methodCall.arguments == SystemSoundType.click.toString())
+ _clickSoundCount++;
+ });
}
/// Number of times haptic feedback was requested (vibration).
@@ -22,17 +27,8 @@
int get clickSoundCount => _clickSoundCount;
int _clickSoundCount = 0;
- Future<void> _handler(MethodCall methodCall) async {
- if (methodCall.method == 'HapticFeedback.vibrate')
- _hapticCount++;
- if (methodCall.method == 'SystemSound.play' &&
- methodCall.arguments == SystemSoundType.click.toString())
- _clickSoundCount++;
- }
-
/// Stops tracking.
void dispose() {
- assert(TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.checkMockMessageHandler(SystemChannels.platform.name, _handler));
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null);
+ SystemChannels.platform.setMockMethodCallHandler(null);
}
}
diff --git a/packages/flutter/test/material/input_date_picker_form_field_test.dart b/packages/flutter/test/material/input_date_picker_form_field_test.dart
index 2e9c376..1ffe812 100644
--- a/packages/flutter/test/material/input_date_picker_form_field_test.dart
+++ b/packages/flutter/test/material/input_date_picker_form_field_test.dart
@@ -241,9 +241,9 @@
// Fill the clipboard so that the Paste option is available in the text
// selection menu.
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
+ SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
await Clipboard.setData(const ClipboardData(text: 'Clipboard data'));
- addTearDown(() => tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null));
+ addTearDown(() => SystemChannels.platform.setMockMethodCallHandler(null));
await tester.pumpWidget(_inputDatePickerField(autofocus: true));
await tester.pumpAndSettle();
diff --git a/packages/flutter/test/material/radio_list_tile_test.dart b/packages/flutter/test/material/radio_list_tile_test.dart
index 332ee8f..07f4ced 100644
--- a/packages/flutter/test/material/radio_list_tile_test.dart
+++ b/packages/flutter/test/material/radio_list_tile_test.dart
@@ -537,7 +537,7 @@
final Key key = UniqueKey();
dynamic semanticEvent;
int? radioValue = 2;
- tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
+ SystemChannels.accessibility.setMockMessageHandler((dynamic message) async {
semanticEvent = message;
});
@@ -568,7 +568,7 @@
expect(object.debugSemantics!.getSemanticsData().hasAction(SemanticsAction.tap), true);
semantics.dispose();
- tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
+ SystemChannels.accessibility.setMockMessageHandler(null);
});
testWidgets('RadioListTile can autofocus unless disabled.', (WidgetTester tester) async {
diff --git a/packages/flutter/test/material/radio_test.dart b/packages/flutter/test/material/radio_test.dart
index 048e147..bd8efbb 100644
--- a/packages/flutter/test/material/radio_test.dart
+++ b/packages/flutter/test/material/radio_test.dart
@@ -292,7 +292,7 @@
final Key key = UniqueKey();
dynamic semanticEvent;
int? radioValue = 2;
- tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
+ SystemChannels.accessibility.setMockMessageHandler((dynamic message) async {
semanticEvent = message;
});
@@ -319,7 +319,7 @@
expect(object.debugSemantics!.getSemanticsData().hasAction(SemanticsAction.tap), true);
semantics.dispose();
- tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
+ SystemChannels.accessibility.setMockMessageHandler(null);
});
testWidgets('Radio ink ripple is displayed correctly', (WidgetTester tester) async {
diff --git a/packages/flutter/test/material/search_test.dart b/packages/flutter/test/material/search_test.dart
index 32c968f..c3444bb 100644
--- a/packages/flutter/test/material/search_test.dart
+++ b/packages/flutter/test/material/search_test.dart
@@ -32,12 +32,12 @@
setUp(() async {
// Fill the clipboard so that the Paste option is available in the text
// selection menu.
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
+ SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
await Clipboard.setData(const ClipboardData(text: 'Clipboard data'));
});
tearDown(() {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null);
+ SystemChannels.platform.setMockMethodCallHandler(null);
});
testWidgets('Can open and close search', (WidgetTester tester) async {
diff --git a/packages/flutter/test/material/switch_test.dart b/packages/flutter/test/material/switch_test.dart
index 34199a7..b3d8f32 100644
--- a/packages/flutter/test/material/switch_test.dart
+++ b/packages/flutter/test/material/switch_test.dart
@@ -577,7 +577,7 @@
testWidgets('switch has semantic events', (WidgetTester tester) async {
dynamic semanticEvent;
bool value = false;
- tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
+ SystemChannels.accessibility.setMockMessageHandler((dynamic message) async {
semanticEvent = message;
});
final SemanticsTester semanticsTester = SemanticsTester(tester);
@@ -615,13 +615,13 @@
expect(object.debugSemantics!.getSemanticsData().hasAction(SemanticsAction.tap), true);
semanticsTester.dispose();
- tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
+ SystemChannels.accessibility.setMockMessageHandler(null);
});
testWidgets('switch sends semantic events from parent if fully merged', (WidgetTester tester) async {
dynamic semanticEvent;
bool value = false;
- tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
+ SystemChannels.accessibility.setMockMessageHandler((dynamic message) async {
semanticEvent = message;
});
final SemanticsTester semanticsTester = SemanticsTester(tester);
@@ -665,7 +665,7 @@
expect(object.debugSemantics!.getSemanticsData().hasAction(SemanticsAction.tap), true);
semanticsTester.dispose();
- tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
+ SystemChannels.accessibility.setMockMessageHandler(null);
});
testWidgets('Switch.adaptive', (WidgetTester tester) async {
diff --git a/packages/flutter/test/material/text_field_test.dart b/packages/flutter/test/material/text_field_test.dart
index 1332a9b..9f40e36 100644
--- a/packages/flutter/test/material/text_field_test.dart
+++ b/packages/flutter/test/material/text_field_test.dart
@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-import 'dart:async';
import 'dart:math' as math;
import 'dart:ui' as ui show window, BoxHeightStyle, BoxWidthStyle;
@@ -165,20 +164,14 @@
setUp(() async {
debugResetSemanticsIdCounter();
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(
- SystemChannels.platform,
- mockClipboard.handleMethodCall,
- );
+ SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
// Fill the clipboard so that the Paste option is available in the text
// selection menu.
await Clipboard.setData(const ClipboardData(text: 'Clipboard data'));
});
tearDown(() {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(
- SystemChannels.platform,
- null,
- );
+ SystemChannels.platform.setMockMethodCallHandler(null);
});
final Key textFieldKey = UniqueKey();
@@ -346,7 +339,7 @@
testWidgets('TextField has consistent size', (WidgetTester tester) async {
final Key textFieldKey = UniqueKey();
- String? textFieldValue;
+ late String textFieldValue;
await tester.pumpWidget(
overlay(
@@ -369,16 +362,15 @@
Future<void> checkText(String testValue) async {
return TestAsyncUtils.guard(() async {
- expect(textFieldValue, isNull);
await tester.enterText(find.byType(TextField), testValue);
// Check that the onChanged event handler fired.
expect(textFieldValue, equals(testValue));
- textFieldValue = null;
await skipPastScrollingAnimation(tester);
});
}
await checkText(' ');
+
expect(findTextFieldBox(), equals(inputBox));
expect(inputBox.size, equals(emptyInputSize));
@@ -424,8 +416,6 @@
text: 'X',
selection: TextSelection.collapsed(offset: 1),
));
- await tester.idle();
- expect(tester.state(find.byType(EditableText)), editableText);
await checkCursorToggle();
});
@@ -4704,8 +4694,8 @@
);
String clipboardContent = '';
- tester.binding.defaultBinaryMessenger
- .setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform
+ .setMockMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'Clipboard.setData')
clipboardContent = methodCall.arguments['text'] as String;
else if (methodCall.method == 'Clipboard.getData')
@@ -4777,8 +4767,8 @@
);
String clipboardContent = '';
- tester.binding.defaultBinaryMessenger
- .setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform
+ .setMockMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'Clipboard.setData')
clipboardContent = methodCall.arguments['text'] as String;
else if (methodCall.method == 'Clipboard.getData')
@@ -4850,8 +4840,8 @@
);
const String clipboardContent = 'I love Flutter!';
- tester.binding.defaultBinaryMessenger
- .setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform
+ .setMockMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'Clipboard.getData')
return <String, dynamic>{'text': clipboardContent};
return null;
@@ -4900,8 +4890,8 @@
maxLines: 3,
);
String clipboardContent = '';
- tester.binding.defaultBinaryMessenger
- .setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform
+ .setMockMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'Clipboard.setData')
clipboardContent = methodCall.arguments['text'] as String;
else if (methodCall.method == 'Clipboard.getData')
@@ -4974,8 +4964,8 @@
obscureText: true,
);
String clipboardContent = '';
- tester.binding.defaultBinaryMessenger
- .setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform
+ .setMockMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'Clipboard.setData')
clipboardContent = methodCall.arguments['text'] as String;
else if (methodCall.method == 'Clipboard.getData')
@@ -9380,8 +9370,8 @@
);
bool triedToReadClipboard = false;
- tester.binding.defaultBinaryMessenger
- .setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform
+ .setMockMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'Clipboard.getData') {
triedToReadClipboard = true;
}
diff --git a/packages/flutter/test/material/text_form_field_test.dart b/packages/flutter/test/material/text_form_field_test.dart
index af077b9..d7c5d21 100644
--- a/packages/flutter/test/material/text_form_field_test.dart
+++ b/packages/flutter/test/material/text_form_field_test.dart
@@ -32,7 +32,7 @@
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final MockClipboard mockClipboard = MockClipboard();
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
+ SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
setUp(() async {
// Fill the clipboard so that the Paste option is available in the text
diff --git a/packages/flutter/test/material/text_selection_test.dart b/packages/flutter/test/material/text_selection_test.dart
index 4fa7537..91bfb43 100644
--- a/packages/flutter/test/material/text_selection_test.dart
+++ b/packages/flutter/test/material/text_selection_test.dart
@@ -28,7 +28,7 @@
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final MockClipboard mockClipboard = MockClipboard();
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
+ SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
setUp(() async {
await Clipboard.setData(const ClipboardData(text: 'clipboard data'));
diff --git a/packages/flutter/test/material/tooltip_test.dart b/packages/flutter/test/material/tooltip_test.dart
index f1f6055..7f37413 100644
--- a/packages/flutter/test/material/tooltip_test.dart
+++ b/packages/flutter/test/material/tooltip_test.dart
@@ -1193,7 +1193,7 @@
testWidgets('has semantic events', (WidgetTester tester) async {
final List<dynamic> semanticEvents = <dynamic>[];
- tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
+ SystemChannels.accessibility.setMockMessageHandler((dynamic message) async {
semanticEvents.add(message);
});
final SemanticsTester semantics = SemanticsTester(tester);
@@ -1230,7 +1230,7 @@
},
]));
semantics.dispose();
- tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
+ SystemChannels.accessibility.setMockMessageHandler(null);
});
testWidgets('default Tooltip debugFillProperties', (WidgetTester tester) async {
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
diff --git a/packages/flutter/test/material/tooltip_theme_test.dart b/packages/flutter/test/material/tooltip_theme_test.dart
index f81d8cc..e18adf1 100644
--- a/packages/flutter/test/material/tooltip_theme_test.dart
+++ b/packages/flutter/test/material/tooltip_theme_test.dart
@@ -1153,7 +1153,7 @@
testWidgets('has semantic events by default - ThemeData.tooltipTheme', (WidgetTester tester) async {
final List<dynamic> semanticEvents = <dynamic>[];
- tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
+ SystemChannels.accessibility.setMockMessageHandler((dynamic message) async {
semanticEvents.add(message);
});
final SemanticsTester semantics = SemanticsTester(tester);
@@ -1191,12 +1191,12 @@
},
]));
semantics.dispose();
- tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
+ SystemChannels.accessibility.setMockMessageHandler(null);
});
testWidgets('has semantic events by default - TooltipTheme', (WidgetTester tester) async {
final List<dynamic> semanticEvents = <dynamic>[];
- tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
+ SystemChannels.accessibility.setMockMessageHandler((dynamic message) async {
semanticEvents.add(message);
});
final SemanticsTester semantics = SemanticsTester(tester);
@@ -1236,7 +1236,7 @@
},
]));
semantics.dispose();
- tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
+ SystemChannels.accessibility.setMockMessageHandler(null);
});
testWidgets('default Tooltip debugFillProperties', (WidgetTester tester) async {
diff --git a/packages/flutter/test/rendering/first_frame_test.dart b/packages/flutter/test/rendering/first_frame_test.dart
index c6fe2c7..6b766c9 100644
--- a/packages/flutter/test/rendering/first_frame_test.dart
+++ b/packages/flutter/test/rendering/first_frame_test.dart
@@ -12,11 +12,11 @@
import 'package:flutter_test/flutter_test.dart';
void main() {
- final TestRenderBinding binding = TestRenderBinding();
test('Flutter dispatches first frame event on the web only', () async {
final Completer<void> completer = Completer<void>();
+ final TestRenderBinding binding = TestRenderBinding();
const MethodChannel firstFrameChannel = MethodChannel('flutter/service_worker');
- binding.defaultBinaryMessenger.setMockMethodCallHandler(firstFrameChannel, (MethodCall methodCall) async {
+ firstFrameChannel.setMockMethodCallHandler((MethodCall methodCall) async {
completer.complete();
});
@@ -27,10 +27,4 @@
}, skip: !kIsWeb);
}
-class TestRenderBinding extends BindingBase
- with SchedulerBinding,
- ServicesBinding,
- GestureBinding,
- SemanticsBinding,
- RendererBinding,
- TestDefaultBinaryMessengerBinding { }
+class TestRenderBinding extends BindingBase with SchedulerBinding, ServicesBinding, GestureBinding, SemanticsBinding, RendererBinding {}
diff --git a/packages/flutter/test/rendering/mouse_tracker_cursor_test.dart b/packages/flutter/test/rendering/mouse_tracker_cursor_test.dart
index 331b2a3..7e8423f 100644
--- a/packages/flutter/test/rendering/mouse_tracker_cursor_test.dart
+++ b/packages/flutter/test/rendering/mouse_tracker_cursor_test.dart
@@ -56,14 +56,14 @@
setUp(() {
_binding.postFrameCallbacks.clear();
- _binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.mouseCursor, (MethodCall call) async {
+ SystemChannels.mouseCursor.setMockMethodCallHandler((MethodCall call) async {
if (_methodCallHandler != null)
return _methodCallHandler!(call);
});
});
tearDown(() {
- _binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.mouseCursor, null);
+ SystemChannels.mouseCursor.setMockMethodCallHandler(null);
});
test('Should work on platforms that does not support mouse cursor', () async {
diff --git a/packages/flutter/test/rendering/mouse_tracker_test_utils.dart b/packages/flutter/test/rendering/mouse_tracker_test_utils.dart
index c4c0906..a5bd1ed 100644
--- a/packages/flutter/test/rendering/mouse_tracker_test_utils.dart
+++ b/packages/flutter/test/rendering/mouse_tracker_test_utils.dart
@@ -9,7 +9,6 @@
import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
-import 'package:flutter_test/flutter_test.dart' show TestDefaultBinaryMessengerBinding;
class _TestHitTester extends RenderBox {
_TestHitTester(this.hitTestOverride);
@@ -25,7 +24,7 @@
// A binding used to test MouseTracker, allowing the test to override hit test
// searching.
class TestMouseTrackerFlutterBinding extends BindingBase
- with SchedulerBinding, ServicesBinding, GestureBinding, SemanticsBinding, RendererBinding, TestDefaultBinaryMessengerBinding {
+ with SchedulerBinding, ServicesBinding, GestureBinding, SemanticsBinding, RendererBinding {
@override
void initInstances() {
super.initInstances();
diff --git a/packages/flutter/test/rendering/rendering_tester.dart b/packages/flutter/test/rendering/rendering_tester.dart
index 65ba5ae..b6b0dd9 100644
--- a/packages/flutter/test/rendering/rendering_tester.dart
+++ b/packages/flutter/test/rendering/rendering_tester.dart
@@ -9,12 +9,12 @@
import 'package:flutter/rendering.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
-import 'package:flutter_test/flutter_test.dart' show TestDefaultBinaryMessengerBinding, EnginePhase, fail;
+import 'package:flutter_test/flutter_test.dart' show EnginePhase, fail;
export 'package:flutter/foundation.dart' show FlutterError, FlutterErrorDetails;
-export 'package:flutter_test/flutter_test.dart' show TestDefaultBinaryMessengerBinding, EnginePhase;
+export 'package:flutter_test/flutter_test.dart' show EnginePhase;
-class TestRenderingFlutterBinding extends BindingBase with SchedulerBinding, ServicesBinding, GestureBinding, PaintingBinding, SemanticsBinding, RendererBinding, TestDefaultBinaryMessengerBinding {
+class TestRenderingFlutterBinding extends BindingBase with SchedulerBinding, ServicesBinding, GestureBinding, PaintingBinding, SemanticsBinding, RendererBinding {
/// Creates a binding for testing rendering library functionality.
///
/// If [onErrors] is not null, it is called if [FlutterError] caught any errors
diff --git a/packages/flutter/test/semantics/semantics_service_test.dart b/packages/flutter/test/semantics/semantics_service_test.dart
index a7ff5e0..b384e0f 100644
--- a/packages/flutter/test/semantics/semantics_service_test.dart
+++ b/packages/flutter/test/semantics/semantics_service_test.dart
@@ -13,13 +13,12 @@
test('Semantic announcement', () async {
final List<Map<dynamic, dynamic>> log = <Map<dynamic, dynamic>>[];
-
Future<dynamic> handleMessage(dynamic mockMessage) async {
final Map<dynamic, dynamic> message = mockMessage as Map<dynamic, dynamic>;
log.add(message);
}
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, handleMessage);
+ SystemChannels.accessibility.setMockMessageHandler(handleMessage);
await SemanticsService.announce('announcement 1', TextDirection.ltr);
await SemanticsService.announce('announcement 2', TextDirection.rtl);
diff --git a/packages/flutter/test/services/autofill_test.dart b/packages/flutter/test/services/autofill_test.dart
index 5af15da..428f6c7 100644
--- a/packages/flutter/test/services/autofill_test.dart
+++ b/packages/flutter/test/services/autofill_test.dart
@@ -191,6 +191,15 @@
incoming = handler;
}
+ @override
+ bool checkMethodCallHandler(Future<void> Function(MethodCall call)? handler) => throw UnimplementedError();
+
+ @override
+ void setMockMethodCallHandler(Future<void>? Function(MethodCall call)? handler) => throw UnimplementedError();
+
+ @override
+ bool checkMockMethodCallHandler(Future<void> Function(MethodCall call)? handler) => throw UnimplementedError();
+
void validateOutgoingMethodCalls(List<MethodCall> calls) {
expect(outgoingCalls.length, calls.length);
bool hasError = false;
diff --git a/packages/flutter/test/services/binding_test.dart b/packages/flutter/test/services/binding_test.dart
index ff92a14..6830810 100644
--- a/packages/flutter/test/services/binding_test.dart
+++ b/packages/flutter/test/services/binding_test.dart
@@ -34,7 +34,7 @@
L2Paragraph3''';
-const String combinedLicenses = '''
+const String licenses = '''
$license1
--------------------------------------------------------------------------------
$license2
@@ -42,25 +42,29 @@
class TestBinding extends BindingBase with SchedulerBinding, ServicesBinding {
@override
- TestDefaultBinaryMessenger get defaultBinaryMessenger => super.defaultBinaryMessenger as TestDefaultBinaryMessenger;
-
- @override
- TestDefaultBinaryMessenger createBinaryMessenger() {
- return TestDefaultBinaryMessenger(super.createBinaryMessenger());
+ BinaryMessenger createBinaryMessenger() {
+ return super.createBinaryMessenger()
+ ..setMockMessageHandler('flutter/assets', (ByteData? message) async {
+ if (const StringCodec().decodeMessage(message) == 'NOTICES') {
+ return const StringCodec().encodeMessage(licenses);
+ }
+ return null;
+ })
+ ..setMockMessageHandler('flutter/assets', (ByteData? message) async {
+ if (const StringCodec().decodeMessage(message) == 'NOTICES.Z' && !kIsWeb) {
+ return Uint8List.fromList(gzip.encode(utf8.encode(licenses))).buffer.asByteData();
+ }
+ if (const StringCodec().decodeMessage(message) == 'NOTICES' && kIsWeb) {
+ return const StringCodec().encodeMessage(licenses);
+ }
+ return null;
+ });
}
}
void main() {
test('Adds rootBundle LICENSES to LicenseRegistry', () async {
- TestBinding().defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (ByteData? message) async {
- if (const StringCodec().decodeMessage(message) == 'NOTICES.Z' && !kIsWeb) {
- return Uint8List.fromList(gzip.encode(utf8.encode(combinedLicenses))).buffer.asByteData();
- }
- if (const StringCodec().decodeMessage(message) == 'NOTICES' && kIsWeb) {
- return const StringCodec().encodeMessage(combinedLicenses);
- }
- return null;
- });
+ TestBinding(); // The test binding registers a mock handler that returns licenses for the LICENSE key
final List<LicenseEntry> licenses = await LicenseRegistry.licenses.toList();
diff --git a/packages/flutter/test/services/default_binary_messenger_test.dart b/packages/flutter/test/services/default_binary_messenger_test.dart
index 4ce14e8..e6a768d 100644
--- a/packages/flutter/test/services/default_binary_messenger_test.dart
+++ b/packages/flutter/test/services/default_binary_messenger_test.dart
@@ -2,10 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
-
+import 'dart:ui' as ui;
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
@@ -20,39 +19,36 @@
}
test('default binary messenger calls callback once', () async {
- int countInbound = 0;
- int countOutbound = 0;
+ int count = 0;
const String channel = 'foo';
- final ByteData bar = _makeByteData('bar');
- final Completer<void> done = Completer<void>();
- ServicesBinding.instance!.channelBuffers.push(
+ ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
channel,
- bar,
+ _makeByteData('bar'),
(ByteData? message) async {
- expect(message, isNull);
- countOutbound += 1;
- done.complete();
+ count += 1;
},
);
- expect(countInbound, equals(0));
- expect(countOutbound, equals(0));
- ServicesBinding.instance!.defaultBinaryMessenger.setMessageHandler(
- channel,
- (ByteData? message) async {
- expect(message, bar);
- countInbound += 1;
- },
- );
- expect(countInbound, equals(0));
- expect(countOutbound, equals(0));
- await done.future;
- expect(countInbound, equals(1));
- expect(countOutbound, equals(1));
+ expect(count, equals(0));
+ await ui.channelBuffers.drain(channel, (ByteData? data, ui.PlatformMessageResponseCallback callback) async {
+ callback(null);
+ });
+ expect(count, equals(1));
+ });
+
+ test('can check the handler', () {
+ Future<ByteData> handler(ByteData? call) => Future<ByteData>.value(null);
+ final BinaryMessenger messenger = ServicesBinding.instance!.defaultBinaryMessenger;
+
+ expect(messenger.checkMessageHandler('test_channel', null), true);
+ expect(messenger.checkMessageHandler('test_channel', handler), false);
+ messenger.setMessageHandler('test_channel', handler);
+ expect(messenger.checkMessageHandler('test_channel', handler), true);
+ messenger.setMessageHandler('test_channel', null);
});
test('can check the mock handler', () {
Future<ByteData> handler(ByteData? call) => Future<ByteData>.value(null);
- final TestDefaultBinaryMessenger messenger = TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger;
+ final BinaryMessenger messenger = ServicesBinding.instance!.defaultBinaryMessenger;
expect(messenger.checkMockMessageHandler('test_channel', null), true);
expect(messenger.checkMockMessageHandler('test_channel', handler), false);
diff --git a/packages/flutter/test/services/deferred_component_test.dart b/packages/flutter/test/services/deferred_component_test.dart
index 6665f28..cc40b8e 100644
--- a/packages/flutter/test/services/deferred_component_test.dart
+++ b/packages/flutter/test/services/deferred_component_test.dart
@@ -11,7 +11,7 @@
test('installDeferredComponent test', () async {
final List<MethodCall> log = <MethodCall>[];
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.deferredComponent, (MethodCall methodCall) async {
+ SystemChannels.deferredComponent.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -27,7 +27,7 @@
test('uninstallDeferredComponent test', () async {
final List<MethodCall> log = <MethodCall>[];
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.deferredComponent, (MethodCall methodCall) async {
+ SystemChannels.deferredComponent.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
diff --git a/packages/flutter/test/services/fake_platform_views.dart b/packages/flutter/test/services/fake_platform_views.dart
index 7695c4a..9efdce7 100644
--- a/packages/flutter/test/services/fake_platform_views.dart
+++ b/packages/flutter/test/services/fake_platform_views.dart
@@ -8,7 +8,6 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
-import 'package:flutter_test/flutter_test.dart';
/// Used in internal testing.
class FakePlatformViewController extends PlatformViewController {
@@ -123,7 +122,7 @@
class FakeAndroidPlatformViewsController {
FakeAndroidPlatformViewsController() {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform_views, _onMethodCall);
+ SystemChannels.platform_views.setMockMethodCallHandler(_onMethodCall);
}
Iterable<FakeAndroidPlatformView> get views => _views.values;
@@ -302,7 +301,7 @@
class FakeIosPlatformViewsController {
FakeIosPlatformViewsController() {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform_views, _onMethodCall);
+ SystemChannels.platform_views.setMockMethodCallHandler(_onMethodCall);
}
Iterable<FakeUiKitView> get views => _views.values;
@@ -397,7 +396,7 @@
class FakeHtmlPlatformViewsController {
FakeHtmlPlatformViewsController() {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform_views, _onMethodCall);
+ SystemChannels.platform_views.setMockMethodCallHandler(_onMethodCall);
}
Iterable<FakeHtmlPlatformView> get views => _views.values;
diff --git a/packages/flutter/test/services/haptic_feedback_test.dart b/packages/flutter/test/services/haptic_feedback_test.dart
index fa4c67e..6234a97 100644
--- a/packages/flutter/test/services/haptic_feedback_test.dart
+++ b/packages/flutter/test/services/haptic_feedback_test.dart
@@ -11,7 +11,7 @@
test('Haptic feedback control test', () async {
final List<MethodCall> log = <MethodCall>[];
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -25,7 +25,7 @@
Future<void> callAndVerifyHapticFunction(Function hapticFunction, String platformMethodArgument) async {
final List<MethodCall> log = <MethodCall>[];
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
diff --git a/packages/flutter/test/services/platform_channel_test.dart b/packages/flutter/test/services/platform_channel_test.dart
index 6adc07b..7b7f135 100644
--- a/packages/flutter/test/services/platform_channel_test.dart
+++ b/packages/flutter/test/services/platform_channel_test.dart
@@ -12,7 +12,7 @@
const MessageCodec<String?> string = StringCodec();
const BasicMessageChannel<String?> channel = BasicMessageChannel<String?>('ch', string);
test('can send string message and get reply', () async {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch',
(ByteData? message) async => string.encodeMessage(string.decodeMessage(message)! + ' world'),
);
@@ -23,7 +23,7 @@
test('can receive string message and send reply', () async {
channel.setMessageHandler((String? message) async => message! + ' world');
String? reply;
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
'ch',
const StringCodec().encodeMessage('hello'),
(ByteData? replyBinary) {
@@ -40,7 +40,7 @@
const MethodChannel channel = MethodChannel('ch7', jsonMethod);
const OptionalMethodChannel optionalMethodChannel = OptionalMethodChannel('ch8', jsonMethod);
test('can invoke method and get result', () async {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch7',
(ByteData? message) async {
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
@@ -56,7 +56,7 @@
});
test('can invoke list method and get result', () async {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch7',
(ByteData? message) async {
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
@@ -72,7 +72,7 @@
});
test('can invoke list method and get null result', () async {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch7',
(ByteData? message) async {
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
@@ -87,7 +87,7 @@
});
test('can invoke map method and get result', () async {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch7',
(ByteData? message) async {
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
@@ -103,7 +103,7 @@
});
test('can invoke map method and get null result', () async {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch7',
(ByteData? message) async {
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
@@ -118,7 +118,7 @@
});
test('can invoke method and get error', () async {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch7',
(ByteData? message) async {
return jsonMessage.encodeMessage(<dynamic>[
@@ -141,7 +141,7 @@
});
test('can invoke unimplemented method', () async {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch7',
(ByteData? message) async => null,
);
@@ -157,7 +157,7 @@
});
test('can invoke unimplemented method (optional)', () async {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch8',
(ByteData? message) async => null,
);
@@ -169,7 +169,7 @@
channel.setMethodCallHandler(null);
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
ByteData? envelope;
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
envelope = result;
});
await null; // just in case there's something async happening
@@ -179,7 +179,7 @@
test('can handle method call with no registered plugin (setting after)', () async {
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
ByteData? envelope;
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
envelope = result;
});
channel.setMethodCallHandler(null);
@@ -193,7 +193,7 @@
});
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
ByteData? envelope;
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
envelope = result;
});
expect(envelope, isNull);
@@ -203,7 +203,7 @@
channel.setMethodCallHandler((MethodCall call) async => '${call.arguments}, world');
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
ByteData? envelope;
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
envelope = result;
});
expect(jsonMethod.decodeEnvelope(envelope!), equals('hello, world'));
@@ -215,7 +215,7 @@
});
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
ByteData? envelope;
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
envelope = result;
});
try {
@@ -235,7 +235,7 @@
});
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
ByteData? envelope;
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
envelope = result;
});
try {
@@ -249,14 +249,24 @@
}
});
- test('can check the mock handler', () async {
+ test('can check the handler', () {
Future<dynamic> handler(MethodCall call) => Future<dynamic>.value(null);
const MethodChannel channel = MethodChannel('test_handler');
- expect(TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.checkMockMessageHandler(channel.name, null), true);
- expect(TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.checkMockMessageHandler(channel.name, handler), false);
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(channel, handler);
- expect(TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.checkMockMessageHandler(channel.name, handler), true);
+ expect(channel.checkMethodCallHandler(null), true);
+ expect(channel.checkMethodCallHandler(handler), false);
+ channel.setMethodCallHandler(handler);
+ expect(channel.checkMethodCallHandler(handler), true);
+ });
+
+ test('can check the mock handler', () {
+ Future<dynamic> handler(MethodCall call) => Future<dynamic>.value(null);
+
+ const MethodChannel channel = MethodChannel('test_handler');
+ expect(channel.checkMockMethodCallHandler(null), true);
+ expect(channel.checkMockMethodCallHandler(handler), false);
+ channel.setMockMethodCallHandler(handler);
+ expect(channel.checkMockMethodCallHandler(handler), true);
});
});
@@ -265,7 +275,7 @@
const MethodCodec jsonMethod = JSONMethodCodec();
const EventChannel channel = EventChannel('ch', jsonMethod);
void emitEvent(ByteData? event) {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
'ch',
event,
(ByteData? reply) {},
@@ -273,7 +283,7 @@
}
test('can receive event stream', () async {
bool canceled = false;
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch',
(ByteData? message) async {
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
@@ -298,7 +308,7 @@
});
test('can receive error event', () async {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch',
(ByteData? message) async {
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
diff --git a/packages/flutter/test/services/platform_messages_test.dart b/packages/flutter/test/services/platform_messages_test.dart
index 8fd3937..9aa9bf1 100644
--- a/packages/flutter/test/services/platform_messages_test.dart
+++ b/packages/flutter/test/services/platform_messages_test.dart
@@ -7,23 +7,24 @@
import 'package:flutter_test/flutter_test.dart';
void main() {
- TestWidgetsFlutterBinding.ensureInitialized();
-
test('Mock binary message handler control test', () async {
+ // Initialize all bindings because defaultBinaryMessenger.send() needs a window.
+ TestWidgetsFlutterBinding.ensureInitialized();
+
final List<ByteData?> log = <ByteData>[];
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('test1', (ByteData? message) async {
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('test1', (ByteData? message) async {
log.add(message);
return null;
});
final ByteData message = ByteData(2)..setUint16(0, 0xABCD);
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.send('test1', message);
+ await ServicesBinding.instance!.defaultBinaryMessenger.send('test1', message);
expect(log, equals(<ByteData>[message]));
log.clear();
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('test1', null);
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.send('test1', message);
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('test1', null);
+ await ServicesBinding.instance!.defaultBinaryMessenger.send('test1', message);
expect(log, isEmpty);
});
}
diff --git a/packages/flutter/test/services/raw_keyboard_test.dart b/packages/flutter/test/services/raw_keyboard_test.dart
index 3bbc185..7f65991 100644
--- a/packages/flutter/test/services/raw_keyboard_test.dart
+++ b/packages/flutter/test/services/raw_keyboard_test.dart
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
@@ -29,7 +30,6 @@
RawKeyboard.instance.removeListener(handleKey);
}
});
-
testWidgets('No character is produced for non-printables', (WidgetTester tester) async {
for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'web']) {
void handleKey(RawKeyEvent event) {
@@ -40,7 +40,6 @@
RawKeyboard.instance.removeListener(handleKey);
}
});
-
testWidgets('keysPressed is maintained', (WidgetTester tester) async {
for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'ios']) {
RawKeyboard.instance.clearKeysPressed();
@@ -210,7 +209,7 @@
// when this event is received, but it's not in keysPressed yet.
data['modifiers'] |= RawKeyEventDataMacOs.modifierLeftShift | RawKeyEventDataMacOs.modifierShift;
// dispatch the modified data.
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData? data) {},
@@ -235,7 +234,7 @@
// when this event is received, but it's not in keysPressed yet.
data['modifiers'] |= RawKeyEventDataMacOs.modifierLeftShift | RawKeyEventDataMacOs.modifierShift;
// dispatch the modified data.
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData? data) {},
@@ -260,7 +259,7 @@
// when this event is received, but it's not in keysPressed yet.
data['modifiers'] |= RawKeyEventDataWindows.modifierLeftShift | RawKeyEventDataWindows.modifierShift;
// dispatch the modified data.
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData? data) {},
@@ -285,7 +284,7 @@
// when this event is received, but it's not in keysPressed yet.
data['metaState'] |= RawKeyEventDataAndroid.modifierLeftShift | RawKeyEventDataAndroid.modifierShift;
// dispatch the modified data.
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData? data) {},
@@ -310,7 +309,7 @@
// when this event is received, but it's not in keysPressed yet.
data['modifiers'] |= RawKeyEventDataFuchsia.modifierLeftShift;
// dispatch the modified data.
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData? data) {},
@@ -335,7 +334,7 @@
// when this event is received, but it's not in keysPressed yet.
data['modifiers'] |= GLFWKeyHelper.modifierShift;
// dispatch the modified data.
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData? data) {},
@@ -365,7 +364,7 @@
isDown: true,
)..['metaState'] |= RawKeyEventDataWeb.modifierShift;
// Dispatch the modified data.
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData? data) {},
@@ -457,7 +456,7 @@
RawKeyEventDataAndroid.modifierControl |
RawKeyEventDataAndroid.modifierMeta;
// dispatch the modified data.
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData? data) {},
@@ -495,7 +494,7 @@
RawKeyEventDataMacOs.modifierCommand |
RawKeyEventDataMacOs.modifierControl;
// dispatch the modified data.
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData? data) {},
@@ -571,7 +570,7 @@
RawKeyEventDataWindows.modifierAlt |
RawKeyEventDataWindows.modifierControl;
// dispatch the modified data.
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData? data) {},
@@ -608,7 +607,7 @@
GLFWKeyHelper.modifierControl |
GLFWKeyHelper.modifierMeta;
// dispatch the modified data.
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData? data) {},
@@ -646,7 +645,7 @@
RawKeyEventDataWeb.modifierControl |
RawKeyEventDataWeb.modifierMeta;
// dispatch the modified data.
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData? data) {},
@@ -666,6 +665,12 @@
});
testWidgets('RawKeyboard asserts if no keys are in keysPressed after receiving a key down event', (WidgetTester tester) async {
+ FlutterErrorDetails? errorDetails;
+ final FlutterExceptionHandler? oldHandler = FlutterError.onError;
+ FlutterError.onError = (FlutterErrorDetails details) {
+ errorDetails = details;
+ };
+
final Map<String, dynamic> keyEventMessage;
if (kIsWeb) {
keyEventMessage = const <String, dynamic>{
@@ -687,15 +692,19 @@
}
try {
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ await ServicesBinding.instance!.defaultBinaryMessenger
+ .handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(keyEventMessage),
- (ByteData? data) { },
+ (ByteData? data) {},
);
- fail('Expected an exception, but did not get one.');
- } on AssertionError catch (error) {
- expect(error.toString(), contains('Attempted to send a key down event when no keys are in keysPressed'));
+ } finally {
+ FlutterError.onError = oldHandler;
}
+ expect(errorDetails, isNotNull);
+ expect(errorDetails!.stack, isNotNull);
+ final String fullErrorMessage = errorDetails.toString().replaceAll('\n', ' ');
+ expect(fullErrorMessage, contains('Attempted to send a key down event when no keys are in keysPressed'));
});
});
@@ -748,7 +757,6 @@
}
}
});
-
test('modifier keys are recognized when combined', () {
for (final int modifier in modifierTests.keys) {
if (modifier == RawKeyEventDataAndroid.modifierFunction) {
@@ -791,7 +799,6 @@
}
}
});
-
test('Printable keyboard keys are correctly translated', () {
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(<String, dynamic>{
'type': 'keydown',
@@ -810,7 +817,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
expect(data.keyLabel, equals('a'));
});
-
test('Control keyboard keys are correctly translated', () {
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -827,7 +833,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
expect(data.keyLabel, isEmpty);
});
-
test('Modifier keyboard keys are correctly translated', () {
final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -845,7 +850,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
expect(data.keyLabel, isEmpty);
});
-
test('DPAD keys from a joystick give physical key mappings', () {
final RawKeyEvent joystickDpadDown = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -863,7 +867,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowDown));
expect(data.keyLabel, isEmpty);
});
-
test('Arrow keys from a keyboard give correct physical key mappings', () {
final RawKeyEvent joystickDpadDown = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -880,7 +883,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowDown));
expect(data.keyLabel, isEmpty);
});
-
test('DPAD center from a game pad gives physical key mappings', () {
final RawKeyEvent joystickDpadCenter = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -898,7 +900,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.select));
expect(data.keyLabel, isEmpty);
});
-
test('Device id is read from message', () {
final RawKeyEvent joystickDpadCenter = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -914,7 +915,6 @@
final RawKeyEventDataAndroid data = joystickDpadCenter.data as RawKeyEventDataAndroid;
expect(data.deviceId, equals(10));
});
-
test('Repeat count is passed correctly', () {
final RawKeyEvent repeatCountEvent = RawKeyEvent.fromMessage(<String, dynamic>{
'type': 'keydown',
@@ -931,7 +931,6 @@
final RawKeyEventDataAndroid data = repeatCountEvent.data as RawKeyEventDataAndroid;
expect(data.repeatCount, equals(42));
});
-
testWidgets('Key events are responded to correctly.', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty);
// Generate the data for a regular key down event.
@@ -941,7 +940,7 @@
isDown: true,
);
Map<String, dynamic>? message;
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData? data) {
@@ -964,7 +963,7 @@
focusNode.requestFocus();
await tester.pump();
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData? data) {
@@ -972,7 +971,7 @@
},
);
expect(message, equals(<String, dynamic>{ 'handled': true }));
- tester.binding.defaultBinaryMessenger.setMockMessageHandler(SystemChannels.keyEvent.name, null);
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(SystemChannels.keyEvent.name, null);
});
}, skip: isBrowser); // This is an Android-specific group.
@@ -1020,7 +1019,6 @@
}
}
});
-
test('modifier keys are recognized when combined', () {
for (final int modifier in modifierTests.keys) {
if (modifier == RawKeyEventDataFuchsia.modifierCapsLock) {
@@ -1054,7 +1052,6 @@
}
}
});
-
test('Printable keyboard keys are correctly translated', () {
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(<String, dynamic>{
'type': 'keydown',
@@ -1068,7 +1065,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
expect(data.keyLabel, equals('a'));
});
-
test('Control keyboard keys are correctly translated', () {
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -1140,7 +1136,6 @@
}
}
});
-
test('modifier keys are recognized when combined', () {
for (final int modifier in modifierTests.keys) {
if (modifier == RawKeyEventDataMacOs.modifierCapsLock) {
@@ -1180,7 +1175,6 @@
}
}
});
-
test('Printable keyboard keys are correctly translated', () {
const String unmodifiedCharacter = 'a';
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
@@ -1196,7 +1190,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
expect(data.keyLabel, equals('a'));
});
-
test('Control keyboard keys are correctly translated', () {
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -1288,7 +1281,6 @@
}
}
});
-
test('modifier keys are recognized when combined', () {
for (final int modifier in modifierTests.keys) {
if (modifier == RawKeyEventDataIos.modifierCapsLock) {
@@ -1328,7 +1320,6 @@
}
}
});
-
test('Printable keyboard keys are correctly translated', () {
const String unmodifiedCharacter = 'a';
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
@@ -1344,7 +1335,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
expect(data.keyLabel, equals('a'));
});
-
test('Control keyboard keys are correctly translated', () {
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -1437,7 +1427,6 @@
}
}
});
-
test('modifier keys are recognized when combined', () {
for (final int modifier in modifierTests.keys) {
if (modifier == RawKeyEventDataWindows.modifierCaps) {
@@ -1477,7 +1466,6 @@
}
}
});
-
test('Printable keyboard keys are correctly translated', () {
const int unmodifiedCharacter = 97; // ASCII value for 'a'.
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
@@ -1493,7 +1481,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
expect(data.keyLabel, equals('a'));
});
-
test('Control keyboard keys are correctly translated', () {
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -1508,7 +1495,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
expect(data.keyLabel, isEmpty);
});
-
test('Modifier keyboard keys are correctly translated', () {
final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -1523,7 +1509,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
expect(data.keyLabel, isEmpty);
});
-
test('Unprintable keyboard keys are correctly translated', () {
final RawKeyEvent leftArrowKey = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -1537,7 +1522,6 @@
expect(data.physicalKey, equals(PhysicalKeyboardKey.arrowLeft));
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
});
-
testWidgets('Win32 VK_PROCESSKEY events are skipped', (WidgetTester tester) async {
const String platform = 'windows';
bool lastHandled = true;
@@ -1636,7 +1620,6 @@
}
}
});
-
test('modifier keys are recognized when combined', () {
for (final int modifier in modifierTests.keys) {
if (modifier == GLFWKeyHelper.modifierControl) {
@@ -1677,7 +1660,6 @@
}
}
});
-
test('Printable keyboard keys are correctly translated', () {
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -1693,7 +1675,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.keyQ));
expect(data.keyLabel, equals('q'));
});
-
test('Code points with two Unicode scalar values are allowed', () {
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -1742,7 +1723,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
expect(data.keyLabel, isEmpty);
});
-
test('Modifier keyboard keys are correctly translated', () {
final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -1824,7 +1804,6 @@
}
}
});
-
test('modifier keys are recognized when combined', () {
for (final int modifier in modifierTests.keys) {
if (modifier == GtkKeyHelper.modifierControl) {
@@ -1865,7 +1844,6 @@
}
}
});
-
test('Printable keyboard keys are correctly translated', () {
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -1881,7 +1859,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.keyQ));
expect(data.keyLabel, equals('q'));
});
-
test('Code points with two Unicode scalar values are allowed', () {
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -1930,7 +1907,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
expect(data.keyLabel, isEmpty);
});
-
test('Modifier keyboard keys are correctly translated', () {
final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -1984,7 +1960,6 @@
}
}
});
-
test('modifier keys are recognized when combined', () {
for (final int modifier in modifierTests.keys) {
if (modifier == RawKeyEventDataWeb.modifierMeta) {
@@ -2017,7 +1992,6 @@
}
}
});
-
test('Printable keyboard keys are correctly translated', () {
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -2031,7 +2005,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
expect(data.keyLabel, equals('a'));
});
-
test('Control keyboard keys are correctly translated', () {
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -2044,7 +2017,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
expect(data.keyLabel, isEmpty);
});
-
test('Modifier keyboard keys are correctly translated', () {
final RawKeyEvent shiftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
@@ -2057,7 +2029,6 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
expect(data.keyLabel, isEmpty);
});
-
test('Arrow keys from a keyboard give correct physical key mappings', () {
final RawKeyEvent arrowKeyDown = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
diff --git a/packages/flutter/test/services/restoration_test.dart b/packages/flutter/test/services/restoration_test.dart
index 7a92d4d..2def380 100644
--- a/packages/flutter/test/services/restoration_test.dart
+++ b/packages/flutter/test/services/restoration_test.dart
@@ -18,7 +18,7 @@
testWidgets('root bucket retrieval', (WidgetTester tester) async {
final List<MethodCall> callsToEngine = <MethodCall>[];
final Completer<Map<dynamic, dynamic>> result = Completer<Map<dynamic, dynamic>>();
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.restoration, (MethodCall call) {
+ SystemChannels.restoration.setMockMethodCallHandler((MethodCall call) {
callsToEngine.add(call);
return result.future;
});
@@ -64,7 +64,7 @@
testWidgets('root bucket received from engine before retrieval', (WidgetTester tester) async {
SystemChannels.restoration.setMethodCallHandler(null);
final List<MethodCall> callsToEngine = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.restoration, (MethodCall call) async {
+ SystemChannels.restoration.setMockMethodCallHandler((MethodCall call) async {
callsToEngine.add(call);
});
final RestorationManager manager = RestorationManager();
@@ -83,7 +83,7 @@
SystemChannels.restoration.setMethodCallHandler(null);
final List<MethodCall> callsToEngine = <MethodCall>[];
final Completer<Map<dynamic, dynamic>> result = Completer<Map<dynamic, dynamic>>();
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.restoration, (MethodCall call) {
+ SystemChannels.restoration.setMockMethodCallHandler((MethodCall call) {
callsToEngine.add(call);
return result.future;
});
@@ -110,7 +110,7 @@
});
testWidgets('root bucket is properly replaced when new data is available', (WidgetTester tester) async {
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.restoration, (MethodCall call) async {
+ SystemChannels.restoration.setMockMethodCallHandler((MethodCall call) async {
return _createEncodedRestorationData1();
});
final RestorationManager manager = RestorationManager();
@@ -152,7 +152,7 @@
testWidgets('returns null as root bucket when restoration is disabled', (WidgetTester tester) async {
final List<MethodCall> callsToEngine = <MethodCall>[];
final Completer<Map<dynamic, dynamic>> result = Completer<Map<dynamic, dynamic>>();
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.restoration, (MethodCall call) {
+ SystemChannels.restoration.setMockMethodCallHandler((MethodCall call) {
callsToEngine.add(call);
return result.future;
});
@@ -195,7 +195,7 @@
testWidgets('flushData', (WidgetTester tester) async {
final List<MethodCall> callsToEngine = <MethodCall>[];
final Completer<Map<dynamic, dynamic>> result = Completer<Map<dynamic, dynamic>>();
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.restoration, (MethodCall call) {
+ SystemChannels.restoration.setMockMethodCallHandler((MethodCall call) {
callsToEngine.add(call);
return result.future;
});
@@ -230,7 +230,7 @@
testWidgets('isReplacing', (WidgetTester tester) async {
final Completer<Map<dynamic, dynamic>> result = Completer<Map<dynamic, dynamic>>();
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.restoration, (MethodCall call) {
+ SystemChannels.restoration.setMockMethodCallHandler((MethodCall call) {
return result.future;
});
diff --git a/packages/flutter/test/services/system_chrome_test.dart b/packages/flutter/test/services/system_chrome_test.dart
index 3b196c8..5356e4d 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_test/flutter_test.dart';
void main() {
- TestWidgetsFlutterBinding.ensureInitialized();
-
testWidgets('SystemChrome overlay style test', (WidgetTester tester) async {
// The first call is a cache miss and will queue a microtask
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
@@ -26,7 +24,7 @@
test('setPreferredOrientations control test', () async {
final List<MethodCall> log = <MethodCall>[];
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -44,7 +42,7 @@
test('setApplicationSwitcherDescription control test', () async {
final List<MethodCall> log = <MethodCall>[];
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -62,7 +60,7 @@
test('setApplicationSwitcherDescription missing plugin', () async {
final List<ByteData?> log = <ByteData>[];
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('flutter/platform', (ByteData? message) async {
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('flutter/platform', (ByteData? message) async {
log.add(message);
});
@@ -76,7 +74,7 @@
test('setEnabledSystemUIOverlays control test', () async {
final List<MethodCall> log = <MethodCall>[];
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
diff --git a/packages/flutter/test/services/system_navigator_test.dart b/packages/flutter/test/services/system_navigator_test.dart
index 251bca6..bc69985 100644
--- a/packages/flutter/test/services/system_navigator_test.dart
+++ b/packages/flutter/test/services/system_navigator_test.dart
@@ -12,7 +12,7 @@
test('System navigator control test', () async {
final List<MethodCall> log = <MethodCall>[];
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
diff --git a/packages/flutter/test/services/system_sound_test.dart b/packages/flutter/test/services/system_sound_test.dart
index 823d7f0..20a6d5a 100644
--- a/packages/flutter/test/services/system_sound_test.dart
+++ b/packages/flutter/test/services/system_sound_test.dart
@@ -12,7 +12,7 @@
test('System sound control test', () async {
final List<MethodCall> log = <MethodCall>[];
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
diff --git a/packages/flutter/test/services/text_input_test.dart b/packages/flutter/test/services/text_input_test.dart
index ca3ec02..7d03836 100644
--- a/packages/flutter/test/services/text_input_test.dart
+++ b/packages/flutter/test/services/text_input_test.dart
@@ -442,6 +442,16 @@
@override
void setMethodCallHandler(Future<void> Function(MethodCall call)? handler) => incoming = handler;
+ @override
+ bool checkMethodCallHandler(Future<void> Function(MethodCall call)? handler) => throw UnimplementedError();
+
+
+ @override
+ void setMockMethodCallHandler(Future<void>? Function(MethodCall call)? handler) => throw UnimplementedError();
+
+ @override
+ bool checkMockMethodCallHandler(Future<void> Function(MethodCall call)? handler) => throw UnimplementedError();
+
void validateOutgoingMethodCalls(List<MethodCall> calls) {
expect(outgoingCalls.length, calls.length);
bool hasError = false;
diff --git a/packages/flutter/test/widgets/draggable_test.dart b/packages/flutter/test/widgets/draggable_test.dart
index 99a292b..27b14eb 100644
--- a/packages/flutter/test/widgets/draggable_test.dart
+++ b/packages/flutter/test/widgets/draggable_test.dart
@@ -3107,7 +3107,7 @@
bool onDragStartedCalled = false;
int hapticFeedbackCalls = 0;
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'HapticFeedback.vibrate') {
hapticFeedbackCalls++;
}
diff --git a/packages/flutter/test/widgets/editable_text_cursor_test.dart b/packages/flutter/test/widgets/editable_text_cursor_test.dart
index b069b4e..b05571a 100644
--- a/packages/flutter/test/widgets/editable_text_cursor_test.dart
+++ b/packages/flutter/test/widgets/editable_text_cursor_test.dart
@@ -79,7 +79,7 @@
// Populate a fake clipboard.
const String clipboardContent = ' ';
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'Clipboard.getData')
return const <String, dynamic>{'text': clipboardContent};
return null;
@@ -131,7 +131,7 @@
// Populate a fake clipboard.
const String clipboardContent = ' ';
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'Clipboard.getData')
return const <String, dynamic>{'text': clipboardContent};
return null;
@@ -853,7 +853,7 @@
// Populate a fake clipboard.
const String clipboardContent = 'Hello world!';
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'Clipboard.getData')
return const <String, dynamic>{'text': clipboardContent};
return null;
@@ -911,7 +911,7 @@
// Populate a fake clipboard.
const String clipboardContent = 'Hello world!';
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'Clipboard.getData')
return const <String, dynamic>{'text': clipboardContent};
return null;
diff --git a/packages/flutter/test/widgets/editable_text_test.dart b/packages/flutter/test/widgets/editable_text_test.dart
index 644d90c..109767f 100644
--- a/packages/flutter/test/widgets/editable_text_test.dart
+++ b/packages/flutter/test/widgets/editable_text_test.dart
@@ -65,9 +65,9 @@
}
void main() {
+ TestWidgetsFlutterBinding.ensureInitialized();
final MockClipboard mockClipboard = MockClipboard();
- (TestWidgetsFlutterBinding.ensureInitialized() as TestWidgetsFlutterBinding)
- .defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
+ SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
setUp(() async {
debugResetSemanticsIdCounter();
@@ -1982,7 +1982,7 @@
await tester.pump(); // An extra pump to allow focus request to go through.
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
+ SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -3234,7 +3234,7 @@
// Regression test for https://github.com/flutter/flutter/issues/22212.
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
+ SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -3265,7 +3265,7 @@
testWidgets('location of widget is sent on show keyboard', (WidgetTester tester) async {
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
+ SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -3302,7 +3302,7 @@
testWidgets('transform and size is reset when text connection opens', (WidgetTester tester) async {
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
+ SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -3390,7 +3390,7 @@
testWidgets('size and transform are sent when they change', (WidgetTester tester) async {
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
+ SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -3432,7 +3432,7 @@
testWidgets('text styling info is sent on show keyboard', (WidgetTester tester) async {
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
+ SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -3519,7 +3519,7 @@
await tester.showKeyboard(find.byType(EditableText));
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
+ SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
setState(() {
@@ -3748,7 +3748,7 @@
// Regression test for https://github.com/flutter/flutter/issues/22212.
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
+ SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -5720,7 +5720,7 @@
testWidgets('Synchronous test of local and remote editing values', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/65059
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
+ SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
final TextInputFormatter formatter = TextInputFormatter.withFunction((TextEditingValue oldValue, TextEditingValue newValue) {
@@ -5848,7 +5848,7 @@
testWidgets('Send text input state to engine when the input formatter rejects user input', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/67828
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
+ SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
final TextInputFormatter formatter = TextInputFormatter.withFunction((TextEditingValue oldValue, TextEditingValue newValue) {
@@ -5927,7 +5927,7 @@
testWidgets('Repeatedly receiving [TextEditingValue] will not trigger a keyboard request', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/66036
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
+ SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
final TextEditingController controller = TextEditingController();
@@ -6048,7 +6048,7 @@
testWidgets('TextEditingController.clear() behavior test', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/66316
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
+ SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
final TextEditingController controller = TextEditingController();
diff --git a/packages/flutter/test/widgets/modal_barrier_test.dart b/packages/flutter/test/widgets/modal_barrier_test.dart
index 050941d..310ec98 100644
--- a/packages/flutter/test/widgets/modal_barrier_test.dart
+++ b/packages/flutter/test/widgets/modal_barrier_test.dart
@@ -159,7 +159,7 @@
testWidgets('ModalBarrier plays system alert sound when user tries to dismiss it', (WidgetTester tester) async {
final List<String> playedSystemSounds = <String>[];
try {
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'SystemSound.play')
playedSystemSounds.add(methodCall.arguments as String);
});
@@ -176,7 +176,7 @@
await tester.tap(find.text('target'), warnIfMissed: false);
await tester.pumpWidget(subject);
} finally {
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null);
+ SystemChannels.platform.setMockMethodCallHandler(null);
}
expect(playedSystemSounds, hasLength(1));
expect(playedSystemSounds[0], SystemSoundType.alert.toString());
diff --git a/packages/flutter/test/widgets/mouse_region_test.dart b/packages/flutter/test/widgets/mouse_region_test.dart
index ce9ae72..71773d3 100644
--- a/packages/flutter/test/widgets/mouse_region_test.dart
+++ b/packages/flutter/test/widgets/mouse_region_test.dart
@@ -1591,7 +1591,7 @@
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
await gesture.addPointer(location: const Offset(100, 100));
addTearDown(gesture.removePointer);
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.mouseCursor, (_) async {
+ SystemChannels.mouseCursor.setMockMethodCallHandler((_) async {
logCursors.add('cursor');
});
diff --git a/packages/flutter/test/widgets/platform_view_test.dart b/packages/flutter/test/widgets/platform_view_test.dart
index 774604c..5e3dcd1 100644
--- a/packages/flutter/test/widgets/platform_view_test.dart
+++ b/packages/flutter/test/widgets/platform_view_test.dart
@@ -1075,7 +1075,7 @@
await tester.pump();
late int lastPlatformViewTextClient;
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall call) {
+ SystemChannels.textInput.setMockMethodCallHandler((MethodCall call) {
if (call.method == 'TextInput.setPlatformViewClient') {
lastPlatformViewTextClient = call.arguments as int;
}
diff --git a/packages/flutter/test/widgets/route_notification_messages_test.dart b/packages/flutter/test/widgets/route_notification_messages_test.dart
index d6c50c6..ea61888 100644
--- a/packages/flutter/test/widgets/route_notification_messages_test.dart
+++ b/packages/flutter/test/widgets/route_notification_messages_test.dart
@@ -55,7 +55,7 @@
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.navigation, (MethodCall methodCall) async {
+ SystemChannels.navigation.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -110,7 +110,7 @@
testWidgets('Navigator does not report route name by default', (WidgetTester tester) async {
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.navigation, (MethodCall methodCall) async {
+ SystemChannels.navigation.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -160,7 +160,7 @@
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.navigation, (MethodCall methodCall) async {
+ SystemChannels.navigation.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -215,7 +215,7 @@
testWidgets('Nameless routes should send platform messages', (WidgetTester tester) async {
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.navigation, (MethodCall methodCall) async {
+ SystemChannels.navigation.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
@@ -262,7 +262,7 @@
testWidgets('PlatformRouteInformationProvider reports URL', (WidgetTester tester) async {
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.navigation, (MethodCall methodCall) async {
+ SystemChannels.navigation.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
diff --git a/packages/flutter/test/widgets/selectable_text_test.dart b/packages/flutter/test/widgets/selectable_text_test.dart
index f38ac55..c3894c0 100644
--- a/packages/flutter/test/widgets/selectable_text_test.dart
+++ b/packages/flutter/test/widgets/selectable_text_test.dart
@@ -124,7 +124,7 @@
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final MockClipboard mockClipboard = MockClipboard();
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
+ SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
const String kThreeLines =
'First line of text is\n'
@@ -1626,7 +1626,7 @@
final FocusNode focusNode = FocusNode();
String clipboardContent = '';
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
if (methodCall.method == 'Clipboard.setData')
clipboardContent = methodCall.arguments['text'] as String;
else if (methodCall.method == 'Clipboard.getData')
diff --git a/packages/flutter/test/widgets/text_selection_test.dart b/packages/flutter/test/widgets/text_selection_test.dart
index 48107e8..8192d15 100644
--- a/packages/flutter/test/widgets/text_selection_test.dart
+++ b/packages/flutter/test/widgets/text_selection_test.dart
@@ -19,15 +19,15 @@
'text': null,
};
- Future<Object?> handleMethodCall(MethodCall methodCall) async {
+ Future<dynamic> handleMethodCall(MethodCall methodCall) async {
switch (methodCall.method) {
case 'Clipboard.getData':
- if (getDataThrows)
+ if (getDataThrows) {
throw Exception();
+ }
return _clipboardData;
case 'Clipboard.setData':
_clipboardData = methodCall.arguments;
- break;
}
}
}
@@ -758,11 +758,11 @@
group('when Clipboard fails', () {
setUp(() {
final MockClipboard mockClipboard = MockClipboard(getDataThrows: true);
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
+ SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
});
tearDown(() {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null);
+ SystemChannels.platform.setMockMethodCallHandler(null);
});
test('Clipboard API failure is gracefully recovered from', () async {
@@ -778,11 +778,11 @@
final MockClipboard mockClipboard = MockClipboard();
setUp(() {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
+ SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
});
tearDown(() {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null);
+ SystemChannels.platform.setMockMethodCallHandler(null);
});
test('update sets value based on clipboard contents', () async {
diff --git a/packages/flutter/test/widgets/title_test.dart b/packages/flutter/test/widgets/title_test.dart
index b3e9a87..9e7a91e 100644
--- a/packages/flutter/test/widgets/title_test.dart
+++ b/packages/flutter/test/widgets/title_test.dart
@@ -36,7 +36,7 @@
testWidgets('should not pass "null" to setApplicationSwitcherDescription', (WidgetTester tester) async {
final List<MethodCall> log = <MethodCall>[];
- tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
+ SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
log.add(methodCall);
});
diff --git a/packages/flutter_driver/lib/src/extension/extension.dart b/packages/flutter_driver/lib/src/extension/extension.dart
index c9caa19..2150a6e 100644
--- a/packages/flutter_driver/lib/src/extension/extension.dart
+++ b/packages/flutter_driver/lib/src/extension/extension.dart
@@ -30,7 +30,7 @@
/// eventually completes to a string response.
typedef DataHandler = Future<String> Function(String? message);
-class _DriverBinding extends BindingBase with SchedulerBinding, ServicesBinding, GestureBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding, TestDefaultBinaryMessengerBinding {
+class _DriverBinding extends BindingBase with SchedulerBinding, ServicesBinding, GestureBinding, PaintingBinding, SemanticsBinding, RendererBinding, WidgetsBinding {
_DriverBinding(this._handler, this._silenceErrors, this._enableTextEntryEmulation, this.finders, this.commands);
final DataHandler? _handler;
@@ -51,6 +51,11 @@
registerWebServiceExtension(extension.call);
}
}
+
+ @override
+ BinaryMessenger createBinaryMessenger() {
+ return TestDefaultBinaryMessenger(super.createBinaryMessenger());
+ }
}
/// Enables Flutter Driver VM service extension.
@@ -325,11 +330,11 @@
registerTextInput();
}
- for (final FinderExtension finder in finders) {
+ for(final FinderExtension finder in finders) {
_finderExtensions[finder.finderType] = finder;
}
- for (final CommandExtension command in commands) {
+ for(final CommandExtension command in commands) {
_commandExtensions[command.commandKind] = command;
}
}
@@ -413,7 +418,7 @@
@override
Command deserializeCommand(Map<String, String> params, DeserializeFinderFactory finderFactory) {
final String? kind = params['command'];
- if (_commandExtensions.containsKey(kind)) {
+ if(_commandExtensions.containsKey(kind)) {
return _commandExtensions[kind]!.deserialize(params, finderFactory, this);
}
@@ -429,7 +434,7 @@
@override
Future<Result> handleCommand(Command command, WidgetController prober, CreateFinderFactory finderFactory) {
final String kind = command.kind;
- if (_commandExtensions.containsKey(kind)) {
+ if(_commandExtensions.containsKey(kind)) {
return _commandExtensions[kind]!.call(command, prober, finderFactory, this);
}
diff --git a/packages/flutter_driver/test/src/real_tests/extension_test.dart b/packages/flutter_driver/test/src/real_tests/extension_test.dart
index 24c3983..6857a21 100644
--- a/packages/flutter_driver/test/src/real_tests/extension_test.dart
+++ b/packages/flutter_driver/test/src/real_tests/extension_test.dart
@@ -279,7 +279,7 @@
'waiting for NoPendingPlatformMessages returns until a single method channel call returns', (WidgetTester tester) async {
const MethodChannel channel = MethodChannel('helloChannel', JSONMethodCodec());
const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
- tester.binding.defaultBinaryMessenger.setMockMessageHandler(
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'helloChannel', (ByteData? message) {
return Future<ByteData>.delayed(
const Duration(milliseconds: 10),
@@ -313,7 +313,7 @@
const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
// Configures channel 1
const MethodChannel channel1 = MethodChannel('helloChannel1', JSONMethodCodec());
- tester.binding.defaultBinaryMessenger.setMockMessageHandler(
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'helloChannel1', (ByteData? message) {
return Future<ByteData>.delayed(
const Duration(milliseconds: 10),
@@ -322,7 +322,7 @@
// Configures channel 2
const MethodChannel channel2 = MethodChannel('helloChannel2', JSONMethodCodec());
- tester.binding.defaultBinaryMessenger.setMockMessageHandler(
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'helloChannel2', (ByteData? message) {
return Future<ByteData>.delayed(
const Duration(milliseconds: 20),
@@ -362,7 +362,7 @@
const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
// Configures channel 1
const MethodChannel channel1 = MethodChannel('helloChannel1', JSONMethodCodec());
- tester.binding.defaultBinaryMessenger.setMockMessageHandler(
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'helloChannel1', (ByteData? message) {
return Future<ByteData>.delayed(
const Duration(milliseconds: 10),
@@ -371,7 +371,7 @@
// Configures channel 2
const MethodChannel channel2 = MethodChannel('helloChannel2', JSONMethodCodec());
- tester.binding.defaultBinaryMessenger.setMockMessageHandler(
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'helloChannel2', (ByteData? message) {
return Future<ByteData>.delayed(
const Duration(milliseconds: 20),
@@ -413,7 +413,7 @@
const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
// Configures channel 1
const MethodChannel channel1 = MethodChannel('helloChannel1', JSONMethodCodec());
- tester.binding.defaultBinaryMessenger.setMockMessageHandler(
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'helloChannel1', (ByteData? message) {
return Future<ByteData>.delayed(
const Duration(milliseconds: 20),
@@ -422,7 +422,7 @@
// Configures channel 2
const MethodChannel channel2 = MethodChannel('helloChannel2', JSONMethodCodec());
- tester.binding.defaultBinaryMessenger.setMockMessageHandler(
+ ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'helloChannel2', (ByteData? message) {
return Future<ByteData>.delayed(
const Duration(milliseconds: 10),
diff --git a/packages/flutter_test/lib/flutter_test.dart b/packages/flutter_test/lib/flutter_test.dart
index d7531ff..fbeb6f1 100644
--- a/packages/flutter_test/lib/flutter_test.dart
+++ b/packages/flutter_test/lib/flutter_test.dart
@@ -61,7 +61,6 @@
export 'src/animation_sheet.dart';
export 'src/binding.dart';
export 'src/controller.dart';
-export 'src/deprecated.dart';
export 'src/event_simulation.dart';
export 'src/finders.dart';
export 'src/frame_timing_summarizer.dart';
@@ -74,7 +73,6 @@
export 'src/stack_manipulation.dart';
export 'src/test_async_utils.dart';
export 'src/test_compat.dart';
-export 'src/test_default_binary_messenger.dart';
export 'src/test_exception_reporter.dart';
export 'src/test_pointer.dart';
export 'src/test_text_input.dart';
diff --git a/packages/flutter_test/lib/src/_binding_io.dart b/packages/flutter_test/lib/src/_binding_io.dart
index f09b3e1..19ec7db 100644
--- a/packages/flutter_test/lib/src/_binding_io.dart
+++ b/packages/flutter_test/lib/src/_binding_io.dart
@@ -13,8 +13,8 @@
// ignore: deprecated_member_use
import 'package:test_api/test_api.dart' as test_package;
+
import 'binding.dart';
-import 'deprecated.dart';
/// Ensure the [WidgetsBinding] is initialized.
WidgetsBinding ensureInitialized([@visibleForTesting Map<String, String>? environment]) {
diff --git a/packages/flutter_test/lib/src/binding.dart b/packages/flutter_test/lib/src/binding.dart
index fce5aa1..4a22d99 100644
--- a/packages/flutter_test/lib/src/binding.dart
+++ b/packages/flutter_test/lib/src/binding.dart
@@ -15,7 +15,8 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart' show TestWindow;
import 'package:stack_trace/stack_trace.dart' as stack_trace;
-import 'package:test_api/test_api.dart' as test_package; // ignore: deprecated_member_use
+// ignore: deprecated_member_use
+import 'package:test_api/test_api.dart' as test_package;
import 'package:vector_math/vector_math_64.dart';
import '_binding_io.dart' if (dart.library.html) '_binding_web.dart' as binding;
@@ -24,7 +25,6 @@
import 'restoration.dart';
import 'stack_manipulation.dart';
import 'test_async_utils.dart';
-import 'test_default_binary_messenger.dart';
import 'test_exception_reporter.dart';
import 'test_text_input.dart';
@@ -79,29 +79,74 @@
const Size _kDefaultTestViewportSize = Size(800.0, 600.0);
-/// Overrides the [ServicesBinding]'s binary messenger logic to use
-/// [TestDefaultBinaryMessenger].
+/// A [BinaryMessenger] subclass that is used as the default binary messenger
+/// under testing environment.
///
-/// Test bindings that are used by tests that mock message handlers for plugins
-/// should mix in this binding to enable the use of the
-/// [TestDefaultBinaryMessenger] APIs.
-mixin TestDefaultBinaryMessengerBinding on BindingBase, ServicesBinding {
+/// It tracks status of data sent across the Flutter platform barrier, which is
+/// useful for testing frameworks to monitor and synchronize against the
+/// platform messages.
+class TestDefaultBinaryMessenger extends BinaryMessenger {
+ /// Creates a [TestDefaultBinaryMessenger] instance.
+ ///
+ /// The [delegate] instance must not be null.
+ TestDefaultBinaryMessenger(this.delegate): assert(delegate != null);
+
+ /// The delegate [BinaryMessenger].
+ final BinaryMessenger delegate;
+
+ final List<Future<ByteData?>> _pendingMessages = <Future<ByteData?>>[];
+
+ /// The number of incomplete/pending calls sent to the platform channels.
+ int get pendingMessageCount => _pendingMessages.length;
+
@override
- void initInstances() {
- super.initInstances();
- _instance = this;
+ Future<ByteData?>? send(String channel, ByteData? message) {
+ final Future<ByteData?>? resultFuture = delegate.send(channel, message);
+ if (resultFuture != null) {
+ _pendingMessages.add(resultFuture);
+ resultFuture
+ .catchError((Object error) { /* errors are the responsibility of the caller */ })
+ .whenComplete(() => _pendingMessages.remove(resultFuture));
+ }
+ return resultFuture;
}
- /// The current [TestDefaultBinaryMessengerBinding], if one has been created.
- static TestDefaultBinaryMessengerBinding? get instance => _instance;
- static TestDefaultBinaryMessengerBinding? _instance;
+ /// Returns a Future that completes after all the platform calls are finished.
+ ///
+ /// If a new platform message is sent after this method is called, this new
+ /// message is not tracked. Use with [pendingMessageCount] to guarantee no
+ /// pending message calls.
+ Future<void> get platformMessagesFinished {
+ return Future.wait<void>(_pendingMessages);
+ }
@override
- TestDefaultBinaryMessenger get defaultBinaryMessenger => super.defaultBinaryMessenger as TestDefaultBinaryMessenger;
+ Future<void> handlePlatformMessage(
+ String channel,
+ ByteData? data,
+ ui.PlatformMessageResponseCallback? callback,
+ ) {
+ return delegate.handlePlatformMessage(channel, data, callback);
+ }
@override
- TestDefaultBinaryMessenger createBinaryMessenger() {
- return TestDefaultBinaryMessenger(super.createBinaryMessenger());
+ void setMessageHandler(String channel, MessageHandler? handler) {
+ delegate.setMessageHandler(channel, handler);
+ }
+
+ @override
+ bool checkMessageHandler(String channel, MessageHandler? handler) {
+ return delegate.checkMessageHandler(channel, handler);
+ }
+
+ @override
+ void setMockMessageHandler(String channel, MessageHandler? handler) {
+ delegate.setMockMessageHandler(channel, handler);
+ }
+
+ @override
+ bool checkMockMessageHandler(String channel, MessageHandler? handler) {
+ return delegate.checkMockMessageHandler(channel, handler);
}
}
@@ -126,8 +171,7 @@
SemanticsBinding,
RendererBinding,
PaintingBinding,
- WidgetsBinding,
- TestDefaultBinaryMessengerBinding {
+ WidgetsBinding {
/// Constructor for [TestWidgetsFlutterBinding].
///
@@ -151,15 +195,9 @@
/// Called by the test framework at the beginning of a widget test to
/// prepare the binding for the next test.
- ///
- /// If [registerTestTextInput] returns true when this method is called,
- /// the [testTextInput] is configured to simulate the keyboard.
void reset() {
_restorationManager = null;
resetGestureBinding();
- testTextInput.reset();
- if (registerTestTextInput)
- _testTextInput.register();
}
@override
@@ -199,8 +237,7 @@
@protected
bool get overrideHttpClient => true;
- /// Determines whether the binding automatically registers [testTextInput] as
- /// a fake keyboard implementation.
+ /// Determines whether the binding automatically registers [testTextInput].
///
/// Unit tests make use of this to mock out text input communication for
/// widgets. An integration test would set this to false, to test real IME
@@ -208,19 +245,6 @@
///
/// [TestTextInput.isRegistered] reports whether the text input mock is
/// registered or not.
- ///
- /// Some of the properties and methods on [testTextInput] are only valid if
- /// [registerTestTextInput] returns true when a test starts. If those
- /// members are accessed when using a binding that sets this flag to false,
- /// they will throw.
- ///
- /// If this property returns true when a test ends, the [testTextInput] is
- /// unregistered.
- ///
- /// This property should not change the value it returns during the lifetime
- /// of the binding. Changing the value of this property risks very confusing
- /// behavior as the [TestTextInput] may be inconsistently registered or
- /// unregistered.
@protected
bool get registerTestTextInput => true;
@@ -295,6 +319,9 @@
binding.setupHttpOverrides();
}
_testTextInput = TestTextInput(onCleared: _resetFocusedEditable);
+ if (registerTestTextInput) {
+ _testTextInput.register();
+ }
}
@override
@@ -304,6 +331,11 @@
// doesn't get generated for tests.
}
+ @override
+ BinaryMessenger createBinaryMessenger() {
+ return TestDefaultBinaryMessenger(super.createBinaryMessenger());
+ }
+
/// Whether there is currently a test executing.
bool get inTest;
@@ -483,20 +515,12 @@
TestTextInput get testTextInput => _testTextInput;
late TestTextInput _testTextInput;
- /// The [State] of the current [EditableText] client of the onscreen keyboard.
- ///
- /// Setting this property to a new value causes the given [EditableTextState]
- /// to focus itself and request the keyboard to establish a
- /// [TextInputConnection].
- ///
- /// Callers must pump an additional frame after setting this property to
- /// complete the focus change.
+ /// The current client of the onscreen keyboard. Callers must pump
+ /// an additional frame after setting this property to complete the
+ /// focus change.
///
/// Instead of setting this directly, consider using
/// [WidgetTester.showKeyboard].
- //
- // TODO(ianh): We should just remove this property and move the call to
- // requestKeyboard to the WidgetTester.showKeyboard method.
EditableTextState? get focusedEditable => _focusedEditable;
EditableTextState? _focusedEditable;
set focusedEditable(EditableTextState? value) {
@@ -775,8 +799,6 @@
// alone so that we don't cause more spurious errors.
runApp(Container(key: UniqueKey(), child: _postTestMessage)); // Unmount any remaining widgets.
await pump();
- if (registerTestTextInput)
- _testTextInput.unregister();
invariantTester();
_verifyAutoUpdateGoldensUnset(autoUpdateGoldensBeforeTest && !isBrowser);
_verifyReportTestExceptionUnset(reportTestExceptionBeforeTest);
diff --git a/packages/flutter_test/lib/src/deprecated.dart b/packages/flutter_test/lib/src/deprecated.dart
deleted file mode 100644
index b1e1d63..0000000
--- a/packages/flutter_test/lib/src/deprecated.dart
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright 2014 The Flutter 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';
-
-import 'binding.dart';
-
-// TODO(ianh): Once https://github.com/dart-lang/dartdoc/issues/2033 is fixed, update the hyperlinks marked HYPERLINK below.
-// TODO(ianh): Once cocoon and other customer_tests are migrated, deprecate these transitional APIs
-
-/// Shim to support the obsolete [setMockMessageHandler] and
-/// [checkMockMessageHandler] methods on [BinaryMessenger] in tests.
-///
-/// The implementations defer to [TestDefaultBinaryMessengerBinding.defaultBinaryMessenger].
-///
-/// Rather than calling [setMockMessageHandler] on the
-/// `ServicesBinding.defaultBinaryMessenger`, use
-/// `tester.binding.defaultBinaryMessenger.setMockMessageHandler` directly. This
-/// more accurately represents the actual method invocation.
-extension TestBinaryMessengerExtension on BinaryMessenger {
- /// Shim for `TestDefaultBinaryMessenger.setMockMessageHandler`.
- // HYPERLINK ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- // TODO(ianh): deprecate this method: @NotYetDeprecated(
- // 'Use tester.binding.defaultBinaryMessenger.setMockMessageHandler or '
- // 'TestDefaultBinaryMessenger.instance.defaultBinaryMessenger.setMockMessageHandler instead. '
- // 'This feature was deprecated after v2.1.0-10.0.pre.'
- // )
- void setMockMessageHandler(String channel, MessageHandler? handler) {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(channel, handler);
- }
-
- /// Shim for `TestDefaultBinaryMessenger.checkMockMessageHandler`.
- // HYPERLINK ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- // TODO(ianh): deprecate this method: @NotYetDeprecated(
- // 'Use tester.binding.defaultBinaryMessenger.checkMockMessageHandler or '
- // 'TestDefaultBinaryMessenger.instance.defaultBinaryMessenger.checkMockMessageHandler instead.'
- // 'This feature was deprecated after v2.1.0-10.0.pre.'
- // )
- bool checkMockMessageHandler(String channel, Object? handler) {
- return TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.checkMockMessageHandler(channel, handler);
- }
-}
-
-/// Shim to support the obsolete [setMockMessageHandler] and
-/// [checkMockMessageHandler] methods on [BasicMessageChannel] in tests.
-///
-/// The implementations defer to [TestDefaultBinaryMessengerBinding.defaultBinaryMessenger].
-///
-/// Rather than calling [setMockMessageHandler] on the message channel, use
-/// `tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler`
-/// directly. This more accurately represents the actual method invocation.
-extension TestBasicMessageChannelExtension<T> on BasicMessageChannel<T> {
- /// Shim for `TestDefaultBinaryMessenger.setMockDecodedMessageHandler`.
- // HYPERLINK ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- // TODO(ianh): deprecate this method: @NotYetDeprecated(
- // 'Use tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler or '
- // 'TestDefaultBinaryMessenger.instance.defaultBinaryMessenger.setMockDecodedMessageHandler instead. '
- // 'This feature was deprecated after v2.1.0-10.0.pre.'
- // )
- void setMockMessageHandler(Future<T> Function(T? message)? handler) {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockDecodedMessageHandler<T>(this, handler);
- }
-
- /// Shim for `TestDefaultBinaryMessenger.checkMockMessageHandler`.
- // HYPERLINK ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- // TODO(ianh): deprecate this method: @NotYetDeprecated(
- // 'Use tester.binding.defaultBinaryMessenger.checkMockMessageHandler or '
- // 'TestDefaultBinaryMessenger.instance.defaultBinaryMessenger.checkMockMessageHandler instead. '
- // 'For the first argument, pass channel.name. '
- // 'This feature was deprecated after v2.1.0-10.0.pre.'
- // )
- bool checkMockMessageHandler(Object? handler) {
- return TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.checkMockMessageHandler(name, handler);
- }
-}
-
-/// Shim to support the obsolete [setMockMethodCallHandler] and
-/// [checkMockMethodCallHandler] methods on [MethodChannel] in tests.
-///
-/// The implementations defer to [TestDefaultBinaryMessengerBinding.defaultBinaryMessenger].
-///
-/// Rather than calling [setMockMethodCallHandler] on the method channel, use
-/// `tester.binding.defaultBinaryMessenger.setMockMethodCallHandler` directly.
-/// This more accurately represents the actual method invocation.
-extension TestMethodChannelExtension on MethodChannel {
- /// Shim for `TestDefaultBinaryMessenger.setMockMethodCallHandler`.
- // HYPERLINK ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- // TODO(ianh): deprecate this method: @NotYetDeprecated(
- // 'Use tester.binding.defaultBinaryMessenger.setMockMethodCallHandler or '
- // 'TestDefaultBinaryMessenger.instance.defaultBinaryMessenger.setMockMethodCallHandler instead. '
- // 'This feature was deprecated after v2.1.0-10.0.pre.'
- // )
- void setMockMethodCallHandler(Future<dynamic>? Function(MethodCall call)? handler) {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(this, handler);
- }
-
- /// Shim for `TestDefaultBinaryMessenger.checkMockMessageHandler`.
- // HYPERLINK ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- // TODO(ianh): deprecate this method: @NotYetDeprecated(
- // 'Use tester.binding.defaultBinaryMessenger.checkMockMessageHandler or '
- // 'TestDefaultBinaryMessenger.instance.defaultBinaryMessenger.checkMockMessageHandler instead. '
- // 'For the first argument, pass channel.name. '
- // 'This feature was deprecated after v2.1.0-10.0.pre.'
- // )
- bool checkMockMethodCallHandler(Object? handler) {
- return TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.checkMockMessageHandler(name, handler);
- }
-}
diff --git a/packages/flutter_test/lib/src/event_simulation.dart b/packages/flutter_test/lib/src/event_simulation.dart
index f769ab0..121c20d 100644
--- a/packages/flutter_test/lib/src/event_simulation.dart
+++ b/packages/flutter_test/lib/src/event_simulation.dart
@@ -2,13 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-import 'dart:async';
import 'dart:io';
import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter/services.dart';
-
-import 'binding.dart';
import 'test_async_utils.dart';
// TODO(gspencergoog): Replace this with more robust key simulation code once
@@ -640,20 +637,21 @@
assert(_osIsSupported(platform!), 'Platform $platform not supported for key simulation');
final Map<String, dynamic> data = getKeyData(key, platform: platform!, isDown: true, physicalKey: physicalKey);
- final Completer<bool> result = Completer<bool>();
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ bool result = false;
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData? data) {
if (data == null) {
- result.complete(false);
return;
}
final Map<String, dynamic> decoded = SystemChannels.keyEvent.codec.decodeMessage(data) as Map<String, dynamic>;
- result.complete(decoded['handled'] as bool);
+ if (decoded['handled'] as bool) {
+ result = true;
+ }
}
);
- return result.future;
+ return result;
});
}
@@ -679,7 +677,7 @@
final Map<String, dynamic> data = getKeyData(key, platform: platform!, isDown: false, physicalKey: physicalKey);
bool result = false;
- await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData? data) {
diff --git a/packages/flutter_test/lib/src/test_default_binary_messenger.dart b/packages/flutter_test/lib/src/test_default_binary_messenger.dart
deleted file mode 100644
index d0e18ac..0000000
--- a/packages/flutter_test/lib/src/test_default_binary_messenger.dart
+++ /dev/null
@@ -1,306 +0,0 @@
-// Copyright 2014 The Flutter 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 'dart:async';
-import 'dart:ui' as ui;
-
-import 'package:fake_async/fake_async.dart';
-import 'package:flutter/services.dart';
-
-/// A [BinaryMessenger] subclass that is used as the default binary messenger
-/// under testing environment.
-///
-/// It tracks status of data sent across the Flutter platform barrier, which is
-/// useful for testing frameworks to monitor and synchronize against the
-/// platform messages.
-///
-/// ## Messages from the framework to the platform
-///
-/// Messages are sent from the framework to the platform via the
-/// [send] method.
-///
-/// To intercept a message sent from the framework to the platform,
-/// consider using [setMockMessageHandler],
-/// [setMockDecodedMessageHandler], and [setMockMethodCallHandler]
-/// (see also [checkMockMessageHandler]).
-///
-/// To wait for all pending framework-to-platform messages, the
-/// [platformMessagesFinished] getter provides an appropriate
-/// [Future]. The [pendingMessageCount] getter returns the current
-/// number of outstanding messages.
-///
-/// ## Messages from the platform to the framework
-///
-/// The platform sends messages via the [ChannelBuffers] API. Mock
-/// messages can be sent to the framework using
-/// [handlePlatformMessage].
-///
-/// Listeners for these messages are configured using [setMessageHandler].
-class TestDefaultBinaryMessenger extends BinaryMessenger {
- /// Creates a [TestDefaultBinaryMessenger] instance.
- ///
- /// The [delegate] instance must not be null.
- TestDefaultBinaryMessenger(this.delegate): assert(delegate != null);
-
- /// The delegate [BinaryMessenger].
- final BinaryMessenger delegate;
-
- // The handlers for messages from the engine (including fake
- // messages sent by handlePlatformMessage).
- final Map<String, MessageHandler> _inboundHandlers = <String, MessageHandler>{};
-
- /// Send a mock message to the framework as if it came from the platform.
- ///
- /// If a listener has been set using [setMessageHandler], that listener is
- /// invoked to handle the message, and this method returns a future that
- /// completes with that handler's result.
- ///
- /// {@template flutter.flutter_test.TestDefaultBinaryMessenger.handlePlatformMessage.asyncHandlers}
- /// It is strongly recommended that all handlers used with this API be
- /// synchronous (not requiring any microtasks to complete), because
- /// [testWidgets] tests run in a [FakeAsync] zone in which microtasks do not
- /// progress except when time is explicitly advanced (e.g. with
- /// [WidgetTester.pump]), which means that `await`ing a [Future] will result
- /// in the test hanging.
- /// {@endtemplate}
- ///
- /// If no listener is configured, this method returns right away with null.
- ///
- /// The `callback` argument, if non-null, will be called just before this
- /// method's future completes, either with the result of the listener
- /// registered with [setMessageHandler], or with null if no listener has
- /// been registered.
- ///
- /// Messages can also be sent via [ChannelBuffers.push] (see
- /// [ServicesBinding.channelBuffers]); the effect is the same, though that API
- /// will not wait for a response.
- // TODO(ianh): When the superclass `handlePlatformMessage` is removed,
- // remove this @override (but leave the method).
- @override
- Future<ByteData?> handlePlatformMessage(
- String channel,
- ByteData? data,
- ui.PlatformMessageResponseCallback? callback,
- ) {
- Future<ByteData?>? result;
- if (_inboundHandlers.containsKey(channel))
- result = _inboundHandlers[channel]!(data);
- result ??= Future<ByteData?>.value(null);
- if (callback != null)
- result = result.then((ByteData? result) { callback(result); return result; });
- return result;
- }
-
- @override
- void setMessageHandler(String channel, MessageHandler? handler) {
- if (handler == null) {
- _inboundHandlers.remove(channel);
- delegate.setMessageHandler(channel, null);
- } else {
- _inboundHandlers[channel] = handler; // used to handle fake messages sent via handlePlatformMessage
- delegate.setMessageHandler(channel, handler); // used to handle real messages from the engine
- }
- }
-
- final List<Future<ByteData?>> _pendingMessages = <Future<ByteData?>>[];
-
- /// The number of incomplete/pending calls sent to the platform channels.
- int get pendingMessageCount => _pendingMessages.length;
-
- // Handlers that intercept and respond to outgoing messages,
- // pretending to be the platform.
- final Map<String, MessageHandler> _outboundHandlers = <String, MessageHandler>{};
-
- // The outbound callbacks that were actually registered, so that we
- // can implement the [checkMockMessageHandler] method.
- final Map<String, Object> _outboundHandlerIdentities = <String, Object>{};
-
- @override
- Future<ByteData?>? send(String channel, ByteData? message) {
- final Future<ByteData?>? resultFuture;
- final MessageHandler? handler = _outboundHandlers[channel];
- if (handler != null) {
- resultFuture = handler(message);
- } else {
- resultFuture = delegate.send(channel, message);
- }
- if (resultFuture != null) {
- _pendingMessages.add(resultFuture);
- resultFuture
- .catchError((Object error) { /* errors are the responsibility of the caller */ })
- .whenComplete(() => _pendingMessages.remove(resultFuture));
- }
- return resultFuture;
- }
-
- /// Returns a Future that completes after all the platform calls are finished.
- ///
- /// If a new platform message is sent after this method is called, this new
- /// message is not tracked. Use with [pendingMessageCount] to guarantee no
- /// pending message calls.
- Future<void> get platformMessagesFinished {
- return Future.wait<void>(_pendingMessages);
- }
-
- /// Set a callback for intercepting messages sent to the platform on
- /// the given channel, without decoding them.
- ///
- /// Intercepted messages are not forwarded to the platform.
- ///
- /// The given callback will replace the currently registered
- /// callback for that channel, if any. To stop intercepting messages
- /// at all, pass null as the handler.
- ///
- /// The handler's return value, if non-null, is used as a response,
- /// unencoded.
- ///
- /// {@macro flutter.flutter_test.TestDefaultBinaryMessenger.handlePlatformMessage.asyncHandlers}
- ///
- /// The `identity` argument, if non-null, is used to identify the
- /// callback when checked by [checkMockMessageHandler]. If null, the
- /// `handler` is used instead. (This allows closures to be passed as
- /// the `handler` with an alias used as the `identity` so that a
- /// reference to the closure need not be used. In practice, this is
- /// used by [setMockDecodedMessageHandler] and
- /// [setMockMethodCallHandler] to allow [checkMockMessageHandler] to
- /// recognize the closures that were passed to those methods even
- /// though those methods wrap those closures when passing them to
- /// this method.)
- ///
- /// Registered callbacks are cleared after each test.
- ///
- /// See also:
- ///
- /// * [checkMockMessageHandler], which can verify if a handler is still
- /// registered, which is useful in tests to ensure that no unexpected
- /// handlers are being registered.
- ///
- /// * [setMockDecodedMessageHandler], which wraps this method but
- /// decodes the messages using a [MessageCodec].
- ///
- /// * [setMockMethodCallHandler], which wraps this method but decodes
- /// the messages using a [MethodCodec].
- void setMockMessageHandler(String channel, MessageHandler? handler, [ Object? identity ]) {
- if (handler == null) {
- _outboundHandlers.remove(channel);
- _outboundHandlerIdentities.remove(channel);
- } else {
- identity ??= handler;
- _outboundHandlers[channel] = handler;
- _outboundHandlerIdentities[channel] = identity;
- }
- }
-
- /// Set a callback for intercepting messages sent to the platform on
- /// the given channel.
- ///
- /// Intercepted messages are not forwarded to the platform.
- ///
- /// The given callback will replace the currently registered
- /// callback for that channel, if any. To stop intercepting messages
- /// at all, pass null as the handler.
- ///
- /// Messages are decoded using the codec of the channel.
- ///
- /// The handler's return value, if non-null, is used as a response,
- /// after encoding it using the channel's codec.
- ///
- /// {@macro flutter.flutter_test.TestDefaultBinaryMessenger.handlePlatformMessage.asyncHandlers}
- ///
- /// Registered callbacks are cleared after each test.
- ///
- /// See also:
- ///
- /// * [checkMockMessageHandler], which can verify if a handler is still
- /// registered, which is useful in tests to ensure that no unexpected
- /// handlers are being registered.
- ///
- /// * [setMockMessageHandler], which is similar but provides raw
- /// access to the underlying bytes.
- ///
- /// * [setMockMethodCallHandler], which is similar but decodes
- /// the messages using a [MethodCodec].
- void setMockDecodedMessageHandler<T>(BasicMessageChannel<T> channel, Future<T> Function(T? message)? handler) {
- if (handler == null) {
- setMockMessageHandler(channel.name, null);
- return;
- }
- setMockMessageHandler(channel.name, (ByteData? message) async {
- return channel.codec.encodeMessage(await handler(channel.codec.decodeMessage(message)));
- }, handler);
- }
-
- /// Set a callback for intercepting method calls sent to the
- /// platform on the given channel.
- ///
- /// Intercepted method calls are not forwarded to the platform.
- ///
- /// The given callback will replace the currently registered
- /// callback for that channel, if any. To stop intercepting messages
- /// at all, pass null as the handler.
- ///
- /// Methods are decoded using the codec of the channel.
- ///
- /// The handler's return value, if non-null, is used as a response,
- /// after re-encoding it using the channel's codec.
- ///
- /// To send an error, throw a [PlatformException] in the handler.
- /// Other exceptions are not caught.
- ///
- /// {@macro flutter.flutter_test.TestDefaultBinaryMessenger.handlePlatformMessage.asyncHandlers}
- ///
- /// Registered callbacks are cleared after each test.
- ///
- /// See also:
- ///
- /// * [checkMockMessageHandler], which can verify if a handler is still
- /// registered, which is useful in tests to ensure that no unexpected
- /// handlers are being registered.
- ///
- /// * [setMockMessageHandler], which is similar but provides raw
- /// access to the underlying bytes.
- ///
- /// * [setMockDecodedMessageHandler], which is similar but decodes
- /// the messages using a [MessageCodec].
- void setMockMethodCallHandler(MethodChannel channel, Future<Object?>? Function(MethodCall message)? handler) {
- if (handler == null) {
- setMockMessageHandler(channel.name, null);
- return;
- }
- setMockMessageHandler(channel.name, (ByteData? message) async {
- final MethodCall call = channel.codec.decodeMethodCall(message);
- try {
- return channel.codec.encodeSuccessEnvelope(await handler(call));
- } on PlatformException catch (error) {
- return channel.codec.encodeErrorEnvelope(
- code: error.code,
- message: error.message,
- details: error.details,
- );
- } on MissingPluginException {
- return null;
- } catch (error) {
- return channel.codec.encodeErrorEnvelope(code: 'error', message: '$error', details: null);
- }
- }, handler);
- }
-
- /// Returns true if the `handler` argument matches the `handler`
- /// previously passed to [setMockMessageHandler],
- /// [setMockDecodedMessageHandler], or [setMockMethodCallHandler].
- ///
- /// Specifically, it compares the argument provided to the `identity`
- /// argument provided to [setMockMessageHandler], defaulting to the
- /// `handler` argument passed to that method is `identity` was null.
- ///
- /// This method is useful for tests or test harnesses that want to assert the
- /// mock handler for the specified channel has not been altered by a previous
- /// test.
- ///
- /// Passing null for the `handler` returns true if the handler for the
- /// `channel` is not set.
- ///
- /// Registered callbacks are cleared after each test.
- bool checkMockMessageHandler(String channel, Object? handler) => _outboundHandlerIdentities[channel] == handler;
-}
diff --git a/packages/flutter_test/lib/src/test_text_input.dart b/packages/flutter_test/lib/src/test_text_input.dart
index a99bcef..c20fd56 100644
--- a/packages/flutter_test/lib/src/test_text_input.dart
+++ b/packages/flutter_test/lib/src/test_text_input.dart
@@ -8,28 +8,12 @@
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
-import 'binding.dart' show TestDefaultBinaryMessengerBinding;
-import 'deprecated.dart';
-import 'test_async_utils.dart';
-
export 'package:flutter/services.dart' show TextEditingValue, TextInputAction;
/// A testing stub for the system's onscreen keyboard.
///
/// Typical app tests will not need to use this class directly.
///
-/// The [TestWidgetsFlutterBinding] class registers a [TestTextInput] instance
-/// ([TestWidgetsFlutterBinding.testTextInput]) as a stub keyboard
-/// implementation if its [TestWidgetsFlutterBinding.registerTestTextInput]
-/// property returns true when a test starts, and unregisters it when the test
-/// ends (unless it ends with a failure).
-///
-/// See [register], [unregister], and [isRegistered] for details.
-///
-/// The [enterText], [updateEditingValue], [receiveAction], and
-/// [closeConnection] methods can be used even when the [TestTextInput] is not
-/// registered. All other methods will assert if [isRegistered] is false.
-///
/// See also:
///
/// * [WidgetTester.enterText], which uses this class to simulate keyboard input.
@@ -49,76 +33,61 @@
/// first be requested, e.g. using [WidgetTester.showKeyboard].
final VoidCallback? onCleared;
+ /// The messenger which sends the bytes for this channel, not null.
+ BinaryMessenger get _binaryMessenger => ServicesBinding.instance!.defaultBinaryMessenger;
+
+ /// Resets any internal state of this object and calls [register].
+ ///
+ /// This method is invoked by the testing framework between tests. It should
+ /// not ordinarily be called by tests directly.
+ void resetAndRegister() {
+ log.clear();
+ editingState = null;
+ setClientArgs = null;
+ _client = 0;
+ _isVisible = false;
+ register();
+ }
+ /// Installs this object as a mock handler for [SystemChannels.textInput].
+ void register() => SystemChannels.textInput.setMockMethodCallHandler(_handleTextInputCall);
+
+ /// Removes this object as a mock handler for [SystemChannels.textInput].
+ ///
+ /// After calling this method, the channel will exchange messages with the
+ /// Flutter engine. Use this with [FlutterDriver] tests that need to display
+ /// on-screen keyboard provided by the operating system.
+ void unregister() => SystemChannels.textInput.setMockMethodCallHandler(null);
+
/// Log for method calls.
///
/// For all registered channels, handled calls are added to the list. Can
/// be cleaned using `log.clear()`.
final List<MethodCall> log = <MethodCall>[];
- /// Installs this object as a mock handler for [SystemChannels.textInput].
- ///
- /// Called by the binding at the top of a test when
- /// [TestWidgetsFlutterBinding.registerTestTextInput] is true.
- void register() => SystemChannels.textInput.setMockMethodCallHandler(_handleTextInputCall);
-
- /// Removes this object as a mock handler for [SystemChannels.textInput].
- ///
- /// After calling this method, the channel will exchange messages with the
- /// Flutter engine instead of the stub.
- ///
- /// Called by the binding at the end of a (successful) test when
- /// [TestWidgetsFlutterBinding.registerTestTextInput] is true.
- void unregister() => SystemChannels.textInput.setMockMethodCallHandler(null);
-
/// Whether this [TestTextInput] is registered with [SystemChannels.textInput].
///
- /// The binding uses the [register] and [unregister] methods to control this
- /// value when [TestWidgetsFlutterBinding.registerTestTextInput] is true.
+ /// Use [register] and [unregister] methods to control this value.
bool get isRegistered => SystemChannels.textInput.checkMockMethodCallHandler(_handleTextInputCall);
- int? _client;
-
/// Whether there are any active clients listening to text input.
bool get hasAnyClients {
assert(isRegistered);
- return _client != null && _client! > 0;
+ return _client > 0;
}
- /// The last set of arguments supplied to the `TextInput.setClient` and
- /// `TextInput.updateConfig` methods of this stub implementation.
+ int _client = 0;
+
+ /// Arguments supplied to the TextInput.setClient method call.
Map<String, dynamic>? setClientArgs;
/// The last set of arguments that [TextInputConnection.setEditingState] sent
- /// to this stub implementation (i.e. the arguments set to
- /// `TextInput.setEditingState`).
+ /// to the embedder.
///
/// This is a map representation of a [TextEditingValue] object. For example,
/// it will have a `text` entry whose value matches the most recent
/// [TextEditingValue.text] that was sent to the embedder.
Map<String, dynamic>? editingState;
- /// Whether the onscreen keyboard is visible to the user.
- ///
- /// Specifically, this reflects the last call to `TextInput.show` or
- /// `TextInput.hide` received by the stub implementation.
- bool get isVisible {
- assert(isRegistered);
- return _isVisible;
- }
- bool _isVisible = false;
-
- /// Resets any internal state of this object.
- ///
- /// This method is invoked by the testing framework between tests. It should
- /// not ordinarily be called by tests directly.
- void reset() {
- log.clear();
- _client = null;
- setClientArgs = null;
- editingState = null;
- _isVisible = false;
- }
-
Future<dynamic> _handleTextInputCall(MethodCall methodCall) async {
log.add(methodCall);
switch (methodCall.method) {
@@ -130,7 +99,7 @@
setClientArgs = methodCall.arguments as Map<String, dynamic>;
break;
case 'TextInput.clearClient':
- _client = null;
+ _client = 0;
_isVisible = false;
onCleared?.call();
break;
@@ -146,86 +115,87 @@
}
}
- /// Simulates the user hiding the onscreen keyboard.
- ///
- /// This does nothing but set the internal flag.
- void hide() {
+ /// Whether the onscreen keyboard is visible to the user.
+ bool get isVisible {
assert(isRegistered);
- _isVisible = false;
+ return _isVisible;
+ }
+ bool _isVisible = false;
+
+ /// Simulates the user changing the [TextEditingValue] to the given value.
+ void updateEditingValue(TextEditingValue value) {
+ assert(isRegistered);
+ // Not using the `expect` function because in the case of a FlutterDriver
+ // test this code does not run in a package:test test zone.
+ if (_client == 0)
+ throw TestFailure('Tried to use TestTextInput with no keyboard attached. You must use WidgetTester.showKeyboard() first.');
+ _binaryMessenger.handlePlatformMessage(
+ SystemChannels.textInput.name,
+ SystemChannels.textInput.codec.encodeMethodCall(
+ MethodCall(
+ 'TextInputClient.updateEditingState',
+ <dynamic>[_client, value.toJSON()],
+ ),
+ ),
+ (ByteData? data) { /* response from framework is discarded */ },
+ );
}
- /// Simulates the user changing the text of the focused text field, and resets
- /// the selection.
+ /// Simulates the user closing the text input connection.
+ ///
+ /// For example:
+ /// - User pressed the home button and sent the application to background.
+ /// - User closed the virtual keyboard.
+ void closeConnection() {
+ assert(isRegistered);
+ // Not using the `expect` function because in the case of a FlutterDriver
+ // test this code does not run in a package:test test zone.
+ if (_client == 0)
+ throw TestFailure('Tried to use TestTextInput with no keyboard attached. You must use WidgetTester.showKeyboard() first.');
+ _binaryMessenger.handlePlatformMessage(
+ SystemChannels.textInput.name,
+ SystemChannels.textInput.codec.encodeMethodCall(
+ MethodCall(
+ 'TextInputClient.onConnectionClosed',
+ <dynamic>[_client,]
+ ),
+ ),
+ (ByteData? data) { /* response from framework is discarded */ },
+ );
+ }
+
+ /// Simulates the user typing the given text.
///
/// Calling this method replaces the content of the connected input field with
/// `text`, and places the caret at the end of the text.
- ///
- /// To update the UI under test after this method is invoked, use
- /// [WidgetTester.pump].
- ///
- /// This can be called even if the [TestTextInput] has not been [register]ed.
- ///
- /// If this is used to inject text when there is a real IME connection, for
- /// example when using the [integration_test] library, there is a risk that
- /// the real IME will become confused as to the current state of input.
- ///
- /// See also:
- ///
- /// * [updateEditingValue], which takes a [TextEditingValue] so that one can
- /// also change the selection.
void enterText(String text) {
+ assert(isRegistered);
updateEditingValue(TextEditingValue(
text: text,
selection: TextSelection.collapsed(offset: text.length),
));
}
- /// Simulates the user changing the [TextEditingValue] to the given value.
- ///
- /// To update the UI under test after this method is invoked, use
- /// [WidgetTester.pump].
- ///
- /// This can be called even if the [TestTextInput] has not been [register]ed.
- ///
- /// If this is used to inject text when there is a real IME connection, for
- /// example when using the [integration_test] library, there is a risk that
- /// the real IME will become confused as to the current state of input.
- ///
- /// See also:
- ///
- /// * [enterText], which is similar but takes only a String and resets the
- /// selection.
- void updateEditingValue(TextEditingValue value) {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
- SystemChannels.textInput.name,
- SystemChannels.textInput.codec.encodeMethodCall(
- MethodCall(
- 'TextInputClient.updateEditingState',
- <dynamic>[_client ?? -1, value.toJSON()],
- ),
- ),
- (ByteData? data) { /* ignored */ },
- );
- }
-
/// Simulates the user pressing one of the [TextInputAction] buttons.
/// Does not check that the [TextInputAction] performed is an acceptable one
/// based on the `inputAction` [setClientArgs].
- ///
- /// This can be called even if the [TestTextInput] has not been [register]ed.
- ///
- /// If this is used to inject an action when there is a real IME connection,
- /// for example when using the [integration_test] library, there is a risk
- /// that the real IME will become confused as to the current state of input.
Future<void> receiveAction(TextInputAction action) async {
+ assert(isRegistered);
return TestAsyncUtils.guard(() {
+ // Not using the `expect` function because in the case of a FlutterDriver
+ // test this code does not run in a package:test test zone.
+ if (_client == 0) {
+ throw TestFailure('Tried to use TestTextInput with no keyboard attached. You must use WidgetTester.showKeyboard() first.');
+ }
+
final Completer<void> completer = Completer<void>();
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+
+ _binaryMessenger.handlePlatformMessage(
SystemChannels.textInput.name,
SystemChannels.textInput.codec.encodeMethodCall(
MethodCall(
'TextInputClient.performAction',
- <dynamic>[_client ?? -1, action.toString()],
+ <dynamic>[_client, action.toString()],
),
),
(ByteData? data) {
@@ -234,7 +204,8 @@
// Decoding throws a PlatformException if the data represents an
// error, and that's all we care about here.
SystemChannels.textInput.codec.decodeEnvelope(data!);
- // If we reach here then no error was found. Complete without issue.
+
+ // No error was found. Complete without issue.
completer.complete();
} catch (error) {
// An exception occurred as a result of receiveAction()'ing. Report
@@ -243,32 +214,14 @@
}
},
);
+
return completer.future;
});
}
- /// Simulates the user closing the text input connection.
- ///
- /// For example:
- ///
- /// * User pressed the home button and sent the application to background.
- /// * User closed the virtual keyboard.
- ///
- /// This can be called even if the [TestTextInput] has not been [register]ed.
- ///
- /// If this is used to inject text when there is a real IME connection, for
- /// example when using the [integration_test] library, there is a risk that
- /// the real IME will become confused as to the current state of input.
- void closeConnection() {
- TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
- SystemChannels.textInput.name,
- SystemChannels.textInput.codec.encodeMethodCall(
- MethodCall(
- 'TextInputClient.onConnectionClosed',
- <dynamic>[_client ?? -1],
- ),
- ),
- (ByteData? data) { /* response from framework is discarded */ },
- );
+ /// Simulates the user hiding the onscreen keyboard.
+ void hide() {
+ assert(isRegistered);
+ _isVisible = false;
}
}
diff --git a/packages/flutter_test/lib/src/widget_tester.dart b/packages/flutter_test/lib/src/widget_tester.dart
index 50c23a5..e5ca5d9 100644
--- a/packages/flutter_test/lib/src/widget_tester.dart
+++ b/packages/flutter_test/lib/src/widget_tester.dart
@@ -129,7 +129,7 @@
dynamic tags,
}) {
assert(variant != null);
- assert(variant.values.isNotEmpty, 'There must be at least one value to test in the testing variant.');
+ assert(variant.values.isNotEmpty, 'There must be at least on value to test in the testing variant');
final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized() as TestWidgetsFlutterBinding;
final WidgetTester tester = WidgetTester._(binding);
for (final dynamic value in variant.values) {
@@ -147,8 +147,9 @@
test_package.addTearDown(binding.postTest);
return binding.runTest(
() async {
- binding.reset(); // TODO(ianh): the binding should just do this itself in _runTest
+ binding.reset();
debugResetSemanticsIdCounter();
+ tester.resetTestTextInput();
Object? memento;
try {
memento = await variant.setUp(value);
@@ -917,12 +918,10 @@
/// Acts as if the application went idle.
///
/// Runs all remaining microtasks, including those scheduled as a result of
- /// running them, until there are no more microtasks scheduled. Then, runs any
- /// previously scheduled timers with zero time, and completes the returned future.
+ /// running them, until there are no more microtasks scheduled.
///
- /// May result in an infinite loop or run out of memory if microtasks continue
- /// to recursively schedule new microtasks. Will not run any timers scheduled
- /// after this method was invoked, even if they are zero-time timers.
+ /// Does not run timers. May result in an infinite loop or run out of memory
+ /// if microtasks continue to recursively schedule new microtasks.
Future<void> idle() {
return TestAsyncUtils.guard<void>(() => binding.idle());
}
@@ -1003,14 +1002,19 @@
///
/// Typical app tests will not need to use this value. To add text to widgets
/// like [TextField] or [TextFormField], call [enterText].
- ///
- /// Some of the properties and methods on this value are only valid if the
- /// binding's [TestWidgetsFlutterBinding.registerTestTextInput] flag is set to
- /// true as a test is starting (meaning that the keyboard is to be simulated
- /// by the test framework). If those members are accessed when using a binding
- /// that sets this flag to false, they will throw.
TestTextInput get testTextInput => binding.testTextInput;
+ /// Ensures that [testTextInput] is registered and [TestTextInput.log] is
+ /// reset.
+ ///
+ /// This is called by the testing framework before test runs, so that if a
+ /// previous test has set its own handler on [SystemChannels.textInput], the
+ /// [testTextInput] regains control and the log is fresh for the new test.
+ /// It should not typically need to be called by tests.
+ void resetTestTextInput() {
+ testTextInput.resetAndRegister();
+ }
+
/// Give the text input widget specified by [finder] the focus, as if the
/// onscreen keyboard had appeared.
///
@@ -1031,9 +1035,6 @@
matchRoot: true,
),
);
- // Setting focusedEditable causes the binding to call requestKeyboard()
- // on the EditableTextState, which itself eventually calls TextInput.attach
- // to establish the connection.
binding.focusedEditable = editable;
await pump();
});
@@ -1051,12 +1052,6 @@
///
/// To just give [finder] the focus without entering any text,
/// see [showKeyboard].
- ///
- /// To enter text into other widgets (e.g. a custom widget that maintains a
- /// TextInputConnection the way that a [EditableText] does), first ensure that
- /// that widget has an open connection (e.g. by using [tap] to to focus it),
- /// then call `testTextInput.enterText` directly (see
- /// [TestTextInput.enterText]).
Future<void> enterText(Finder finder, String text) async {
return TestAsyncUtils.guard<void>(() async {
await showKeyboard(finder);
diff --git a/packages/flutter_test/lib/src/window.dart b/packages/flutter_test/lib/src/window.dart
index c27c57d..500dd68 100644
--- a/packages/flutter_test/lib/src/window.dart
+++ b/packages/flutter_test/lib/src/window.dart
@@ -379,16 +379,8 @@
platformDispatcher.sendPlatformMessage(name, data, callback);
}
- @Deprecated(
- 'Instead of calling this callback, use ServicesBinding.instance.channelBuffers.push. '
- 'This feature was deprecated after v2.1.0-10.0.pre.'
- )
@override
ui.PlatformMessageCallback? get onPlatformMessage => platformDispatcher.onPlatformMessage;
- @Deprecated(
- 'Instead of setting this callback, use ServicesBinding.instance.defaultBinaryMessenger.setMessageHandler. '
- 'This feature was deprecated after v2.1.0-10.0.pre.'
- )
@override
set onPlatformMessage(ui.PlatformMessageCallback? callback) {
platformDispatcher.onPlatformMessage = callback;
diff --git a/packages/flutter_test/test/bindings_test.dart b/packages/flutter_test/test/bindings_test.dart
index bc98524..15e1431 100644
--- a/packages/flutter_test/test/bindings_test.dart
+++ b/packages/flutter_test/test/bindings_test.dart
@@ -11,8 +11,6 @@
import 'package:test_api/test_api.dart' as test_package;
void main() {
- final AutomatedTestWidgetsFlutterBinding binding = AutomatedTestWidgetsFlutterBinding();
-
group(TestViewConfiguration, () {
test('is initialized with top-level window if one is not provided', () {
// The code below will throw without the default.
@@ -22,32 +20,15 @@
group(AutomatedTestWidgetsFlutterBinding, () {
test('allows setting defaultTestTimeout to 5 minutes', () {
+ final AutomatedTestWidgetsFlutterBinding binding = AutomatedTestWidgetsFlutterBinding();
binding.defaultTestTimeout = const test_package.Timeout(Duration(minutes: 5));
expect(binding.defaultTestTimeout.duration, const Duration(minutes: 5));
});
});
- // The next three tests must run in order -- first using `test`, then `testWidgets`, then `test` again.
-
- int order = 0;
-
test('Initializes httpOverrides and testTextInput', () async {
- assert(order == 0);
- expect(binding.testTextInput, isNotNull);
- expect(binding.testTextInput.isRegistered, isFalse);
+ final TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized() as TestWidgetsFlutterBinding;
+ expect(binding.testTextInput.isRegistered, true);
expect(HttpOverrides.current, isNotNull);
- order += 1;
- });
-
- testWidgets('Registers testTextInput', (WidgetTester tester) async {
- assert(order == 1);
- expect(tester.testTextInput.isRegistered, isTrue);
- order += 1;
- });
-
- test('Unregisters testTextInput', () async {
- assert(order == 2);
- expect(binding.testTextInput.isRegistered, isFalse);
- order += 1;
});
}
diff --git a/packages/flutter_test/test/test_default_binary_messenger_test.dart b/packages/flutter_test/test/test_default_binary_messenger_test.dart
index 30cf93d..82cb18f 100644
--- a/packages/flutter_test/test/test_default_binary_messenger_test.dart
+++ b/packages/flutter_test/test/test_default_binary_messenger_test.dart
@@ -20,6 +20,12 @@
Future<void> handlePlatformMessage(String channel, ByteData? data, ui.PlatformMessageResponseCallback? callback) => throw UnimplementedError();
@override
void setMessageHandler(String channel, MessageHandler? handler) => throw UnimplementedError();
+ @override
+ bool checkMessageHandler(String channel, MessageHandler? handler) => throw UnimplementedError();
+ @override
+ void setMockMessageHandler(String channel, MessageHandler? handler) => throw UnimplementedError();
+ @override
+ bool checkMockMessageHandler(String channel, MessageHandler? handler) => throw UnimplementedError();
}
void main() {
diff --git a/packages/flutter_web_plugins/lib/src/plugin_registry.dart b/packages/flutter_web_plugins/lib/src/plugin_registry.dart
index cc397b7..ecd273f 100644
--- a/packages/flutter_web_plugins/lib/src/plugin_registry.dart
+++ b/packages/flutter_web_plugins/lib/src/plugin_registry.dart
@@ -61,7 +61,7 @@
/// the [dart:ui] library. That function is only available when
/// compiling for the web.
void registerMessageHandler() {
- // The `ui.webOnlySetPluginHandler` function below is only defined in the Web dart:ui.
+ // The function below is only defined in the Web dart:ui.
// ignore: undefined_function
ui.webOnlySetPluginHandler(handleFrameworkMessage);
}
@@ -141,7 +141,7 @@
@override
Future<ByteData?> send(String channel, ByteData? message) {
final Completer<ByteData?> completer = Completer<ByteData?>();
- ui.channelBuffers.push(channel, message, (ByteData? reply) {
+ ui.window.onPlatformMessage!(channel, message, (ByteData? reply) {
try {
completer.complete(reply);
} catch (exception, stack) {
@@ -163,6 +163,26 @@
else
_handlers[channel] = handler;
}
+
+ @override
+ bool checkMessageHandler(String channel, MessageHandler? handler) => _handlers[channel] == handler;
+
+ @override
+ void setMockMessageHandler(
+ String channel,
+ MessageHandler? handler,
+ ) {
+ throw FlutterError(
+ 'Setting mock handlers is not supported on the platform side.',
+ );
+ }
+
+ @override
+ bool checkMockMessageHandler(String channel, MessageHandler? handler) {
+ throw FlutterError(
+ 'Setting mock handlers is not supported on the platform side.',
+ );
+ }
}
/// This class was previously separate from [Registrar] but was merged into it
diff --git a/packages/flutter_web_plugins/test/plugin_registry_test.dart b/packages/flutter_web_plugins/test/plugin_registry_test.dart
index 73cb681..008d721 100644
--- a/packages/flutter_web_plugins/test/plugin_registry_test.dart
+++ b/packages/flutter_web_plugins/test/plugin_registry_test.dart
@@ -71,5 +71,12 @@
ServicesBinding.instance!.defaultBinaryMessenger
.setMessageHandler('test_send', null);
});
+
+ test('throws when trying to set a mock handler', () {
+ expect(
+ () => pluginBinaryMessenger.setMockMessageHandler(
+ 'test', (ByteData? data) async => ByteData(0)),
+ throwsFlutterError);
+ });
});
}