mirror of
https://github.com/flutter/packages.git
synced 2025-06-30 23:03:11 +08:00
Actually call argument-less methods. (#265)
I accidentally broke this in an earlier patch.
This commit is contained in:
@ -38,7 +38,7 @@ linter:
|
||||
- always_specify_types
|
||||
- annotate_overrides
|
||||
# - avoid_annotating_with_dynamic # conflicts with always_specify_types
|
||||
# - avoid_as # conflicts with NNBD
|
||||
# - avoid_as # no longer relevant with null safety
|
||||
- avoid_bool_literals_in_conditional_expressions
|
||||
# - avoid_catches_without_on_clauses # we do this commonly
|
||||
# - avoid_catching_errors # we do this commonly
|
||||
|
@ -1,3 +1,8 @@
|
||||
## 0.1.19
|
||||
|
||||
* Fixed a bug introduced in 0.1.17 where methods without arguments were
|
||||
no longer being called.
|
||||
|
||||
## 0.1.18
|
||||
|
||||
* Null safe requires Dart 2.12.
|
||||
|
@ -88,6 +88,7 @@ void _writeFlutterApi(
|
||||
}) {
|
||||
assert(api.location == ApiLocation.flutter);
|
||||
final String nullTag = opt.isNullSafe ? '?' : '';
|
||||
final String unwrapOperator = opt.isNullSafe ? '!' : '';
|
||||
indent.write('abstract class ${api.name} ');
|
||||
indent.scoped('{', '}', () {
|
||||
for (Method func in api.methods) {
|
||||
@ -106,10 +107,10 @@ void _writeFlutterApi(
|
||||
indent.writeln(
|
||||
'const BasicMessageChannel<Object$nullTag> channel =',
|
||||
);
|
||||
final String channelName = channelNameFunc == null
|
||||
? makeChannelName(api, func)
|
||||
: channelNameFunc(func);
|
||||
indent.nest(2, () {
|
||||
final String channelName = channelNameFunc == null
|
||||
? makeChannelName(api, func)
|
||||
: channelNameFunc(func);
|
||||
indent.writeln(
|
||||
'BasicMessageChannel<Object$nullTag>(\'$channelName\', StandardMessageCodec());',
|
||||
);
|
||||
@ -134,16 +135,16 @@ void _writeFlutterApi(
|
||||
: func.returnType == 'void'
|
||||
? 'return;'
|
||||
: 'return null;';
|
||||
indent.write('if (message == null) ');
|
||||
indent.scoped('{', '}', () {
|
||||
indent.writeln(emptyReturnStatement);
|
||||
});
|
||||
String call;
|
||||
if (argType == 'void') {
|
||||
indent.writeln('// ignore message');
|
||||
call = 'api.${func.name}()';
|
||||
} else {
|
||||
indent.writeln(
|
||||
'final $argType input = $argType.decode(message);',
|
||||
'assert(message != null, \'Argument for $channelName was null. Expected $argType.\');',
|
||||
);
|
||||
indent.writeln(
|
||||
'final $argType input = $argType.decode(message$unwrapOperator);',
|
||||
);
|
||||
call = 'api.${func.name}(input)';
|
||||
}
|
||||
@ -213,7 +214,6 @@ void generateDart(DartOptions opt, Root root, StringSink sink) {
|
||||
if (klass.fields.isNotEmpty) {
|
||||
indent.writeln('');
|
||||
}
|
||||
indent.writeln('// ignore: unused_element');
|
||||
indent.write('Object encode() ');
|
||||
indent.scoped('{', '}', () {
|
||||
indent.writeln(
|
||||
@ -232,7 +232,6 @@ void generateDart(DartOptions opt, Root root, StringSink sink) {
|
||||
indent.writeln('return pigeonMap;');
|
||||
});
|
||||
indent.writeln('');
|
||||
indent.writeln('// ignore: unused_element');
|
||||
indent.write(
|
||||
'static ${klass.name} decode(Object message) ',
|
||||
);
|
||||
|
@ -7,8 +7,8 @@ import 'dart:io';
|
||||
import 'dart:mirrors';
|
||||
import 'ast.dart';
|
||||
|
||||
/// The current version of pigeon.
|
||||
const String pigeonVersion = '0.1.18';
|
||||
/// The current version of pigeon. This must match the version in pubspec.yaml.
|
||||
const String pigeonVersion = '0.1.19';
|
||||
|
||||
/// Read all the content from [stdin] to a String.
|
||||
String readStdin() {
|
||||
|
@ -1,16 +1,16 @@
|
||||
// Autogenerated from Pigeon (v0.1.15), do not edit directly.
|
||||
// Autogenerated from Pigeon (v0.1.19), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import
|
||||
// @dart = 2.8
|
||||
import 'dart:async';
|
||||
import 'dart:typed_data' show Uint8List, Int32List, Int64List, Float64List;
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class SearchReply {
|
||||
String result;
|
||||
String error;
|
||||
|
||||
// ignore: unused_element
|
||||
Object encode() {
|
||||
final Map<Object, Object> pigeonMap = <Object, Object>{};
|
||||
pigeonMap['result'] = result;
|
||||
@ -18,7 +18,6 @@ class SearchReply {
|
||||
return pigeonMap;
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
static SearchReply decode(Object message) {
|
||||
final Map<Object, Object> pigeonMap = message as Map<Object, Object>;
|
||||
return SearchReply()
|
||||
@ -32,7 +31,6 @@ class SearchRequest {
|
||||
int anInt;
|
||||
bool aBool;
|
||||
|
||||
// ignore: unused_element
|
||||
Object encode() {
|
||||
final Map<Object, Object> pigeonMap = <Object, Object>{};
|
||||
pigeonMap['query'] = query;
|
||||
@ -41,7 +39,6 @@ class SearchRequest {
|
||||
return pigeonMap;
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
static SearchRequest decode(Object message) {
|
||||
final Map<Object, Object> pigeonMap = message as Map<Object, Object>;
|
||||
return SearchRequest()
|
||||
@ -54,14 +51,12 @@ class SearchRequest {
|
||||
class Nested {
|
||||
SearchRequest request;
|
||||
|
||||
// ignore: unused_element
|
||||
Object encode() {
|
||||
final Map<Object, Object> pigeonMap = <Object, Object>{};
|
||||
pigeonMap['request'] = request == null ? null : request.encode();
|
||||
return pigeonMap;
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
static Nested decode(Object message) {
|
||||
final Map<Object, Object> pigeonMap = message as Map<Object, Object>;
|
||||
return Nested()
|
||||
@ -81,9 +76,8 @@ abstract class FlutterSearchApi {
|
||||
channel.setMessageHandler(null);
|
||||
} else {
|
||||
channel.setMessageHandler((Object message) async {
|
||||
if (message == null) {
|
||||
return null;
|
||||
}
|
||||
assert(message != null,
|
||||
'Argument for dev.flutter.pigeon.FlutterSearchApi.search was null. Expected SearchRequest.');
|
||||
final SearchRequest input = SearchRequest.decode(message);
|
||||
final SearchReply output = api.search(input);
|
||||
return output.encode();
|
||||
@ -121,6 +115,30 @@ class NestedApi {
|
||||
}
|
||||
|
||||
class Api {
|
||||
Future<void> initialize() async {
|
||||
const BasicMessageChannel<Object> channel = BasicMessageChannel<Object>(
|
||||
'dev.flutter.pigeon.Api.initialize', StandardMessageCodec());
|
||||
final Map<Object, Object> replyMap =
|
||||
await channel.send(null) as Map<Object, Object>;
|
||||
if (replyMap == null) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
details: null,
|
||||
);
|
||||
} else if (replyMap['error'] != null) {
|
||||
final Map<Object, Object> error =
|
||||
replyMap['error'] as Map<Object, Object>;
|
||||
throw PlatformException(
|
||||
code: error['code'] as String,
|
||||
message: error['message'] as String,
|
||||
details: error['details'],
|
||||
);
|
||||
} else {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
|
||||
Future<SearchReply> search(SearchRequest arg) async {
|
||||
final Object encoded = arg.encode();
|
||||
const BasicMessageChannel<Object> channel = BasicMessageChannel<Object>(
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Autogenerated from Pigeon (v0.1.15), do not edit directly.
|
||||
// Autogenerated from Pigeon (v0.1.19), do not edit directly.
|
||||
// See also: https://pub.dev/packages/pigeon
|
||||
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import
|
||||
// @dart = 2.8
|
||||
@ -19,9 +19,8 @@ abstract class TestNestedApi {
|
||||
channel.setMockMessageHandler(null);
|
||||
} else {
|
||||
channel.setMockMessageHandler((Object message) async {
|
||||
if (message == null) {
|
||||
return <Object, Object>{};
|
||||
}
|
||||
assert(message != null,
|
||||
'Argument for dev.flutter.pigeon.NestedApi.search was null. Expected Nested.');
|
||||
final Nested input = Nested.decode(message);
|
||||
final SearchReply output = api.search(input);
|
||||
return <Object, Object>{'result': output.encode()};
|
||||
@ -32,8 +31,22 @@ abstract class TestNestedApi {
|
||||
}
|
||||
|
||||
abstract class TestHostApi {
|
||||
void initialize();
|
||||
SearchReply search(SearchRequest arg);
|
||||
static void setup(TestHostApi api) {
|
||||
{
|
||||
const BasicMessageChannel<Object> channel = BasicMessageChannel<Object>(
|
||||
'dev.flutter.pigeon.Api.initialize', StandardMessageCodec());
|
||||
if (api == null) {
|
||||
channel.setMockMessageHandler(null);
|
||||
} else {
|
||||
channel.setMockMessageHandler((Object message) async {
|
||||
// ignore message
|
||||
api.initialize();
|
||||
return <Object, Object>{};
|
||||
});
|
||||
}
|
||||
}
|
||||
{
|
||||
const BasicMessageChannel<Object> channel = BasicMessageChannel<Object>(
|
||||
'dev.flutter.pigeon.Api.search', StandardMessageCodec());
|
||||
@ -41,9 +54,8 @@ abstract class TestHostApi {
|
||||
channel.setMockMessageHandler(null);
|
||||
} else {
|
||||
channel.setMockMessageHandler((Object message) async {
|
||||
if (message == null) {
|
||||
return <Object, Object>{};
|
||||
}
|
||||
assert(message != null,
|
||||
'Argument for dev.flutter.pigeon.Api.search was null. Expected SearchRequest.');
|
||||
final SearchRequest input = SearchRequest.decode(message);
|
||||
final SearchReply output = api.search(input);
|
||||
return <Object, Object>{'result': output.encode()};
|
||||
|
@ -2,16 +2,25 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'message.dart';
|
||||
import 'test.dart';
|
||||
|
||||
class Mock implements TestHostApi {
|
||||
bool didCall = false;
|
||||
List<String> log = <String>[];
|
||||
|
||||
@override
|
||||
void initialize() {
|
||||
log.add('initialize');
|
||||
}
|
||||
|
||||
@override
|
||||
SearchReply search(SearchRequest arg) {
|
||||
didCall = true;
|
||||
log.add('search');
|
||||
return SearchReply()..result = arg.query;
|
||||
}
|
||||
}
|
||||
@ -46,7 +55,48 @@ void main() {
|
||||
final Mock mock = Mock();
|
||||
TestHostApi.setup(mock);
|
||||
final SearchReply reply = await api.search(SearchRequest()..query = 'foo');
|
||||
expect(mock.didCall, true);
|
||||
expect(mock.log, <String>['search']);
|
||||
expect(reply.result, 'foo');
|
||||
});
|
||||
|
||||
test('no-arg calls', () async {
|
||||
final Api api = Api();
|
||||
final Mock mock = Mock();
|
||||
TestHostApi.setup(mock);
|
||||
await api.initialize();
|
||||
expect(mock.log, <String>['initialize']);
|
||||
});
|
||||
|
||||
test(
|
||||
'calling methods with null',
|
||||
() async {
|
||||
final Mock mock = Mock();
|
||||
TestHostApi.setup(mock);
|
||||
expect(
|
||||
await const BasicMessageChannel<Object>(
|
||||
'dev.flutter.pigeon.Api.initialize',
|
||||
StandardMessageCodec(),
|
||||
).send(null),
|
||||
isEmpty,
|
||||
);
|
||||
try {
|
||||
await const BasicMessageChannel<Object>(
|
||||
'dev.flutter.pigeon.Api.search',
|
||||
StandardMessageCodec(),
|
||||
).send(null) as Map<Object, Object>;
|
||||
expect(true, isFalse); // should not reach here
|
||||
} catch (error) {
|
||||
expect(error, isAssertionError);
|
||||
expect(
|
||||
error.toString(),
|
||||
contains(
|
||||
'Argument for dev.flutter.pigeon.Api.search was null. Expected SearchRequest.',
|
||||
),
|
||||
);
|
||||
}
|
||||
expect(mock.log, <String>['initialize']);
|
||||
},
|
||||
// TODO(ianh): skip can be removed after first stable release in 2021
|
||||
skip: Platform.environment['CHANNEL'] == 'stable',
|
||||
);
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ class SearchReply {
|
||||
|
||||
@HostApi(dartHostTestHandler: 'TestHostApi')
|
||||
abstract class Api {
|
||||
void initialize();
|
||||
SearchReply search(SearchRequest request);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
name: pigeon
|
||||
version: 0.1.18
|
||||
version: 0.1.19 # This must match the version in lib/generator_tools.dart
|
||||
description: Code generator tool to make communication between Flutter and the host platform type-safe and easier.
|
||||
homepage: https://github.com/flutter/packages/tree/master/packages/pigeon
|
||||
dependencies:
|
||||
|
@ -144,7 +144,10 @@ void main() {
|
||||
final StringBuffer sink = StringBuffer();
|
||||
generateDart(DartOptions(), root, sink);
|
||||
final String code = sink.toString();
|
||||
expect(code, isNot(matches('=.*doSomething')));
|
||||
// The next line verifies that we're not setting a variable to the value of "doSomething", but
|
||||
// ignores the line where we assert the value of the argument isn't null, since on that line
|
||||
// we mention "doSomething" in the assertion message.
|
||||
expect(code, isNot(matches('[^!]=.*doSomething')));
|
||||
expect(code, contains('doSomething('));
|
||||
expect(code, isNot(contains('.encode()')));
|
||||
});
|
||||
|
@ -11,7 +11,7 @@ void main() {
|
||||
test('pigeon version matches pubspec', () {
|
||||
final String pubspecPath = '${Directory.current.path}/pubspec.yaml';
|
||||
final String pubspec = File(pubspecPath).readAsStringSync();
|
||||
final RegExp regex = RegExp('version:\s*(.*)');
|
||||
final RegExp regex = RegExp('version:\s*(.*?) #');
|
||||
final RegExpMatch match = regex.firstMatch(pubspec);
|
||||
expect(match, isNotNull);
|
||||
expect(pigeonVersion, match.group(1).trim());
|
||||
|
Reference in New Issue
Block a user