Unverified Commit 58287ace authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Convert services tests to NNBD (#62694)

This converts the packages/flutter/test/services directory to NNBD, now that the services package is converted.

I changed the signature of checkMessageHandler and checkMockMessageHandler on BinaryMessenger to take a nullable handler, since the tests wanted to check to make sure a handler wasn't set, and that functionality no longer works if the handler is non-nullable.
parent ddab09f5
......@@ -3,6 +3,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
set -e
# The tests to run on Firebase Test Lab.
# Currently, the test consists on building an Android App Bundle and ensuring
# that the app doesn't crash upon startup.
......@@ -26,8 +28,6 @@ devices=(
"model=griffin,version=24"
)
set -e
GIT_REVISION=$(git rev-parse HEAD)
DEVICE_FLAG=""
......@@ -35,6 +35,12 @@ for device in ${devices[*]}; do
DEVICE_FLAG+="--device $device "
done
# If running tests locally, the key env var needs to be set.
if [[ -z $GCLOUD_FIREBASE_TESTLAB_KEY ]]; then
echo "Not running firebase test lab tests because GCLOUD_FIREBASE_TESTLAB_KEY isn't set."
exit 0
fi
# New contributors will not have permissions to run this test - they won't be
# able to access the service account information. We should just mark the test
# as passed - it will run fine on post submit, where it will still catch
......
......@@ -48,6 +48,9 @@ abstract class BinaryMessenger {
///
/// 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
......@@ -69,6 +72,9 @@ abstract class BinaryMessenger {
/// 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);
}
......
......@@ -389,6 +389,9 @@ class MethodChannel {
///
/// 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.
......@@ -422,6 +425,9 @@ class MethodChannel {
///
/// 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> handler(MethodCall call)) async {
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:convert';
import 'dart:typed_data';
......@@ -41,7 +39,7 @@ void main() {
expect(bundle.loadCallCount['one'], 1);
Object loadException;
late Object loadException;
try {
await bundle.loadString('foo');
} catch (e) {
......@@ -61,7 +59,7 @@ void main() {
test('NetworkAssetBundle control test', () async {
final Uri uri = Uri.http('example.org', '/path');
final NetworkAssetBundle bundle = NetworkAssetBundle(uri);
FlutterError error;
late FlutterError error;
try {
await bundle.load('key');
} on FlutterError catch (e) {
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:convert' show utf8;
import 'package:flutter/services.dart';
......@@ -13,13 +11,12 @@ void main() {
TestWidgetsFlutterBinding.ensureInitialized();
group('TextInput message channels', () {
FakeTextChannel fakeTextChannel;
FakeAutofillScope scope;
late FakeTextChannel fakeTextChannel;
final FakeAutofillScope scope = FakeAutofillScope();
setUp(() {
fakeTextChannel = FakeTextChannel((MethodCall call) async {});
TextInput.setChannel(fakeTextChannel);
scope ??= FakeAutofillScope();
scope.clients.clear();
});
......@@ -28,35 +25,8 @@ void main() {
TextInput.setChannel(SystemChannels.textInput);
});
test('mandatory fields are mandatory', () async {
AutofillConfiguration config;
try {
config = AutofillConfiguration(
uniqueIdentifier: null,
autofillHints: const <String>['test'],
currentEditingValue: const TextEditingValue(),
);
} catch (e) {
expect(e.toString(), contains('uniqueIdentifier != null'));
}
expect(config, isNull);
try {
config = AutofillConfiguration(
uniqueIdentifier: 'id',
autofillHints: null,
currentEditingValue: const TextEditingValue(),
);
} catch (e) {
expect(e.toString(), contains('autofillHints != null'));
}
expect(config, isNull);
});
test('throws if the hint list is empty', () async {
Map<String, dynamic> json;
Map<String, dynamic>? json;
try {
const AutofillConfiguration config = AutofillConfiguration(
uniqueIdentifier: 'id',
......@@ -113,7 +83,7 @@ void main() {
]);
const TextEditingValue text2 = TextEditingValue(text: 'Text 2');
fakeTextChannel.incoming(MethodCall(
fakeTextChannel.incoming?.call(MethodCall(
'TextInputClient.updateEditingStateWithTag',
<dynamic>[0, <String, dynamic>{ client2.autofillId : text2.toJSON() }],
));
......@@ -130,7 +100,7 @@ class FakeAutofillClient implements TextInputClient, AutofillClient {
String get autofillId => hashCode.toString();
@override
TextInputConfiguration textInputConfiguration;
late TextInputConfiguration textInputConfiguration;
@override
void updateEditingValue(TextEditingValue newEditingValue) {
......@@ -139,7 +109,7 @@ class FakeAutofillClient implements TextInputClient, AutofillClient {
}
@override
AutofillScope currentAutofillScope;
AutofillScope? currentAutofillScope;
String latestMethodCall = '';
......@@ -179,7 +149,7 @@ class FakeAutofillScope with AutofillScopeMixin implements AutofillScope {
Iterable<AutofillClient> get autofillClients => clients.values;
@override
AutofillClient getAutofillClient(String autofillId) => clients[autofillId];
AutofillClient getAutofillClient(String autofillId) => clients[autofillId]!;
void register(AutofillClient client) {
clients.putIfAbsent(client.autofillId, () => client);
......@@ -190,7 +160,7 @@ class FakeTextChannel implements MethodChannel {
FakeTextChannel(this.outgoing) : assert(outgoing != null);
Future<dynamic> Function(MethodCall) outgoing;
Future<void> Function(MethodCall) incoming;
Future<void> Function(MethodCall)? incoming;
List<MethodCall> outgoingCalls = <MethodCall>[];
......@@ -217,18 +187,18 @@ class FakeTextChannel implements MethodChannel {
String get name => 'flutter/textinput';
@override
void setMethodCallHandler(Future<void> Function(MethodCall call) handler) {
void setMethodCallHandler(Future<void> Function(MethodCall call)? handler) {
incoming = handler;
}
@override
bool checkMethodCallHandler(Future<void> Function(MethodCall call) handler) => throw UnimplementedError();
bool checkMethodCallHandler(Future<void> Function(MethodCall call)? handler) => throw UnimplementedError();
@override
void setMockMethodCallHandler(Future<void> Function(MethodCall call) handler) => throw UnimplementedError();
void setMockMethodCallHandler(Future<void> Function(MethodCall call)? handler) => throw UnimplementedError();
@override
bool checkMockMethodCallHandler(Future<void> Function(MethodCall call) handler) => throw UnimplementedError();
bool checkMockMethodCallHandler(Future<void> Function(MethodCall call)? handler) => throw UnimplementedError();
void validateOutgoingMethodCalls(List<MethodCall> calls) {
expect(outgoingCalls.length, calls.length);
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
......@@ -45,7 +43,7 @@ class TestBinding extends BindingBase with SchedulerBinding, ServicesBinding {
@override
BinaryMessenger createBinaryMessenger() {
return super.createBinaryMessenger()
..setMockMessageHandler('flutter/assets', (ByteData message) async {
..setMockMessageHandler('flutter/assets', (ByteData? message) async {
if (const StringCodec().decodeMessage(message) == 'NOTICES') {
return const StringCodec().encodeMessage(licenses);
}
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// TODO(yjbanov): enable Web when https://github.com/flutter/engine/pull/12747 rolls into the framework.
@TestOn('!chrome')
......@@ -35,15 +33,15 @@ void main() {
final TestChannelBuffersFlutterBinding binding = TestChannelBuffersFlutterBinding();
expect(binding.defaultBinaryMessenger, isNotNull);
bool didCallCallback = false;
final ui.PlatformMessageResponseCallback callback = (ByteData responseData) {
final ui.PlatformMessageResponseCallback callback = (ByteData? responseData) {
didCallCallback = true;
};
const String payload = 'bar';
final ByteData data = _makeByteData(payload);
ui.channelBuffers.push(channel, data, callback);
bool didDrainData = false;
binding.defaultBinaryMessenger.setMessageHandler(channel, (ByteData message) async {
expect(_getString(message), payload);
binding.defaultBinaryMessenger.setMessageHandler(channel, (ByteData? message) async {
expect(_getString(message!), payload);
didDrainData = true;
return null;
});
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:convert';
import 'dart:typed_data';
import 'dart:ui' as ui;
......@@ -23,22 +21,21 @@ void main() {
test('default binary messenger calls callback once', () async {
int count = 0;
const String channel = 'foo';
ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
channel, _makeByteData('bar'), (ByteData message) async {
ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
channel, _makeByteData('bar'), (ByteData? message) async {
count += 1;
});
expect(count, equals(0));
await ui.channelBuffers.drain(channel,
(ByteData data, ui.PlatformMessageResponseCallback callback) {
(ByteData? data, ui.PlatformMessageResponseCallback callback) async {
callback(null);
return null;
});
expect(count, equals(1));
});
test('can check the handler', () {
Future<ByteData> handler(ByteData call) => Future<ByteData>.value(null);
final BinaryMessenger messenger = ServicesBinding.instance.defaultBinaryMessenger;
Future<ByteData> handler(ByteData? call) => Future<ByteData>.value(null);
final BinaryMessenger messenger = ServicesBinding.instance!.defaultBinaryMessenger;
expect(messenger.checkMessageHandler('test_channel', null), true);
expect(messenger.checkMessageHandler('test_channel', handler), false);
......@@ -48,8 +45,8 @@ void main() {
});
test('can check the mock handler', () {
Future<ByteData> handler(ByteData call) => Future<ByteData>.value(null);
final BinaryMessenger messenger = ServicesBinding.instance.defaultBinaryMessenger;
Future<ByteData> handler(ByteData? call) => Future<ByteData>.value(null);
final BinaryMessenger messenger = ServicesBinding.instance!.defaultBinaryMessenger;
expect(messenger.checkMockMessageHandler('test_channel', null), true);
expect(messenger.checkMockMessageHandler('test_channel', handler), false);
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:async';
import 'dart:typed_data';
......@@ -14,10 +12,7 @@ import 'package:flutter/widgets.dart';
/// Used in internal testing.
class FakePlatformViewController extends PlatformViewController {
FakePlatformViewController(int id) {
_id = id;
}
FakePlatformViewController(this.viewId);
bool disposed = false;
bool focusCleared = false;
......@@ -25,10 +20,8 @@ class FakePlatformViewController extends PlatformViewController {
/// Events that are dispatched.
List<PointerEvent> dispatchedPointerEvents = <PointerEvent>[];
int _id;
@override
int get viewId => _id;
final int viewId;
@override
Future<void> dispatchPointerEvent(PointerEvent event) async {
......@@ -66,7 +59,7 @@ class FakeAndroidViewController implements AndroidViewController {
final int viewId;
@override
Offset Function(Offset position) pointTransformer;
Offset Function(Offset position)? pointTransformer;
@override
Future<void> dispatchPointerEvent(PointerEvent event) async {
......@@ -98,7 +91,7 @@ class FakeAndroidViewController implements AndroidViewController {
int get textureId => throw UnimplementedError();
@override
bool isCreated;
bool get isCreated => throw UnimplementedError();
@override
void addOnPlatformViewCreatedListener(PlatformViewCreatedCallback listener) =>
......@@ -133,7 +126,6 @@ class FakeAndroidPlatformViewsController {
SystemChannels.platform_views.setMockMethodCallHandler(_onMethodCall);
}
Iterable<FakeAndroidPlatformView> get views => _views.values;
final Map<int, FakeAndroidPlatformView> _views = <int, FakeAndroidPlatformView>{};
......@@ -143,11 +135,11 @@ class FakeAndroidPlatformViewsController {
int _textureCounter = 0;
Completer<void> resizeCompleter;
Completer<void>? resizeCompleter;
Completer<void> createCompleter;
Completer<void>? createCompleter;
int lastClearedFocusViewId;
int? lastClearedFocusViewId;
void registerViewType(String viewType) {
_registeredViewTypes.add(viewType);
......@@ -156,7 +148,8 @@ class FakeAndroidPlatformViewsController {
void invokeViewFocused(int viewId) {
final MethodCodec codec = SystemChannels.platform_views.codec;
final ByteData data = codec.encodeMethodCall(MethodCall('viewFocused', viewId));
ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(SystemChannels.platform_views.name, data, (ByteData data) {});
ServicesBinding.instance!.defaultBinaryMessenger
.handlePlatformMessage(SystemChannels.platform_views.name, data, (ByteData? data) {});
}
Future<dynamic> _onMethodCall(MethodCall call) {
......@@ -200,7 +193,7 @@ class FakeAndroidPlatformViewsController {
);
if (createCompleter != null) {
await createCompleter.future;
await createCompleter!.future;
}
_views[id] = FakeAndroidPlatformView(id, viewType,
......@@ -219,9 +212,9 @@ class FakeAndroidPlatformViewsController {
final int id = call.arguments['id'] as int;
final bool hybrid = call.arguments['hybrid'] as bool;
if (hybrid && !_views[id].hybrid) {
if (hybrid && !_views[id]!.hybrid!) {
throw ArgumentError('An $AndroidViewController using hybrid composition must pass `hybrid: true`');
} else if (!hybrid && _views[id].hybrid != null && _views[id].hybrid) {
} else if (!hybrid && (_views[id]!.hybrid ?? false)) {
throw ArgumentError('An $AndroidViewController not using hybrid composition must pass `hybrid: false`');
}
......@@ -248,9 +241,9 @@ class FakeAndroidPlatformViewsController {
);
if (resizeCompleter != null) {
await resizeCompleter.future;
await resizeCompleter!.future;
}
_views[id] = _views[id].copyWith(size: Size(width, height));
_views[id] = _views[id]!.copyWith(size: Size(width, height));
return Future<dynamic>.sync(() => null);
}
......@@ -273,7 +266,7 @@ class FakeAndroidPlatformViewsController {
if (!motionEvents.containsKey(id))
motionEvents[id] = <FakeAndroidMotionEvent> [];
motionEvents[id].add(FakeAndroidMotionEvent(action, pointerIds, pointerOffsets));
motionEvents[id]!.add(FakeAndroidMotionEvent(action, pointerIds, pointerOffsets));
return Future<dynamic>.sync(() => null);
}
......@@ -288,7 +281,7 @@ class FakeAndroidPlatformViewsController {
message: 'Trying to resize a platform view with unknown id: $id',
);
_views[id] = _views[id].copyWith(layoutDirection: layoutDirection);
_views[id] = _views[id]!.copyWith(layoutDirection: layoutDirection);
return Future<dynamic>.sync(() => null);
}
......@@ -312,7 +305,6 @@ class FakeIosPlatformViewsController {
SystemChannels.platform_views.setMockMethodCallHandler(_onMethodCall);
}
Iterable<FakeUiKitView> get views => _views.values;
final Map<int, FakeUiKitView> _views = <int, FakeUiKitView>{};
......@@ -320,7 +312,7 @@ class FakeIosPlatformViewsController {
// When this completer is non null, the 'create' method channel call will be
// delayed until it completes.
Completer<void> creationDelay;
Completer<void>? creationDelay;
// Maps a view id to the number of gestures it accepted so far.
final Map<int, int> gesturesAccepted = <int, int>{};
......@@ -348,7 +340,7 @@ class FakeIosPlatformViewsController {
Future<dynamic> _create(MethodCall call) async {
if (creationDelay != null)
await creationDelay.future;
await creationDelay!.future;
final Map<dynamic, dynamic> args = call.arguments as Map<dynamic, dynamic>;
final int id = args['id'] as int;
final String viewType = args['viewType'] as String;
......@@ -371,21 +363,21 @@ class FakeIosPlatformViewsController {
_views[id] = FakeUiKitView(id, viewType, creationParams);
gesturesAccepted[id] = 0;
gesturesRejected[id] = 0;
return Future<int>.sync(() => null);
return Future<int?>.sync(() => null);
}
Future<dynamic> _acceptGesture(MethodCall call) async {
final Map<dynamic, dynamic> args = call.arguments as Map<dynamic, dynamic>;
final int id = args['id'] as int;
gesturesAccepted[id] += 1;
return Future<int>.sync(() => null);
gesturesAccepted[id] = gesturesAccepted[id]! + 1;
return Future<int?>.sync(() => null);
}
Future<dynamic> _rejectGesture(MethodCall call) async {
final Map<dynamic, dynamic> args = call.arguments as Map<dynamic, dynamic>;
final int id = args['id'] as int;
gesturesRejected[id] += 1;
return Future<int>.sync(() => null);
gesturesRejected[id] = gesturesRejected[id]! + 1;
return Future<int?>.sync(() => null);
}
Future<dynamic> _dispose(MethodCall call) {
......@@ -413,9 +405,9 @@ class FakeHtmlPlatformViewsController {
final Set<String> _registeredViewTypes = <String>{};
Completer<void> resizeCompleter;
late Completer<void> resizeCompleter;
Completer<void> createCompleter;
Completer<void>? createCompleter;
void registerViewType(String viewType) {
_registeredViewTypes.add(viewType);
......@@ -449,11 +441,11 @@ class FakeHtmlPlatformViewsController {
);
if (createCompleter != null) {
await createCompleter.future;
await createCompleter!.future;
}
_views[id] = FakeHtmlPlatformView(id, viewType);
return Future<int>.sync(() => null);
return Future<int?>.sync(() => null);
}
Future<dynamic> _dispose(MethodCall call) {
......@@ -476,12 +468,12 @@ class FakeAndroidPlatformView {
final int id;
final String type;
final Uint8List creationParams;
final Size size;
final Uint8List? creationParams;
final Size? size;
final int layoutDirection;
final bool hybrid;
final bool? hybrid;
FakeAndroidPlatformView copyWith({Size size, int layoutDirection}) => FakeAndroidPlatformView(
FakeAndroidPlatformView copyWith({Size? size, int? layoutDirection}) => FakeAndroidPlatformView(
id,
type,
size ?? this.size,
......@@ -544,7 +536,7 @@ class FakeUiKitView {
final int id;
final String type;
final Uint8List creationParams;
final Uint8List? creationParams;
@override
bool operator ==(Object other) {
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:typed_data';
import 'package:flutter/services.dart';
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/services.dart';
......@@ -11,7 +9,7 @@ void main() {
testWidgets('initialLifecycleState is used to init state paused', (WidgetTester tester) async {
// The lifecycleState is null initially in tests as there is no
// initialLifecycleState.
expect(ServicesBinding.instance.lifecycleState, equals(null));
expect(ServicesBinding.instance!.lifecycleState, equals(null));
// Mock the Window to provide paused as the AppLifecycleState
final TestWidgetsFlutterBinding binding = tester.binding;
// Use paused as the initial state.
......@@ -20,6 +18,6 @@ void main() {
// The lifecycleState should now be the state we passed above,
// even though no lifecycle event was fired from the platform.
expect(ServicesBinding.instance.lifecycleState.toString(), equals('AppLifecycleState.paused'));
expect(ServicesBinding.instance!.lifecycleState.toString(), equals('AppLifecycleState.paused'));
});
}
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// This files contains message codec tests that are supported both on the Web
// and in the VM. For VM-only tests see message_codecs_vm_test.dart.
......@@ -18,26 +16,25 @@ import 'message_codecs_testing.dart';
void main() {
group('Binary codec', () {
const MessageCodec<ByteData> binary = BinaryCodec();
const MessageCodec<ByteData?> binary = BinaryCodec();
test('should encode and decode simple messages', () {
checkEncodeDecode<ByteData>(binary, null);
checkEncodeDecode<ByteData>(binary, ByteData(0));
checkEncodeDecode<ByteData>(binary, ByteData(4)..setInt32(0, -7));
checkEncodeDecode<ByteData?>(binary, null);
checkEncodeDecode<ByteData?>(binary, ByteData(0));
checkEncodeDecode<ByteData?>(binary, ByteData(4)..setInt32(0, -7));
});
});
group('String codec', () {
const MessageCodec<String> string = StringCodec();
const MessageCodec<String?> string = StringCodec();
test('should encode and decode simple messages', () {
checkEncodeDecode<String>(string, null);
checkEncodeDecode<String>(string, '');
checkEncodeDecode<String>(string, 'hello');
checkEncodeDecode<String>(string, 'special chars >\u263A\u{1F602}<');
checkEncodeDecode<String?>(string, null);
checkEncodeDecode<String?>(string, '');
checkEncodeDecode<String?>(string, 'hello');
checkEncodeDecode<String?>(string, 'special chars >\u263A\u{1F602}<');
});
test('ByteData with offset', () {
const MessageCodec<String> string = StringCodec();
final ByteData helloWorldByteData = string.encodeMessage('hello world');
final ByteData helloByteData = string.encodeMessage('hello');
const MessageCodec<String?> string = StringCodec();
final ByteData helloWorldByteData = string.encodeMessage('hello world')!;
final ByteData helloByteData = string.encodeMessage('hello')!;
final ByteData offsetByteData = ByteData.view(
helloWorldByteData.buffer,
helloByteData.lengthInBytes,
......@@ -97,7 +94,7 @@ void main() {
e.details == 'errorDetails')));
});
test('should decode error envelope with native stacktrace.', () {
final ByteData errorData = stringCodec.encodeMessage(json
final ByteData? errorData = stringCodec.encodeMessage(json
.encode(<dynamic>[
'errorCode',
'errorMessage',
......@@ -105,7 +102,7 @@ void main() {
'errorStacktrace'
]));
expect(
() => jsonMethodCodec.decodeEnvelope(errorData),
() => jsonMethodCodec.decodeEnvelope(errorData!),
throwsA(predicate((PlatformException e) =>
e is PlatformException && e.stacktrace == 'errorStacktrace')));
});
......
......@@ -23,9 +23,9 @@ void checkEncodeDecode<T>(MessageCodec<T> codec, T message) {
expect(decoded, isNull);
} else {
expect(deepEquals(message, decoded), isTrue);
final ByteData encodedAgain = codec.encodeMessage(decoded)!;
final ByteData? encodedAgain = codec.encodeMessage(decoded);
expect(
encodedAgain.buffer.asUint8List(),
encodedAgain!.buffer.asUint8List(),
orderedEquals(encoded!.buffer.asUint8List()),
);
}
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// This file contains tests that are only supported by the Dart VM. For
// example, on the Web there's no way to express large integers.
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:typed_data';
import 'package:flutter/services.dart';
......@@ -15,24 +13,24 @@ void main() {
TestWidgetsFlutterBinding.ensureInitialized();
group('BasicMessageChannel', () {
const MessageCodec<String> string = StringCodec();
const BasicMessageChannel<String> channel = BasicMessageChannel<String>('ch', string);
const MessageCodec<String?> string = StringCodec();
const BasicMessageChannel<String?> channel = BasicMessageChannel<String?>('ch', string);
test('can send string message and get reply', () async {
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch',
(ByteData message) async => string.encodeMessage(string.decodeMessage(message) + ' world'),
(ByteData? message) async => string.encodeMessage(string.decodeMessage(message)! + ' world'),
);
final String reply = await channel.send('hello');
final String? reply = await channel.send('hello');
expect(reply, equals('hello world'));
});
test('can receive string message and send reply', () async {
channel.setMessageHandler((String message) async => message + ' world');
String reply;
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
channel.setMessageHandler((String? message) async => message! + ' world');
String? reply;
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
'ch',
const StringCodec().encodeMessage('hello'),
(ByteData replyBinary) {
(ByteData? replyBinary) {
reply = string.decodeMessage(replyBinary);
},
);
......@@ -46,9 +44,9 @@ void main() {
const MethodChannel channel = MethodChannel('ch7', jsonMethod);
const OptionalMethodChannel optionalMethodChannel = OptionalMethodChannel('ch8', jsonMethod);
test('can invoke method and get result', () async {
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch7',
(ByteData message) async {
(ByteData? message) async {
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
if (methodCall['method'] == 'sayHello') {
return jsonMessage.encodeMessage(<dynamic>['${methodCall['args']} world']);
......@@ -57,14 +55,14 @@ void main() {
}
},
);
final String result = await channel.invokeMethod('sayHello', 'hello');
final String? result = await channel.invokeMethod('sayHello', 'hello');
expect(result, equals('hello world'));
});
test('can invoke list method and get result', () async {
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch7',
(ByteData message) async {
(ByteData? message) async {
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
if (methodCall['method'] == 'sayHello') {
return jsonMessage.encodeMessage(<dynamic>[<String>['${methodCall['args']}', 'world']]);
......@@ -78,9 +76,9 @@ void main() {
});
test('can invoke list method and get null result', () async {
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch7',
(ByteData message) async {
(ByteData? message) async {
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
if (methodCall['method'] == 'sayHello') {
return jsonMessage.encodeMessage(<dynamic>[null]);
......@@ -93,9 +91,9 @@ void main() {
});
test('can invoke map method and get result', () async {
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch7',
(ByteData message) async {
(ByteData? message) async {
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
if (methodCall['method'] == 'sayHello') {
return jsonMessage.encodeMessage(<dynamic>[<String, String>{'${methodCall['args']}': 'world'}]);
......@@ -109,9 +107,9 @@ void main() {
});
test('can invoke map method and get null result', () async {
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch7',
(ByteData message) async {
(ByteData? message) async {
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
if (methodCall['method'] == 'sayHello') {
return jsonMessage.encodeMessage(<dynamic>[null]);
......@@ -124,9 +122,9 @@ void main() {
});
test('can invoke method and get error', () async {
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch7',
(ByteData message) async {
(ByteData? message) async {
return jsonMessage.encodeMessage(<dynamic>[
'bad',
'Something happened',
......@@ -147,9 +145,9 @@ void main() {
});
test('can invoke unimplemented method', () async {
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch7',
(ByteData message) async => null,
(ByteData? message) async => null,
);
try {
await channel.invokeMethod<void>('sayHello', 'hello');
......@@ -163,19 +161,19 @@ void main() {
});
test('can invoke unimplemented method (optional)', () async {
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch8',
(ByteData message) async => null,
(ByteData? message) async => null,
);
final String result = await optionalMethodChannel.invokeMethod<String>('sayHello', 'hello');
final String? result = await optionalMethodChannel.invokeMethod<String>('sayHello', 'hello');
expect(result, isNull);
});
test('can handle method call with no registered plugin (setting before)', () async {
channel.setMethodCallHandler(null);
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
ByteData envelope;
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
ByteData? envelope;
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
envelope = result;
});
await null; // just in case there's something async happening
......@@ -184,8 +182,8 @@ void main() {
test('can handle method call with no registered plugin (setting after)', () async {
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
ByteData envelope;
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
ByteData? envelope;
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
envelope = result;
});
channel.setMethodCallHandler(null);
......@@ -198,8 +196,8 @@ void main() {
throw MissingPluginException();
});
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
ByteData envelope;
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
ByteData? envelope;
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
envelope = result;
});
expect(envelope, isNull);
......@@ -208,11 +206,11 @@ void main() {
test('can handle method call with successful result', () async {
channel.setMethodCallHandler((MethodCall call) async => '${call.arguments}, world');
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
ByteData envelope;
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
ByteData? envelope;
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
envelope = result;
});
expect(jsonMethod.decodeEnvelope(envelope), equals('hello, world'));
expect(jsonMethod.decodeEnvelope(envelope!), equals('hello, world'));
});
test('can handle method call with expressive error result', () async {
......@@ -220,12 +218,12 @@ void main() {
throw PlatformException(code: 'bad', message: 'sayHello failed', details: null);
});
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
ByteData envelope;
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
ByteData? envelope;
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
envelope = result;
});
try {
jsonMethod.decodeEnvelope(envelope);
jsonMethod.decodeEnvelope(envelope!);
fail('Exception expected');
} on PlatformException catch (e) {
expect(e.code, equals('bad'));
......@@ -240,12 +238,12 @@ void main() {
throw ArgumentError('bad');
});
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
ByteData envelope;
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
ByteData? envelope;
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData? result) {
envelope = result;
});
try {
jsonMethod.decodeEnvelope(envelope);
jsonMethod.decodeEnvelope(envelope!);
fail('Exception expected');
} on PlatformException catch (e) {
expect(e.code, equals('error'));
......@@ -280,18 +278,18 @@ void main() {
const MessageCodec<dynamic> jsonMessage = JSONMessageCodec();
const MethodCodec jsonMethod = JSONMethodCodec();
const EventChannel channel = EventChannel('ch', jsonMethod);
void emitEvent(ByteData event) {
ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
void emitEvent(ByteData? event) {
ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
'ch',
event,
(ByteData reply) { },
(ByteData? reply) {},
);
}
test('can receive event stream', () async {
bool canceled = false;
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch',
(ByteData message) async {
(ByteData? message) async {
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
if (methodCall['method'] == 'listen') {
final String argument = methodCall['args'] as String;
......@@ -314,9 +312,9 @@ void main() {
});
test('can receive error event', () async {
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(
'ch',
(ByteData message) async {
(ByteData? message) async {
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message) as Map<dynamic, dynamic>;
if (methodCall['method'] == 'listen') {
final String argument = methodCall['args'] as String;
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
@TestOn('!chrome') // missing web infrastructure for plugins.
......@@ -16,20 +15,20 @@ void main() {
// Initialize all bindings because defaultBinaryMessenger.send() needs a window.
TestWidgetsFlutterBinding.ensureInitialized();
final List<ByteData> log = <ByteData>[];
final List<ByteData?> log = <ByteData>[];
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler('test1', (ByteData message) async {
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('test1', (ByteData? message) async {
log.add(message);
return null;
});
final ByteData message = ByteData(2)..setUint16(0, 0xABCD);
await ServicesBinding.instance.defaultBinaryMessenger.send('test1', message);
await ServicesBinding.instance!.defaultBinaryMessenger.send('test1', message);
expect(log, equals(<ByteData>[message]));
log.clear();
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler('test1', null);
await ServicesBinding.instance.defaultBinaryMessenger.send('test1', message);
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('test1', null);
await ServicesBinding.instance!.defaultBinaryMessenger.send('test1', message);
expect(log, isEmpty);
});
}
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/painting.dart';
import 'package:flutter/services.dart';
......@@ -15,7 +14,7 @@ void main() {
TestWidgetsFlutterBinding.ensureInitialized();
group('Android', () {
FakeAndroidPlatformViewsController viewsController;
late FakeAndroidPlatformViewsController viewsController;
setUp(() {
viewsController = FakeAndroidPlatformViewsController();
});
......@@ -202,7 +201,7 @@ void main() {
});
group('iOS', () {
FakeIosPlatformViewsController viewsController;
late FakeIosPlatformViewsController viewsController;
setUp(() {
viewsController = FakeIosPlatformViewsController();
});
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
......@@ -209,10 +208,10 @@ void main() {
// when this event is received, but it's not in keysPressed yet.
data['modifiers'] |= RawKeyEventDataMacOs.modifierLeftShift | RawKeyEventDataMacOs.modifierShift;
// dispatch the modified data.
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData data) {},
(ByteData? data) {},
);
expect(
RawKeyboard.instance.keysPressed,
......@@ -234,10 +233,10 @@ void main() {
// when this event is received, but it's not in keysPressed yet.
data['modifiers'] |= RawKeyEventDataWindows.modifierLeftShift | RawKeyEventDataWindows.modifierShift;
// dispatch the modified data.
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData data) {},
(ByteData? data) {},
);
expect(
RawKeyboard.instance.keysPressed,
......@@ -259,10 +258,10 @@ void main() {
// when this event is received, but it's not in keysPressed yet.
data['metaState'] |= RawKeyEventDataAndroid.modifierLeftShift | RawKeyEventDataAndroid.modifierShift;
// dispatch the modified data.
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData data) {},
(ByteData? data) {},
);
expect(
RawKeyboard.instance.keysPressed,
......@@ -284,10 +283,10 @@ void main() {
// when this event is received, but it's not in keysPressed yet.
data['modifiers'] |= RawKeyEventDataFuchsia.modifierLeftShift;
// dispatch the modified data.
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData data) {},
(ByteData? data) {},
);
expect(
RawKeyboard.instance.keysPressed,
......@@ -309,10 +308,10 @@ void main() {
// when this event is received, but it's not in keysPressed yet.
data['modifiers'] |= GLFWKeyHelper.modifierShift;
// dispatch the modified data.
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData data) {},
(ByteData? data) {},
);
expect(
RawKeyboard.instance.keysPressed,
......@@ -343,10 +342,10 @@ void main() {
RawKeyEventDataAndroid.modifierControl |
RawKeyEventDataAndroid.modifierMeta;
// dispatch the modified data.
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData data) {},
(ByteData? data) {},
);
expect(
RawKeyboard.instance.keysPressed,
......@@ -381,10 +380,10 @@ void main() {
RawKeyEventDataMacOs.modifierCommand |
RawKeyEventDataMacOs.modifierControl;
// dispatch the modified data.
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData data) {},
(ByteData? data) {},
);
expect(
RawKeyboard.instance.keysPressed,
......@@ -419,10 +418,10 @@ void main() {
RawKeyEventDataWindows.modifierAlt |
RawKeyEventDataWindows.modifierControl;
// dispatch the modified data.
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData data) {},
(ByteData? data) {},
);
expect(
RawKeyboard.instance.keysPressed,
......@@ -456,10 +455,10 @@ void main() {
GLFWKeyHelper.modifierControl |
GLFWKeyHelper.modifierMeta;
// dispatch the modified data.
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData data) {},
(ByteData? data) {},
);
expect(
RawKeyboard.instance.keysPressed,
......@@ -480,13 +479,13 @@ void main() {
});
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;
FlutterErrorDetails? errorDetails;
final FlutterExceptionHandler? oldHandler = FlutterError.onError;
FlutterError.onError = (FlutterErrorDetails details) {
errorDetails = details;
};
try {
await ServicesBinding.instance.defaultBinaryMessenger
await ServicesBinding.instance!.defaultBinaryMessenger
.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(const <String, dynamic>{
......@@ -498,13 +497,13 @@ void main() {
'source': 0x101,
'deviceId': 1,
}),
(ByteData data) {},
(ByteData? data) {},
);
} finally {
FlutterError.onError = oldHandler;
}
expect(errorDetails, isNotNull);
expect(errorDetails.stack, 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'));
});
......@@ -542,16 +541,16 @@ void main() {
});
final RawKeyEventDataAndroid data = event.data as RawKeyEventDataAndroid;
for (final ModifierKey key in ModifierKey.values) {
if (modifierTests[modifier].key == key) {
if (modifierTests[modifier]!.key == key) {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isTrue,
reason: "$key should be pressed with metaState $modifier, but isn't.",
);
expect(data.getModifierSide(key), equals(modifierTests[modifier].side));
expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
} else {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isFalse,
reason: '$key should not be pressed with metaState $modifier.',
);
......@@ -578,21 +577,21 @@ void main() {
});
final RawKeyEventDataAndroid data = event.data as RawKeyEventDataAndroid;
for (final ModifierKey key in ModifierKey.values) {
if (modifierTests[modifier].key == key || key == ModifierKey.functionModifier) {
if (modifierTests[modifier]!.key == key || key == ModifierKey.functionModifier) {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isTrue,
reason: '$key should be pressed with metaState $modifier '
"and additional key ${RawKeyEventDataAndroid.modifierFunction}, but isn't.",
);
if (key != ModifierKey.functionModifier) {
expect(data.getModifierSide(key), equals(modifierTests[modifier].side));
expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
} else {
expect(data.getModifierSide(key), equals(KeyboardSide.all));
}
} else {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isFalse,
reason: '$key should not be pressed with metaState $modifier '
'and additional key ${RawKeyEventDataAndroid.modifierFunction}.',
......@@ -741,11 +740,11 @@ void main() {
platform: 'android',
isDown: true,
);
Map<String, dynamic> message;
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
Map<String, dynamic>? message;
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData data) {
(ByteData? data) {
message = SystemChannels.keyEvent.codec.decodeMessage(data) as Map<String, dynamic>;
},
);
......@@ -765,15 +764,15 @@ void main() {
focusNode.requestFocus();
await tester.pump();
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData data) {
(ByteData? data) {
message = SystemChannels.keyEvent.codec.decodeMessage(data) as Map<String, dynamic>;
},
);
expect(message, equals(<String, dynamic>{ 'handled': true }));
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(SystemChannels.keyEvent.name, null);
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(SystemChannels.keyEvent.name, null);
});
});
group('RawKeyEventDataFuchsia', () {
......@@ -804,15 +803,15 @@ void main() {
});
final RawKeyEventDataFuchsia data = event.data as RawKeyEventDataFuchsia;
for (final ModifierKey key in ModifierKey.values) {
if (modifierTests[modifier].key == key) {
if (modifierTests[modifier]!.key == key) {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isTrue,
reason: "$key should be pressed with metaState $modifier, but isn't.",
);
} else {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isFalse,
reason: '$key should not be pressed with metaState $modifier.',
);
......@@ -835,16 +834,16 @@ void main() {
});
final RawKeyEventDataFuchsia data = event.data as RawKeyEventDataFuchsia;
for (final ModifierKey key in ModifierKey.values) {
if (modifierTests[modifier].key == key || key == ModifierKey.capsLockModifier) {
if (modifierTests[modifier]!.key == key || key == ModifierKey.capsLockModifier) {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isTrue,
reason: '$key should be pressed with metaState $modifier '
"and additional key ${RawKeyEventDataFuchsia.modifierCapsLock}, but isn't.",
);
} else {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isFalse,
reason: '$key should not be pressed with metaState $modifier '
'and additional key ${RawKeyEventDataFuchsia.modifierCapsLock}.',
......@@ -920,16 +919,16 @@ void main() {
});
final RawKeyEventDataMacOs data = event.data as RawKeyEventDataMacOs;
for (final ModifierKey key in ModifierKey.values) {
if (modifierTests[modifier].key == key) {
if (modifierTests[modifier]!.key == key) {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isTrue,
reason: "$key should be pressed with metaState $modifier, but isn't.",
);
expect(data.getModifierSide(key), equals(modifierTests[modifier].side));
expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
} else {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isFalse,
reason: '$key should not be pressed with metaState $modifier.',
);
......@@ -954,21 +953,21 @@ void main() {
});
final RawKeyEventDataMacOs data = event.data as RawKeyEventDataMacOs;
for (final ModifierKey key in ModifierKey.values) {
if (modifierTests[modifier].key == key || key == ModifierKey.capsLockModifier) {
if (modifierTests[modifier]!.key == key || key == ModifierKey.capsLockModifier) {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isTrue,
reason: '$key should be pressed with metaState $modifier '
"and additional key ${RawKeyEventDataMacOs.modifierCapsLock}, but isn't.",
);
if (key != ModifierKey.capsLockModifier) {
expect(data.getModifierSide(key), equals(modifierTests[modifier].side));
expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
} else {
expect(data.getModifierSide(key), equals(KeyboardSide.all));
}
} else {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isFalse,
reason: '$key should not be pressed with metaState $modifier '
'and additional key ${RawKeyEventDataMacOs.modifierCapsLock}.',
......@@ -1068,16 +1067,16 @@ void main() {
});
final RawKeyEventDataWindows data = event.data as RawKeyEventDataWindows;
for (final ModifierKey key in ModifierKey.values) {
if (modifierTests[modifier].key == key) {
if (modifierTests[modifier]!.key == key) {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isTrue,
reason: "$key should be pressed with modifier $modifier, but isn't.",
);
expect(data.getModifierSide(key), equals(modifierTests[modifier].side));
expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
} else {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isFalse,
reason: '$key should not be pressed with metaState $modifier.',
);
......@@ -1101,21 +1100,21 @@ void main() {
});
final RawKeyEventDataWindows data = event.data as RawKeyEventDataWindows;
for (final ModifierKey key in ModifierKey.values) {
if (modifierTests[modifier].key == key || key == ModifierKey.capsLockModifier) {
if (modifierTests[modifier]!.key == key || key == ModifierKey.capsLockModifier) {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isTrue,
reason: '$key should be pressed with metaState $modifier '
"and additional key ${RawKeyEventDataWindows.modifierCaps}, but isn't.",
);
if (key != ModifierKey.capsLockModifier) {
expect(data.getModifierSide(key), equals(modifierTests[modifier].side));
expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
} else {
expect(data.getModifierSide(key), equals(KeyboardSide.all));
}
} else {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isFalse,
reason: '$key should not be pressed with metaState $modifier '
'and additional key ${RawKeyEventDataWindows.modifierCaps}.',
......@@ -1194,7 +1193,7 @@ void main() {
};
// How modifiers are interpreted depends upon the keyCode for GLFW.
int keyCodeForModifier(int modifier, {bool isLeft}) {
int keyCodeForModifier(int modifier, {required bool isLeft}) {
switch (modifier) {
case GLFWKeyHelper.modifierAlt:
return isLeft ? 342 : 346;
......@@ -1229,16 +1228,16 @@ void main() {
});
final RawKeyEventDataLinux data = event.data as RawKeyEventDataLinux;
for (final ModifierKey key in ModifierKey.values) {
if (modifierTests[modifier].key == key) {
if (modifierTests[modifier]!.key == key) {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isDown ? isTrue : isFalse,
reason: "${isLeft ? 'left' : 'right'} $key ${isDown ? 'should' : 'should not'} be pressed with metaState $modifier, when key is ${isDown ? 'down' : 'up'}, but isn't.",
);
expect(data.getModifierSide(key), equals(modifierTests[modifier].side));
expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
} else {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isFalse,
reason: "${isLeft ? 'left' : 'right'} $key should not be pressed with metaState $modifier, wwhen key is ${isDown ? 'down' : 'up'}, but is.",
);
......@@ -1265,21 +1264,21 @@ void main() {
});
final RawKeyEventDataLinux data = event.data as RawKeyEventDataLinux;
for (final ModifierKey key in ModifierKey.values) {
if (modifierTests[modifier].key == key || key == ModifierKey.controlModifier) {
if (modifierTests[modifier]!.key == key || key == ModifierKey.controlModifier) {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isTrue,
reason: '$key should be pressed with metaState $modifier '
"and additional key ${GLFWKeyHelper.modifierControl}, but isn't.",
);
if (key != ModifierKey.controlModifier) {
expect(data.getModifierSide(key), equals(modifierTests[modifier].side));
expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
} else {
expect(data.getModifierSide(key), equals(KeyboardSide.all));
}
} else {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isFalse,
reason: '$key should not be pressed with metaState $modifier '
'and additional key ${GLFWKeyHelper.modifierControl}.',
......@@ -1378,7 +1377,7 @@ void main() {
};
// How modifiers are interpreted depends upon the keyCode for GTK.
int keyCodeForModifier(int modifier, {bool isLeft}) {
int keyCodeForModifier(int modifier, {required bool isLeft}) {
switch (modifier) {
case GtkKeyHelper.modifierMod1:
return isLeft ? 65513 : 65513;
......@@ -1413,16 +1412,16 @@ void main() {
});
final RawKeyEventDataLinux data = event.data as RawKeyEventDataLinux;
for (final ModifierKey key in ModifierKey.values) {
if (modifierTests[modifier].key == key) {
if (modifierTests[modifier]!.key == key) {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isDown ? isTrue : isFalse,
reason: "${isLeft ? 'left' : 'right'} $key ${isDown ? 'should' : 'should not'} be pressed with metaState $modifier, when key is ${isDown ? 'down' : 'up'}, but isn't.",
);
expect(data.getModifierSide(key), equals(modifierTests[modifier].side));
expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
} else {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isFalse,
reason: "${isLeft ? 'left' : 'right'} $key should not be pressed with metaState $modifier, wwhen key is ${isDown ? 'down' : 'up'}, but is.",
);
......@@ -1449,21 +1448,21 @@ void main() {
});
final RawKeyEventDataLinux data = event.data as RawKeyEventDataLinux;
for (final ModifierKey key in ModifierKey.values) {
if (modifierTests[modifier].key == key || key == ModifierKey.controlModifier) {
if (modifierTests[modifier]!.key == key || key == ModifierKey.controlModifier) {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isTrue,
reason: '$key should be pressed with metaState $modifier '
"and additional key ${GtkKeyHelper.modifierControl}, but isn't.",
);
if (key != ModifierKey.controlModifier) {
expect(data.getModifierSide(key), equals(modifierTests[modifier].side));
expect(data.getModifierSide(key), equals(modifierTests[modifier]!.side));
} else {
expect(data.getModifierSide(key), equals(KeyboardSide.all));
}
} else {
expect(
data.isModifierPressed(key, side: modifierTests[modifier].side),
data.isModifierPressed(key, side: modifierTests[modifier]!.side),
isFalse,
reason: '$key should not be pressed with metaState $modifier '
'and additional key ${GtkKeyHelper.modifierControl}.',
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
......@@ -54,7 +53,7 @@ void main() {
expect(manager.updateScheduled, isFalse);
// Can store null.
bucket.write<bool>('value4', null);
bucket.write<bool?>('value4', null);
expect(manager.updateScheduled, isTrue);
expect(bucket.read<int>('value4'), null);
manager.doSerialization();
......@@ -111,7 +110,7 @@ void main() {
expect(manager.updateScheduled, isFalse);
// Can store null.
child.write<bool>('value4', null);
child.write<bool?>('value4', null);
expect(manager.updateScheduled, isTrue);
expect(child.read<int>('value4'), null);
manager.doSerialization();
......@@ -327,7 +326,7 @@ void main() {
final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);
final RestorationBucket child = root.claimChild('child1', debugOwner: 'owner1');
final Object rawChildData = rawData[childrenMapKey]['child1'];
final Object rawChildData = rawData[childrenMapKey]['child1'] as Object;
expect(rawChildData, isNotNull);
expect(manager.updateScheduled, isFalse);
......@@ -370,9 +369,9 @@ void main() {
final RestorationBucket child2 = root.claimChild('child2', debugOwner: 'owner1');
manager.doSerialization();
final Object rawChild1Data = rawData[childrenMapKey]['child1'];
final Object rawChild1Data = rawData[childrenMapKey]['child1'] as Object;
expect(rawChild1Data, isNotNull);
final Object rawChild2Data = rawData[childrenMapKey]['child2'];
final Object rawChild2Data = rawData[childrenMapKey]['child2'] as Object;
expect(rawChild2Data, isNotNull);
expect(child1.restorationId, 'child1');
......@@ -396,7 +395,7 @@ void main() {
final Map<String, dynamic> rawData = _createRawDataSet();
final RestorationBucket root = RestorationBucket.root(manager: manager, rawData: rawData);
final Object rawChild1Data = rawData[childrenMapKey]['child1'];
final Object rawChild1Data = rawData[childrenMapKey]['child1'] as Object;
expect(rawChild1Data, isNotNull);
final RestorationBucket child1 = root.claimChild('child1', debugOwner: 'owner1');
......@@ -462,7 +461,7 @@ void main() {
manager.doSerialization();
expect(manager.updateScheduled, isFalse);
final Object childOfChildData = rawData[childrenMapKey]['child1'][childrenMapKey]['childOfChild'];
final Object childOfChildData = rawData[childrenMapKey]['child1'][childrenMapKey]['childOfChild'] as Object;
expect(childOfChildData, isNotEmpty);
root.adoptChild(childOfChild);
......@@ -497,7 +496,7 @@ void main() {
final RestorationBucket childOfChild = child.claimChild('child1', debugOwner: 'owner2');
childOfChild.write<String>('foo', 'bar');
final Object childOfChildData = rawData[childrenMapKey]['child1'][childrenMapKey]['child1'];
final Object childOfChildData = rawData[childrenMapKey]['child1'][childrenMapKey]['child1'] as Object;
expect(childOfChildData, isNotEmpty);
expect(manager.updateScheduled, isTrue);
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:async';
import 'dart:typed_data';
......@@ -25,9 +24,9 @@ void main() {
});
final RestorationManager manager = RestorationManager();
final Future<RestorationBucket> rootBucketFuture = manager.rootBucket;
RestorationBucket rootBucket;
rootBucketFuture.then((RestorationBucket bucket) {
final Future<RestorationBucket?> rootBucketFuture = manager.rootBucket;
RestorationBucket? rootBucket;
rootBucketFuture.then((RestorationBucket? bucket) {
rootBucket = bucket;
});
expect(rootBucketFuture, isNotNull);
......@@ -48,14 +47,14 @@ void main() {
expect(rootBucket, isNotNull);
// Root bucket contains the expected data.
expect(rootBucket.read<int>('value1'), 10);
expect(rootBucket.read<String>('value2'), 'Hello');
final RestorationBucket child = rootBucket.claimChild('child1', debugOwner: null);
expect(rootBucket!.read<int>('value1'), 10);
expect(rootBucket!.read<String>('value2'), 'Hello');
final RestorationBucket child = rootBucket!.claimChild('child1', debugOwner: null);
expect(child.read<int>('another value'), 22);
// Accessing the root bucket again completes synchronously with same bucket.
RestorationBucket synchronousBucket;
manager.rootBucket.then((RestorationBucket bucket) {
RestorationBucket? synchronousBucket;
manager.rootBucket.then((RestorationBucket? bucket) {
synchronousBucket = bucket;
});
expect(synchronousBucket, isNotNull);
......@@ -65,16 +64,15 @@ void main() {
testWidgets('root bucket received from engine before retrieval', (WidgetTester tester) async {
SystemChannels.restoration.setMethodCallHandler(null);
final List<MethodCall> callsToEngine = <MethodCall>[];
SystemChannels.restoration.setMockMethodCallHandler((MethodCall call) {
SystemChannels.restoration.setMockMethodCallHandler((MethodCall call) async {
callsToEngine.add(call);
return null;
});
final RestorationManager manager = RestorationManager();
await _pushDataFromEngine(_createEncodedRestorationData1());
RestorationBucket rootBucket;
manager.rootBucket.then((RestorationBucket bucket) => rootBucket = bucket);
RestorationBucket? rootBucket;
manager.rootBucket.then((RestorationBucket? bucket) => rootBucket = bucket);
// Root bucket is available synchronously.
expect(rootBucket, isNotNull);
// Engine was never asked.
......@@ -91,24 +89,24 @@ void main() {
});
final RestorationManager manager = RestorationManager();
RestorationBucket rootBucket;
manager.rootBucket.then((RestorationBucket bucket) => rootBucket = bucket);
RestorationBucket? rootBucket;
manager.rootBucket.then((RestorationBucket? bucket) => rootBucket = bucket);
expect(rootBucket, isNull);
expect(callsToEngine.single.method, 'get');
await _pushDataFromEngine(_createEncodedRestorationData1());
expect(rootBucket, isNotNull);
expect(rootBucket.read<int>('value1'), 10);
expect(rootBucket!.read<int>('value1'), 10);
result.complete(_createEncodedRestorationData2());
await tester.pump();
RestorationBucket rootBucket2;
manager.rootBucket.then((RestorationBucket bucket) => rootBucket2 = bucket);
RestorationBucket? rootBucket2;
manager.rootBucket.then((RestorationBucket? bucket) => rootBucket2 = bucket);
expect(rootBucket2, isNotNull);
expect(rootBucket2, same(rootBucket));
expect(rootBucket2.read<int>('value1'), 10);
expect(rootBucket2.contains('foo'), isFalse);
expect(rootBucket2!.read<int>('value1'), 10);
expect(rootBucket2!.contains('foo'), isFalse);
});
testWidgets('root bucket is properly replaced when new data is available', (WidgetTester tester) async {
......@@ -116,21 +114,21 @@ void main() {
return _createEncodedRestorationData1();
});
final RestorationManager manager = RestorationManager();
RestorationBucket rootBucket;
manager.rootBucket.then((RestorationBucket bucket) {
RestorationBucket? rootBucket;
manager.rootBucket.then((RestorationBucket? bucket) {
rootBucket = bucket;
});
await tester.pump();
expect(rootBucket, isNotNull);
expect(rootBucket.read<int>('value1'), 10);
final RestorationBucket child = rootBucket.claimChild('child1', debugOwner: null);
expect(rootBucket!.read<int>('value1'), 10);
final RestorationBucket child = rootBucket!.claimChild('child1', debugOwner: null);
expect(child.read<int>('another value'), 22);
bool rootReplaced = false;
RestorationBucket newRoot;
RestorationBucket? newRoot;
manager.addListener(() {
rootReplaced = true;
manager.rootBucket.then((RestorationBucket bucket) {
manager.rootBucket.then((RestorationBucket? bucket) {
newRoot = bucket;
});
// The new bucket is available synchronously.
......@@ -145,9 +143,9 @@ void main() {
child.dispose();
expect(newRoot.read<int>('foo'), 33);
expect(newRoot.read<int>('value1'), null);
final RestorationBucket newChild = newRoot.claimChild('childFoo', debugOwner: null);
expect(newRoot!.read<int>('foo'), 33);
expect(newRoot!.read<int>('value1'), null);
final RestorationBucket newChild = newRoot!.claimChild('childFoo', debugOwner: null);
expect(newChild.read<String>('bar'), 'Hello');
});
......@@ -162,9 +160,9 @@ void main() {
final RestorationManager manager = RestorationManager()..addListener(() {
listenerCount++;
});
RestorationBucket rootBucket;
RestorationBucket? rootBucket;
bool rootBucketResolved = false;
manager.rootBucket.then((RestorationBucket bucket) {
manager.rootBucket.then((RestorationBucket? bucket) {
rootBucketResolved = true;
rootBucket = bucket;
});
......@@ -180,7 +178,7 @@ void main() {
// Switch to non-null.
await _pushDataFromEngine(_createEncodedRestorationData1());
expect(listenerCount, 1);
manager.rootBucket.then((RestorationBucket bucket) {
manager.rootBucket.then((RestorationBucket? bucket) {
rootBucket = bucket;
});
expect(rootBucket, isNotNull);
......@@ -188,7 +186,7 @@ void main() {
// Switch to null again.
await _pushDataFromEngine(_packageRestorationData(enabled: false));
expect(listenerCount, 2);
manager.rootBucket.then((RestorationBucket bucket) {
manager.rootBucket.then((RestorationBucket? bucket) {
rootBucket = bucket;
});
expect(rootBucket, isNull);
......@@ -203,9 +201,9 @@ void main() {
});
final RestorationManager manager = RestorationManager();
final Future<RestorationBucket> rootBucketFuture = manager.rootBucket;
RestorationBucket rootBucket;
rootBucketFuture.then((RestorationBucket bucket) {
final Future<RestorationBucket?> rootBucketFuture = manager.rootBucket;
RestorationBucket? rootBucket;
rootBucketFuture.then((RestorationBucket? bucket) {
rootBucket = bucket;
});
result.complete(_createEncodedRestorationData1());
......@@ -214,8 +212,8 @@ void main() {
callsToEngine.clear();
// Schedule a frame.
SchedulerBinding.instance.ensureVisualUpdate();
rootBucket.write('foo', 1);
SchedulerBinding.instance!.ensureVisualUpdate();
rootBucket!.write('foo', 1);
// flushData is no-op because frame is scheduled.
manager.flushData();
expect(callsToEngine, isEmpty);
......@@ -225,7 +223,7 @@ void main() {
callsToEngine.clear();
// flushData without frame sends data directly.
rootBucket.write('foo', 2);
rootBucket!.write('foo', 2);
manager.flushData();
expect(callsToEngine, hasLength(1));
});
......@@ -239,40 +237,40 @@ void main() {
final TestRestorationManager manager = TestRestorationManager();
expect(manager.isReplacing, isFalse);
RestorationBucket rootBucket;
manager.rootBucket.then((RestorationBucket bucket) {
RestorationBucket? rootBucket;
manager.rootBucket.then((RestorationBucket? bucket) {
rootBucket = bucket;
});
result.complete(_createEncodedRestorationData1());
await tester.idle();
expect(rootBucket, isNotNull);
expect(rootBucket.isReplacing, isFalse);
expect(rootBucket!.isReplacing, isFalse);
expect(manager.isReplacing, isFalse);
tester.binding.scheduleFrame();
await tester.pump();
expect(manager.isReplacing, isFalse);
expect(rootBucket.isReplacing, isFalse);
expect(rootBucket!.isReplacing, isFalse);
manager.receiveDataFromEngine(enabled: true, data: null);
RestorationBucket rootBucket2;
manager.rootBucket.then((RestorationBucket bucket) {
RestorationBucket? rootBucket2;
manager.rootBucket.then((RestorationBucket? bucket) {
rootBucket2 = bucket;
});
expect(rootBucket2, isNotNull);
expect(rootBucket2, isNot(same(rootBucket)));
expect(rootBucket2!, isNot(same(rootBucket)));
expect(manager.isReplacing, isTrue);
expect(rootBucket2.isReplacing, isTrue);
expect(rootBucket2!.isReplacing, isTrue);
await tester.idle();
expect(manager.isReplacing, isTrue);
expect(rootBucket2.isReplacing, isTrue);
expect(rootBucket2!.isReplacing, isTrue);
tester.binding.scheduleFrame();
await tester.pump();
expect(manager.isReplacing, isFalse);
expect(rootBucket2.isReplacing, isFalse);
expect(rootBucket2!.isReplacing, isFalse);
manager.receiveDataFromEngine(enabled: false, data: null);
RestorationBucket rootBucket3;
manager.rootBucket.then((RestorationBucket bucket) {
RestorationBucket? rootBucket3;
manager.rootBucket.then((RestorationBucket? bucket) {
rootBucket3 = bucket;
});
expect(rootBucket3, isNull);
......@@ -307,7 +305,7 @@ void main() {
}
Future<void> _pushDataFromEngine(Map<dynamic, dynamic> data) async {
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
'flutter/restoration',
const StandardMethodCodec().encodeMethodCall(MethodCall('push', data)),
(_) { },
......@@ -347,16 +345,16 @@ Map<dynamic, dynamic> _createEncodedRestorationData2() {
return _packageRestorationData(data: data);
}
Map<dynamic, dynamic> _packageRestorationData({bool enabled = true, Map<dynamic, dynamic> data}) {
final ByteData encoded = const StandardMessageCodec().encodeMessage(data);
Map<dynamic, dynamic> _packageRestorationData({bool enabled = true, Map<dynamic, dynamic>? data}) {
final ByteData? encoded = const StandardMessageCodec().encodeMessage(data);
return <dynamic, dynamic>{
'enabled': enabled,
'data': encoded == null ? null : encoded.buffer.asUint8List(encoded.offsetInBytes, encoded.lengthInBytes)
'data': encoded?.buffer.asUint8List(encoded.offsetInBytes, encoded.lengthInBytes),
};
}
class TestRestorationManager extends RestorationManager {
void receiveDataFromEngine({@required bool enabled, @required Uint8List data}) {
void receiveDataFromEngine({required bool enabled, required Uint8List? data}) {
handleRestorationUpdateFromEngine(enabled: enabled, data: data);
}
}
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:typed_data';
......@@ -61,11 +60,10 @@ void main() {
});
test('setApplicationSwitcherDescription missing plugin', () async {
final List<ByteData> log = <ByteData>[];
final List<ByteData?> log = <ByteData>[];
ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler('flutter/platform', (ByteData message) {
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler('flutter/platform', (ByteData? message) async {
log.add(message);
return null;
});
await SystemChrome.setApplicationSwitcherDescription(
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
......
......@@ -2,27 +2,25 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
TextEditingValue testOldValue;
TextEditingValue testNewValue;
TextEditingValue testOldValue = TextEditingValue.empty;
TextEditingValue testNewValue = TextEditingValue.empty;
test('withFunction wraps formatting function', () {
testOldValue = const TextEditingValue();
testNewValue = const TextEditingValue();
TextEditingValue calledOldValue;
TextEditingValue calledNewValue;
late TextEditingValue calledOldValue;
late TextEditingValue calledNewValue;
final TextInputFormatter formatterUnderTest = TextInputFormatter.withFunction(
(TextEditingValue oldValue, TextEditingValue newValue) {
calledOldValue = oldValue;
calledNewValue = newValue;
return null;
return TextEditingValue.empty;
}
);
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'dart:convert' show utf8;
import 'dart:convert' show jsonDecode;
......@@ -15,7 +14,7 @@ void main() {
TestWidgetsFlutterBinding.ensureInitialized();
group('TextInput message channels', () {
FakeTextChannel fakeTextChannel;
late FakeTextChannel fakeTextChannel;
setUp(() {
fakeTextChannel = FakeTextChannel((MethodCall call) async {});
......@@ -34,7 +33,7 @@ void main() {
MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
]);
fakeTextChannel.incoming(const MethodCall('TextInputClient.requestExistingInputState', null));
fakeTextChannel.incoming!(const MethodCall('TextInputClient.requestExistingInputState', null));
expect(fakeTextChannel.outgoingCalls.length, 3);
fakeTextChannel.validateOutgoingMethodCalls(<MethodCall>[
......@@ -47,20 +46,32 @@ void main() {
});
test('text input client handler responds to reattach with setClient (null TextEditingValue)', () async {
final FakeTextInputClient client = FakeTextInputClient(null);
final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
TextInput.attach(client, client.configuration);
fakeTextChannel.validateOutgoingMethodCalls(<MethodCall>[
MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
]);
fakeTextChannel.incoming(const MethodCall('TextInputClient.requestExistingInputState', null));
fakeTextChannel.incoming!(const MethodCall('TextInputClient.requestExistingInputState', null));
expect(fakeTextChannel.outgoingCalls.length, 2);
expect(fakeTextChannel.outgoingCalls.length, 3);
fakeTextChannel.validateOutgoingMethodCalls(<MethodCall>[
// From original attach
MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
// From requestExistingInputState
// From original attach
MethodCall('TextInput.setClient', <dynamic>[1, client.configuration.toJson()]),
// From requestExistingInputState
const MethodCall(
'TextInput.setEditingState',
<String, dynamic>{
'text': '',
'selectionBase': -1,
'selectionExtent': -1,
'selectionAffinity': 'TextAffinity.downstream',
'selectionIsDirectional': false,
'composingBase': -1,
'composingExtent': -1,
}),
]);
});
});
......@@ -162,14 +173,14 @@ void main() {
expect(client.latestMethodCall, isEmpty);
// Send onConnectionClosed message.
final ByteData messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
final ByteData? messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
'args': <dynamic>[1],
'method': 'TextInputClient.onConnectionClosed',
});
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
'flutter/textinput',
messageBytes,
(ByteData _) {},
(ByteData? _) {},
);
expect(client.latestMethodCall, 'connectionClosed');
......@@ -177,14 +188,14 @@ void main() {
test('TextInputClient performPrivateCommand method is called', () async {
// Assemble a TextInputConnection so we can verify its change in state.
final FakeTextInputClient client = FakeTextInputClient(null);
final FakeTextInputClient client = FakeTextInputClient(TextEditingValue.empty);
const TextInputConfiguration configuration = TextInputConfiguration();
TextInput.attach(client, configuration);
expect(client.latestMethodCall, isEmpty);
// Send performPrivateCommand message.
final ByteData messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
final ByteData? messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
'args': <dynamic>[
1,
jsonDecode(
......@@ -192,10 +203,10 @@ void main() {
],
'method': 'TextInputClient.performPrivateCommand',
});
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
'flutter/textinput',
messageBytes,
(ByteData _) {},
(ByteData? _) {},
);
expect(client.latestMethodCall, 'performPrivateCommand');
......@@ -204,14 +215,14 @@ void main() {
test('TextInputClient performPrivateCommand method is called with float',
() async {
// Assemble a TextInputConnection so we can verify its change in state.
final FakeTextInputClient client = FakeTextInputClient(null);
final FakeTextInputClient client = FakeTextInputClient(const TextEditingValue());
const TextInputConfiguration configuration = TextInputConfiguration();
TextInput.attach(client, configuration);
expect(client.latestMethodCall, isEmpty);
// Send performPrivateCommand message.
final ByteData messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
final ByteData? messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
'args': <dynamic>[
1,
jsonDecode(
......@@ -219,10 +230,10 @@ void main() {
],
'method': 'TextInputClient.performPrivateCommand',
});
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
'flutter/textinput',
messageBytes,
(ByteData _) {},
(ByteData? _) {},
);
expect(client.latestMethodCall, 'performPrivateCommand');
......@@ -232,14 +243,14 @@ void main() {
'TextInputClient performPrivateCommand method is called with CharSequence array',
() async {
// Assemble a TextInputConnection so we can verify its change in state.
final FakeTextInputClient client = FakeTextInputClient(null);
final FakeTextInputClient client = FakeTextInputClient(const TextEditingValue());
const TextInputConfiguration configuration = TextInputConfiguration();
TextInput.attach(client, configuration);
expect(client.latestMethodCall, isEmpty);
// Send performPrivateCommand message.
final ByteData messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
final ByteData? messageBytes = const JSONMessageCodec().encodeMessage(<String, dynamic>{
'args': <dynamic>[
1,
jsonDecode(
......@@ -247,10 +258,10 @@ void main() {
],
'method': 'TextInputClient.performPrivateCommand',
});
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
'flutter/textinput',
messageBytes,
(ByteData _) {},
(ByteData? _) {},
);
expect(client.latestMethodCall, 'performPrivateCommand');
......@@ -260,14 +271,14 @@ void main() {
'TextInputClient performPrivateCommand method is called with CharSequence',
() async {
// Assemble a TextInputConnection so we can verify its change in state.
final FakeTextInputClient client = FakeTextInputClient(null);
final FakeTextInputClient client = FakeTextInputClient(const TextEditingValue());
const TextInputConfiguration configuration = TextInputConfiguration();
TextInput.attach(client, configuration);
expect(client.latestMethodCall, isEmpty);
// Send performPrivateCommand message.
final ByteData messageBytes =
final ByteData? messageBytes =
const JSONMessageCodec().encodeMessage(<String, dynamic>{
'args': <dynamic>[
1,
......@@ -276,10 +287,10 @@ void main() {
],
'method': 'TextInputClient.performPrivateCommand',
});
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
'flutter/textinput',
messageBytes,
(ByteData _) {},
(ByteData? _) {},
);
expect(client.latestMethodCall, 'performPrivateCommand');
......@@ -289,14 +300,14 @@ void main() {
'TextInputClient performPrivateCommand method is called with float array',
() async {
// Assemble a TextInputConnection so we can verify its change in state.
final FakeTextInputClient client = FakeTextInputClient(null);
final FakeTextInputClient client = FakeTextInputClient(const TextEditingValue());
const TextInputConfiguration configuration = TextInputConfiguration();
TextInput.attach(client, configuration);
expect(client.latestMethodCall, isEmpty);
// Send performPrivateCommand message.
final ByteData messageBytes =
final ByteData? messageBytes =
const JSONMessageCodec().encodeMessage(<String, dynamic>{
'args': <dynamic>[
1,
......@@ -305,10 +316,10 @@ void main() {
],
'method': 'TextInputClient.performPrivateCommand',
});
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
'flutter/textinput',
messageBytes,
(ByteData _) {},
(ByteData? _) {},
);
expect(client.latestMethodCall, 'performPrivateCommand');
......@@ -317,22 +328,22 @@ void main() {
test('TextInputClient showAutocorrectionPromptRect method is called',
() async {
// Assemble a TextInputConnection so we can verify its change in state.
final FakeTextInputClient client = FakeTextInputClient(null);
final FakeTextInputClient client = FakeTextInputClient(const TextEditingValue());
const TextInputConfiguration configuration = TextInputConfiguration();
TextInput.attach(client, configuration);
expect(client.latestMethodCall, isEmpty);
// Send onConnectionClosed message.
final ByteData messageBytes =
final ByteData? messageBytes =
const JSONMessageCodec().encodeMessage(<String, dynamic>{
'args': <dynamic>[1, 0, 1],
'method': 'TextInputClient.showAutocorrectionPromptRect',
});
await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
'flutter/textinput',
messageBytes,
(ByteData _) {},
(ByteData? _) {},
);
expect(client.latestMethodCall, 'showAutocorrectionPromptRect');
......@@ -376,7 +387,7 @@ class FakeTextInputClient implements TextInputClient {
TextEditingValue currentTextEditingValue;
@override
AutofillScope get currentAutofillScope => null;
AutofillScope? get currentAutofillScope => null;
@override
void performAction(TextInputAction action) {
......@@ -415,7 +426,7 @@ class FakeTextChannel implements MethodChannel {
FakeTextChannel(this.outgoing) : assert(outgoing != null);
Future<dynamic> Function(MethodCall) outgoing;
Future<void> Function(MethodCall) incoming;
Future<void> Function(MethodCall)? incoming;
List<MethodCall> outgoingCalls = <MethodCall>[];
......@@ -442,19 +453,17 @@ class FakeTextChannel implements MethodChannel {
String get name => 'flutter/textinput';
@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();
bool checkMethodCallHandler(Future<void> Function(MethodCall call)? handler) => throw UnimplementedError();
@override
void setMockMethodCallHandler(Future<void> Function(MethodCall call) handler) => throw UnimplementedError();
void setMockMethodCallHandler(Future<void> Function(MethodCall call)? handler) => throw UnimplementedError();
@override
bool checkMockMethodCallHandler(Future<void> Function(MethodCall call) handler) => throw UnimplementedError();
bool checkMockMethodCallHandler(Future<void> Function(MethodCall call)? handler) => throw UnimplementedError();
void validateOutgoingMethodCalls(List<MethodCall> calls) {
expect(outgoingCalls.length, calls.length);
......@@ -468,8 +477,8 @@ class FakeTextChannel implements MethodChannel {
if (outgoingString != expectedString) {
print(
'Index $i did not match:\n'
' actual: ${outgoingCalls[i]}\n'
' expected: ${calls[i]}');
' actual: $outgoingString\n'
' expected: $expectedString');
hasError = true;
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment