mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
This auto-formats all *.dart files in the repository outside of the `engine` subdirectory and enforces that these files stay formatted with a presubmit check. **Reviewers:** Please carefully review all the commits except for the one titled "formatted". The "formatted" commit was auto-generated by running `dev/tools/format.sh -a -f`. The other commits were hand-crafted to prepare the repo for the formatting change. I recommend reviewing the commits one-by-one via the "Commits" tab and avoiding Github's "Files changed" tab as it will likely slow down your browser because of the size of this PR. --------- Co-authored-by: Kate Lovett <katelovett@google.com> Co-authored-by: LongCatIsLooong <31859944+LongCatIsLooong@users.noreply.github.com>
281 lines
9.4 KiB
Dart
281 lines
9.4 KiB
Dart
// 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.
|
|
|
|
// 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.
|
|
|
|
import 'dart:convert';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
import 'message_codecs_testing.dart';
|
|
|
|
void main() {
|
|
group('Binary codec', () {
|
|
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));
|
|
});
|
|
});
|
|
group('String codec', () {
|
|
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}<');
|
|
});
|
|
test('ByteData with offset', () {
|
|
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,
|
|
helloWorldByteData.lengthInBytes - helloByteData.lengthInBytes,
|
|
);
|
|
|
|
expect(string.decodeMessage(offsetByteData), ' world');
|
|
});
|
|
});
|
|
group('Standard method codec', () {
|
|
const MethodCodec method = StandardMethodCodec();
|
|
const StandardMessageCodec messageCodec = StandardMessageCodec();
|
|
|
|
test('Should encode and decode objects produced from codec', () {
|
|
final ByteData? data = messageCodec.encodeMessage(<Object, Object>{'foo': true, 3: 'fizz'});
|
|
|
|
expect(messageCodec.decodeMessage(data), <Object?, Object?>{'foo': true, 3: 'fizz'});
|
|
});
|
|
|
|
test('should decode error envelope without native stacktrace', () {
|
|
final ByteData errorData = method.encodeErrorEnvelope(
|
|
code: 'errorCode',
|
|
message: 'errorMessage',
|
|
details: 'errorDetails',
|
|
);
|
|
expect(
|
|
() => method.decodeEnvelope(errorData),
|
|
throwsA(
|
|
predicate(
|
|
(PlatformException e) =>
|
|
e.code == 'errorCode' && e.message == 'errorMessage' && e.details == 'errorDetails',
|
|
),
|
|
),
|
|
);
|
|
});
|
|
|
|
test('should decode error envelope with native stacktrace.', () {
|
|
final WriteBuffer buffer = WriteBuffer();
|
|
buffer.putUint8(1);
|
|
messageCodec.writeValue(buffer, 'errorCode');
|
|
messageCodec.writeValue(buffer, 'errorMessage');
|
|
messageCodec.writeValue(buffer, 'errorDetails');
|
|
messageCodec.writeValue(buffer, 'errorStacktrace');
|
|
final ByteData errorData = buffer.done();
|
|
expect(
|
|
() => method.decodeEnvelope(errorData),
|
|
throwsA(predicate((PlatformException e) => e.stacktrace == 'errorStacktrace')),
|
|
);
|
|
});
|
|
|
|
test('should allow null error message,', () {
|
|
final ByteData errorData = method.encodeErrorEnvelope(
|
|
code: 'errorCode',
|
|
details: 'errorDetails',
|
|
);
|
|
expect(
|
|
() => method.decodeEnvelope(errorData),
|
|
throwsA(
|
|
predicate((PlatformException e) {
|
|
return e.code == 'errorCode' && e.message == null && e.details == 'errorDetails';
|
|
}),
|
|
),
|
|
);
|
|
});
|
|
});
|
|
group('Json method codec', () {
|
|
const JsonCodec json = JsonCodec();
|
|
const StringCodec stringCodec = StringCodec();
|
|
const JSONMethodCodec jsonMethodCodec = JSONMethodCodec();
|
|
test('should decode error envelope without native stacktrace', () {
|
|
final ByteData errorData = jsonMethodCodec.encodeErrorEnvelope(
|
|
code: 'errorCode',
|
|
message: 'errorMessage',
|
|
details: 'errorDetails',
|
|
);
|
|
expect(
|
|
() => jsonMethodCodec.decodeEnvelope(errorData),
|
|
throwsA(
|
|
predicate(
|
|
(PlatformException e) =>
|
|
e.code == 'errorCode' && e.message == 'errorMessage' && e.details == 'errorDetails',
|
|
),
|
|
),
|
|
);
|
|
});
|
|
test('should decode error envelope with native stacktrace.', () {
|
|
final ByteData? errorData = stringCodec.encodeMessage(
|
|
json.encode(<dynamic>['errorCode', 'errorMessage', 'errorDetails', 'errorStacktrace']),
|
|
);
|
|
expect(
|
|
() => jsonMethodCodec.decodeEnvelope(errorData!),
|
|
throwsA(predicate((PlatformException e) => e.stacktrace == 'errorStacktrace')),
|
|
);
|
|
});
|
|
});
|
|
group('JSON message codec', () {
|
|
const MessageCodec<dynamic> json = JSONMessageCodec();
|
|
test('should encode and decode simple messages', () {
|
|
checkEncodeDecode<dynamic>(json, null);
|
|
checkEncodeDecode<dynamic>(json, true);
|
|
checkEncodeDecode<dynamic>(json, false);
|
|
checkEncodeDecode<dynamic>(json, 7);
|
|
checkEncodeDecode<dynamic>(json, -7);
|
|
checkEncodeDecode<dynamic>(json, 98742923489);
|
|
checkEncodeDecode<dynamic>(json, -98742923489);
|
|
checkEncodeDecode<dynamic>(json, 3.14);
|
|
checkEncodeDecode<dynamic>(json, '');
|
|
checkEncodeDecode<dynamic>(json, 'hello');
|
|
checkEncodeDecode<dynamic>(json, 'special chars >\u263A\u{1F602}<');
|
|
});
|
|
test('should encode and decode composite message', () {
|
|
final List<dynamic> message = <dynamic>[
|
|
null,
|
|
true,
|
|
false,
|
|
-707,
|
|
-7000000007,
|
|
-3.14,
|
|
'',
|
|
'hello',
|
|
<dynamic>['nested', <dynamic>[]],
|
|
<dynamic, dynamic>{'a': 'nested', 'b': <dynamic, dynamic>{}},
|
|
'world',
|
|
];
|
|
checkEncodeDecode<dynamic>(json, message);
|
|
});
|
|
});
|
|
group('Standard message codec', () {
|
|
const MessageCodec<dynamic> standard = StandardMessageCodec();
|
|
test('should encode sizes correctly at boundary cases', () {
|
|
checkEncoding<dynamic>(standard, Uint8List(253), <int>[8, 253, ...List<int>.filled(253, 0)]);
|
|
checkEncoding<dynamic>(standard, Uint8List(254), <int>[
|
|
8,
|
|
254,
|
|
254,
|
|
0,
|
|
...List<int>.filled(254, 0),
|
|
]);
|
|
checkEncoding<dynamic>(standard, Uint8List(0xffff), <int>[
|
|
8,
|
|
254,
|
|
0xff,
|
|
0xff,
|
|
...List<int>.filled(0xffff, 0),
|
|
]);
|
|
checkEncoding<dynamic>(standard, Uint8List(0xffff + 1), <int>[
|
|
8,
|
|
255,
|
|
0,
|
|
0,
|
|
1,
|
|
0,
|
|
...List<int>.filled(0xffff + 1, 0),
|
|
]);
|
|
});
|
|
test('should encode and decode simple messages', () {
|
|
checkEncodeDecode<dynamic>(standard, null);
|
|
checkEncodeDecode<dynamic>(standard, true);
|
|
checkEncodeDecode<dynamic>(standard, false);
|
|
checkEncodeDecode<dynamic>(standard, 7);
|
|
checkEncodeDecode<dynamic>(standard, -7);
|
|
checkEncodeDecode<dynamic>(standard, 98742923489);
|
|
checkEncodeDecode<dynamic>(standard, -98742923489);
|
|
checkEncodeDecode<dynamic>(standard, 3.14);
|
|
checkEncodeDecode<dynamic>(standard, double.infinity);
|
|
checkEncodeDecode<dynamic>(standard, double.nan);
|
|
checkEncodeDecode<dynamic>(standard, '');
|
|
checkEncodeDecode<dynamic>(standard, 'hello');
|
|
checkEncodeDecode<dynamic>(standard, 'special chars >\u263A\u{1F602}<');
|
|
});
|
|
test('should encode and decode composite message', () {
|
|
final List<dynamic> message = <dynamic>[
|
|
null,
|
|
true,
|
|
false,
|
|
-707,
|
|
-7000000007,
|
|
-3.14,
|
|
'',
|
|
'hello',
|
|
Uint8List.fromList(<int>[0xBA, 0x5E, 0xBA, 0x11]),
|
|
Int32List.fromList(<int>[-0x7fffffff - 1, 0, 0x7fffffff]),
|
|
null, // ensures the offset of the following list is unaligned.
|
|
null, // ensures the offset of the following list is unaligned.
|
|
Float64List.fromList(<double>[
|
|
double.negativeInfinity,
|
|
-double.maxFinite,
|
|
-double.minPositive,
|
|
-0.0,
|
|
0.0,
|
|
double.minPositive,
|
|
double.maxFinite,
|
|
double.infinity,
|
|
double.nan,
|
|
]),
|
|
Float32List.fromList(<double>[
|
|
double.negativeInfinity,
|
|
-double.maxFinite,
|
|
-double.minPositive,
|
|
-0.0,
|
|
0.0,
|
|
double.minPositive,
|
|
double.maxFinite,
|
|
double.infinity,
|
|
double.nan,
|
|
]),
|
|
<dynamic>['nested', <dynamic>[]],
|
|
<dynamic, dynamic>{'a': 'nested', null: <dynamic, dynamic>{}},
|
|
'world',
|
|
];
|
|
checkEncodeDecode<dynamic>(standard, message);
|
|
});
|
|
test('should align doubles to 8 bytes', () {
|
|
checkEncoding<dynamic>(standard, 1.0, <int>[
|
|
6,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0xf0,
|
|
0x3f,
|
|
]);
|
|
});
|
|
});
|
|
|
|
test('toString works as intended', () async {
|
|
const MethodCall methodCall = MethodCall('sample method');
|
|
final PlatformException platformException = PlatformException(code: '100');
|
|
final MissingPluginException missingPluginException = MissingPluginException();
|
|
|
|
expect(methodCall.toString(), 'MethodCall(sample method, null)');
|
|
expect(platformException.toString(), 'PlatformException(100, null, null, null)');
|
|
expect(missingPluginException.toString(), 'MissingPluginException(null)');
|
|
});
|
|
}
|