This reverts commit c26ed03c8a77810136cc087ae60048ace062842d.
This commit is contained in:
parent
e2ddeb0427
commit
b74df388e1
@ -11,6 +11,6 @@ void main() {
|
|||||||
Ticker((Duration duration) { }).start();
|
Ticker((Duration duration) { }).start();
|
||||||
|
|
||||||
final ByteData? message = const StringCodec().encodeMessage('AppLifecycleState.paused');
|
final ByteData? message = const StringCodec().encodeMessage('AppLifecycleState.paused');
|
||||||
await tester.binding.defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) {});
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) {});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:flutter_driver/flutter_driver.dart';
|
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';
|
import 'package:webdriver/async_io.dart';
|
||||||
|
|
||||||
/// The following test is used as a simple smoke test for verifying Flutter
|
/// The following test is used as a simple smoke test for verifying Flutter
|
||||||
@ -33,7 +33,6 @@ void main() {
|
|||||||
test('enable accessibility', () async {
|
test('enable accessibility', () async {
|
||||||
await driver.enableAccessibility();
|
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));
|
await Future<void>.delayed(const Duration(seconds: 2));
|
||||||
|
|
||||||
// Elements with tag "flt-semantics" would show up after enabling
|
// Elements with tag "flt-semantics" would show up after enabling
|
||||||
|
@ -104,8 +104,8 @@ abstract class BindingBase {
|
|||||||
/// A number of additional bindings are defined as extensions of
|
/// A number of additional bindings are defined as extensions of
|
||||||
/// [BindingBase], e.g., [ServicesBinding], [RendererBinding], and
|
/// [BindingBase], e.g., [ServicesBinding], [RendererBinding], and
|
||||||
/// [WidgetsBinding]. Each of these bindings define behaviors that interact
|
/// [WidgetsBinding]. Each of these bindings define behaviors that interact
|
||||||
/// with a [ui.PlatformDispatcher], e.g., [ServicesBinding] registers
|
/// with a [ui.PlatformDispatcher], e.g., [ServicesBinding] registers a
|
||||||
/// listeners with the [ChannelBuffers], and [RendererBinding]
|
/// [ui.PlatformDispatcher.onPlatformMessage] handler, and [RendererBinding]
|
||||||
/// registers [ui.PlatformDispatcher.onMetricsChanged],
|
/// registers [ui.PlatformDispatcher.onMetricsChanged],
|
||||||
/// [ui.PlatformDispatcher.onTextScaleFactorChanged],
|
/// [ui.PlatformDispatcher.onTextScaleFactorChanged],
|
||||||
/// [ui.PlatformDispatcher.onSemanticsEnabledChanged], and
|
/// [ui.PlatformDispatcher.onSemanticsEnabledChanged], and
|
||||||
|
@ -2,9 +2,12 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'dart:ui' as ui;
|
import 'dart:ui' as ui;
|
||||||
|
|
||||||
|
import 'binding.dart';
|
||||||
|
|
||||||
/// A function which takes a platform message and asynchronously returns an encoded response.
|
/// A function which takes a platform message and asynchronously returns an encoded response.
|
||||||
typedef MessageHandler = Future<ByteData?>? Function(ByteData? message);
|
typedef MessageHandler = Future<ByteData?>? Function(ByteData? message);
|
||||||
|
|
||||||
@ -16,39 +19,12 @@ abstract class BinaryMessenger {
|
|||||||
/// const constructors so that they can be used in const expressions.
|
/// const constructors so that they can be used in const expressions.
|
||||||
const BinaryMessenger();
|
const BinaryMessenger();
|
||||||
|
|
||||||
/// Queues a message.
|
/// Calls the handler registered for the given channel.
|
||||||
///
|
///
|
||||||
/// The returned future completes immediately.
|
/// Typically called by [ServicesBinding] to handle platform messages received
|
||||||
///
|
/// from [dart:ui.PlatformDispatcher.onPlatformMessage].
|
||||||
/// 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).
|
|
||||||
///
|
///
|
||||||
/// To register a handler for a given message channel, see [setMessageHandler].
|
/// 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);
|
Future<void> handlePlatformMessage(String channel, ByteData? data, ui.PlatformMessageResponseCallback? callback);
|
||||||
|
|
||||||
/// Send a binary message to the platform plugins on the given channel.
|
/// Send a binary message to the platform plugins on the given channel.
|
||||||
@ -67,6 +43,37 @@ abstract class BinaryMessenger {
|
|||||||
/// The handler's return value, if non-null, is sent as a response, unencoded.
|
/// The handler's return value, if non-null, is sent as a response, unencoded.
|
||||||
void setMessageHandler(String channel, MessageHandler? handler);
|
void setMessageHandler(String channel, MessageHandler? handler);
|
||||||
|
|
||||||
// Looking for setMockMessageHandler or checkMockMessageHandler?
|
/// Returns true if the `handler` argument matches the `handler` previously
|
||||||
// See this shim package: packages/flutter_test/lib/src/deprecated.dart
|
/// 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);
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ mixin ServicesBinding on BindingBase, SchedulerBinding {
|
|||||||
_instance = this;
|
_instance = this;
|
||||||
_defaultBinaryMessenger = createBinaryMessenger();
|
_defaultBinaryMessenger = createBinaryMessenger();
|
||||||
_restorationManager = createRestorationManager();
|
_restorationManager = createRestorationManager();
|
||||||
|
window.onPlatformMessage = defaultBinaryMessenger.handlePlatformMessage;
|
||||||
initLicenses();
|
initLicenses();
|
||||||
SystemChannels.system.setMessageHandler((dynamic message) => handleSystemMessage(message as Object));
|
SystemChannels.system.setMessageHandler((dynamic message) => handleSystemMessage(message as Object));
|
||||||
SystemChannels.lifecycle.setMessageHandler(_handleLifecycleMessage);
|
SystemChannels.lifecycle.setMessageHandler(_handleLifecycleMessage);
|
||||||
@ -46,28 +47,6 @@ mixin ServicesBinding on BindingBase, SchedulerBinding {
|
|||||||
BinaryMessenger get defaultBinaryMessenger => _defaultBinaryMessenger;
|
BinaryMessenger get defaultBinaryMessenger => _defaultBinaryMessenger;
|
||||||
late BinaryMessenger _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
|
/// Creates a default [BinaryMessenger] instance that can be used for sending
|
||||||
/// platform messages.
|
/// platform messages.
|
||||||
@protected
|
@protected
|
||||||
@ -75,6 +54,7 @@ mixin ServicesBinding on BindingBase, SchedulerBinding {
|
|||||||
return const _DefaultBinaryMessenger._();
|
return const _DefaultBinaryMessenger._();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Called when the operating system notifies the application of a memory
|
/// Called when the operating system notifies the application of a memory
|
||||||
/// pressure situation.
|
/// pressure situation.
|
||||||
///
|
///
|
||||||
@ -257,20 +237,17 @@ mixin ServicesBinding on BindingBase, SchedulerBinding {
|
|||||||
class _DefaultBinaryMessenger extends BinaryMessenger {
|
class _DefaultBinaryMessenger extends BinaryMessenger {
|
||||||
const _DefaultBinaryMessenger._();
|
const _DefaultBinaryMessenger._();
|
||||||
|
|
||||||
@override
|
// Handlers for incoming messages from platform plugins.
|
||||||
Future<void> handlePlatformMessage(
|
// This is static so that this class can have a const constructor.
|
||||||
String channel,
|
static final Map<String, MessageHandler> _handlers =
|
||||||
ByteData? message,
|
<String, MessageHandler>{};
|
||||||
ui.PlatformMessageResponseCallback? callback,
|
|
||||||
) async {
|
|
||||||
ui.channelBuffers.push(channel, message, (ByteData? data) {
|
|
||||||
if (callback != null)
|
|
||||||
callback(data);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
// Mock handlers that intercept and respond to outgoing messages.
|
||||||
Future<ByteData?> send(String channel, ByteData? message) {
|
// 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?>();
|
final Completer<ByteData?> completer = Completer<ByteData?>();
|
||||||
// ui.PlatformDispatcher.instance is accessed directly instead of using
|
// ui.PlatformDispatcher.instance is accessed directly instead of using
|
||||||
// ServicesBinding.instance.platformDispatcher because this method might be
|
// ServicesBinding.instance.platformDispatcher because this method might be
|
||||||
@ -279,8 +256,6 @@ class _DefaultBinaryMessenger extends BinaryMessenger {
|
|||||||
// ui.PlatformDispatcher.instance because the PlatformDispatcher may be
|
// ui.PlatformDispatcher.instance because the PlatformDispatcher may be
|
||||||
// dependency injected elsewhere with a different instance. However, static
|
// dependency injected elsewhere with a different instance. However, static
|
||||||
// access at this location seems to be the least bad option.
|
// 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) {
|
ui.PlatformDispatcher.instance.sendPlatformMessage(channel, message, (ByteData? reply) {
|
||||||
try {
|
try {
|
||||||
completer.complete(reply);
|
completer.complete(reply);
|
||||||
@ -296,27 +271,70 @@ class _DefaultBinaryMessenger extends BinaryMessenger {
|
|||||||
return completer.future;
|
return completer.future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@override
|
||||||
void setMessageHandler(String channel, MessageHandler? handler) {
|
void setMessageHandler(String channel, MessageHandler? handler) {
|
||||||
if (handler == null) {
|
if (handler == null) {
|
||||||
ui.channelBuffers.clearListener(channel);
|
_handlers.remove(channel);
|
||||||
} else {
|
} else {
|
||||||
ui.channelBuffers.setListener(channel, (ByteData? data, ui.PlatformMessageResponseCallback callback) async {
|
_handlers[channel] = handler;
|
||||||
ByteData? response;
|
ui.channelBuffers.drain(channel, (ByteData? data, ui.PlatformMessageResponseCallback callback) async {
|
||||||
try {
|
await handlePlatformMessage(channel, data, callback);
|
||||||
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);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,7 @@ abstract class MethodCodec {
|
|||||||
ByteData encodeErrorEnvelope({ required String code, String? message, Object? details});
|
ByteData encodeErrorEnvelope({ required String code, String? message, Object? details});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Thrown to indicate that a platform interaction failed in the platform
|
/// Thrown to indicate that a platform interaction failed in the platform
|
||||||
/// plugin.
|
/// plugin.
|
||||||
///
|
///
|
||||||
|
@ -75,10 +75,31 @@ class BasicMessageChannel<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Looking for setMockMessageHandler?
|
/// Sets a mock callback for intercepting messages sent on this channel.
|
||||||
// See this shim package: packages/flutter_test/lib/src/deprecated.dart
|
/// 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
|
/// A named channel for communicating with platform plugins using asynchronous
|
||||||
/// method calls.
|
/// method calls.
|
||||||
///
|
///
|
||||||
@ -353,6 +374,7 @@ class MethodChannel {
|
|||||||
/// similarly to what happens if no method call handler has been set.
|
/// similarly to what happens if no method call handler has been set.
|
||||||
/// Any other exception results in an error envelope being sent.
|
/// Any other exception results in an error envelope being sent.
|
||||||
void setMethodCallHandler(Future<dynamic> Function(MethodCall call)? handler) {
|
void setMethodCallHandler(Future<dynamic> Function(MethodCall call)? handler) {
|
||||||
|
_methodChannelHandlers[this] = handler;
|
||||||
binaryMessenger.setMessageHandler(
|
binaryMessenger.setMessageHandler(
|
||||||
name,
|
name,
|
||||||
handler == null
|
handler == null
|
||||||
@ -361,7 +383,53 @@ class MethodChannel {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
final MethodCall call = codec.decodeMethodCall(message);
|
||||||
try {
|
try {
|
||||||
return codec.encodeSuccessEnvelope(await handler(call));
|
return codec.encodeSuccessEnvelope(await handler(call));
|
||||||
@ -377,9 +445,6 @@ class MethodChannel {
|
|||||||
return codec.encodeErrorEnvelope(code: 'error', message: e.toString(), details: null);
|
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.
|
/// A [MethodChannel] that ignores missing platform plugins.
|
||||||
@ -407,6 +472,7 @@ class OptionalMethodChannel extends MethodChannel {
|
|||||||
final Map<dynamic, dynamic>? result = await invokeMethod<Map<dynamic, dynamic>>(method, arguments);
|
final Map<dynamic, dynamic>? result = await invokeMethod<Map<dynamic, dynamic>>(method, arguments);
|
||||||
return result?.cast<K, V>();
|
return result?.cast<K, V>();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A named channel for communicating with platform plugins using event streams.
|
/// A named channel for communicating with platform plugins using event streams.
|
||||||
|
@ -166,6 +166,7 @@ class RestorationManager extends ChangeNotifier {
|
|||||||
/// that communications channel, or to set it up differently, as necessary.
|
/// that communications channel, or to set it up differently, as necessary.
|
||||||
@protected
|
@protected
|
||||||
void initChannels() {
|
void initChannels() {
|
||||||
|
assert(!SystemChannels.restoration.checkMethodCallHandler(_methodHandler));
|
||||||
SystemChannels.restoration.setMethodCallHandler(_methodHandler);
|
SystemChannels.restoration.setMethodCallHandler(_methodHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1517,7 +1517,7 @@ class TextInput {
|
|||||||
assert(shouldSave != null);
|
assert(shouldSave != null);
|
||||||
TextInput._instance._channel.invokeMethod<void>(
|
TextInput._instance._channel.invokeMethod<void>(
|
||||||
'TextInput.finishAutofillContext',
|
'TextInput.finishAutofillContext',
|
||||||
shouldSave,
|
shouldSave ,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2360,13 +2360,11 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
|
|||||||
|
|
||||||
void _cursorWaitForStart(Timer timer) {
|
void _cursorWaitForStart(Timer timer) {
|
||||||
assert(_kCursorBlinkHalfPeriod > _fadeDuration);
|
assert(_kCursorBlinkHalfPeriod > _fadeDuration);
|
||||||
assert(!EditableText.debugDeterministicCursor);
|
|
||||||
_cursorTimer?.cancel();
|
_cursorTimer?.cancel();
|
||||||
_cursorTimer = Timer.periodic(_kCursorBlinkHalfPeriod, _cursorTick);
|
_cursorTimer = Timer.periodic(_kCursorBlinkHalfPeriod, _cursorTick);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _startCursorTimer() {
|
void _startCursorTimer() {
|
||||||
assert(_cursorTimer == null);
|
|
||||||
_targetCursorVisibility = true;
|
_targetCursorVisibility = true;
|
||||||
_cursorBlinkOpacityController.value = 1.0;
|
_cursorBlinkOpacityController.value = 1.0;
|
||||||
if (EditableText.debugDeterministicCursor)
|
if (EditableText.debugDeterministicCursor)
|
||||||
|
@ -202,7 +202,7 @@ void main() {
|
|||||||
final List<int> selectedItems = <int>[];
|
final List<int> selectedItems = <int>[];
|
||||||
final List<MethodCall> systemCalls = <MethodCall>[];
|
final List<MethodCall> systemCalls = <MethodCall>[];
|
||||||
|
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
systemCalls.add(methodCall);
|
systemCalls.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -253,7 +253,7 @@ void main() {
|
|||||||
final List<int> selectedItems = <int>[];
|
final List<int> selectedItems = <int>[];
|
||||||
final List<MethodCall> systemCalls = <MethodCall>[];
|
final List<MethodCall> systemCalls = <MethodCall>[];
|
||||||
|
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
systemCalls.add(methodCall);
|
systemCalls.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ void main() {
|
|||||||
testWidgets('drag past threshold triggers refresh task', (WidgetTester tester) async {
|
testWidgets('drag past threshold triggers refresh task', (WidgetTester tester) async {
|
||||||
final List<MethodCall> platformCallLog = <MethodCall>[];
|
final List<MethodCall> platformCallLog = <MethodCall>[];
|
||||||
|
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
platformCallLog.add(methodCall);
|
platformCallLog.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -132,9 +132,9 @@ void main() {
|
|||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
int hapticFeedbackCalls = 0;
|
int hapticFeedbackCalls = 0;
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
if (methodCall.method == 'HapticFeedback.vibrate') {
|
if (methodCall.method == 'HapticFeedback.vibrate') {
|
||||||
hapticFeedbackCalls += 1;
|
hapticFeedbackCalls++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -680,9 +680,9 @@ void main() {
|
|||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
int hapticFeedbackCalls = 0;
|
int hapticFeedbackCalls = 0;
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
if (methodCall.method == 'HapticFeedback.vibrate') {
|
if (methodCall.method == 'HapticFeedback.vibrate') {
|
||||||
hapticFeedbackCalls += 1;
|
hapticFeedbackCalls++;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ void main() {
|
|||||||
|
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
|
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -87,7 +87,7 @@ void main() {
|
|||||||
bool value2 = false;
|
bool value2 = false;
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
|
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ void main() {
|
|||||||
bool value = false;
|
bool value = false;
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
|
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -192,7 +192,7 @@ void main() {
|
|||||||
bool value = false;
|
bool value = false;
|
||||||
|
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ class PathPointsMatcher extends Matcher {
|
|||||||
void main() {
|
void main() {
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
final MockClipboard mockClipboard = MockClipboard();
|
final MockClipboard mockClipboard = MockClipboard();
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
|
SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
|
||||||
|
|
||||||
// Returns the first RenderEditable.
|
// Returns the first RenderEditable.
|
||||||
RenderEditable findRenderEditable(WidgetTester tester) {
|
RenderEditable findRenderEditable(WidgetTester tester) {
|
||||||
@ -3227,7 +3227,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('text field respects keyboardAppearance from theme', (WidgetTester tester) async {
|
testWidgets('text field respects keyboardAppearance from theme', (WidgetTester tester) async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
|
SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -3250,7 +3250,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('text field can override keyboardAppearance from theme', (WidgetTester tester) async {
|
testWidgets('text field can override keyboardAppearance from theme', (WidgetTester tester) async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
|
SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ const _LongCupertinoLocalizations longLocalizations = _LongCupertinoLocalization
|
|||||||
void main() {
|
void main() {
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
final MockClipboard mockClipboard = MockClipboard();
|
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.
|
// Returns true iff the button is visually enabled.
|
||||||
bool appearsEnabled(WidgetTester tester, String text) {
|
bool appearsEnabled(WidgetTester tester, String text) {
|
||||||
|
@ -21,8 +21,7 @@ class TestServiceExtensionsBinding extends BindingBase
|
|||||||
PaintingBinding,
|
PaintingBinding,
|
||||||
SemanticsBinding,
|
SemanticsBinding,
|
||||||
RendererBinding,
|
RendererBinding,
|
||||||
WidgetsBinding,
|
WidgetsBinding {
|
||||||
TestDefaultBinaryMessengerBinding {
|
|
||||||
|
|
||||||
final Map<String, ServiceExtensionCallback> extensions = <String, ServiceExtensionCallback>{};
|
final Map<String, ServiceExtensionCallback> extensions = <String, ServiceExtensionCallback>{};
|
||||||
|
|
||||||
@ -468,7 +467,7 @@ void main() {
|
|||||||
bool completed;
|
bool completed;
|
||||||
|
|
||||||
completed = false;
|
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');
|
expect(utf8.decode(message!.buffer.asUint8List()), 'test');
|
||||||
completed = true;
|
completed = true;
|
||||||
return ByteData(5); // 0x0000000000
|
return ByteData(5); // 0x0000000000
|
||||||
@ -495,7 +494,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
expect(data, isFalse);
|
expect(data, isFalse);
|
||||||
expect(completed, isTrue);
|
expect(completed, isTrue);
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', null);
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Service extensions - exit', () async {
|
test('Service extensions - exit', () async {
|
||||||
|
@ -2,6 +2,12 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// 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 'dart:ui' as ui;
|
||||||
|
|
||||||
import 'package:clock/clock.dart';
|
import 'package:clock/clock.dart';
|
||||||
|
@ -267,7 +267,7 @@ void main() {
|
|||||||
testWidgets('has semantic events', (WidgetTester tester) async {
|
testWidgets('has semantic events', (WidgetTester tester) async {
|
||||||
dynamic semanticEvent;
|
dynamic semanticEvent;
|
||||||
bool? checkboxValue = false;
|
bool? checkboxValue = false;
|
||||||
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
|
SystemChannels.accessibility.setMockMessageHandler((dynamic message) async {
|
||||||
semanticEvent = message;
|
semanticEvent = message;
|
||||||
});
|
});
|
||||||
final SemanticsTester semanticsTester = SemanticsTester(tester);
|
final SemanticsTester semanticsTester = SemanticsTester(tester);
|
||||||
@ -300,7 +300,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
expect(object.debugSemantics!.getSemanticsData().hasAction(SemanticsAction.tap), true);
|
expect(object.debugSemantics!.getSemanticsData().hasAction(SemanticsAction.tap), true);
|
||||||
|
|
||||||
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
|
SystemChannels.accessibility.setMockMessageHandler(null);
|
||||||
semanticsTester.dispose();
|
semanticsTester.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -27,14 +27,14 @@ void main () {
|
|||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
semanticEvents = <Map<String, Object>>[];
|
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>;
|
final Map<dynamic, dynamic> typedMessage = message as Map<dynamic, dynamic>;
|
||||||
semanticEvents.add(typedMessage.cast<String, Object>());
|
semanticEvents.add(typedMessage.cast<String, Object>());
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
|
SystemChannels.accessibility.setMockMessageHandler(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('forTap', (WidgetTester tester) async {
|
testWidgets('forTap', (WidgetTester tester) async {
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
|
|
||||||
/// Tracks how often feedback has been requested since its instantiation.
|
/// Tracks how often feedback has been requested since its instantiation.
|
||||||
///
|
///
|
||||||
@ -11,7 +10,13 @@ import 'package:flutter_test/flutter_test.dart';
|
|||||||
/// cannot be used in combination with other classes that do the same.
|
/// cannot be used in combination with other classes that do the same.
|
||||||
class FeedbackTester {
|
class FeedbackTester {
|
||||||
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).
|
/// Number of times haptic feedback was requested (vibration).
|
||||||
@ -22,17 +27,8 @@ class FeedbackTester {
|
|||||||
int get clickSoundCount => _clickSoundCount;
|
int get clickSoundCount => _clickSoundCount;
|
||||||
int _clickSoundCount = 0;
|
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.
|
/// Stops tracking.
|
||||||
void dispose() {
|
void dispose() {
|
||||||
assert(TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.checkMockMessageHandler(SystemChannels.platform.name, _handler));
|
SystemChannels.platform.setMockMethodCallHandler(null);
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,9 +241,9 @@ void main() {
|
|||||||
|
|
||||||
// Fill the clipboard so that the Paste option is available in the text
|
// Fill the clipboard so that the Paste option is available in the text
|
||||||
// selection menu.
|
// selection menu.
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
|
SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
|
||||||
await Clipboard.setData(const ClipboardData(text: 'Clipboard data'));
|
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.pumpWidget(_inputDatePickerField(autofocus: true));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
@ -539,7 +539,7 @@ void main() {
|
|||||||
final Key key = UniqueKey();
|
final Key key = UniqueKey();
|
||||||
dynamic semanticEvent;
|
dynamic semanticEvent;
|
||||||
int? radioValue = 2;
|
int? radioValue = 2;
|
||||||
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
|
SystemChannels.accessibility.setMockMessageHandler((dynamic message) async {
|
||||||
semanticEvent = message;
|
semanticEvent = message;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -570,7 +570,7 @@ void main() {
|
|||||||
expect(object.debugSemantics!.getSemanticsData().hasAction(SemanticsAction.tap), true);
|
expect(object.debugSemantics!.getSemanticsData().hasAction(SemanticsAction.tap), true);
|
||||||
|
|
||||||
semantics.dispose();
|
semantics.dispose();
|
||||||
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
|
SystemChannels.accessibility.setMockMessageHandler(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('RadioListTile can autofocus unless disabled.', (WidgetTester tester) async {
|
testWidgets('RadioListTile can autofocus unless disabled.', (WidgetTester tester) async {
|
||||||
|
@ -292,7 +292,7 @@ void main() {
|
|||||||
final Key key = UniqueKey();
|
final Key key = UniqueKey();
|
||||||
dynamic semanticEvent;
|
dynamic semanticEvent;
|
||||||
int? radioValue = 2;
|
int? radioValue = 2;
|
||||||
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
|
SystemChannels.accessibility.setMockMessageHandler((dynamic message) async {
|
||||||
semanticEvent = message;
|
semanticEvent = message;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -319,7 +319,7 @@ void main() {
|
|||||||
expect(object.debugSemantics!.getSemanticsData().hasAction(SemanticsAction.tap), true);
|
expect(object.debugSemantics!.getSemanticsData().hasAction(SemanticsAction.tap), true);
|
||||||
|
|
||||||
semantics.dispose();
|
semantics.dispose();
|
||||||
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
|
SystemChannels.accessibility.setMockMessageHandler(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Radio ink ripple is displayed correctly', (WidgetTester tester) async {
|
testWidgets('Radio ink ripple is displayed correctly', (WidgetTester tester) async {
|
||||||
|
@ -32,12 +32,12 @@ void main() {
|
|||||||
setUp(() async {
|
setUp(() async {
|
||||||
// Fill the clipboard so that the Paste option is available in the text
|
// Fill the clipboard so that the Paste option is available in the text
|
||||||
// selection menu.
|
// selection menu.
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
|
SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
|
||||||
await Clipboard.setData(const ClipboardData(text: 'Clipboard data'));
|
await Clipboard.setData(const ClipboardData(text: 'Clipboard data'));
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null);
|
SystemChannels.platform.setMockMethodCallHandler(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Can open and close search', (WidgetTester tester) async {
|
testWidgets('Can open and close search', (WidgetTester tester) async {
|
||||||
|
@ -571,7 +571,7 @@ void main() {
|
|||||||
testWidgets('switch has semantic events', (WidgetTester tester) async {
|
testWidgets('switch has semantic events', (WidgetTester tester) async {
|
||||||
dynamic semanticEvent;
|
dynamic semanticEvent;
|
||||||
bool value = false;
|
bool value = false;
|
||||||
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
|
SystemChannels.accessibility.setMockMessageHandler((dynamic message) async {
|
||||||
semanticEvent = message;
|
semanticEvent = message;
|
||||||
});
|
});
|
||||||
final SemanticsTester semanticsTester = SemanticsTester(tester);
|
final SemanticsTester semanticsTester = SemanticsTester(tester);
|
||||||
@ -609,13 +609,13 @@ void main() {
|
|||||||
expect(object.debugSemantics!.getSemanticsData().hasAction(SemanticsAction.tap), true);
|
expect(object.debugSemantics!.getSemanticsData().hasAction(SemanticsAction.tap), true);
|
||||||
|
|
||||||
semanticsTester.dispose();
|
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 {
|
testWidgets('switch sends semantic events from parent if fully merged', (WidgetTester tester) async {
|
||||||
dynamic semanticEvent;
|
dynamic semanticEvent;
|
||||||
bool value = false;
|
bool value = false;
|
||||||
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
|
SystemChannels.accessibility.setMockMessageHandler((dynamic message) async {
|
||||||
semanticEvent = message;
|
semanticEvent = message;
|
||||||
});
|
});
|
||||||
final SemanticsTester semanticsTester = SemanticsTester(tester);
|
final SemanticsTester semanticsTester = SemanticsTester(tester);
|
||||||
@ -659,7 +659,7 @@ void main() {
|
|||||||
expect(object.debugSemantics!.getSemanticsData().hasAction(SemanticsAction.tap), true);
|
expect(object.debugSemantics!.getSemanticsData().hasAction(SemanticsAction.tap), true);
|
||||||
|
|
||||||
semanticsTester.dispose();
|
semanticsTester.dispose();
|
||||||
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
|
SystemChannels.accessibility.setMockMessageHandler(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Switch.adaptive', (WidgetTester tester) async {
|
testWidgets('Switch.adaptive', (WidgetTester tester) async {
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:async';
|
|
||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
import 'dart:ui' as ui show window, BoxHeightStyle, BoxWidthStyle;
|
import 'dart:ui' as ui show window, BoxHeightStyle, BoxWidthStyle;
|
||||||
|
|
||||||
@ -165,20 +164,14 @@ void main() {
|
|||||||
|
|
||||||
setUp(() async {
|
setUp(() async {
|
||||||
debugResetSemanticsIdCounter();
|
debugResetSemanticsIdCounter();
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(
|
SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
|
||||||
SystemChannels.platform,
|
|
||||||
mockClipboard.handleMethodCall,
|
|
||||||
);
|
|
||||||
// Fill the clipboard so that the Paste option is available in the text
|
// Fill the clipboard so that the Paste option is available in the text
|
||||||
// selection menu.
|
// selection menu.
|
||||||
await Clipboard.setData(const ClipboardData(text: 'Clipboard data'));
|
await Clipboard.setData(const ClipboardData(text: 'Clipboard data'));
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(
|
SystemChannels.platform.setMockMethodCallHandler(null);
|
||||||
SystemChannels.platform,
|
|
||||||
null,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
final Key textFieldKey = UniqueKey();
|
final Key textFieldKey = UniqueKey();
|
||||||
@ -344,7 +337,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('TextField has consistent size', (WidgetTester tester) async {
|
testWidgets('TextField has consistent size', (WidgetTester tester) async {
|
||||||
final Key textFieldKey = UniqueKey();
|
final Key textFieldKey = UniqueKey();
|
||||||
String? textFieldValue;
|
late String textFieldValue;
|
||||||
|
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
overlay(
|
overlay(
|
||||||
@ -367,16 +360,15 @@ void main() {
|
|||||||
|
|
||||||
Future<void> checkText(String testValue) async {
|
Future<void> checkText(String testValue) async {
|
||||||
return TestAsyncUtils.guard(() async {
|
return TestAsyncUtils.guard(() async {
|
||||||
expect(textFieldValue, isNull);
|
|
||||||
await tester.enterText(find.byType(TextField), testValue);
|
await tester.enterText(find.byType(TextField), testValue);
|
||||||
// Check that the onChanged event handler fired.
|
// Check that the onChanged event handler fired.
|
||||||
expect(textFieldValue, equals(testValue));
|
expect(textFieldValue, equals(testValue));
|
||||||
textFieldValue = null;
|
|
||||||
await skipPastScrollingAnimation(tester);
|
await skipPastScrollingAnimation(tester);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await checkText(' ');
|
await checkText(' ');
|
||||||
|
|
||||||
expect(findTextFieldBox(), equals(inputBox));
|
expect(findTextFieldBox(), equals(inputBox));
|
||||||
expect(inputBox.size, equals(emptyInputSize));
|
expect(inputBox.size, equals(emptyInputSize));
|
||||||
|
|
||||||
@ -422,8 +414,6 @@ void main() {
|
|||||||
text: 'X',
|
text: 'X',
|
||||||
selection: TextSelection.collapsed(offset: 1),
|
selection: TextSelection.collapsed(offset: 1),
|
||||||
));
|
));
|
||||||
await tester.idle();
|
|
||||||
expect(tester.state(find.byType(EditableText)), editableText);
|
|
||||||
await checkCursorToggle();
|
await checkCursorToggle();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -4697,8 +4687,8 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
String clipboardContent = '';
|
String clipboardContent = '';
|
||||||
tester.binding.defaultBinaryMessenger
|
SystemChannels.platform
|
||||||
.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
if (methodCall.method == 'Clipboard.setData')
|
if (methodCall.method == 'Clipboard.setData')
|
||||||
clipboardContent = methodCall.arguments['text'] as String;
|
clipboardContent = methodCall.arguments['text'] as String;
|
||||||
else if (methodCall.method == 'Clipboard.getData')
|
else if (methodCall.method == 'Clipboard.getData')
|
||||||
@ -4770,8 +4760,8 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
String clipboardContent = '';
|
String clipboardContent = '';
|
||||||
tester.binding.defaultBinaryMessenger
|
SystemChannels.platform
|
||||||
.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
if (methodCall.method == 'Clipboard.setData')
|
if (methodCall.method == 'Clipboard.setData')
|
||||||
clipboardContent = methodCall.arguments['text'] as String;
|
clipboardContent = methodCall.arguments['text'] as String;
|
||||||
else if (methodCall.method == 'Clipboard.getData')
|
else if (methodCall.method == 'Clipboard.getData')
|
||||||
@ -4843,8 +4833,8 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const String clipboardContent = 'I love Flutter!';
|
const String clipboardContent = 'I love Flutter!';
|
||||||
tester.binding.defaultBinaryMessenger
|
SystemChannels.platform
|
||||||
.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
if (methodCall.method == 'Clipboard.getData')
|
if (methodCall.method == 'Clipboard.getData')
|
||||||
return <String, dynamic>{'text': clipboardContent};
|
return <String, dynamic>{'text': clipboardContent};
|
||||||
return null;
|
return null;
|
||||||
@ -4893,8 +4883,8 @@ void main() {
|
|||||||
maxLines: 3,
|
maxLines: 3,
|
||||||
);
|
);
|
||||||
String clipboardContent = '';
|
String clipboardContent = '';
|
||||||
tester.binding.defaultBinaryMessenger
|
SystemChannels.platform
|
||||||
.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
if (methodCall.method == 'Clipboard.setData')
|
if (methodCall.method == 'Clipboard.setData')
|
||||||
clipboardContent = methodCall.arguments['text'] as String;
|
clipboardContent = methodCall.arguments['text'] as String;
|
||||||
else if (methodCall.method == 'Clipboard.getData')
|
else if (methodCall.method == 'Clipboard.getData')
|
||||||
@ -4967,8 +4957,8 @@ void main() {
|
|||||||
obscureText: true,
|
obscureText: true,
|
||||||
);
|
);
|
||||||
String clipboardContent = '';
|
String clipboardContent = '';
|
||||||
tester.binding.defaultBinaryMessenger
|
SystemChannels.platform
|
||||||
.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
if (methodCall.method == 'Clipboard.setData')
|
if (methodCall.method == 'Clipboard.setData')
|
||||||
clipboardContent = methodCall.arguments['text'] as String;
|
clipboardContent = methodCall.arguments['text'] as String;
|
||||||
else if (methodCall.method == 'Clipboard.getData')
|
else if (methodCall.method == 'Clipboard.getData')
|
||||||
@ -9328,8 +9318,8 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
bool triedToReadClipboard = false;
|
bool triedToReadClipboard = false;
|
||||||
tester.binding.defaultBinaryMessenger
|
SystemChannels.platform
|
||||||
.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
if (methodCall.method == 'Clipboard.getData') {
|
if (methodCall.method == 'Clipboard.getData') {
|
||||||
triedToReadClipboard = true;
|
triedToReadClipboard = true;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ class MockClipboard {
|
|||||||
void main() {
|
void main() {
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
final MockClipboard mockClipboard = MockClipboard();
|
final MockClipboard mockClipboard = MockClipboard();
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
|
SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() async {
|
||||||
// Fill the clipboard so that the Paste option is available in the text
|
// Fill the clipboard so that the Paste option is available in the text
|
||||||
|
@ -28,7 +28,7 @@ class MockClipboard {
|
|||||||
void main() {
|
void main() {
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
final MockClipboard mockClipboard = MockClipboard();
|
final MockClipboard mockClipboard = MockClipboard();
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
|
SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() async {
|
||||||
await Clipboard.setData(const ClipboardData(text: 'clipboard data'));
|
await Clipboard.setData(const ClipboardData(text: 'clipboard data'));
|
||||||
|
@ -1193,7 +1193,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('has semantic events', (WidgetTester tester) async {
|
testWidgets('has semantic events', (WidgetTester tester) async {
|
||||||
final List<dynamic> semanticEvents = <dynamic>[];
|
final List<dynamic> semanticEvents = <dynamic>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
|
SystemChannels.accessibility.setMockMessageHandler((dynamic message) async {
|
||||||
semanticEvents.add(message);
|
semanticEvents.add(message);
|
||||||
});
|
});
|
||||||
final SemanticsTester semantics = SemanticsTester(tester);
|
final SemanticsTester semantics = SemanticsTester(tester);
|
||||||
@ -1230,7 +1230,7 @@ void main() {
|
|||||||
},
|
},
|
||||||
]));
|
]));
|
||||||
semantics.dispose();
|
semantics.dispose();
|
||||||
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
|
SystemChannels.accessibility.setMockMessageHandler(null);
|
||||||
});
|
});
|
||||||
testWidgets('default Tooltip debugFillProperties', (WidgetTester tester) async {
|
testWidgets('default Tooltip debugFillProperties', (WidgetTester tester) async {
|
||||||
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
|
||||||
|
@ -1153,7 +1153,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('has semantic events by default - ThemeData.tooltipTheme', (WidgetTester tester) async {
|
testWidgets('has semantic events by default - ThemeData.tooltipTheme', (WidgetTester tester) async {
|
||||||
final List<dynamic> semanticEvents = <dynamic>[];
|
final List<dynamic> semanticEvents = <dynamic>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
|
SystemChannels.accessibility.setMockMessageHandler((dynamic message) async {
|
||||||
semanticEvents.add(message);
|
semanticEvents.add(message);
|
||||||
});
|
});
|
||||||
final SemanticsTester semantics = SemanticsTester(tester);
|
final SemanticsTester semantics = SemanticsTester(tester);
|
||||||
@ -1191,12 +1191,12 @@ void main() {
|
|||||||
},
|
},
|
||||||
]));
|
]));
|
||||||
semantics.dispose();
|
semantics.dispose();
|
||||||
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
|
SystemChannels.accessibility.setMockMessageHandler(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('has semantic events by default - TooltipTheme', (WidgetTester tester) async {
|
testWidgets('has semantic events by default - TooltipTheme', (WidgetTester tester) async {
|
||||||
final List<dynamic> semanticEvents = <dynamic>[];
|
final List<dynamic> semanticEvents = <dynamic>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, (dynamic message) async {
|
SystemChannels.accessibility.setMockMessageHandler((dynamic message) async {
|
||||||
semanticEvents.add(message);
|
semanticEvents.add(message);
|
||||||
});
|
});
|
||||||
final SemanticsTester semantics = SemanticsTester(tester);
|
final SemanticsTester semantics = SemanticsTester(tester);
|
||||||
@ -1236,7 +1236,7 @@ void main() {
|
|||||||
},
|
},
|
||||||
]));
|
]));
|
||||||
semantics.dispose();
|
semantics.dispose();
|
||||||
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
|
SystemChannels.accessibility.setMockMessageHandler(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('default Tooltip debugFillProperties', (WidgetTester tester) async {
|
testWidgets('default Tooltip debugFillProperties', (WidgetTester tester) async {
|
||||||
|
@ -12,11 +12,11 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
final TestRenderBinding binding = TestRenderBinding();
|
|
||||||
test('Flutter dispatches first frame event on the web only', () async {
|
test('Flutter dispatches first frame event on the web only', () async {
|
||||||
final Completer<void> completer = Completer<void>();
|
final Completer<void> completer = Completer<void>();
|
||||||
|
final TestRenderBinding binding = TestRenderBinding();
|
||||||
const MethodChannel firstFrameChannel = MethodChannel('flutter/service_worker');
|
const MethodChannel firstFrameChannel = MethodChannel('flutter/service_worker');
|
||||||
binding.defaultBinaryMessenger.setMockMethodCallHandler(firstFrameChannel, (MethodCall methodCall) async {
|
firstFrameChannel.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
completer.complete();
|
completer.complete();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -27,10 +27,4 @@ void main() {
|
|||||||
}, skip: !kIsWeb);
|
}, skip: !kIsWeb);
|
||||||
}
|
}
|
||||||
|
|
||||||
class TestRenderBinding extends BindingBase
|
class TestRenderBinding extends BindingBase with SchedulerBinding, ServicesBinding, GestureBinding, SemanticsBinding, RendererBinding {}
|
||||||
with SchedulerBinding,
|
|
||||||
ServicesBinding,
|
|
||||||
GestureBinding,
|
|
||||||
SemanticsBinding,
|
|
||||||
RendererBinding,
|
|
||||||
TestDefaultBinaryMessengerBinding { }
|
|
||||||
|
@ -56,14 +56,14 @@ void main() {
|
|||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
_binding.postFrameCallbacks.clear();
|
_binding.postFrameCallbacks.clear();
|
||||||
_binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.mouseCursor, (MethodCall call) async {
|
SystemChannels.mouseCursor.setMockMethodCallHandler((MethodCall call) async {
|
||||||
if (_methodCallHandler != null)
|
if (_methodCallHandler != null)
|
||||||
return _methodCallHandler!(call);
|
return _methodCallHandler!(call);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
_binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.mouseCursor, null);
|
SystemChannels.mouseCursor.setMockMethodCallHandler(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Should work on platforms that does not support mouse cursor', () async {
|
test('Should work on platforms that does not support mouse cursor', () async {
|
||||||
|
@ -9,7 +9,6 @@ import 'package:flutter/gestures.dart';
|
|||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart' show TestDefaultBinaryMessengerBinding;
|
|
||||||
|
|
||||||
class _TestHitTester extends RenderBox {
|
class _TestHitTester extends RenderBox {
|
||||||
_TestHitTester(this.hitTestOverride);
|
_TestHitTester(this.hitTestOverride);
|
||||||
@ -25,7 +24,7 @@ class _TestHitTester extends RenderBox {
|
|||||||
// A binding used to test MouseTracker, allowing the test to override hit test
|
// A binding used to test MouseTracker, allowing the test to override hit test
|
||||||
// searching.
|
// searching.
|
||||||
class TestMouseTrackerFlutterBinding extends BindingBase
|
class TestMouseTrackerFlutterBinding extends BindingBase
|
||||||
with SchedulerBinding, ServicesBinding, GestureBinding, SemanticsBinding, RendererBinding, TestDefaultBinaryMessengerBinding {
|
with SchedulerBinding, ServicesBinding, GestureBinding, SemanticsBinding, RendererBinding {
|
||||||
@override
|
@override
|
||||||
void initInstances() {
|
void initInstances() {
|
||||||
super.initInstances();
|
super.initInstances();
|
||||||
|
@ -9,12 +9,12 @@ import 'package:flutter/gestures.dart';
|
|||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:flutter/services.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/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.
|
/// Creates a binding for testing rendering library functionality.
|
||||||
///
|
///
|
||||||
/// If [onErrors] is not null, it is called if [FlutterError] caught any errors
|
/// If [onErrors] is not null, it is called if [FlutterError] caught any errors
|
||||||
|
@ -13,13 +13,12 @@ void main() {
|
|||||||
|
|
||||||
test('Semantic announcement', () async {
|
test('Semantic announcement', () async {
|
||||||
final List<Map<dynamic, dynamic>> log = <Map<dynamic, dynamic>>[];
|
final List<Map<dynamic, dynamic>> log = <Map<dynamic, dynamic>>[];
|
||||||
|
|
||||||
Future<dynamic> handleMessage(dynamic mockMessage) async {
|
Future<dynamic> handleMessage(dynamic mockMessage) async {
|
||||||
final Map<dynamic, dynamic> message = mockMessage as Map<dynamic, dynamic>;
|
final Map<dynamic, dynamic> message = mockMessage as Map<dynamic, dynamic>;
|
||||||
log.add(message);
|
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 1', TextDirection.ltr);
|
||||||
await SemanticsService.announce('announcement 2', TextDirection.rtl);
|
await SemanticsService.announce('announcement 2', TextDirection.rtl);
|
||||||
|
@ -191,6 +191,15 @@ class FakeTextChannel implements MethodChannel {
|
|||||||
incoming = 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) {
|
void validateOutgoingMethodCalls(List<MethodCall> calls) {
|
||||||
expect(outgoingCalls.length, calls.length);
|
expect(outgoingCalls.length, calls.length);
|
||||||
bool hasError = false;
|
bool hasError = false;
|
||||||
|
@ -30,7 +30,7 @@ L2Paragraph2
|
|||||||
|
|
||||||
L2Paragraph3''';
|
L2Paragraph3''';
|
||||||
|
|
||||||
const String combinedLicenses = '''
|
const String licenses = '''
|
||||||
$license1
|
$license1
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
$license2
|
$license2
|
||||||
@ -38,22 +38,20 @@ $license2
|
|||||||
|
|
||||||
class TestBinding extends BindingBase with SchedulerBinding, ServicesBinding {
|
class TestBinding extends BindingBase with SchedulerBinding, ServicesBinding {
|
||||||
@override
|
@override
|
||||||
TestDefaultBinaryMessenger get defaultBinaryMessenger => super.defaultBinaryMessenger as TestDefaultBinaryMessenger;
|
BinaryMessenger createBinaryMessenger() {
|
||||||
|
return super.createBinaryMessenger()
|
||||||
@override
|
..setMockMessageHandler('flutter/assets', (ByteData? message) async {
|
||||||
TestDefaultBinaryMessenger createBinaryMessenger() {
|
if (const StringCodec().decodeMessage(message) == 'NOTICES') {
|
||||||
return TestDefaultBinaryMessenger(super.createBinaryMessenger());
|
return const StringCodec().encodeMessage(licenses);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
test('Adds rootBundle LICENSES to LicenseRegistry', () async {
|
test('Adds rootBundle LICENSES to LicenseRegistry', () async {
|
||||||
TestBinding().defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (ByteData? message) async {
|
TestBinding(); // The test binding registers a mock handler that returns licenses for the LICENSE key
|
||||||
if (const StringCodec().decodeMessage(message) == 'NOTICES') {
|
|
||||||
return const StringCodec().encodeMessage(combinedLicenses);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
|
|
||||||
final List<LicenseEntry> licenses = await LicenseRegistry.licenses.toList();
|
final List<LicenseEntry> licenses = await LicenseRegistry.licenses.toList();
|
||||||
|
|
||||||
|
@ -2,10 +2,9 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:async';
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
import 'dart:ui' as ui;
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
@ -20,39 +19,36 @@ void main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test('default binary messenger calls callback once', () async {
|
test('default binary messenger calls callback once', () async {
|
||||||
int countInbound = 0;
|
int count = 0;
|
||||||
int countOutbound = 0;
|
|
||||||
const String channel = 'foo';
|
const String channel = 'foo';
|
||||||
final ByteData bar = _makeByteData('bar');
|
ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
final Completer<void> done = Completer<void>();
|
|
||||||
ServicesBinding.instance!.channelBuffers.push(
|
|
||||||
channel,
|
channel,
|
||||||
bar,
|
_makeByteData('bar'),
|
||||||
(ByteData? message) async {
|
(ByteData? message) async {
|
||||||
expect(message, isNull);
|
count += 1;
|
||||||
countOutbound += 1;
|
|
||||||
done.complete();
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
expect(countInbound, equals(0));
|
expect(count, equals(0));
|
||||||
expect(countOutbound, equals(0));
|
await ui.channelBuffers.drain(channel, (ByteData? data, ui.PlatformMessageResponseCallback callback) async {
|
||||||
ServicesBinding.instance!.defaultBinaryMessenger.setMessageHandler(
|
callback(null);
|
||||||
channel,
|
});
|
||||||
(ByteData? message) async {
|
expect(count, equals(1));
|
||||||
expect(message, bar);
|
});
|
||||||
countInbound += 1;
|
|
||||||
},
|
test('can check the handler', () {
|
||||||
);
|
Future<ByteData> handler(ByteData? call) => Future<ByteData>.value(null);
|
||||||
expect(countInbound, equals(0));
|
final BinaryMessenger messenger = ServicesBinding.instance!.defaultBinaryMessenger;
|
||||||
expect(countOutbound, equals(0));
|
|
||||||
await done.future;
|
expect(messenger.checkMessageHandler('test_channel', null), true);
|
||||||
expect(countInbound, equals(1));
|
expect(messenger.checkMessageHandler('test_channel', handler), false);
|
||||||
expect(countOutbound, equals(1));
|
messenger.setMessageHandler('test_channel', handler);
|
||||||
|
expect(messenger.checkMessageHandler('test_channel', handler), true);
|
||||||
|
messenger.setMessageHandler('test_channel', null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('can check the mock handler', () {
|
test('can check the mock handler', () {
|
||||||
Future<ByteData> handler(ByteData? call) => Future<ByteData>.value(null);
|
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', null), true);
|
||||||
expect(messenger.checkMockMessageHandler('test_channel', handler), false);
|
expect(messenger.checkMockMessageHandler('test_channel', handler), false);
|
||||||
|
@ -11,7 +11,7 @@ void main() {
|
|||||||
test('installDeferredComponent test', () async {
|
test('installDeferredComponent test', () async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
|
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.deferredComponent, (MethodCall methodCall) async {
|
SystemChannels.deferredComponent.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -27,7 +27,7 @@ void main() {
|
|||||||
test('uninstallDeferredComponent test', () async {
|
test('uninstallDeferredComponent test', () async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
|
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.deferredComponent, (MethodCall methodCall) async {
|
SystemChannels.deferredComponent.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ import 'dart:typed_data';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
|
|
||||||
/// Used in internal testing.
|
/// Used in internal testing.
|
||||||
class FakePlatformViewController extends PlatformViewController {
|
class FakePlatformViewController extends PlatformViewController {
|
||||||
@ -123,7 +122,7 @@ class FakeAndroidViewController implements AndroidViewController {
|
|||||||
|
|
||||||
class FakeAndroidPlatformViewsController {
|
class FakeAndroidPlatformViewsController {
|
||||||
FakeAndroidPlatformViewsController() {
|
FakeAndroidPlatformViewsController() {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform_views, _onMethodCall);
|
SystemChannels.platform_views.setMockMethodCallHandler(_onMethodCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterable<FakeAndroidPlatformView> get views => _views.values;
|
Iterable<FakeAndroidPlatformView> get views => _views.values;
|
||||||
@ -302,7 +301,7 @@ class FakeAndroidPlatformViewsController {
|
|||||||
|
|
||||||
class FakeIosPlatformViewsController {
|
class FakeIosPlatformViewsController {
|
||||||
FakeIosPlatformViewsController() {
|
FakeIosPlatformViewsController() {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform_views, _onMethodCall);
|
SystemChannels.platform_views.setMockMethodCallHandler(_onMethodCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterable<FakeUiKitView> get views => _views.values;
|
Iterable<FakeUiKitView> get views => _views.values;
|
||||||
@ -397,7 +396,7 @@ class FakeIosPlatformViewsController {
|
|||||||
|
|
||||||
class FakeHtmlPlatformViewsController {
|
class FakeHtmlPlatformViewsController {
|
||||||
FakeHtmlPlatformViewsController() {
|
FakeHtmlPlatformViewsController() {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform_views, _onMethodCall);
|
SystemChannels.platform_views.setMockMethodCallHandler(_onMethodCall);
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterable<FakeHtmlPlatformView> get views => _views.values;
|
Iterable<FakeHtmlPlatformView> get views => _views.values;
|
||||||
|
@ -11,7 +11,7 @@ void main() {
|
|||||||
test('Haptic feedback control test', () async {
|
test('Haptic feedback control test', () async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
|
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ void main() {
|
|||||||
Future<void> callAndVerifyHapticFunction(Function hapticFunction, String platformMethodArgument) async {
|
Future<void> callAndVerifyHapticFunction(Function hapticFunction, String platformMethodArgument) async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
|
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ void main() {
|
|||||||
const MessageCodec<String?> string = StringCodec();
|
const MessageCodec<String?> string = StringCodec();
|
||||||
const BasicMessageChannel<String?> channel = BasicMessageChannel<String?>('ch', string);
|
const BasicMessageChannel<String?> channel = BasicMessageChannel<String?>('ch', string);
|
||||||
test('can send string message and get reply', () async {
|
test('can send string message and get reply', () async {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch',
|
'ch',
|
||||||
(ByteData? message) async => string.encodeMessage(string.decodeMessage(message)! + ' world'),
|
(ByteData? message) async => string.encodeMessage(string.decodeMessage(message)! + ' world'),
|
||||||
);
|
);
|
||||||
@ -23,7 +23,7 @@ void main() {
|
|||||||
test('can receive string message and send reply', () async {
|
test('can receive string message and send reply', () async {
|
||||||
channel.setMessageHandler((String? message) async => message! + ' world');
|
channel.setMessageHandler((String? message) async => message! + ' world');
|
||||||
String? reply;
|
String? reply;
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
'ch',
|
'ch',
|
||||||
const StringCodec().encodeMessage('hello'),
|
const StringCodec().encodeMessage('hello'),
|
||||||
(ByteData? replyBinary) {
|
(ByteData? replyBinary) {
|
||||||
@ -40,7 +40,7 @@ void main() {
|
|||||||
const MethodChannel channel = MethodChannel('ch7', jsonMethod);
|
const MethodChannel channel = MethodChannel('ch7', jsonMethod);
|
||||||
const OptionalMethodChannel optionalMethodChannel = OptionalMethodChannel('ch8', jsonMethod);
|
const OptionalMethodChannel optionalMethodChannel = OptionalMethodChannel('ch8', jsonMethod);
|
||||||
test('can invoke method and get result', () async {
|
test('can invoke method and get result', () async {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch7',
|
'ch7',
|
||||||
(ByteData? message) async {
|
(ByteData? message) async {
|
||||||
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
|
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
|
||||||
@ -56,7 +56,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can invoke list method and get result', () async {
|
test('can invoke list method and get result', () async {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch7',
|
'ch7',
|
||||||
(ByteData? message) async {
|
(ByteData? message) async {
|
||||||
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
|
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
|
||||||
@ -72,7 +72,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can invoke list method and get null result', () async {
|
test('can invoke list method and get null result', () async {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch7',
|
'ch7',
|
||||||
(ByteData? message) async {
|
(ByteData? message) async {
|
||||||
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
|
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
|
||||||
@ -87,7 +87,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can invoke map method and get result', () async {
|
test('can invoke map method and get result', () async {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch7',
|
'ch7',
|
||||||
(ByteData? message) async {
|
(ByteData? message) async {
|
||||||
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
|
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
|
||||||
@ -103,7 +103,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can invoke map method and get null result', () async {
|
test('can invoke map method and get null result', () async {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch7',
|
'ch7',
|
||||||
(ByteData? message) async {
|
(ByteData? message) async {
|
||||||
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
|
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
|
||||||
@ -118,7 +118,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can invoke method and get error', () async {
|
test('can invoke method and get error', () async {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch7',
|
'ch7',
|
||||||
(ByteData? message) async {
|
(ByteData? message) async {
|
||||||
return jsonMessage.encodeMessage(<dynamic>[
|
return jsonMessage.encodeMessage(<dynamic>[
|
||||||
@ -141,7 +141,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can invoke unimplemented method', () async {
|
test('can invoke unimplemented method', () async {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch7',
|
'ch7',
|
||||||
(ByteData? message) async => null,
|
(ByteData? message) async => null,
|
||||||
);
|
);
|
||||||
@ -157,7 +157,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can invoke unimplemented method (optional)', () async {
|
test('can invoke unimplemented method (optional)', () async {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch8',
|
'ch8',
|
||||||
(ByteData? message) async => null,
|
(ByteData? message) async => null,
|
||||||
);
|
);
|
||||||
@ -169,7 +169,7 @@ void main() {
|
|||||||
channel.setMethodCallHandler(null);
|
channel.setMethodCallHandler(null);
|
||||||
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
||||||
ByteData? envelope;
|
ByteData? envelope;
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
|
||||||
envelope = result;
|
envelope = result;
|
||||||
});
|
});
|
||||||
await null; // just in case there's something async happening
|
await null; // just in case there's something async happening
|
||||||
@ -179,7 +179,7 @@ void main() {
|
|||||||
test('can handle method call with no registered plugin (setting after)', () async {
|
test('can handle method call with no registered plugin (setting after)', () async {
|
||||||
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
||||||
ByteData? envelope;
|
ByteData? envelope;
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
|
||||||
envelope = result;
|
envelope = result;
|
||||||
});
|
});
|
||||||
channel.setMethodCallHandler(null);
|
channel.setMethodCallHandler(null);
|
||||||
@ -193,7 +193,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
||||||
ByteData? envelope;
|
ByteData? envelope;
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
|
||||||
envelope = result;
|
envelope = result;
|
||||||
});
|
});
|
||||||
expect(envelope, isNull);
|
expect(envelope, isNull);
|
||||||
@ -203,7 +203,7 @@ void main() {
|
|||||||
channel.setMethodCallHandler((MethodCall call) async => '${call.arguments}, world');
|
channel.setMethodCallHandler((MethodCall call) async => '${call.arguments}, world');
|
||||||
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
||||||
ByteData? envelope;
|
ByteData? envelope;
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
|
||||||
envelope = result;
|
envelope = result;
|
||||||
});
|
});
|
||||||
expect(jsonMethod.decodeEnvelope(envelope!), equals('hello, world'));
|
expect(jsonMethod.decodeEnvelope(envelope!), equals('hello, world'));
|
||||||
@ -215,7 +215,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
||||||
ByteData? envelope;
|
ByteData? envelope;
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
|
||||||
envelope = result;
|
envelope = result;
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
@ -235,7 +235,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
||||||
ByteData? envelope;
|
ByteData? envelope;
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
|
||||||
envelope = result;
|
envelope = result;
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
@ -249,14 +249,24 @@ void main() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('can check the mock handler', () async {
|
test('can check the handler', () {
|
||||||
Future<dynamic> handler(MethodCall call) => Future<dynamic>.value(null);
|
Future<dynamic> handler(MethodCall call) => Future<dynamic>.value(null);
|
||||||
|
|
||||||
const MethodChannel channel = MethodChannel('test_handler');
|
const MethodChannel channel = MethodChannel('test_handler');
|
||||||
expect(TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.checkMockMessageHandler(channel.name, null), true);
|
expect(channel.checkMethodCallHandler(null), true);
|
||||||
expect(TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.checkMockMessageHandler(channel.name, handler), false);
|
expect(channel.checkMethodCallHandler(handler), false);
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(channel, handler);
|
channel.setMethodCallHandler(handler);
|
||||||
expect(TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.checkMockMessageHandler(channel.name, handler), true);
|
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 @@ void main() {
|
|||||||
const MethodCodec jsonMethod = JSONMethodCodec();
|
const MethodCodec jsonMethod = JSONMethodCodec();
|
||||||
const EventChannel channel = EventChannel('ch', jsonMethod);
|
const EventChannel channel = EventChannel('ch', jsonMethod);
|
||||||
void emitEvent(ByteData? event) {
|
void emitEvent(ByteData? event) {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
'ch',
|
'ch',
|
||||||
event,
|
event,
|
||||||
(ByteData? reply) {},
|
(ByteData? reply) {},
|
||||||
@ -273,7 +283,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
test('can receive event stream', () async {
|
test('can receive event stream', () async {
|
||||||
bool canceled = false;
|
bool canceled = false;
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch',
|
'ch',
|
||||||
(ByteData? message) async {
|
(ByteData? message) async {
|
||||||
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
|
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
|
||||||
@ -298,7 +308,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can receive error event', () async {
|
test('can receive error event', () async {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch',
|
'ch',
|
||||||
(ByteData? message) async {
|
(ByteData? message) async {
|
||||||
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
|
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
|
||||||
|
@ -7,23 +7,24 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
|
||||||
|
|
||||||
test('Mock binary message handler control test', () async {
|
test('Mock binary message handler control test', () async {
|
||||||
|
// Initialize all bindings because defaultBinaryMessenger.send() needs a window.
|
||||||
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
final List<ByteData?> log = <ByteData>[];
|
final List<ByteData?> log = <ByteData>[];
|
||||||
|
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('test1', (ByteData? message) async {
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('test1', (ByteData? message) async {
|
||||||
log.add(message);
|
log.add(message);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
final ByteData message = ByteData(2)..setUint16(0, 0xABCD);
|
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]));
|
expect(log, equals(<ByteData>[message]));
|
||||||
log.clear();
|
log.clear();
|
||||||
|
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('test1', null);
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('test1', null);
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.send('test1', message);
|
await ServicesBinding.instance!.defaultBinaryMessenger.send('test1', message);
|
||||||
expect(log, isEmpty);
|
expect(log, isEmpty);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
@ -29,7 +30,6 @@ void main() {
|
|||||||
RawKeyboard.instance.removeListener(handleKey);
|
RawKeyboard.instance.removeListener(handleKey);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('No character is produced for non-printables', (WidgetTester tester) async {
|
testWidgets('No character is produced for non-printables', (WidgetTester tester) async {
|
||||||
for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'web']) {
|
for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'web']) {
|
||||||
void handleKey(RawKeyEvent event) {
|
void handleKey(RawKeyEvent event) {
|
||||||
@ -40,7 +40,6 @@ void main() {
|
|||||||
RawKeyboard.instance.removeListener(handleKey);
|
RawKeyboard.instance.removeListener(handleKey);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('keysPressed is maintained', (WidgetTester tester) async {
|
testWidgets('keysPressed is maintained', (WidgetTester tester) async {
|
||||||
for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'ios']) {
|
for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'ios']) {
|
||||||
RawKeyboard.instance.clearKeysPressed();
|
RawKeyboard.instance.clearKeysPressed();
|
||||||
@ -210,7 +209,7 @@ void main() {
|
|||||||
// when this event is received, but it's not in keysPressed yet.
|
// when this event is received, but it's not in keysPressed yet.
|
||||||
data['modifiers'] |= RawKeyEventDataMacOs.modifierLeftShift | RawKeyEventDataMacOs.modifierShift;
|
data['modifiers'] |= RawKeyEventDataMacOs.modifierLeftShift | RawKeyEventDataMacOs.modifierShift;
|
||||||
// dispatch the modified data.
|
// dispatch the modified data.
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData? data) {},
|
(ByteData? data) {},
|
||||||
@ -235,7 +234,7 @@ void main() {
|
|||||||
// when this event is received, but it's not in keysPressed yet.
|
// when this event is received, but it's not in keysPressed yet.
|
||||||
data['modifiers'] |= RawKeyEventDataMacOs.modifierLeftShift | RawKeyEventDataMacOs.modifierShift;
|
data['modifiers'] |= RawKeyEventDataMacOs.modifierLeftShift | RawKeyEventDataMacOs.modifierShift;
|
||||||
// dispatch the modified data.
|
// dispatch the modified data.
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData? data) {},
|
(ByteData? data) {},
|
||||||
@ -260,7 +259,7 @@ void main() {
|
|||||||
// when this event is received, but it's not in keysPressed yet.
|
// when this event is received, but it's not in keysPressed yet.
|
||||||
data['modifiers'] |= RawKeyEventDataWindows.modifierLeftShift | RawKeyEventDataWindows.modifierShift;
|
data['modifiers'] |= RawKeyEventDataWindows.modifierLeftShift | RawKeyEventDataWindows.modifierShift;
|
||||||
// dispatch the modified data.
|
// dispatch the modified data.
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData? data) {},
|
(ByteData? data) {},
|
||||||
@ -285,7 +284,7 @@ void main() {
|
|||||||
// when this event is received, but it's not in keysPressed yet.
|
// when this event is received, but it's not in keysPressed yet.
|
||||||
data['metaState'] |= RawKeyEventDataAndroid.modifierLeftShift | RawKeyEventDataAndroid.modifierShift;
|
data['metaState'] |= RawKeyEventDataAndroid.modifierLeftShift | RawKeyEventDataAndroid.modifierShift;
|
||||||
// dispatch the modified data.
|
// dispatch the modified data.
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData? data) {},
|
(ByteData? data) {},
|
||||||
@ -310,7 +309,7 @@ void main() {
|
|||||||
// when this event is received, but it's not in keysPressed yet.
|
// when this event is received, but it's not in keysPressed yet.
|
||||||
data['modifiers'] |= RawKeyEventDataFuchsia.modifierLeftShift;
|
data['modifiers'] |= RawKeyEventDataFuchsia.modifierLeftShift;
|
||||||
// dispatch the modified data.
|
// dispatch the modified data.
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData? data) {},
|
(ByteData? data) {},
|
||||||
@ -335,7 +334,7 @@ void main() {
|
|||||||
// when this event is received, but it's not in keysPressed yet.
|
// when this event is received, but it's not in keysPressed yet.
|
||||||
data['modifiers'] |= GLFWKeyHelper.modifierShift;
|
data['modifiers'] |= GLFWKeyHelper.modifierShift;
|
||||||
// dispatch the modified data.
|
// dispatch the modified data.
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData? data) {},
|
(ByteData? data) {},
|
||||||
@ -365,7 +364,7 @@ void main() {
|
|||||||
isDown: true,
|
isDown: true,
|
||||||
)..['metaState'] |= RawKeyEventDataWeb.modifierShift;
|
)..['metaState'] |= RawKeyEventDataWeb.modifierShift;
|
||||||
// Dispatch the modified data.
|
// Dispatch the modified data.
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData? data) {},
|
(ByteData? data) {},
|
||||||
@ -457,7 +456,7 @@ void main() {
|
|||||||
RawKeyEventDataAndroid.modifierControl |
|
RawKeyEventDataAndroid.modifierControl |
|
||||||
RawKeyEventDataAndroid.modifierMeta;
|
RawKeyEventDataAndroid.modifierMeta;
|
||||||
// dispatch the modified data.
|
// dispatch the modified data.
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData? data) {},
|
(ByteData? data) {},
|
||||||
@ -495,7 +494,7 @@ void main() {
|
|||||||
RawKeyEventDataMacOs.modifierCommand |
|
RawKeyEventDataMacOs.modifierCommand |
|
||||||
RawKeyEventDataMacOs.modifierControl;
|
RawKeyEventDataMacOs.modifierControl;
|
||||||
// dispatch the modified data.
|
// dispatch the modified data.
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData? data) {},
|
(ByteData? data) {},
|
||||||
@ -571,7 +570,7 @@ void main() {
|
|||||||
RawKeyEventDataWindows.modifierAlt |
|
RawKeyEventDataWindows.modifierAlt |
|
||||||
RawKeyEventDataWindows.modifierControl;
|
RawKeyEventDataWindows.modifierControl;
|
||||||
// dispatch the modified data.
|
// dispatch the modified data.
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData? data) {},
|
(ByteData? data) {},
|
||||||
@ -608,7 +607,7 @@ void main() {
|
|||||||
GLFWKeyHelper.modifierControl |
|
GLFWKeyHelper.modifierControl |
|
||||||
GLFWKeyHelper.modifierMeta;
|
GLFWKeyHelper.modifierMeta;
|
||||||
// dispatch the modified data.
|
// dispatch the modified data.
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData? data) {},
|
(ByteData? data) {},
|
||||||
@ -646,7 +645,7 @@ void main() {
|
|||||||
RawKeyEventDataWeb.modifierControl |
|
RawKeyEventDataWeb.modifierControl |
|
||||||
RawKeyEventDataWeb.modifierMeta;
|
RawKeyEventDataWeb.modifierMeta;
|
||||||
// dispatch the modified data.
|
// dispatch the modified data.
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData? data) {},
|
(ByteData? data) {},
|
||||||
@ -666,6 +665,12 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('RawKeyboard asserts if no keys are in keysPressed after receiving a key down event', (WidgetTester tester) async {
|
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;
|
final Map<String, dynamic> keyEventMessage;
|
||||||
if (kIsWeb) {
|
if (kIsWeb) {
|
||||||
keyEventMessage = const <String, dynamic>{
|
keyEventMessage = const <String, dynamic>{
|
||||||
@ -687,15 +692,19 @@ void main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
await ServicesBinding.instance!.defaultBinaryMessenger
|
||||||
|
.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(keyEventMessage),
|
SystemChannels.keyEvent.codec.encodeMessage(keyEventMessage),
|
||||||
(ByteData? data) { },
|
(ByteData? data) {},
|
||||||
);
|
);
|
||||||
fail('Expected an exception, but did not get one.');
|
} finally {
|
||||||
} on AssertionError catch (error) {
|
FlutterError.onError = oldHandler;
|
||||||
expect(error.toString(), contains('Attempted to send a key down event when no keys are in keysPressed'));
|
|
||||||
}
|
}
|
||||||
|
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 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('modifier keys are recognized when combined', () {
|
test('modifier keys are recognized when combined', () {
|
||||||
for (final int modifier in modifierTests.keys) {
|
for (final int modifier in modifierTests.keys) {
|
||||||
if (modifier == RawKeyEventDataAndroid.modifierFunction) {
|
if (modifier == RawKeyEventDataAndroid.modifierFunction) {
|
||||||
@ -791,7 +799,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Printable keyboard keys are correctly translated', () {
|
test('Printable keyboard keys are correctly translated', () {
|
||||||
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(<String, dynamic>{
|
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(<String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -810,7 +817,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
|
||||||
expect(data.keyLabel, equals('a'));
|
expect(data.keyLabel, equals('a'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Control keyboard keys are correctly translated', () {
|
test('Control keyboard keys are correctly translated', () {
|
||||||
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -827,7 +833,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
|
||||||
expect(data.keyLabel, isEmpty);
|
expect(data.keyLabel, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Modifier keyboard keys are correctly translated', () {
|
test('Modifier keyboard keys are correctly translated', () {
|
||||||
final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -845,7 +850,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
|
||||||
expect(data.keyLabel, isEmpty);
|
expect(data.keyLabel, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('DPAD keys from a joystick give physical key mappings', () {
|
test('DPAD keys from a joystick give physical key mappings', () {
|
||||||
final RawKeyEvent joystickDpadDown = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent joystickDpadDown = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -863,7 +867,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowDown));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowDown));
|
||||||
expect(data.keyLabel, isEmpty);
|
expect(data.keyLabel, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Arrow keys from a keyboard give correct physical key mappings', () {
|
test('Arrow keys from a keyboard give correct physical key mappings', () {
|
||||||
final RawKeyEvent joystickDpadDown = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent joystickDpadDown = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -880,7 +883,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowDown));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowDown));
|
||||||
expect(data.keyLabel, isEmpty);
|
expect(data.keyLabel, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('DPAD center from a game pad gives physical key mappings', () {
|
test('DPAD center from a game pad gives physical key mappings', () {
|
||||||
final RawKeyEvent joystickDpadCenter = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent joystickDpadCenter = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -898,7 +900,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.select));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.select));
|
||||||
expect(data.keyLabel, isEmpty);
|
expect(data.keyLabel, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Device id is read from message', () {
|
test('Device id is read from message', () {
|
||||||
final RawKeyEvent joystickDpadCenter = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent joystickDpadCenter = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -914,7 +915,6 @@ void main() {
|
|||||||
final RawKeyEventDataAndroid data = joystickDpadCenter.data as RawKeyEventDataAndroid;
|
final RawKeyEventDataAndroid data = joystickDpadCenter.data as RawKeyEventDataAndroid;
|
||||||
expect(data.deviceId, equals(10));
|
expect(data.deviceId, equals(10));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Repeat count is passed correctly', () {
|
test('Repeat count is passed correctly', () {
|
||||||
final RawKeyEvent repeatCountEvent = RawKeyEvent.fromMessage(<String, dynamic>{
|
final RawKeyEvent repeatCountEvent = RawKeyEvent.fromMessage(<String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -931,7 +931,6 @@ void main() {
|
|||||||
final RawKeyEventDataAndroid data = repeatCountEvent.data as RawKeyEventDataAndroid;
|
final RawKeyEventDataAndroid data = repeatCountEvent.data as RawKeyEventDataAndroid;
|
||||||
expect(data.repeatCount, equals(42));
|
expect(data.repeatCount, equals(42));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Key events are responded to correctly.', (WidgetTester tester) async {
|
testWidgets('Key events are responded to correctly.', (WidgetTester tester) async {
|
||||||
expect(RawKeyboard.instance.keysPressed, isEmpty);
|
expect(RawKeyboard.instance.keysPressed, isEmpty);
|
||||||
// Generate the data for a regular key down event.
|
// Generate the data for a regular key down event.
|
||||||
@ -941,7 +940,7 @@ void main() {
|
|||||||
isDown: true,
|
isDown: true,
|
||||||
);
|
);
|
||||||
Map<String, dynamic>? message;
|
Map<String, dynamic>? message;
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData? data) {
|
(ByteData? data) {
|
||||||
@ -964,7 +963,7 @@ void main() {
|
|||||||
focusNode.requestFocus();
|
focusNode.requestFocus();
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData? data) {
|
(ByteData? data) {
|
||||||
@ -972,7 +971,7 @@ void main() {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
expect(message, equals(<String, dynamic>{ 'handled': true }));
|
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.
|
}, skip: isBrowser); // This is an Android-specific group.
|
||||||
|
|
||||||
@ -1020,7 +1019,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('modifier keys are recognized when combined', () {
|
test('modifier keys are recognized when combined', () {
|
||||||
for (final int modifier in modifierTests.keys) {
|
for (final int modifier in modifierTests.keys) {
|
||||||
if (modifier == RawKeyEventDataFuchsia.modifierCapsLock) {
|
if (modifier == RawKeyEventDataFuchsia.modifierCapsLock) {
|
||||||
@ -1054,7 +1052,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Printable keyboard keys are correctly translated', () {
|
test('Printable keyboard keys are correctly translated', () {
|
||||||
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(<String, dynamic>{
|
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(<String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -1068,7 +1065,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
|
||||||
expect(data.keyLabel, equals('a'));
|
expect(data.keyLabel, equals('a'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Control keyboard keys are correctly translated', () {
|
test('Control keyboard keys are correctly translated', () {
|
||||||
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -1140,7 +1136,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('modifier keys are recognized when combined', () {
|
test('modifier keys are recognized when combined', () {
|
||||||
for (final int modifier in modifierTests.keys) {
|
for (final int modifier in modifierTests.keys) {
|
||||||
if (modifier == RawKeyEventDataMacOs.modifierCapsLock) {
|
if (modifier == RawKeyEventDataMacOs.modifierCapsLock) {
|
||||||
@ -1180,7 +1175,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Printable keyboard keys are correctly translated', () {
|
test('Printable keyboard keys are correctly translated', () {
|
||||||
const String unmodifiedCharacter = 'a';
|
const String unmodifiedCharacter = 'a';
|
||||||
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
@ -1196,7 +1190,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
|
||||||
expect(data.keyLabel, equals('a'));
|
expect(data.keyLabel, equals('a'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Control keyboard keys are correctly translated', () {
|
test('Control keyboard keys are correctly translated', () {
|
||||||
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -1288,7 +1281,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('modifier keys are recognized when combined', () {
|
test('modifier keys are recognized when combined', () {
|
||||||
for (final int modifier in modifierTests.keys) {
|
for (final int modifier in modifierTests.keys) {
|
||||||
if (modifier == RawKeyEventDataIos.modifierCapsLock) {
|
if (modifier == RawKeyEventDataIos.modifierCapsLock) {
|
||||||
@ -1328,7 +1320,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Printable keyboard keys are correctly translated', () {
|
test('Printable keyboard keys are correctly translated', () {
|
||||||
const String unmodifiedCharacter = 'a';
|
const String unmodifiedCharacter = 'a';
|
||||||
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
@ -1344,7 +1335,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
|
||||||
expect(data.keyLabel, equals('a'));
|
expect(data.keyLabel, equals('a'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Control keyboard keys are correctly translated', () {
|
test('Control keyboard keys are correctly translated', () {
|
||||||
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -1437,7 +1427,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('modifier keys are recognized when combined', () {
|
test('modifier keys are recognized when combined', () {
|
||||||
for (final int modifier in modifierTests.keys) {
|
for (final int modifier in modifierTests.keys) {
|
||||||
if (modifier == RawKeyEventDataWindows.modifierCaps) {
|
if (modifier == RawKeyEventDataWindows.modifierCaps) {
|
||||||
@ -1477,7 +1466,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Printable keyboard keys are correctly translated', () {
|
test('Printable keyboard keys are correctly translated', () {
|
||||||
const int unmodifiedCharacter = 97; // ASCII value for 'a'.
|
const int unmodifiedCharacter = 97; // ASCII value for 'a'.
|
||||||
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
@ -1493,7 +1481,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
|
||||||
expect(data.keyLabel, equals('a'));
|
expect(data.keyLabel, equals('a'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Control keyboard keys are correctly translated', () {
|
test('Control keyboard keys are correctly translated', () {
|
||||||
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -1508,7 +1495,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
|
||||||
expect(data.keyLabel, isEmpty);
|
expect(data.keyLabel, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Modifier keyboard keys are correctly translated', () {
|
test('Modifier keyboard keys are correctly translated', () {
|
||||||
final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -1523,7 +1509,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
|
||||||
expect(data.keyLabel, isEmpty);
|
expect(data.keyLabel, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Unprintable keyboard keys are correctly translated', () {
|
test('Unprintable keyboard keys are correctly translated', () {
|
||||||
final RawKeyEvent leftArrowKey = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent leftArrowKey = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -1537,7 +1522,6 @@ void main() {
|
|||||||
expect(data.physicalKey, equals(PhysicalKeyboardKey.arrowLeft));
|
expect(data.physicalKey, equals(PhysicalKeyboardKey.arrowLeft));
|
||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('Win32 VK_PROCESSKEY events are skipped', (WidgetTester tester) async {
|
testWidgets('Win32 VK_PROCESSKEY events are skipped', (WidgetTester tester) async {
|
||||||
const String platform = 'windows';
|
const String platform = 'windows';
|
||||||
bool lastHandled = true;
|
bool lastHandled = true;
|
||||||
@ -1636,7 +1620,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('modifier keys are recognized when combined', () {
|
test('modifier keys are recognized when combined', () {
|
||||||
for (final int modifier in modifierTests.keys) {
|
for (final int modifier in modifierTests.keys) {
|
||||||
if (modifier == GLFWKeyHelper.modifierControl) {
|
if (modifier == GLFWKeyHelper.modifierControl) {
|
||||||
@ -1677,7 +1660,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Printable keyboard keys are correctly translated', () {
|
test('Printable keyboard keys are correctly translated', () {
|
||||||
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -1693,7 +1675,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.keyQ));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.keyQ));
|
||||||
expect(data.keyLabel, equals('q'));
|
expect(data.keyLabel, equals('q'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Code points with two Unicode scalar values are allowed', () {
|
test('Code points with two Unicode scalar values are allowed', () {
|
||||||
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -1742,7 +1723,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
|
||||||
expect(data.keyLabel, isEmpty);
|
expect(data.keyLabel, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Modifier keyboard keys are correctly translated', () {
|
test('Modifier keyboard keys are correctly translated', () {
|
||||||
final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -1824,7 +1804,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('modifier keys are recognized when combined', () {
|
test('modifier keys are recognized when combined', () {
|
||||||
for (final int modifier in modifierTests.keys) {
|
for (final int modifier in modifierTests.keys) {
|
||||||
if (modifier == GtkKeyHelper.modifierControl) {
|
if (modifier == GtkKeyHelper.modifierControl) {
|
||||||
@ -1865,7 +1844,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Printable keyboard keys are correctly translated', () {
|
test('Printable keyboard keys are correctly translated', () {
|
||||||
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -1881,7 +1859,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.keyQ));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.keyQ));
|
||||||
expect(data.keyLabel, equals('q'));
|
expect(data.keyLabel, equals('q'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Code points with two Unicode scalar values are allowed', () {
|
test('Code points with two Unicode scalar values are allowed', () {
|
||||||
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -1930,7 +1907,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
|
||||||
expect(data.keyLabel, isEmpty);
|
expect(data.keyLabel, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Modifier keyboard keys are correctly translated', () {
|
test('Modifier keyboard keys are correctly translated', () {
|
||||||
final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -1984,7 +1960,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('modifier keys are recognized when combined', () {
|
test('modifier keys are recognized when combined', () {
|
||||||
for (final int modifier in modifierTests.keys) {
|
for (final int modifier in modifierTests.keys) {
|
||||||
if (modifier == RawKeyEventDataWeb.modifierMeta) {
|
if (modifier == RawKeyEventDataWeb.modifierMeta) {
|
||||||
@ -2017,7 +1992,6 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Printable keyboard keys are correctly translated', () {
|
test('Printable keyboard keys are correctly translated', () {
|
||||||
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -2031,7 +2005,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
|
||||||
expect(data.keyLabel, equals('a'));
|
expect(data.keyLabel, equals('a'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Control keyboard keys are correctly translated', () {
|
test('Control keyboard keys are correctly translated', () {
|
||||||
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -2044,7 +2017,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
|
||||||
expect(data.keyLabel, isEmpty);
|
expect(data.keyLabel, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Modifier keyboard keys are correctly translated', () {
|
test('Modifier keyboard keys are correctly translated', () {
|
||||||
final RawKeyEvent shiftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent shiftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
@ -2057,7 +2029,6 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
|
||||||
expect(data.keyLabel, isEmpty);
|
expect(data.keyLabel, isEmpty);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Arrow keys from a keyboard give correct physical key mappings', () {
|
test('Arrow keys from a keyboard give correct physical key mappings', () {
|
||||||
final RawKeyEvent arrowKeyDown = RawKeyEvent.fromMessage(const <String, dynamic>{
|
final RawKeyEvent arrowKeyDown = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
|
@ -18,7 +18,7 @@ void main() {
|
|||||||
testWidgets('root bucket retrieval', (WidgetTester tester) async {
|
testWidgets('root bucket retrieval', (WidgetTester tester) async {
|
||||||
final List<MethodCall> callsToEngine = <MethodCall>[];
|
final List<MethodCall> callsToEngine = <MethodCall>[];
|
||||||
final Completer<Map<dynamic, dynamic>> result = Completer<Map<dynamic, dynamic>>();
|
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);
|
callsToEngine.add(call);
|
||||||
return result.future;
|
return result.future;
|
||||||
});
|
});
|
||||||
@ -64,7 +64,7 @@ void main() {
|
|||||||
testWidgets('root bucket received from engine before retrieval', (WidgetTester tester) async {
|
testWidgets('root bucket received from engine before retrieval', (WidgetTester tester) async {
|
||||||
SystemChannels.restoration.setMethodCallHandler(null);
|
SystemChannels.restoration.setMethodCallHandler(null);
|
||||||
final List<MethodCall> callsToEngine = <MethodCall>[];
|
final List<MethodCall> callsToEngine = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.restoration, (MethodCall call) async {
|
SystemChannels.restoration.setMockMethodCallHandler((MethodCall call) async {
|
||||||
callsToEngine.add(call);
|
callsToEngine.add(call);
|
||||||
});
|
});
|
||||||
final RestorationManager manager = RestorationManager();
|
final RestorationManager manager = RestorationManager();
|
||||||
@ -83,7 +83,7 @@ void main() {
|
|||||||
SystemChannels.restoration.setMethodCallHandler(null);
|
SystemChannels.restoration.setMethodCallHandler(null);
|
||||||
final List<MethodCall> callsToEngine = <MethodCall>[];
|
final List<MethodCall> callsToEngine = <MethodCall>[];
|
||||||
final Completer<Map<dynamic, dynamic>> result = Completer<Map<dynamic, dynamic>>();
|
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);
|
callsToEngine.add(call);
|
||||||
return result.future;
|
return result.future;
|
||||||
});
|
});
|
||||||
@ -110,7 +110,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('root bucket is properly replaced when new data is available', (WidgetTester tester) async {
|
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();
|
return _createEncodedRestorationData1();
|
||||||
});
|
});
|
||||||
final RestorationManager manager = RestorationManager();
|
final RestorationManager manager = RestorationManager();
|
||||||
@ -152,7 +152,7 @@ void main() {
|
|||||||
testWidgets('returns null as root bucket when restoration is disabled', (WidgetTester tester) async {
|
testWidgets('returns null as root bucket when restoration is disabled', (WidgetTester tester) async {
|
||||||
final List<MethodCall> callsToEngine = <MethodCall>[];
|
final List<MethodCall> callsToEngine = <MethodCall>[];
|
||||||
final Completer<Map<dynamic, dynamic>> result = Completer<Map<dynamic, dynamic>>();
|
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);
|
callsToEngine.add(call);
|
||||||
return result.future;
|
return result.future;
|
||||||
});
|
});
|
||||||
@ -195,7 +195,7 @@ void main() {
|
|||||||
testWidgets('flushData', (WidgetTester tester) async {
|
testWidgets('flushData', (WidgetTester tester) async {
|
||||||
final List<MethodCall> callsToEngine = <MethodCall>[];
|
final List<MethodCall> callsToEngine = <MethodCall>[];
|
||||||
final Completer<Map<dynamic, dynamic>> result = Completer<Map<dynamic, dynamic>>();
|
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);
|
callsToEngine.add(call);
|
||||||
return result.future;
|
return result.future;
|
||||||
});
|
});
|
||||||
@ -230,7 +230,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('isReplacing', (WidgetTester tester) async {
|
testWidgets('isReplacing', (WidgetTester tester) async {
|
||||||
final Completer<Map<dynamic, dynamic>> result = Completer<Map<dynamic, dynamic>>();
|
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;
|
return result.future;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -7,8 +7,6 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
|
||||||
|
|
||||||
testWidgets('SystemChrome overlay style test', (WidgetTester tester) async {
|
testWidgets('SystemChrome overlay style test', (WidgetTester tester) async {
|
||||||
// The first call is a cache miss and will queue a microtask
|
// The first call is a cache miss and will queue a microtask
|
||||||
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
|
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle.light);
|
||||||
@ -26,7 +24,7 @@ void main() {
|
|||||||
test('setPreferredOrientations control test', () async {
|
test('setPreferredOrientations control test', () async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
|
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -44,7 +42,7 @@ void main() {
|
|||||||
test('setApplicationSwitcherDescription control test', () async {
|
test('setApplicationSwitcherDescription control test', () async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
|
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -62,7 +60,7 @@ void main() {
|
|||||||
test('setApplicationSwitcherDescription missing plugin', () async {
|
test('setApplicationSwitcherDescription missing plugin', () async {
|
||||||
final List<ByteData?> log = <ByteData>[];
|
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);
|
log.add(message);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -76,7 +74,7 @@ void main() {
|
|||||||
test('setEnabledSystemUIOverlays control test', () async {
|
test('setEnabledSystemUIOverlays control test', () async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
|
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ void main() {
|
|||||||
test('System navigator control test', () async {
|
test('System navigator control test', () async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
|
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ void main() {
|
|||||||
test('System sound control test', () async {
|
test('System sound control test', () async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
|
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -442,6 +442,16 @@ class FakeTextChannel implements MethodChannel {
|
|||||||
@override
|
@override
|
||||||
void setMethodCallHandler(Future<void> Function(MethodCall call)? handler) => incoming = handler;
|
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) {
|
void validateOutgoingMethodCalls(List<MethodCall> calls) {
|
||||||
expect(outgoingCalls.length, calls.length);
|
expect(outgoingCalls.length, calls.length);
|
||||||
bool hasError = false;
|
bool hasError = false;
|
||||||
|
@ -3101,7 +3101,7 @@ Future<void> _testLongPressDraggableHapticFeedback({ required WidgetTester teste
|
|||||||
bool onDragStartedCalled = false;
|
bool onDragStartedCalled = false;
|
||||||
|
|
||||||
int hapticFeedbackCalls = 0;
|
int hapticFeedbackCalls = 0;
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
if (methodCall.method == 'HapticFeedback.vibrate') {
|
if (methodCall.method == 'HapticFeedback.vibrate') {
|
||||||
hapticFeedbackCalls++;
|
hapticFeedbackCalls++;
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ void main() {
|
|||||||
|
|
||||||
// Populate a fake clipboard.
|
// Populate a fake clipboard.
|
||||||
const String clipboardContent = ' ';
|
const String clipboardContent = ' ';
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
if (methodCall.method == 'Clipboard.getData')
|
if (methodCall.method == 'Clipboard.getData')
|
||||||
return const <String, dynamic>{'text': clipboardContent};
|
return const <String, dynamic>{'text': clipboardContent};
|
||||||
return null;
|
return null;
|
||||||
@ -127,7 +127,7 @@ void main() {
|
|||||||
|
|
||||||
// Populate a fake clipboard.
|
// Populate a fake clipboard.
|
||||||
const String clipboardContent = ' ';
|
const String clipboardContent = ' ';
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
if (methodCall.method == 'Clipboard.getData')
|
if (methodCall.method == 'Clipboard.getData')
|
||||||
return const <String, dynamic>{'text': clipboardContent};
|
return const <String, dynamic>{'text': clipboardContent};
|
||||||
return null;
|
return null;
|
||||||
@ -820,7 +820,7 @@ void main() {
|
|||||||
|
|
||||||
// Populate a fake clipboard.
|
// Populate a fake clipboard.
|
||||||
const String clipboardContent = 'Hello world!';
|
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')
|
if (methodCall.method == 'Clipboard.getData')
|
||||||
return const <String, dynamic>{'text': clipboardContent};
|
return const <String, dynamic>{'text': clipboardContent};
|
||||||
return null;
|
return null;
|
||||||
@ -878,7 +878,7 @@ void main() {
|
|||||||
|
|
||||||
// Populate a fake clipboard.
|
// Populate a fake clipboard.
|
||||||
const String clipboardContent = 'Hello world!';
|
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')
|
if (methodCall.method == 'Clipboard.getData')
|
||||||
return const <String, dynamic>{'text': clipboardContent};
|
return const <String, dynamic>{'text': clipboardContent};
|
||||||
return null;
|
return null;
|
||||||
|
@ -65,9 +65,9 @@ class MockClipboard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
final MockClipboard mockClipboard = MockClipboard();
|
final MockClipboard mockClipboard = MockClipboard();
|
||||||
(TestWidgetsFlutterBinding.ensureInitialized() as TestWidgetsFlutterBinding)
|
SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
|
||||||
.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
|
|
||||||
|
|
||||||
setUp(() async {
|
setUp(() async {
|
||||||
debugResetSemanticsIdCounter();
|
debugResetSemanticsIdCounter();
|
||||||
@ -1985,7 +1985,7 @@ void main() {
|
|||||||
await tester.pump(); // An extra pump to allow focus request to go through.
|
await tester.pump(); // An extra pump to allow focus request to go through.
|
||||||
|
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
|
SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -3176,7 +3176,7 @@ void main() {
|
|||||||
// Regression test for https://github.com/flutter/flutter/issues/22212.
|
// Regression test for https://github.com/flutter/flutter/issues/22212.
|
||||||
|
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
|
SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -3207,7 +3207,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('location of widget is sent on show keyboard', (WidgetTester tester) async {
|
testWidgets('location of widget is sent on show keyboard', (WidgetTester tester) async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
|
SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -3244,7 +3244,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('transform and size is reset when text connection opens', (WidgetTester tester) async {
|
testWidgets('transform and size is reset when text connection opens', (WidgetTester tester) async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
|
SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -3332,7 +3332,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('size and transform are sent when they change', (WidgetTester tester) async {
|
testWidgets('size and transform are sent when they change', (WidgetTester tester) async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
|
SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -3374,7 +3374,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('text styling info is sent on show keyboard', (WidgetTester tester) async {
|
testWidgets('text styling info is sent on show keyboard', (WidgetTester tester) async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
|
SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -3461,7 +3461,7 @@ void main() {
|
|||||||
await tester.showKeyboard(find.byType(EditableText));
|
await tester.showKeyboard(find.byType(EditableText));
|
||||||
|
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
|
SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
setState(() {
|
setState(() {
|
||||||
@ -3678,7 +3678,7 @@ void main() {
|
|||||||
// Regression test for https://github.com/flutter/flutter/issues/22212.
|
// Regression test for https://github.com/flutter/flutter/issues/22212.
|
||||||
|
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
|
SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -5639,7 +5639,7 @@ void main() {
|
|||||||
testWidgets('Synchronous test of local and remote editing values', (WidgetTester tester) async {
|
testWidgets('Synchronous test of local and remote editing values', (WidgetTester tester) async {
|
||||||
// Regression test for https://github.com/flutter/flutter/issues/65059
|
// Regression test for https://github.com/flutter/flutter/issues/65059
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
|
SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
final TextInputFormatter formatter = TextInputFormatter.withFunction((TextEditingValue oldValue, TextEditingValue newValue) {
|
final TextInputFormatter formatter = TextInputFormatter.withFunction((TextEditingValue oldValue, TextEditingValue newValue) {
|
||||||
@ -5767,7 +5767,7 @@ void main() {
|
|||||||
testWidgets('Send text input state to engine when the input formatter rejects user input', (WidgetTester tester) async {
|
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
|
// Regression test for https://github.com/flutter/flutter/issues/67828
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
|
SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
final TextInputFormatter formatter = TextInputFormatter.withFunction((TextEditingValue oldValue, TextEditingValue newValue) {
|
final TextInputFormatter formatter = TextInputFormatter.withFunction((TextEditingValue oldValue, TextEditingValue newValue) {
|
||||||
@ -5846,7 +5846,7 @@ void main() {
|
|||||||
testWidgets('Repeatedly receiving [TextEditingValue] will not trigger a keyboard request', (WidgetTester tester) async {
|
testWidgets('Repeatedly receiving [TextEditingValue] will not trigger a keyboard request', (WidgetTester tester) async {
|
||||||
// Regression test for https://github.com/flutter/flutter/issues/66036
|
// Regression test for https://github.com/flutter/flutter/issues/66036
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
|
SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
final TextEditingController controller = TextEditingController();
|
final TextEditingController controller = TextEditingController();
|
||||||
@ -5967,7 +5967,7 @@ void main() {
|
|||||||
testWidgets('TextEditingController.clear() behavior test', (WidgetTester tester) async {
|
testWidgets('TextEditingController.clear() behavior test', (WidgetTester tester) async {
|
||||||
// Regression test for https://github.com/flutter/flutter/issues/66316
|
// Regression test for https://github.com/flutter/flutter/issues/66316
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall methodCall) async {
|
SystemChannels.textInput.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
final TextEditingController controller = TextEditingController();
|
final TextEditingController controller = TextEditingController();
|
||||||
|
@ -165,7 +165,7 @@ void main() {
|
|||||||
testWidgets('ModalBarrier plays system alert sound when user tries to dismiss it', (WidgetTester tester) async {
|
testWidgets('ModalBarrier plays system alert sound when user tries to dismiss it', (WidgetTester tester) async {
|
||||||
final List<String> playedSystemSounds = <String>[];
|
final List<String> playedSystemSounds = <String>[];
|
||||||
try {
|
try {
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
if (methodCall.method == 'SystemSound.play')
|
if (methodCall.method == 'SystemSound.play')
|
||||||
playedSystemSounds.add(methodCall.arguments as String);
|
playedSystemSounds.add(methodCall.arguments as String);
|
||||||
});
|
});
|
||||||
@ -182,7 +182,7 @@ void main() {
|
|||||||
await tester.tap(find.text('target'), warnIfMissed: false);
|
await tester.tap(find.text('target'), warnIfMissed: false);
|
||||||
await tester.pumpWidget(subject);
|
await tester.pumpWidget(subject);
|
||||||
} finally {
|
} finally {
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null);
|
SystemChannels.platform.setMockMethodCallHandler(null);
|
||||||
}
|
}
|
||||||
expect(playedSystemSounds, hasLength(1));
|
expect(playedSystemSounds, hasLength(1));
|
||||||
expect(playedSystemSounds[0], SystemSoundType.alert.toString());
|
expect(playedSystemSounds[0], SystemSoundType.alert.toString());
|
||||||
|
@ -1588,7 +1588,7 @@ void main() {
|
|||||||
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
|
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
|
||||||
await gesture.addPointer(location: const Offset(100, 100));
|
await gesture.addPointer(location: const Offset(100, 100));
|
||||||
addTearDown(gesture.removePointer);
|
addTearDown(gesture.removePointer);
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.mouseCursor, (_) async {
|
SystemChannels.mouseCursor.setMockMethodCallHandler((_) async {
|
||||||
logCursors.add('cursor');
|
logCursors.add('cursor');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1042,7 +1042,7 @@ void main() {
|
|||||||
await tester.pump();
|
await tester.pump();
|
||||||
|
|
||||||
late int lastPlatformViewTextClient;
|
late int lastPlatformViewTextClient;
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.textInput, (MethodCall call) {
|
SystemChannels.textInput.setMockMethodCallHandler((MethodCall call) {
|
||||||
if (call.method == 'TextInput.setPlatformViewClient') {
|
if (call.method == 'TextInput.setPlatformViewClient') {
|
||||||
lastPlatformViewTextClient = call.arguments as int;
|
lastPlatformViewTextClient = call.arguments as int;
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ void main() {
|
|||||||
|
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
|
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.navigation, (MethodCall methodCall) async {
|
SystemChannels.navigation.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('Navigator does not report route name by default', (WidgetTester tester) async {
|
testWidgets('Navigator does not report route name by default', (WidgetTester tester) async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.navigation, (MethodCall methodCall) async {
|
SystemChannels.navigation.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -153,7 +153,7 @@ void main() {
|
|||||||
|
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
|
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.navigation, (MethodCall methodCall) async {
|
SystemChannels.navigation.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -205,7 +205,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('Nameless routes should send platform messages', (WidgetTester tester) async {
|
testWidgets('Nameless routes should send platform messages', (WidgetTester tester) async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.navigation, (MethodCall methodCall) async {
|
SystemChannels.navigation.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -252,7 +252,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('PlatformRouteInformationProvider reports URL', (WidgetTester tester) async {
|
testWidgets('PlatformRouteInformationProvider reports URL', (WidgetTester tester) async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.navigation, (MethodCall methodCall) async {
|
SystemChannels.navigation.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ double getOpacity(WidgetTester tester, Finder finder) {
|
|||||||
void main() {
|
void main() {
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
final MockClipboard mockClipboard = MockClipboard();
|
final MockClipboard mockClipboard = MockClipboard();
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
|
SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
|
||||||
|
|
||||||
const String kThreeLines =
|
const String kThreeLines =
|
||||||
'First line of text is\n'
|
'First line of text is\n'
|
||||||
@ -1626,7 +1626,7 @@ void main() {
|
|||||||
final FocusNode focusNode = FocusNode();
|
final FocusNode focusNode = FocusNode();
|
||||||
|
|
||||||
String clipboardContent = '';
|
String clipboardContent = '';
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
if (methodCall.method == 'Clipboard.setData')
|
if (methodCall.method == 'Clipboard.setData')
|
||||||
clipboardContent = methodCall.arguments['text'] as String;
|
clipboardContent = methodCall.arguments['text'] as String;
|
||||||
else if (methodCall.method == 'Clipboard.getData')
|
else if (methodCall.method == 'Clipboard.getData')
|
||||||
|
@ -19,15 +19,15 @@ class MockClipboard {
|
|||||||
'text': null,
|
'text': null,
|
||||||
};
|
};
|
||||||
|
|
||||||
Future<Object?> handleMethodCall(MethodCall methodCall) async {
|
Future<dynamic> handleMethodCall(MethodCall methodCall) async {
|
||||||
switch (methodCall.method) {
|
switch (methodCall.method) {
|
||||||
case 'Clipboard.getData':
|
case 'Clipboard.getData':
|
||||||
if (getDataThrows)
|
if (getDataThrows) {
|
||||||
throw Exception();
|
throw Exception();
|
||||||
|
}
|
||||||
return _clipboardData;
|
return _clipboardData;
|
||||||
case 'Clipboard.setData':
|
case 'Clipboard.setData':
|
||||||
_clipboardData = methodCall.arguments;
|
_clipboardData = methodCall.arguments;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -758,11 +758,11 @@ void main() {
|
|||||||
group('when Clipboard fails', () {
|
group('when Clipboard fails', () {
|
||||||
setUp(() {
|
setUp(() {
|
||||||
final MockClipboard mockClipboard = MockClipboard(getDataThrows: true);
|
final MockClipboard mockClipboard = MockClipboard(getDataThrows: true);
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
|
SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null);
|
SystemChannels.platform.setMockMethodCallHandler(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Clipboard API failure is gracefully recovered from', () async {
|
test('Clipboard API failure is gracefully recovered from', () async {
|
||||||
@ -778,11 +778,11 @@ void main() {
|
|||||||
final MockClipboard mockClipboard = MockClipboard();
|
final MockClipboard mockClipboard = MockClipboard();
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, mockClipboard.handleMethodCall);
|
SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null);
|
SystemChannels.platform.setMockMethodCallHandler(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('update sets value based on clipboard contents', () async {
|
test('update sets value based on clipboard contents', () async {
|
||||||
|
@ -36,7 +36,7 @@ void main() {
|
|||||||
testWidgets('should not pass "null" to setApplicationSwitcherDescription', (WidgetTester tester) async {
|
testWidgets('should not pass "null" to setApplicationSwitcherDescription', (WidgetTester tester) async {
|
||||||
final List<MethodCall> log = <MethodCall>[];
|
final List<MethodCall> log = <MethodCall>[];
|
||||||
|
|
||||||
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, (MethodCall methodCall) async {
|
SystemChannels.platform.setMockMethodCallHandler((MethodCall methodCall) async {
|
||||||
log.add(methodCall);
|
log.add(methodCall);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ const String _extensionMethodName = 'driver';
|
|||||||
/// eventually completes to a string response.
|
/// eventually completes to a string response.
|
||||||
typedef DataHandler = Future<String> Function(String? message);
|
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);
|
_DriverBinding(this._handler, this._silenceErrors, this._enableTextEntryEmulation, this.finders, this.commands);
|
||||||
|
|
||||||
final DataHandler? _handler;
|
final DataHandler? _handler;
|
||||||
@ -51,6 +51,11 @@ class _DriverBinding extends BindingBase with SchedulerBinding, ServicesBinding,
|
|||||||
registerWebServiceExtension(extension.call);
|
registerWebServiceExtension(extension.call);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
BinaryMessenger createBinaryMessenger() {
|
||||||
|
return TestDefaultBinaryMessenger(super.createBinaryMessenger());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enables Flutter Driver VM service extension.
|
/// Enables Flutter Driver VM service extension.
|
||||||
@ -325,11 +330,11 @@ class FlutterDriverExtension with DeserializeFinderFactory, CreateFinderFactory,
|
|||||||
registerTextInput();
|
registerTextInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final FinderExtension finder in finders) {
|
for(final FinderExtension finder in finders) {
|
||||||
_finderExtensions[finder.finderType] = finder;
|
_finderExtensions[finder.finderType] = finder;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final CommandExtension command in commands) {
|
for(final CommandExtension command in commands) {
|
||||||
_commandExtensions[command.commandKind] = command;
|
_commandExtensions[command.commandKind] = command;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -413,7 +418,7 @@ class FlutterDriverExtension with DeserializeFinderFactory, CreateFinderFactory,
|
|||||||
@override
|
@override
|
||||||
Command deserializeCommand(Map<String, String> params, DeserializeFinderFactory finderFactory) {
|
Command deserializeCommand(Map<String, String> params, DeserializeFinderFactory finderFactory) {
|
||||||
final String? kind = params['command'];
|
final String? kind = params['command'];
|
||||||
if (_commandExtensions.containsKey(kind)) {
|
if(_commandExtensions.containsKey(kind)) {
|
||||||
return _commandExtensions[kind]!.deserialize(params, finderFactory, this);
|
return _commandExtensions[kind]!.deserialize(params, finderFactory, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,7 +434,7 @@ class FlutterDriverExtension with DeserializeFinderFactory, CreateFinderFactory,
|
|||||||
@override
|
@override
|
||||||
Future<Result> handleCommand(Command command, WidgetController prober, CreateFinderFactory finderFactory) {
|
Future<Result> handleCommand(Command command, WidgetController prober, CreateFinderFactory finderFactory) {
|
||||||
final String kind = command.kind;
|
final String kind = command.kind;
|
||||||
if (_commandExtensions.containsKey(kind)) {
|
if(_commandExtensions.containsKey(kind)) {
|
||||||
return _commandExtensions[kind]!.call(command, prober, finderFactory, this);
|
return _commandExtensions[kind]!.call(command, prober, finderFactory, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ void main() {
|
|||||||
'waiting for NoPendingPlatformMessages returns until a single method channel call returns', (WidgetTester tester) async {
|
'waiting for NoPendingPlatformMessages returns until a single method channel call returns', (WidgetTester tester) async {
|
||||||
const MethodChannel channel = MethodChannel('helloChannel', JSONMethodCodec());
|
const MethodChannel channel = MethodChannel('helloChannel', JSONMethodCodec());
|
||||||
const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
|
const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
|
||||||
tester.binding.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'helloChannel', (ByteData? message) {
|
'helloChannel', (ByteData? message) {
|
||||||
return Future<ByteData>.delayed(
|
return Future<ByteData>.delayed(
|
||||||
const Duration(milliseconds: 10),
|
const Duration(milliseconds: 10),
|
||||||
@ -313,7 +313,7 @@ void main() {
|
|||||||
const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
|
const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
|
||||||
// Configures channel 1
|
// Configures channel 1
|
||||||
const MethodChannel channel1 = MethodChannel('helloChannel1', JSONMethodCodec());
|
const MethodChannel channel1 = MethodChannel('helloChannel1', JSONMethodCodec());
|
||||||
tester.binding.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'helloChannel1', (ByteData? message) {
|
'helloChannel1', (ByteData? message) {
|
||||||
return Future<ByteData>.delayed(
|
return Future<ByteData>.delayed(
|
||||||
const Duration(milliseconds: 10),
|
const Duration(milliseconds: 10),
|
||||||
@ -322,7 +322,7 @@ void main() {
|
|||||||
|
|
||||||
// Configures channel 2
|
// Configures channel 2
|
||||||
const MethodChannel channel2 = MethodChannel('helloChannel2', JSONMethodCodec());
|
const MethodChannel channel2 = MethodChannel('helloChannel2', JSONMethodCodec());
|
||||||
tester.binding.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'helloChannel2', (ByteData? message) {
|
'helloChannel2', (ByteData? message) {
|
||||||
return Future<ByteData>.delayed(
|
return Future<ByteData>.delayed(
|
||||||
const Duration(milliseconds: 20),
|
const Duration(milliseconds: 20),
|
||||||
@ -362,7 +362,7 @@ void main() {
|
|||||||
const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
|
const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
|
||||||
// Configures channel 1
|
// Configures channel 1
|
||||||
const MethodChannel channel1 = MethodChannel('helloChannel1', JSONMethodCodec());
|
const MethodChannel channel1 = MethodChannel('helloChannel1', JSONMethodCodec());
|
||||||
tester.binding.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'helloChannel1', (ByteData? message) {
|
'helloChannel1', (ByteData? message) {
|
||||||
return Future<ByteData>.delayed(
|
return Future<ByteData>.delayed(
|
||||||
const Duration(milliseconds: 10),
|
const Duration(milliseconds: 10),
|
||||||
@ -371,7 +371,7 @@ void main() {
|
|||||||
|
|
||||||
// Configures channel 2
|
// Configures channel 2
|
||||||
const MethodChannel channel2 = MethodChannel('helloChannel2', JSONMethodCodec());
|
const MethodChannel channel2 = MethodChannel('helloChannel2', JSONMethodCodec());
|
||||||
tester.binding.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'helloChannel2', (ByteData? message) {
|
'helloChannel2', (ByteData? message) {
|
||||||
return Future<ByteData>.delayed(
|
return Future<ByteData>.delayed(
|
||||||
const Duration(milliseconds: 20),
|
const Duration(milliseconds: 20),
|
||||||
@ -413,7 +413,7 @@ void main() {
|
|||||||
const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
|
const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
|
||||||
// Configures channel 1
|
// Configures channel 1
|
||||||
const MethodChannel channel1 = MethodChannel('helloChannel1', JSONMethodCodec());
|
const MethodChannel channel1 = MethodChannel('helloChannel1', JSONMethodCodec());
|
||||||
tester.binding.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'helloChannel1', (ByteData? message) {
|
'helloChannel1', (ByteData? message) {
|
||||||
return Future<ByteData>.delayed(
|
return Future<ByteData>.delayed(
|
||||||
const Duration(milliseconds: 20),
|
const Duration(milliseconds: 20),
|
||||||
@ -422,7 +422,7 @@ void main() {
|
|||||||
|
|
||||||
// Configures channel 2
|
// Configures channel 2
|
||||||
const MethodChannel channel2 = MethodChannel('helloChannel2', JSONMethodCodec());
|
const MethodChannel channel2 = MethodChannel('helloChannel2', JSONMethodCodec());
|
||||||
tester.binding.defaultBinaryMessenger.setMockMessageHandler(
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'helloChannel2', (ByteData? message) {
|
'helloChannel2', (ByteData? message) {
|
||||||
return Future<ByteData>.delayed(
|
return Future<ByteData>.delayed(
|
||||||
const Duration(milliseconds: 10),
|
const Duration(milliseconds: 10),
|
||||||
|
@ -61,7 +61,6 @@ export 'src/all_elements.dart';
|
|||||||
export 'src/animation_sheet.dart';
|
export 'src/animation_sheet.dart';
|
||||||
export 'src/binding.dart';
|
export 'src/binding.dart';
|
||||||
export 'src/controller.dart';
|
export 'src/controller.dart';
|
||||||
export 'src/deprecated.dart';
|
|
||||||
export 'src/event_simulation.dart';
|
export 'src/event_simulation.dart';
|
||||||
export 'src/finders.dart';
|
export 'src/finders.dart';
|
||||||
export 'src/frame_timing_summarizer.dart';
|
export 'src/frame_timing_summarizer.dart';
|
||||||
@ -74,7 +73,6 @@ export 'src/restoration.dart';
|
|||||||
export 'src/stack_manipulation.dart';
|
export 'src/stack_manipulation.dart';
|
||||||
export 'src/test_async_utils.dart';
|
export 'src/test_async_utils.dart';
|
||||||
export 'src/test_compat.dart';
|
export 'src/test_compat.dart';
|
||||||
export 'src/test_default_binary_messenger.dart';
|
|
||||||
export 'src/test_exception_reporter.dart';
|
export 'src/test_exception_reporter.dart';
|
||||||
export 'src/test_pointer.dart';
|
export 'src/test_pointer.dart';
|
||||||
export 'src/test_text_input.dart';
|
export 'src/test_text_input.dart';
|
||||||
|
@ -13,8 +13,8 @@ import 'package:path/path.dart' as path;
|
|||||||
// ignore: deprecated_member_use
|
// ignore: deprecated_member_use
|
||||||
import 'package:test_api/test_api.dart' as test_package;
|
import 'package:test_api/test_api.dart' as test_package;
|
||||||
|
|
||||||
|
|
||||||
import 'binding.dart';
|
import 'binding.dart';
|
||||||
import 'deprecated.dart';
|
|
||||||
|
|
||||||
/// Ensure the [WidgetsBinding] is initialized.
|
/// Ensure the [WidgetsBinding] is initialized.
|
||||||
WidgetsBinding ensureInitialized([@visibleForTesting Map<String, String>? environment]) {
|
WidgetsBinding ensureInitialized([@visibleForTesting Map<String, String>? environment]) {
|
||||||
|
@ -15,7 +15,8 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart' show TestWindow;
|
import 'package:flutter_test/flutter_test.dart' show TestWindow;
|
||||||
import 'package:stack_trace/stack_trace.dart' as stack_trace;
|
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 'package:vector_math/vector_math_64.dart';
|
||||||
|
|
||||||
import '_binding_io.dart' if (dart.library.html) '_binding_web.dart' as binding;
|
import '_binding_io.dart' if (dart.library.html) '_binding_web.dart' as binding;
|
||||||
@ -24,7 +25,6 @@ import 'platform.dart';
|
|||||||
import 'restoration.dart';
|
import 'restoration.dart';
|
||||||
import 'stack_manipulation.dart';
|
import 'stack_manipulation.dart';
|
||||||
import 'test_async_utils.dart';
|
import 'test_async_utils.dart';
|
||||||
import 'test_default_binary_messenger.dart';
|
|
||||||
import 'test_exception_reporter.dart';
|
import 'test_exception_reporter.dart';
|
||||||
import 'test_text_input.dart';
|
import 'test_text_input.dart';
|
||||||
|
|
||||||
@ -79,29 +79,74 @@ enum TestBindingEventSource {
|
|||||||
|
|
||||||
const Size _kDefaultTestViewportSize = Size(800.0, 600.0);
|
const Size _kDefaultTestViewportSize = Size(800.0, 600.0);
|
||||||
|
|
||||||
/// Overrides the [ServicesBinding]'s binary messenger logic to use
|
/// A [BinaryMessenger] subclass that is used as the default binary messenger
|
||||||
/// [TestDefaultBinaryMessenger].
|
/// under testing environment.
|
||||||
///
|
///
|
||||||
/// Test bindings that are used by tests that mock message handlers for plugins
|
/// It tracks status of data sent across the Flutter platform barrier, which is
|
||||||
/// should mix in this binding to enable the use of the
|
/// useful for testing frameworks to monitor and synchronize against the
|
||||||
/// [TestDefaultBinaryMessenger] APIs.
|
/// platform messages.
|
||||||
mixin TestDefaultBinaryMessengerBinding on BindingBase, ServicesBinding {
|
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
|
@override
|
||||||
void initInstances() {
|
Future<ByteData?>? send(String channel, ByteData? message) {
|
||||||
super.initInstances();
|
final Future<ByteData?>? resultFuture = delegate.send(channel, message);
|
||||||
_instance = this;
|
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.
|
/// Returns a Future that completes after all the platform calls are finished.
|
||||||
static TestDefaultBinaryMessengerBinding? get instance => _instance;
|
///
|
||||||
static TestDefaultBinaryMessengerBinding? _instance;
|
/// 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
|
@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
|
@override
|
||||||
TestDefaultBinaryMessenger createBinaryMessenger() {
|
void setMessageHandler(String channel, MessageHandler? handler) {
|
||||||
return TestDefaultBinaryMessenger(super.createBinaryMessenger());
|
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 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
|
|||||||
SemanticsBinding,
|
SemanticsBinding,
|
||||||
RendererBinding,
|
RendererBinding,
|
||||||
PaintingBinding,
|
PaintingBinding,
|
||||||
WidgetsBinding,
|
WidgetsBinding {
|
||||||
TestDefaultBinaryMessengerBinding {
|
|
||||||
|
|
||||||
/// Constructor for [TestWidgetsFlutterBinding].
|
/// Constructor for [TestWidgetsFlutterBinding].
|
||||||
///
|
///
|
||||||
@ -304,6 +348,11 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
|
|||||||
// doesn't get generated for tests.
|
// doesn't get generated for tests.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
BinaryMessenger createBinaryMessenger() {
|
||||||
|
return TestDefaultBinaryMessenger(super.createBinaryMessenger());
|
||||||
|
}
|
||||||
|
|
||||||
/// Whether there is currently a test executing.
|
/// Whether there is currently a test executing.
|
||||||
bool get inTest;
|
bool get inTest;
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,13 +2,10 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:async';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
import 'binding.dart';
|
|
||||||
import 'test_async_utils.dart';
|
import 'test_async_utils.dart';
|
||||||
|
|
||||||
// TODO(gspencergoog): Replace this with more robust key simulation code once
|
// TODO(gspencergoog): Replace this with more robust key simulation code once
|
||||||
@ -640,20 +637,21 @@ class KeyEventSimulator {
|
|||||||
assert(_osIsSupported(platform!), 'Platform $platform not supported for key simulation');
|
assert(_osIsSupported(platform!), 'Platform $platform not supported for key simulation');
|
||||||
|
|
||||||
final Map<String, dynamic> data = getKeyData(key, platform: platform!, isDown: true, physicalKey: physicalKey);
|
final Map<String, dynamic> data = getKeyData(key, platform: platform!, isDown: true, physicalKey: physicalKey);
|
||||||
final Completer<bool> result = Completer<bool>();
|
bool result = false;
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData? data) {
|
(ByteData? data) {
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
result.complete(false);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final Map<String, dynamic> decoded = SystemChannels.keyEvent.codec.decodeMessage(data) as Map<String, dynamic>;
|
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 @@ class KeyEventSimulator {
|
|||||||
|
|
||||||
final Map<String, dynamic> data = getKeyData(key, platform: platform!, isDown: false, physicalKey: physicalKey);
|
final Map<String, dynamic> data = getKeyData(key, platform: platform!, isDown: false, physicalKey: physicalKey);
|
||||||
bool result = false;
|
bool result = false;
|
||||||
await TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData? data) {
|
(ByteData? data) {
|
||||||
|
@ -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;
|
|
||||||
}
|
|
@ -8,10 +8,6 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.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;
|
export 'package:flutter/services.dart' show TextEditingValue, TextInputAction;
|
||||||
|
|
||||||
/// A testing stub for the system's onscreen keyboard.
|
/// A testing stub for the system's onscreen keyboard.
|
||||||
@ -49,6 +45,9 @@ class TestTextInput {
|
|||||||
/// first be requested, e.g. using [WidgetTester.showKeyboard].
|
/// first be requested, e.g. using [WidgetTester.showKeyboard].
|
||||||
final VoidCallback? onCleared;
|
final VoidCallback? onCleared;
|
||||||
|
|
||||||
|
/// The messenger which sends the bytes for this channel, not null.
|
||||||
|
BinaryMessenger get _binaryMessenger => ServicesBinding.instance!.defaultBinaryMessenger;
|
||||||
|
|
||||||
/// Log for method calls.
|
/// Log for method calls.
|
||||||
///
|
///
|
||||||
/// For all registered channels, handled calls are added to the list. Can
|
/// For all registered channels, handled calls are added to the list. Can
|
||||||
@ -154,25 +153,16 @@ class TestTextInput {
|
|||||||
_isVisible = false;
|
_isVisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Simulates the user changing the text of the focused text field, and resets
|
/// Simulates the user typing the given text.
|
||||||
/// the selection.
|
|
||||||
///
|
///
|
||||||
/// Calling this method replaces the content of the connected input field with
|
/// Calling this method replaces the content of the connected input field with
|
||||||
/// `text`, and places the caret at the end of the text.
|
/// `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.
|
/// 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
|
/// 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
|
/// 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.
|
/// 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) {
|
void enterText(String text) {
|
||||||
updateEditingValue(TextEditingValue(
|
updateEditingValue(TextEditingValue(
|
||||||
text: text,
|
text: text,
|
||||||
@ -182,21 +172,13 @@ class TestTextInput {
|
|||||||
|
|
||||||
/// Simulates the user changing the [TextEditingValue] to the given value.
|
/// 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.
|
/// 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
|
/// 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
|
/// 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.
|
/// 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) {
|
void updateEditingValue(TextEditingValue value) {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
_binaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.textInput.name,
|
SystemChannels.textInput.name,
|
||||||
SystemChannels.textInput.codec.encodeMethodCall(
|
SystemChannels.textInput.codec.encodeMethodCall(
|
||||||
MethodCall(
|
MethodCall(
|
||||||
@ -204,7 +186,7 @@ class TestTextInput {
|
|||||||
<dynamic>[_client ?? -1, value.toJSON()],
|
<dynamic>[_client ?? -1, value.toJSON()],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
(ByteData? data) { /* ignored */ },
|
(ByteData? data) { /* response from framework is discarded */ },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,7 +202,7 @@ class TestTextInput {
|
|||||||
Future<void> receiveAction(TextInputAction action) async {
|
Future<void> receiveAction(TextInputAction action) async {
|
||||||
return TestAsyncUtils.guard(() {
|
return TestAsyncUtils.guard(() {
|
||||||
final Completer<void> completer = Completer<void>();
|
final Completer<void> completer = Completer<void>();
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
_binaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.textInput.name,
|
SystemChannels.textInput.name,
|
||||||
SystemChannels.textInput.codec.encodeMethodCall(
|
SystemChannels.textInput.codec.encodeMethodCall(
|
||||||
MethodCall(
|
MethodCall(
|
||||||
@ -234,7 +216,8 @@ class TestTextInput {
|
|||||||
// Decoding throws a PlatformException if the data represents an
|
// Decoding throws a PlatformException if the data represents an
|
||||||
// error, and that's all we care about here.
|
// error, and that's all we care about here.
|
||||||
SystemChannels.textInput.codec.decodeEnvelope(data!);
|
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();
|
completer.complete();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// An exception occurred as a result of receiveAction()'ing. Report
|
// An exception occurred as a result of receiveAction()'ing. Report
|
||||||
@ -243,6 +226,7 @@ class TestTextInput {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return completer.future;
|
return completer.future;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -260,7 +244,7 @@ class TestTextInput {
|
|||||||
/// example when using the [integration_test] library, there is a risk that
|
/// 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.
|
/// the real IME will become confused as to the current state of input.
|
||||||
void closeConnection() {
|
void closeConnection() {
|
||||||
TestDefaultBinaryMessengerBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
|
_binaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.textInput.name,
|
SystemChannels.textInput.name,
|
||||||
SystemChannels.textInput.codec.encodeMethodCall(
|
SystemChannels.textInput.codec.encodeMethodCall(
|
||||||
MethodCall(
|
MethodCall(
|
||||||
|
@ -129,7 +129,7 @@ void testWidgets(
|
|||||||
dynamic tags,
|
dynamic tags,
|
||||||
}) {
|
}) {
|
||||||
assert(variant != null);
|
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 TestWidgetsFlutterBinding binding = TestWidgetsFlutterBinding.ensureInitialized() as TestWidgetsFlutterBinding;
|
||||||
final WidgetTester tester = WidgetTester._(binding);
|
final WidgetTester tester = WidgetTester._(binding);
|
||||||
for (final dynamic value in variant.values) {
|
for (final dynamic value in variant.values) {
|
||||||
@ -147,7 +147,7 @@ void testWidgets(
|
|||||||
test_package.addTearDown(binding.postTest);
|
test_package.addTearDown(binding.postTest);
|
||||||
return binding.runTest(
|
return binding.runTest(
|
||||||
() async {
|
() async {
|
||||||
binding.reset(); // TODO(ianh): the binding should just do this itself in _runTest
|
binding.reset();
|
||||||
debugResetSemanticsIdCounter();
|
debugResetSemanticsIdCounter();
|
||||||
Object? memento;
|
Object? memento;
|
||||||
try {
|
try {
|
||||||
@ -917,12 +917,10 @@ class WidgetTester extends WidgetController implements HitTestDispatcher, Ticker
|
|||||||
/// Acts as if the application went idle.
|
/// Acts as if the application went idle.
|
||||||
///
|
///
|
||||||
/// Runs all remaining microtasks, including those scheduled as a result of
|
/// Runs all remaining microtasks, including those scheduled as a result of
|
||||||
/// running them, until there are no more microtasks scheduled. Then, runs any
|
/// running them, until there are no more microtasks scheduled.
|
||||||
/// previously scheduled timers with zero time, and completes the returned future.
|
|
||||||
///
|
///
|
||||||
/// May result in an infinite loop or run out of memory if microtasks continue
|
/// Does not run timers. May result in an infinite loop or run out of memory
|
||||||
/// to recursively schedule new microtasks. Will not run any timers scheduled
|
/// if microtasks continue to recursively schedule new microtasks.
|
||||||
/// after this method was invoked, even if they are zero-time timers.
|
|
||||||
Future<void> idle() {
|
Future<void> idle() {
|
||||||
return TestAsyncUtils.guard<void>(() => binding.idle());
|
return TestAsyncUtils.guard<void>(() => binding.idle());
|
||||||
}
|
}
|
||||||
|
@ -379,16 +379,8 @@ class TestWindow implements ui.SingletonFlutterWindow {
|
|||||||
platformDispatcher.sendPlatformMessage(name, data, callback);
|
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
|
@override
|
||||||
ui.PlatformMessageCallback? get onPlatformMessage => platformDispatcher.onPlatformMessage;
|
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
|
@override
|
||||||
set onPlatformMessage(ui.PlatformMessageCallback? callback) {
|
set onPlatformMessage(ui.PlatformMessageCallback? callback) {
|
||||||
platformDispatcher.onPlatformMessage = callback;
|
platformDispatcher.onPlatformMessage = callback;
|
||||||
|
@ -20,6 +20,12 @@ class TestDelegate extends BinaryMessenger {
|
|||||||
Future<void> handlePlatformMessage(String channel, ByteData? data, ui.PlatformMessageResponseCallback? callback) => throw UnimplementedError();
|
Future<void> handlePlatformMessage(String channel, ByteData? data, ui.PlatformMessageResponseCallback? callback) => throw UnimplementedError();
|
||||||
@override
|
@override
|
||||||
void setMessageHandler(String channel, MessageHandler? handler) => throw UnimplementedError();
|
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() {
|
void main() {
|
||||||
|
@ -61,7 +61,7 @@ class Registrar extends BinaryMessenger {
|
|||||||
/// the [dart:ui] library. That function is only available when
|
/// the [dart:ui] library. That function is only available when
|
||||||
/// compiling for the web.
|
/// compiling for the web.
|
||||||
void registerMessageHandler() {
|
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
|
// ignore: undefined_function
|
||||||
ui.webOnlySetPluginHandler(handleFrameworkMessage);
|
ui.webOnlySetPluginHandler(handleFrameworkMessage);
|
||||||
}
|
}
|
||||||
@ -141,7 +141,7 @@ class Registrar extends BinaryMessenger {
|
|||||||
@override
|
@override
|
||||||
Future<ByteData?> send(String channel, ByteData? message) {
|
Future<ByteData?> send(String channel, ByteData? message) {
|
||||||
final Completer<ByteData?> completer = Completer<ByteData?>();
|
final Completer<ByteData?> completer = Completer<ByteData?>();
|
||||||
ui.channelBuffers.push(channel, message, (ByteData? reply) {
|
ui.window.onPlatformMessage!(channel, message, (ByteData? reply) {
|
||||||
try {
|
try {
|
||||||
completer.complete(reply);
|
completer.complete(reply);
|
||||||
} catch (exception, stack) {
|
} catch (exception, stack) {
|
||||||
@ -163,6 +163,26 @@ class Registrar extends BinaryMessenger {
|
|||||||
else
|
else
|
||||||
_handlers[channel] = handler;
|
_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
|
/// This class was previously separate from [Registrar] but was merged into it
|
||||||
|
@ -71,5 +71,12 @@ void main() {
|
|||||||
ServicesBinding.instance!.defaultBinaryMessenger
|
ServicesBinding.instance!.defaultBinaryMessenger
|
||||||
.setMessageHandler('test_send', null);
|
.setMessageHandler('test_send', null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('throws when trying to set a mock handler', () {
|
||||||
|
expect(
|
||||||
|
() => pluginBinaryMessenger.setMockMessageHandler(
|
||||||
|
'test', (ByteData? data) async => ByteData(0)),
|
||||||
|
throwsFlutterError);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user