mirror of
https://github.com/flutter/packages.git
synced 2025-06-30 23:03:11 +08:00
[pigeon] Eliminate some of the test pigeons (#3213)
* Fold in async_handlers.dart * Remove some largely unused files * Fold in the relevant parts of list.dart * Remove java_double_host_api * Remove unnecessary double-generation of messages.dart * Remove enum_args * Remove some unnecesasry/duplicate unit tests * Eliminate android_unittest * Format * Remove build references on Windows
This commit is contained in:
@ -1,23 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:pigeon/pigeon.dart';
|
||||
|
||||
class Value {
|
||||
int? number;
|
||||
}
|
||||
|
||||
@HostApi()
|
||||
abstract class Api2Host {
|
||||
@async
|
||||
Value calculate(Value value);
|
||||
@async
|
||||
void voidVoid();
|
||||
}
|
||||
|
||||
@FlutterApi()
|
||||
abstract class Api2Flutter {
|
||||
@async
|
||||
Value calculate(Value value);
|
||||
}
|
@ -538,10 +538,68 @@ abstract class FlutterIntegrationCoreApi {
|
||||
@ObjCSelector('echoNullableMap:')
|
||||
@SwiftFunction('echoNullable(_:)')
|
||||
Map<String?, Object?>? echoNullableMap(Map<String?, Object?>? aMap);
|
||||
|
||||
// ========== Async tests ==========
|
||||
// These are minimal since async FlutterApi only changes Dart generation.
|
||||
// Currently they aren't integration tested, but having them here ensures
|
||||
// analysis coverage.
|
||||
|
||||
/// A no-op function taking no arguments and returning no value, to sanity
|
||||
/// test basic asynchronous calling.
|
||||
@async
|
||||
void noopAsync();
|
||||
|
||||
/// Returns the passed in generic Object asynchronously.
|
||||
@async
|
||||
@ObjCSelector('echoAsyncString:')
|
||||
@SwiftFunction('echoAsync(_:)')
|
||||
String echoAsyncString(String aString);
|
||||
}
|
||||
|
||||
/// An API that can be implemented for minimal, compile-only tests.
|
||||
//
|
||||
// This is also here to test that multiple host APIs can be generated
|
||||
// successfully in all languages (e.g., in Java where it requires having a
|
||||
// wrapper class).
|
||||
@HostApi()
|
||||
abstract class HostTrivialApi {
|
||||
void noop();
|
||||
}
|
||||
|
||||
/// A simple API implemented in some unit tests.
|
||||
//
|
||||
// This is separate from HostIntegrationCoreApi to avoid having to update a
|
||||
// lot of unit tests every time we add something to the integration test API.
|
||||
// TODO(stuartmorgan): Restructure the unit tests to reduce the number of
|
||||
// different APIs we define.
|
||||
@HostApi()
|
||||
abstract class HostSmallApi {
|
||||
@async
|
||||
@ObjCSelector('echoString:')
|
||||
String echo(String aString);
|
||||
|
||||
@async
|
||||
void voidVoid();
|
||||
}
|
||||
|
||||
/// A simple API called in some unit tests.
|
||||
//
|
||||
// This is separate from FlutterIntegrationCoreApi to allow for incrementally
|
||||
// moving from the previous fragmented unit test structure to something more
|
||||
// unified.
|
||||
// TODO(stuartmorgan): Restructure the unit tests to reduce the number of
|
||||
// different APIs we define.
|
||||
@FlutterApi()
|
||||
abstract class FlutterSmallApi {
|
||||
@ObjCSelector('echoWrappedList:')
|
||||
@SwiftFunction('echo(_:)')
|
||||
TestMessage echoWrappedList(TestMessage msg);
|
||||
}
|
||||
|
||||
/// A data class containing a List, used in unit tests.
|
||||
// TODO(stuartmorgan): Evaluate whether these unit tests are still useful; see
|
||||
// TODOs above about restructring.
|
||||
class TestMessage {
|
||||
// ignore: always_specify_types, strict_raw_type
|
||||
List? testList;
|
||||
}
|
||||
|
@ -1,20 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:pigeon/pigeon.dart';
|
||||
|
||||
enum EnumArgsState {
|
||||
Pending,
|
||||
Success,
|
||||
Error,
|
||||
}
|
||||
|
||||
class EnumArgsData {
|
||||
EnumArgsState? state;
|
||||
}
|
||||
|
||||
@HostApi()
|
||||
abstract class EnumArgs2Host {
|
||||
void foo(EnumArgsState state);
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:pigeon/pigeon.dart';
|
||||
|
||||
@ConfigurePigeon(PigeonOptions(
|
||||
objcOptions: ObjcOptions(
|
||||
prefix: 'H2F',
|
||||
),
|
||||
))
|
||||
class Host2FlutterSearchRequest {
|
||||
String? query;
|
||||
}
|
||||
|
||||
class Host2FlutterSearchReply {
|
||||
String? result;
|
||||
}
|
||||
|
||||
@FlutterApi()
|
||||
abstract class H2FApi {
|
||||
Host2FlutterSearchReply search(Host2FlutterSearchRequest request);
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:pigeon/pigeon.dart';
|
||||
|
||||
class BridgeResponse {
|
||||
int? result;
|
||||
}
|
||||
|
||||
@HostApi()
|
||||
abstract class BridgeApi1 {
|
||||
@async
|
||||
BridgeResponse call();
|
||||
}
|
||||
|
||||
@HostApi()
|
||||
abstract class BridgeApi2 {
|
||||
@async
|
||||
BridgeResponse call();
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:pigeon/pigeon.dart';
|
||||
|
||||
class TestMessage {
|
||||
// ignore: always_specify_types, strict_raw_type
|
||||
List? testList;
|
||||
}
|
||||
|
||||
@HostApi()
|
||||
abstract class TestApi {
|
||||
void test(TestMessage msg);
|
||||
}
|
||||
|
||||
@FlutterApi()
|
||||
abstract class EchoApi {
|
||||
TestMessage echo(TestMessage msg);
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:pigeon/pigeon.dart';
|
||||
|
||||
class VoidArgFlutterResult {
|
||||
int? code;
|
||||
}
|
||||
|
||||
@FlutterApi()
|
||||
abstract class VoidArgApi {
|
||||
VoidArgFlutterResult getCode();
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:pigeon/pigeon.dart';
|
||||
|
||||
class VoidArgHostResult {
|
||||
int? code;
|
||||
}
|
||||
|
||||
@HostApi()
|
||||
abstract class VoidArgHostApi {
|
||||
VoidArgHostResult getCode();
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:pigeon/pigeon.dart';
|
||||
|
||||
class VoidFlutterSetRequest {
|
||||
int? value;
|
||||
}
|
||||
|
||||
@FlutterApi()
|
||||
abstract class VoidFlutterApi {
|
||||
void setValue(VoidFlutterSetRequest request);
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:pigeon/pigeon.dart';
|
||||
|
||||
class VoidHostSetRequest {
|
||||
int? value;
|
||||
}
|
||||
|
||||
@HostApi()
|
||||
abstract class VoidHostApi {
|
||||
void setValue(VoidHostSetRequest request);
|
||||
}
|
@ -708,6 +708,53 @@ public class CoreTests {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data class containing a List, used in unit tests.
|
||||
*
|
||||
* <p>Generated class from Pigeon that represents data sent in messages.
|
||||
*/
|
||||
public static final class TestMessage {
|
||||
private @Nullable List<Object> testList;
|
||||
|
||||
public @Nullable List<Object> getTestList() {
|
||||
return testList;
|
||||
}
|
||||
|
||||
public void setTestList(@Nullable List<Object> setterArg) {
|
||||
this.testList = setterArg;
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
|
||||
private @Nullable List<Object> testList;
|
||||
|
||||
public @NonNull Builder setTestList(@Nullable List<Object> setterArg) {
|
||||
this.testList = setterArg;
|
||||
return this;
|
||||
}
|
||||
|
||||
public @NonNull TestMessage build() {
|
||||
TestMessage pigeonReturn = new TestMessage();
|
||||
pigeonReturn.setTestList(testList);
|
||||
return pigeonReturn;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
ArrayList<Object> toList() {
|
||||
ArrayList<Object> toListResult = new ArrayList<Object>(1);
|
||||
toListResult.add(testList);
|
||||
return toListResult;
|
||||
}
|
||||
|
||||
static @NonNull TestMessage fromList(@NonNull ArrayList<Object> list) {
|
||||
TestMessage pigeonResult = new TestMessage();
|
||||
Object testList = list.get(0);
|
||||
pigeonResult.setTestList((List<Object>) testList);
|
||||
return pigeonResult;
|
||||
}
|
||||
}
|
||||
|
||||
public interface Result<T> {
|
||||
void success(T result);
|
||||
|
||||
@ -728,6 +775,8 @@ public class CoreTests {
|
||||
return AllNullableTypesWrapper.fromList((ArrayList<Object>) readValue(buffer));
|
||||
case (byte) 130:
|
||||
return AllTypes.fromList((ArrayList<Object>) readValue(buffer));
|
||||
case (byte) 131:
|
||||
return TestMessage.fromList((ArrayList<Object>) readValue(buffer));
|
||||
default:
|
||||
return super.readValueOfType(type, buffer);
|
||||
}
|
||||
@ -744,6 +793,9 @@ public class CoreTests {
|
||||
} else if (value instanceof AllTypes) {
|
||||
stream.write(130);
|
||||
writeValue(stream, ((AllTypes) value).toList());
|
||||
} else if (value instanceof TestMessage) {
|
||||
stream.write(131);
|
||||
writeValue(stream, ((TestMessage) value).toList());
|
||||
} else {
|
||||
super.writeValue(stream, value);
|
||||
}
|
||||
@ -3119,6 +3171,8 @@ public class CoreTests {
|
||||
return AllNullableTypesWrapper.fromList((ArrayList<Object>) readValue(buffer));
|
||||
case (byte) 130:
|
||||
return AllTypes.fromList((ArrayList<Object>) readValue(buffer));
|
||||
case (byte) 131:
|
||||
return TestMessage.fromList((ArrayList<Object>) readValue(buffer));
|
||||
default:
|
||||
return super.readValueOfType(type, buffer);
|
||||
}
|
||||
@ -3135,6 +3189,9 @@ public class CoreTests {
|
||||
} else if (value instanceof AllTypes) {
|
||||
stream.write(130);
|
||||
writeValue(stream, ((AllTypes) value).toList());
|
||||
} else if (value instanceof TestMessage) {
|
||||
stream.write(131);
|
||||
writeValue(stream, ((TestMessage) value).toList());
|
||||
} else {
|
||||
super.writeValue(stream, value);
|
||||
}
|
||||
@ -3453,6 +3510,33 @@ public class CoreTests {
|
||||
callback.reply(output);
|
||||
});
|
||||
}
|
||||
/**
|
||||
* A no-op function taking no arguments and returning no value, to sanity test basic
|
||||
* asynchronous calling.
|
||||
*/
|
||||
public void noopAsync(Reply<Void> callback) {
|
||||
BasicMessageChannel<Object> channel =
|
||||
new BasicMessageChannel<>(
|
||||
binaryMessenger,
|
||||
"dev.flutter.pigeon.FlutterIntegrationCoreApi.noopAsync",
|
||||
getCodec());
|
||||
channel.send(null, channelReply -> callback.reply(null));
|
||||
}
|
||||
/** Returns the passed in generic Object asynchronously. */
|
||||
public void echoAsyncString(@NonNull String aStringArg, Reply<String> callback) {
|
||||
BasicMessageChannel<Object> channel =
|
||||
new BasicMessageChannel<>(
|
||||
binaryMessenger,
|
||||
"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAsyncString",
|
||||
getCodec());
|
||||
channel.send(
|
||||
new ArrayList<Object>(Collections.singletonList(aStringArg)),
|
||||
channelReply -> {
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
String output = (String) channelReply;
|
||||
callback.reply(output);
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* An API that can be implemented for minimal, compile-only tests.
|
||||
@ -3492,4 +3576,154 @@ public class CoreTests {
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* A simple API implemented in some unit tests.
|
||||
*
|
||||
* <p>Generated interface from Pigeon that represents a handler of messages from Flutter.
|
||||
*/
|
||||
public interface HostSmallApi {
|
||||
|
||||
void echo(@NonNull String aString, Result<String> result);
|
||||
|
||||
void voidVoid(Result<Void> result);
|
||||
|
||||
/** The codec used by HostSmallApi. */
|
||||
static MessageCodec<Object> getCodec() {
|
||||
return new StandardMessageCodec();
|
||||
}
|
||||
/** Sets up an instance of `HostSmallApi` to handle messages through the `binaryMessenger`. */
|
||||
static void setup(BinaryMessenger binaryMessenger, HostSmallApi api) {
|
||||
{
|
||||
BasicMessageChannel<Object> channel =
|
||||
new BasicMessageChannel<>(
|
||||
binaryMessenger, "dev.flutter.pigeon.HostSmallApi.echo", getCodec());
|
||||
if (api != null) {
|
||||
channel.setMessageHandler(
|
||||
(message, reply) -> {
|
||||
ArrayList<Object> wrapped = new ArrayList<Object>();
|
||||
try {
|
||||
ArrayList<Object> args = (ArrayList<Object>) message;
|
||||
assert args != null;
|
||||
String aStringArg = (String) args.get(0);
|
||||
if (aStringArg == null) {
|
||||
throw new NullPointerException("aStringArg unexpectedly null.");
|
||||
}
|
||||
Result<String> resultCallback =
|
||||
new Result<String>() {
|
||||
public void success(String result) {
|
||||
wrapped.add(0, result);
|
||||
reply.reply(wrapped);
|
||||
}
|
||||
|
||||
public void error(Throwable error) {
|
||||
ArrayList<Object> wrappedError = wrapError(error);
|
||||
reply.reply(wrappedError);
|
||||
}
|
||||
};
|
||||
|
||||
api.echo(aStringArg, resultCallback);
|
||||
} catch (Error | RuntimeException exception) {
|
||||
ArrayList<Object> wrappedError = wrapError(exception);
|
||||
reply.reply(wrappedError);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel.setMessageHandler(null);
|
||||
}
|
||||
}
|
||||
{
|
||||
BasicMessageChannel<Object> channel =
|
||||
new BasicMessageChannel<>(
|
||||
binaryMessenger, "dev.flutter.pigeon.HostSmallApi.voidVoid", getCodec());
|
||||
if (api != null) {
|
||||
channel.setMessageHandler(
|
||||
(message, reply) -> {
|
||||
ArrayList<Object> wrapped = new ArrayList<Object>();
|
||||
try {
|
||||
Result<Void> resultCallback =
|
||||
new Result<Void>() {
|
||||
public void success(Void result) {
|
||||
wrapped.add(0, null);
|
||||
reply.reply(wrapped);
|
||||
}
|
||||
|
||||
public void error(Throwable error) {
|
||||
ArrayList<Object> wrappedError = wrapError(error);
|
||||
reply.reply(wrappedError);
|
||||
}
|
||||
};
|
||||
|
||||
api.voidVoid(resultCallback);
|
||||
} catch (Error | RuntimeException exception) {
|
||||
ArrayList<Object> wrappedError = wrapError(exception);
|
||||
reply.reply(wrappedError);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel.setMessageHandler(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class FlutterSmallApiCodec extends StandardMessageCodec {
|
||||
public static final FlutterSmallApiCodec INSTANCE = new FlutterSmallApiCodec();
|
||||
|
||||
private FlutterSmallApiCodec() {}
|
||||
|
||||
@Override
|
||||
protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
|
||||
switch (type) {
|
||||
case (byte) 128:
|
||||
return TestMessage.fromList((ArrayList<Object>) readValue(buffer));
|
||||
default:
|
||||
return super.readValueOfType(type, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
|
||||
if (value instanceof TestMessage) {
|
||||
stream.write(128);
|
||||
writeValue(stream, ((TestMessage) value).toList());
|
||||
} else {
|
||||
super.writeValue(stream, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple API called in some unit tests.
|
||||
*
|
||||
* <p>Generated class from Pigeon that represents Flutter messages that can be called from Java.
|
||||
*/
|
||||
public static class FlutterSmallApi {
|
||||
private final BinaryMessenger binaryMessenger;
|
||||
|
||||
public FlutterSmallApi(BinaryMessenger argBinaryMessenger) {
|
||||
this.binaryMessenger = argBinaryMessenger;
|
||||
}
|
||||
|
||||
/** Public interface for sending reply. */
|
||||
public interface Reply<T> {
|
||||
void reply(T reply);
|
||||
}
|
||||
/** The codec used by FlutterSmallApi. */
|
||||
static MessageCodec<Object> getCodec() {
|
||||
return FlutterSmallApiCodec.INSTANCE;
|
||||
}
|
||||
|
||||
public void echoWrappedList(@NonNull TestMessage msgArg, Reply<TestMessage> callback) {
|
||||
BasicMessageChannel<Object> channel =
|
||||
new BasicMessageChannel<>(
|
||||
binaryMessenger, "dev.flutter.pigeon.FlutterSmallApi.echoWrappedList", getCodec());
|
||||
channel.send(
|
||||
new ArrayList<Object>(Collections.singletonList(msgArg)),
|
||||
channelReply -> {
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
TestMessage output = (TestMessage) channelReply;
|
||||
callback.reply(output);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,8 @@ package com.example.alternate_language_test_plugin;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import com.example.alternate_language_test_plugin.AsyncHandlers.*;
|
||||
import androidx.annotation.NonNull;
|
||||
import com.example.alternate_language_test_plugin.CoreTests.*;
|
||||
import io.flutter.plugin.common.BinaryMessenger;
|
||||
import io.flutter.plugin.common.MessageCodec;
|
||||
import java.nio.ByteBuffer;
|
||||
@ -16,9 +17,9 @@ import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
public class AsyncTest {
|
||||
class Success implements Api2Host {
|
||||
class Success implements HostSmallApi {
|
||||
@Override
|
||||
public void calculate(Value value, Result<Value> result) {
|
||||
public void echo(@NonNull String value, Result<String> result) {
|
||||
result.success(value);
|
||||
}
|
||||
|
||||
@ -28,9 +29,9 @@ public class AsyncTest {
|
||||
}
|
||||
}
|
||||
|
||||
class Error implements Api2Host {
|
||||
class Error implements HostSmallApi {
|
||||
@Override
|
||||
public void calculate(Value value, Result<Value> result) {
|
||||
public void echo(@NonNull String value, Result<String> result) {
|
||||
result.error(new Exception("error"));
|
||||
}
|
||||
|
||||
@ -44,13 +45,13 @@ public class AsyncTest {
|
||||
public void asyncSuccess() {
|
||||
Success api = new Success();
|
||||
BinaryMessenger binaryMessenger = mock(BinaryMessenger.class);
|
||||
Api2Host.setup(binaryMessenger, api);
|
||||
HostSmallApi.setup(binaryMessenger, api);
|
||||
ArgumentCaptor<BinaryMessenger.BinaryMessageHandler> handler =
|
||||
ArgumentCaptor.forClass(BinaryMessenger.BinaryMessageHandler.class);
|
||||
verify(binaryMessenger).setMessageHandler(eq("dev.flutter.pigeon.Api2Host.calculate"), any());
|
||||
verify(binaryMessenger).setMessageHandler(eq("dev.flutter.pigeon.HostSmallApi.echo"), any());
|
||||
verify(binaryMessenger)
|
||||
.setMessageHandler(eq("dev.flutter.pigeon.Api2Host.voidVoid"), handler.capture());
|
||||
MessageCodec<Object> codec = Pigeon.AndroidApi.getCodec();
|
||||
.setMessageHandler(eq("dev.flutter.pigeon.HostSmallApi.voidVoid"), handler.capture());
|
||||
MessageCodec<Object> codec = HostSmallApi.getCodec();
|
||||
ByteBuffer message = codec.encodeMessage(null);
|
||||
Boolean[] didCall = {false};
|
||||
handler
|
||||
@ -71,13 +72,13 @@ public class AsyncTest {
|
||||
public void asyncError() {
|
||||
Error api = new Error();
|
||||
BinaryMessenger binaryMessenger = mock(BinaryMessenger.class);
|
||||
Api2Host.setup(binaryMessenger, api);
|
||||
HostSmallApi.setup(binaryMessenger, api);
|
||||
ArgumentCaptor<BinaryMessenger.BinaryMessageHandler> handler =
|
||||
ArgumentCaptor.forClass(BinaryMessenger.BinaryMessageHandler.class);
|
||||
verify(binaryMessenger).setMessageHandler(eq("dev.flutter.pigeon.Api2Host.calculate"), any());
|
||||
verify(binaryMessenger).setMessageHandler(eq("dev.flutter.pigeon.HostSmallApi.echo"), any());
|
||||
verify(binaryMessenger)
|
||||
.setMessageHandler(eq("dev.flutter.pigeon.Api2Host.voidVoid"), handler.capture());
|
||||
MessageCodec<Object> codec = Pigeon.AndroidApi.getCodec();
|
||||
.setMessageHandler(eq("dev.flutter.pigeon.HostSmallApi.voidVoid"), handler.capture());
|
||||
MessageCodec<Object> codec = HostSmallApi.getCodec();
|
||||
ByteBuffer message = codec.encodeMessage(null);
|
||||
Boolean[] didCall = {false};
|
||||
handler
|
||||
|
@ -7,8 +7,8 @@ package com.example.alternate_language_test_plugin;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import com.example.alternate_language_test_plugin.PigeonList.EchoApi;
|
||||
import com.example.alternate_language_test_plugin.PigeonList.TestMessage;
|
||||
import com.example.alternate_language_test_plugin.CoreTests.FlutterSmallApi;
|
||||
import com.example.alternate_language_test_plugin.CoreTests.TestMessage;
|
||||
import io.flutter.plugin.common.BinaryMessenger;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
@ -28,17 +28,17 @@ public class ListTest {
|
||||
ByteBuffer message = invocation.getArgument(1);
|
||||
BinaryMessenger.BinaryReply reply = invocation.getArgument(2);
|
||||
message.position(0);
|
||||
ArrayList args = (ArrayList) EchoApi.getCodec().decodeMessage(message);
|
||||
ByteBuffer replyData = EchoApi.getCodec().encodeMessage(args.get(0));
|
||||
ArrayList args = (ArrayList) FlutterSmallApi.getCodec().decodeMessage(message);
|
||||
ByteBuffer replyData = FlutterSmallApi.getCodec().encodeMessage(args.get(0));
|
||||
replyData.position(0);
|
||||
reply.reply(replyData);
|
||||
return null;
|
||||
})
|
||||
.when(binaryMessenger)
|
||||
.send(anyString(), any(), any());
|
||||
EchoApi api = new EchoApi(binaryMessenger);
|
||||
FlutterSmallApi api = new FlutterSmallApi(binaryMessenger);
|
||||
boolean[] didCall = {false};
|
||||
api.echo(
|
||||
api.echoWrappedList(
|
||||
top,
|
||||
(result) -> {
|
||||
didCall[0] = true;
|
||||
|
@ -7,63 +7,40 @@ package com.example.alternate_language_test_plugin;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import com.example.alternate_language_test_plugin.CoreTests.HostSmallApi;
|
||||
import io.flutter.plugin.common.BinaryMessenger;
|
||||
import io.flutter.plugin.common.MessageCodec;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
public class PigeonTest {
|
||||
@Test
|
||||
public void toListAndBack() {
|
||||
Pigeon.AndroidSetRequest request = new Pigeon.AndroidSetRequest();
|
||||
request.setValue(1234l);
|
||||
request.setState(Pigeon.AndroidLoadingState.COMPLETE);
|
||||
ArrayList<Object> list = request.toList();
|
||||
Pigeon.AndroidSetRequest readRequest = Pigeon.AndroidSetRequest.fromList(list);
|
||||
assertEquals(request.getValue(), readRequest.getValue());
|
||||
assertEquals(request.getState(), readRequest.getState());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toListAndBackNested() {
|
||||
Pigeon.AndroidNestedRequest nested = new Pigeon.AndroidNestedRequest();
|
||||
Pigeon.AndroidSetRequest request = new Pigeon.AndroidSetRequest();
|
||||
request.setValue(1234l);
|
||||
request.setState(Pigeon.AndroidLoadingState.COMPLETE);
|
||||
nested.setRequest(request);
|
||||
ArrayList<Object> list = nested.toList();
|
||||
Pigeon.AndroidNestedRequest readNested = Pigeon.AndroidNestedRequest.fromList(list);
|
||||
assertEquals(nested.getRequest().getValue(), readNested.getRequest().getValue());
|
||||
assertEquals(nested.getRequest().getState(), readNested.getRequest().getState());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clearsHandler() {
|
||||
Pigeon.AndroidApi mockApi = mock(Pigeon.AndroidApi.class);
|
||||
HostSmallApi mockApi = mock(HostSmallApi.class);
|
||||
BinaryMessenger binaryMessenger = mock(BinaryMessenger.class);
|
||||
Pigeon.AndroidApi.setup(binaryMessenger, mockApi);
|
||||
HostSmallApi.setup(binaryMessenger, mockApi);
|
||||
ArgumentCaptor<String> channelName = ArgumentCaptor.forClass(String.class);
|
||||
verify(binaryMessenger).setMessageHandler(channelName.capture(), isNotNull());
|
||||
Pigeon.AndroidApi.setup(binaryMessenger, null);
|
||||
verify(binaryMessenger).setMessageHandler(eq(channelName.getValue()), isNull());
|
||||
verify(binaryMessenger, atLeast(1)).setMessageHandler(channelName.capture(), isNotNull());
|
||||
HostSmallApi.setup(binaryMessenger, null);
|
||||
verify(binaryMessenger, atLeast(1)).setMessageHandler(eq(channelName.getValue()), isNull());
|
||||
}
|
||||
|
||||
/** Causes an exception in the handler by passing in null when a AndroidSetRequest is expected. */
|
||||
/** Causes an exception in the handler by passing in null when a non-null value is expected. */
|
||||
@Test
|
||||
public void errorMessage() {
|
||||
Pigeon.AndroidApi mockApi = mock(Pigeon.AndroidApi.class);
|
||||
HostSmallApi mockApi = mock(HostSmallApi.class);
|
||||
BinaryMessenger binaryMessenger = mock(BinaryMessenger.class);
|
||||
Pigeon.AndroidApi.setup(binaryMessenger, mockApi);
|
||||
HostSmallApi.setup(binaryMessenger, mockApi);
|
||||
ArgumentCaptor<BinaryMessenger.BinaryMessageHandler> handler =
|
||||
ArgumentCaptor.forClass(BinaryMessenger.BinaryMessageHandler.class);
|
||||
verify(binaryMessenger).setMessageHandler(anyString(), handler.capture());
|
||||
MessageCodec<Object> codec = Pigeon.AndroidApi.getCodec();
|
||||
verify(binaryMessenger, atLeast(1)).setMessageHandler(anyString(), handler.capture());
|
||||
MessageCodec<Object> codec = HostSmallApi.getCodec();
|
||||
ByteBuffer message = codec.encodeMessage(null);
|
||||
handler
|
||||
.getValue()
|
||||
.getAllValues()
|
||||
.get(0) // "echo" is the first method.
|
||||
.onMessage(
|
||||
message,
|
||||
(bytes) -> {
|
||||
@ -77,44 +54,4 @@ public class PigeonTest {
|
||||
assertTrue(details.contains("Stacktrace:"));
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void callsVoidMethod() {
|
||||
Pigeon.AndroidApi mockApi = mock(Pigeon.AndroidApi.class);
|
||||
BinaryMessenger binaryMessenger = mock(BinaryMessenger.class);
|
||||
Pigeon.AndroidApi.setup(binaryMessenger, mockApi);
|
||||
ArgumentCaptor<BinaryMessenger.BinaryMessageHandler> handler =
|
||||
ArgumentCaptor.forClass(BinaryMessenger.BinaryMessageHandler.class);
|
||||
verify(binaryMessenger).setMessageHandler(anyString(), handler.capture());
|
||||
Pigeon.AndroidSetRequest request = new Pigeon.AndroidSetRequest();
|
||||
request.setValue(1234l);
|
||||
request.setState(Pigeon.AndroidLoadingState.COMPLETE);
|
||||
MessageCodec<Object> codec = Pigeon.AndroidApi.getCodec();
|
||||
ByteBuffer message = codec.encodeMessage(new ArrayList<Object>(Arrays.asList(request)));
|
||||
message.rewind();
|
||||
handler
|
||||
.getValue()
|
||||
.onMessage(
|
||||
message,
|
||||
(bytes) -> {
|
||||
bytes.rewind();
|
||||
@SuppressWarnings("unchecked")
|
||||
ArrayList wrapped = (ArrayList) codec.decodeMessage(bytes);
|
||||
assertTrue(wrapped.size() == 1);
|
||||
assertNull(wrapped.get(0));
|
||||
});
|
||||
ArgumentCaptor<Pigeon.AndroidSetRequest> receivedRequest =
|
||||
ArgumentCaptor.forClass(Pigeon.AndroidSetRequest.class);
|
||||
verify(mockApi).setValue(receivedRequest.capture());
|
||||
assertEquals(request.getValue(), receivedRequest.getValue().getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeWithNullField() {
|
||||
Pigeon.AndroidNestedRequest request = new Pigeon.AndroidNestedRequest();
|
||||
request.setContext("hello");
|
||||
MessageCodec<Object> codec = Pigeon.AndroidNestedApi.getCodec();
|
||||
ByteBuffer message = codec.encodeMessage(request);
|
||||
assertNotNull(message);
|
||||
}
|
||||
}
|
||||
|
@ -10,26 +10,18 @@
|
||||
#import "MockBinaryMessenger.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@interface Value ()
|
||||
+ (Value *)fromList:(NSArray *)list;
|
||||
- (NSArray *)toList;
|
||||
@end
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@interface MockApi2Host : NSObject <Api2Host>
|
||||
@property(nonatomic, copy) NSNumber *output;
|
||||
@interface MockHostSmallApi : NSObject <HostSmallApi>
|
||||
@property(nonatomic, copy) NSString *output;
|
||||
@property(nonatomic, retain) FlutterError *voidVoidError;
|
||||
@end
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
@implementation MockApi2Host
|
||||
@implementation MockHostSmallApi
|
||||
|
||||
- (void)calculateValue:(Value *)input
|
||||
completion:(nonnull void (^)(Value *_Nullable, FlutterError *_Nullable))completion {
|
||||
- (void)echoString:(NSString *)value
|
||||
completion:(nonnull void (^)(NSString *_Nullable, FlutterError *_Nullable))completion {
|
||||
if (self.output) {
|
||||
Value *output = [[Value alloc] init];
|
||||
output.number = self.output;
|
||||
completion(output, nil);
|
||||
completion(self.output, nil);
|
||||
} else {
|
||||
completion(nil, [FlutterError errorWithCode:@"hey" message:@"ho" details:nil]);
|
||||
}
|
||||
@ -50,15 +42,15 @@
|
||||
|
||||
- (void)testAsyncHost2Flutter {
|
||||
MockBinaryMessenger *binaryMessenger =
|
||||
[[MockBinaryMessenger alloc] initWithCodec:Api2FlutterGetCodec()];
|
||||
binaryMessenger.result = [Value makeWithNumber:@(2)];
|
||||
Api2Flutter *api2Flutter = [[Api2Flutter alloc] initWithBinaryMessenger:binaryMessenger];
|
||||
Value *input = [[Value alloc] init];
|
||||
input.number = @(1);
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"calculate callback"];
|
||||
[api2Flutter calculateValue:input
|
||||
completion:^(Value *_Nonnull output, FlutterError *_Nullable error) {
|
||||
XCTAssertEqual(output.number.intValue, 2);
|
||||
[[MockBinaryMessenger alloc] initWithCodec:FlutterIntegrationCoreApiGetCodec()];
|
||||
NSString *value = @"Test";
|
||||
binaryMessenger.result = value;
|
||||
FlutterIntegrationCoreApi *flutterApi =
|
||||
[[FlutterIntegrationCoreApi alloc] initWithBinaryMessenger:binaryMessenger];
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"echo callback"];
|
||||
[flutterApi echoAsyncString:value
|
||||
completion:^(NSString *_Nonnull output, FlutterError *_Nullable error) {
|
||||
XCTAssertEqualObjects(output, value);
|
||||
[expectation fulfill];
|
||||
}];
|
||||
[self waitForExpectationsWithTimeout:1.0 handler:nil];
|
||||
@ -66,11 +58,10 @@
|
||||
|
||||
- (void)testAsyncFlutter2HostVoidVoid {
|
||||
MockBinaryMessenger *binaryMessenger =
|
||||
[[MockBinaryMessenger alloc] initWithCodec:Api2HostGetCodec()];
|
||||
MockApi2Host *mockApi2Host = [[MockApi2Host alloc] init];
|
||||
mockApi2Host.output = @(2);
|
||||
Api2HostSetup(binaryMessenger, mockApi2Host);
|
||||
NSString *channelName = @"dev.flutter.pigeon.Api2Host.voidVoid";
|
||||
[[MockBinaryMessenger alloc] initWithCodec:HostSmallApiGetCodec()];
|
||||
MockHostSmallApi *mockHostSmallApi = [[MockHostSmallApi alloc] init];
|
||||
HostSmallApiSetup(binaryMessenger, mockHostSmallApi);
|
||||
NSString *channelName = @"dev.flutter.pigeon.HostSmallApi.voidVoid";
|
||||
XCTAssertNotNil(binaryMessenger.handlers[channelName]);
|
||||
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"voidvoid callback"];
|
||||
@ -84,18 +75,20 @@
|
||||
|
||||
- (void)testAsyncFlutter2HostVoidVoidError {
|
||||
MockBinaryMessenger *binaryMessenger =
|
||||
[[MockBinaryMessenger alloc] initWithCodec:Api2HostGetCodec()];
|
||||
MockApi2Host *mockApi2Host = [[MockApi2Host alloc] init];
|
||||
mockApi2Host.voidVoidError = [FlutterError errorWithCode:@"code" message:@"message" details:nil];
|
||||
Api2HostSetup(binaryMessenger, mockApi2Host);
|
||||
NSString *channelName = @"dev.flutter.pigeon.Api2Host.voidVoid";
|
||||
[[MockBinaryMessenger alloc] initWithCodec:HostSmallApiGetCodec()];
|
||||
MockHostSmallApi *mockHostSmallApi = [[MockHostSmallApi alloc] init];
|
||||
mockHostSmallApi.voidVoidError = [FlutterError errorWithCode:@"code"
|
||||
message:@"message"
|
||||
details:nil];
|
||||
HostSmallApiSetup(binaryMessenger, mockHostSmallApi);
|
||||
NSString *channelName = @"dev.flutter.pigeon.HostSmallApi.voidVoid";
|
||||
XCTAssertNotNil(binaryMessenger.handlers[channelName]);
|
||||
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"voidvoid callback"];
|
||||
binaryMessenger.handlers[channelName](nil, ^(NSData *data) {
|
||||
NSArray *outputList = [binaryMessenger.codec decode:data];
|
||||
XCTAssertNotNil(outputList);
|
||||
XCTAssertEqualObjects(outputList[0], mockApi2Host.voidVoidError.code);
|
||||
XCTAssertEqualObjects(outputList[0], mockHostSmallApi.voidVoidError.code);
|
||||
[expectation fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1.0 handler:nil];
|
||||
@ -103,21 +96,20 @@
|
||||
|
||||
- (void)testAsyncFlutter2Host {
|
||||
MockBinaryMessenger *binaryMessenger =
|
||||
[[MockBinaryMessenger alloc] initWithCodec:Api2HostGetCodec()];
|
||||
MockApi2Host *mockApi2Host = [[MockApi2Host alloc] init];
|
||||
mockApi2Host.output = @(2);
|
||||
Api2HostSetup(binaryMessenger, mockApi2Host);
|
||||
NSString *channelName = @"dev.flutter.pigeon.Api2Host.calculate";
|
||||
[[MockBinaryMessenger alloc] initWithCodec:HostSmallApiGetCodec()];
|
||||
MockHostSmallApi *mockHostSmallApi = [[MockHostSmallApi alloc] init];
|
||||
NSString *value = @"Test";
|
||||
mockHostSmallApi.output = value;
|
||||
HostSmallApiSetup(binaryMessenger, mockHostSmallApi);
|
||||
NSString *channelName = @"dev.flutter.pigeon.HostSmallApi.echo";
|
||||
XCTAssertNotNil(binaryMessenger.handlers[channelName]);
|
||||
|
||||
Value *input = [[Value alloc] init];
|
||||
input.number = @(1);
|
||||
NSData *inputEncoded = [binaryMessenger.codec encode:@[ input ]];
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"calculate callback"];
|
||||
NSData *inputEncoded = [binaryMessenger.codec encode:@[ value ]];
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"echo callback"];
|
||||
binaryMessenger.handlers[channelName](inputEncoded, ^(NSData *data) {
|
||||
NSArray *outputList = [binaryMessenger.codec decode:data];
|
||||
Value *output = outputList[0];
|
||||
XCTAssertEqual(output.number.intValue, 2);
|
||||
NSString *output = outputList[0];
|
||||
XCTAssertEqualObjects(output, value);
|
||||
[expectation fulfill];
|
||||
});
|
||||
[self waitForExpectationsWithTimeout:1.0 handler:nil];
|
||||
@ -125,16 +117,14 @@
|
||||
|
||||
- (void)testAsyncFlutter2HostError {
|
||||
MockBinaryMessenger *binaryMessenger =
|
||||
[[MockBinaryMessenger alloc] initWithCodec:Api2HostGetCodec()];
|
||||
MockApi2Host *mockApi2Host = [[MockApi2Host alloc] init];
|
||||
Api2HostSetup(binaryMessenger, mockApi2Host);
|
||||
NSString *channelName = @"dev.flutter.pigeon.Api2Host.calculate";
|
||||
[[MockBinaryMessenger alloc] initWithCodec:HostSmallApiGetCodec()];
|
||||
MockHostSmallApi *mockHostSmallApi = [[MockHostSmallApi alloc] init];
|
||||
HostSmallApiSetup(binaryMessenger, mockHostSmallApi);
|
||||
NSString *channelName = @"dev.flutter.pigeon.HostSmallApi.echo";
|
||||
XCTAssertNotNil(binaryMessenger.handlers[channelName]);
|
||||
|
||||
Value *input = [[Value alloc] init];
|
||||
input.number = @(1);
|
||||
NSData *inputEncoded = [binaryMessenger.codec encode:@[ [input toList] ]];
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"calculate callback"];
|
||||
NSData *inputEncoded = [binaryMessenger.codec encode:@[ @"Test" ]];
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"echo callback"];
|
||||
binaryMessenger.handlers[channelName](inputEncoded, ^(NSData *data) {
|
||||
NSArray *outputList = [binaryMessenger.codec decode:data];
|
||||
XCTAssertNotNil(outputList);
|
||||
|
@ -22,16 +22,16 @@
|
||||
inside.testList = @[ @1, @2, @3 ];
|
||||
top.testList = @[ inside ];
|
||||
EchoBinaryMessenger *binaryMessenger =
|
||||
[[EchoBinaryMessenger alloc] initWithCodec:EchoApiGetCodec()];
|
||||
EchoApi *api = [[EchoApi alloc] initWithBinaryMessenger:binaryMessenger];
|
||||
[[EchoBinaryMessenger alloc] initWithCodec:FlutterSmallApiGetCodec()];
|
||||
FlutterSmallApi *api = [[FlutterSmallApi alloc] initWithBinaryMessenger:binaryMessenger];
|
||||
XCTestExpectation *expectation = [self expectationWithDescription:@"callback"];
|
||||
[api echoMsg:top
|
||||
completion:^(TestMessage *_Nonnull result, FlutterError *_Nullable err) {
|
||||
XCTAssertEqual(1u, result.testList.count);
|
||||
XCTAssertTrue([result.testList[0] isKindOfClass:[TestMessage class]]);
|
||||
XCTAssertEqualObjects(inside.testList, [result.testList[0] testList]);
|
||||
[expectation fulfill];
|
||||
}];
|
||||
[api echoWrappedList:top
|
||||
completion:^(TestMessage *_Nonnull result, FlutterError *_Nullable err) {
|
||||
XCTAssertEqual(1u, result.testList.count);
|
||||
XCTAssertTrue([result.testList[0] isKindOfClass:[TestMessage class]]);
|
||||
XCTAssertEqualObjects(inside.testList, [result.testList[0] testList]);
|
||||
[expectation fulfill];
|
||||
}];
|
||||
[self waitForExpectations:@[ expectation ] timeout:1.0];
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@ typedef NS_ENUM(NSUInteger, AnEnum) {
|
||||
@class AllTypes;
|
||||
@class AllNullableTypes;
|
||||
@class AllNullableTypesWrapper;
|
||||
@class TestMessage;
|
||||
|
||||
@interface AllTypes : NSObject
|
||||
/// `init` unavailable to enforce nonnull fields, see the `make` class method.
|
||||
@ -91,6 +92,12 @@ typedef NS_ENUM(NSUInteger, AnEnum) {
|
||||
@property(nonatomic, strong) AllNullableTypes *values;
|
||||
@end
|
||||
|
||||
/// A data class containing a List, used in unit tests.
|
||||
@interface TestMessage : NSObject
|
||||
+ (instancetype)makeWithTestList:(nullable NSArray *)testList;
|
||||
@property(nonatomic, strong, nullable) NSArray *testList;
|
||||
@end
|
||||
|
||||
/// The codec used by HostIntegrationCoreApi.
|
||||
NSObject<FlutterMessageCodec> *HostIntegrationCoreApiGetCodec(void);
|
||||
|
||||
@ -388,6 +395,12 @@ NSObject<FlutterMessageCodec> *FlutterIntegrationCoreApiGetCodec(void);
|
||||
- (void)echoNullableMap:(nullable NSDictionary<NSString *, id> *)aMap
|
||||
completion:(void (^)(NSDictionary<NSString *, id> *_Nullable,
|
||||
FlutterError *_Nullable))completion;
|
||||
/// A no-op function taking no arguments and returning no value, to sanity
|
||||
/// test basic asynchronous calling.
|
||||
- (void)noopAsyncWithCompletion:(void (^)(FlutterError *_Nullable))completion;
|
||||
/// Returns the passed in generic Object asynchronously.
|
||||
- (void)echoAsyncString:(NSString *)aString
|
||||
completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion;
|
||||
@end
|
||||
|
||||
/// The codec used by HostTrivialApi.
|
||||
@ -401,4 +414,27 @@ NSObject<FlutterMessageCodec> *HostTrivialApiGetCodec(void);
|
||||
extern void HostTrivialApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
|
||||
NSObject<HostTrivialApi> *_Nullable api);
|
||||
|
||||
/// The codec used by HostSmallApi.
|
||||
NSObject<FlutterMessageCodec> *HostSmallApiGetCodec(void);
|
||||
|
||||
/// A simple API implemented in some unit tests.
|
||||
@protocol HostSmallApi
|
||||
- (void)echoString:(NSString *)aString
|
||||
completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion;
|
||||
- (void)voidVoidWithCompletion:(void (^)(FlutterError *_Nullable))completion;
|
||||
@end
|
||||
|
||||
extern void HostSmallApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
|
||||
NSObject<HostSmallApi> *_Nullable api);
|
||||
|
||||
/// The codec used by FlutterSmallApi.
|
||||
NSObject<FlutterMessageCodec> *FlutterSmallApiGetCodec(void);
|
||||
|
||||
/// A simple API called in some unit tests.
|
||||
@interface FlutterSmallApi : NSObject
|
||||
- (instancetype)initWithBinaryMessenger:(id<FlutterBinaryMessenger>)binaryMessenger;
|
||||
- (void)echoWrappedList:(TestMessage *)msg
|
||||
completion:(void (^)(TestMessage *_Nullable, FlutterError *_Nullable))completion;
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
@ -43,6 +43,12 @@ static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) {
|
||||
- (NSArray *)toList;
|
||||
@end
|
||||
|
||||
@interface TestMessage ()
|
||||
+ (TestMessage *)fromList:(NSArray *)list;
|
||||
+ (nullable TestMessage *)nullableFromList:(NSArray *)list;
|
||||
- (NSArray *)toList;
|
||||
@end
|
||||
|
||||
@implementation AllTypes
|
||||
+ (instancetype)makeWithABool:(NSNumber *)aBool
|
||||
anInt:(NSNumber *)anInt
|
||||
@ -210,6 +216,27 @@ static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) {
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation TestMessage
|
||||
+ (instancetype)makeWithTestList:(nullable NSArray *)testList {
|
||||
TestMessage *pigeonResult = [[TestMessage alloc] init];
|
||||
pigeonResult.testList = testList;
|
||||
return pigeonResult;
|
||||
}
|
||||
+ (TestMessage *)fromList:(NSArray *)list {
|
||||
TestMessage *pigeonResult = [[TestMessage alloc] init];
|
||||
pigeonResult.testList = GetNullableObjectAtIndex(list, 0);
|
||||
return pigeonResult;
|
||||
}
|
||||
+ (nullable TestMessage *)nullableFromList:(NSArray *)list {
|
||||
return (list) ? [TestMessage fromList:list] : nil;
|
||||
}
|
||||
- (NSArray *)toList {
|
||||
return @[
|
||||
(self.testList ?: [NSNull null]),
|
||||
];
|
||||
}
|
||||
@end
|
||||
|
||||
@interface HostIntegrationCoreApiCodecReader : FlutterStandardReader
|
||||
@end
|
||||
@implementation HostIntegrationCoreApiCodecReader
|
||||
@ -221,6 +248,8 @@ static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) {
|
||||
return [AllNullableTypesWrapper fromList:[self readValue]];
|
||||
case 130:
|
||||
return [AllTypes fromList:[self readValue]];
|
||||
case 131:
|
||||
return [TestMessage fromList:[self readValue]];
|
||||
default:
|
||||
return [super readValueOfType:type];
|
||||
}
|
||||
@ -240,6 +269,9 @@ static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) {
|
||||
} else if ([value isKindOfClass:[AllTypes class]]) {
|
||||
[self writeByte:130];
|
||||
[self writeValue:[value toList]];
|
||||
} else if ([value isKindOfClass:[TestMessage class]]) {
|
||||
[self writeByte:131];
|
||||
[self writeValue:[value toList]];
|
||||
} else {
|
||||
[super writeValue:value];
|
||||
}
|
||||
@ -1715,6 +1747,8 @@ void HostIntegrationCoreApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
|
||||
return [AllNullableTypesWrapper fromList:[self readValue]];
|
||||
case 130:
|
||||
return [AllTypes fromList:[self readValue]];
|
||||
case 131:
|
||||
return [TestMessage fromList:[self readValue]];
|
||||
default:
|
||||
return [super readValueOfType:type];
|
||||
}
|
||||
@ -1734,6 +1768,9 @@ void HostIntegrationCoreApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
|
||||
} else if ([value isKindOfClass:[AllTypes class]]) {
|
||||
[self writeByte:130];
|
||||
[self writeValue:[value toList]];
|
||||
} else if ([value isKindOfClass:[TestMessage class]]) {
|
||||
[self writeByte:131];
|
||||
[self writeValue:[value toList]];
|
||||
} else {
|
||||
[super writeValue:value];
|
||||
}
|
||||
@ -2022,6 +2059,28 @@ NSObject<FlutterMessageCodec> *FlutterIntegrationCoreApiGetCodec() {
|
||||
completion(output, nil);
|
||||
}];
|
||||
}
|
||||
- (void)noopAsyncWithCompletion:(void (^)(FlutterError *_Nullable))completion {
|
||||
FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
|
||||
messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.noopAsync"
|
||||
binaryMessenger:self.binaryMessenger
|
||||
codec:FlutterIntegrationCoreApiGetCodec()];
|
||||
[channel sendMessage:nil
|
||||
reply:^(id reply) {
|
||||
completion(nil);
|
||||
}];
|
||||
}
|
||||
- (void)echoAsyncString:(NSString *)arg_aString
|
||||
completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion {
|
||||
FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
|
||||
messageChannelWithName:@"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAsyncString"
|
||||
binaryMessenger:self.binaryMessenger
|
||||
codec:FlutterIntegrationCoreApiGetCodec()];
|
||||
[channel sendMessage:@[ arg_aString ?: [NSNull null] ]
|
||||
reply:^(id reply) {
|
||||
NSString *output = reply;
|
||||
completion(output, nil);
|
||||
}];
|
||||
}
|
||||
@end
|
||||
|
||||
NSObject<FlutterMessageCodec> *HostTrivialApiGetCodec() {
|
||||
@ -2050,3 +2109,123 @@ void HostTrivialApiSetup(id<FlutterBinaryMessenger> binaryMessenger,
|
||||
}
|
||||
}
|
||||
}
|
||||
NSObject<FlutterMessageCodec> *HostSmallApiGetCodec() {
|
||||
static FlutterStandardMessageCodec *sSharedObject = nil;
|
||||
sSharedObject = [FlutterStandardMessageCodec sharedInstance];
|
||||
return sSharedObject;
|
||||
}
|
||||
|
||||
void HostSmallApiSetup(id<FlutterBinaryMessenger> binaryMessenger, NSObject<HostSmallApi> *api) {
|
||||
{
|
||||
FlutterBasicMessageChannel *channel =
|
||||
[[FlutterBasicMessageChannel alloc] initWithName:@"dev.flutter.pigeon.HostSmallApi.echo"
|
||||
binaryMessenger:binaryMessenger
|
||||
codec:HostSmallApiGetCodec()];
|
||||
if (api) {
|
||||
NSCAssert([api respondsToSelector:@selector(echoString:completion:)],
|
||||
@"HostSmallApi api (%@) doesn't respond to @selector(echoString:completion:)", api);
|
||||
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
|
||||
NSArray *args = message;
|
||||
NSString *arg_aString = GetNullableObjectAtIndex(args, 0);
|
||||
[api echoString:arg_aString
|
||||
completion:^(NSString *_Nullable output, FlutterError *_Nullable error) {
|
||||
callback(wrapResult(output, error));
|
||||
}];
|
||||
}];
|
||||
} else {
|
||||
[channel setMessageHandler:nil];
|
||||
}
|
||||
}
|
||||
{
|
||||
FlutterBasicMessageChannel *channel =
|
||||
[[FlutterBasicMessageChannel alloc] initWithName:@"dev.flutter.pigeon.HostSmallApi.voidVoid"
|
||||
binaryMessenger:binaryMessenger
|
||||
codec:HostSmallApiGetCodec()];
|
||||
if (api) {
|
||||
NSCAssert([api respondsToSelector:@selector(voidVoidWithCompletion:)],
|
||||
@"HostSmallApi api (%@) doesn't respond to @selector(voidVoidWithCompletion:)",
|
||||
api);
|
||||
[channel setMessageHandler:^(id _Nullable message, FlutterReply callback) {
|
||||
[api voidVoidWithCompletion:^(FlutterError *_Nullable error) {
|
||||
callback(wrapResult(nil, error));
|
||||
}];
|
||||
}];
|
||||
} else {
|
||||
[channel setMessageHandler:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
@interface FlutterSmallApiCodecReader : FlutterStandardReader
|
||||
@end
|
||||
@implementation FlutterSmallApiCodecReader
|
||||
- (nullable id)readValueOfType:(UInt8)type {
|
||||
switch (type) {
|
||||
case 128:
|
||||
return [TestMessage fromList:[self readValue]];
|
||||
default:
|
||||
return [super readValueOfType:type];
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
@interface FlutterSmallApiCodecWriter : FlutterStandardWriter
|
||||
@end
|
||||
@implementation FlutterSmallApiCodecWriter
|
||||
- (void)writeValue:(id)value {
|
||||
if ([value isKindOfClass:[TestMessage class]]) {
|
||||
[self writeByte:128];
|
||||
[self writeValue:[value toList]];
|
||||
} else {
|
||||
[super writeValue:value];
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
@interface FlutterSmallApiCodecReaderWriter : FlutterStandardReaderWriter
|
||||
@end
|
||||
@implementation FlutterSmallApiCodecReaderWriter
|
||||
- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data {
|
||||
return [[FlutterSmallApiCodecWriter alloc] initWithData:data];
|
||||
}
|
||||
- (FlutterStandardReader *)readerWithData:(NSData *)data {
|
||||
return [[FlutterSmallApiCodecReader alloc] initWithData:data];
|
||||
}
|
||||
@end
|
||||
|
||||
NSObject<FlutterMessageCodec> *FlutterSmallApiGetCodec() {
|
||||
static FlutterStandardMessageCodec *sSharedObject = nil;
|
||||
static dispatch_once_t sPred = 0;
|
||||
dispatch_once(&sPred, ^{
|
||||
FlutterSmallApiCodecReaderWriter *readerWriter =
|
||||
[[FlutterSmallApiCodecReaderWriter alloc] init];
|
||||
sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter];
|
||||
});
|
||||
return sSharedObject;
|
||||
}
|
||||
|
||||
@interface FlutterSmallApi ()
|
||||
@property(nonatomic, strong) NSObject<FlutterBinaryMessenger> *binaryMessenger;
|
||||
@end
|
||||
|
||||
@implementation FlutterSmallApi
|
||||
|
||||
- (instancetype)initWithBinaryMessenger:(NSObject<FlutterBinaryMessenger> *)binaryMessenger {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_binaryMessenger = binaryMessenger;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
- (void)echoWrappedList:(TestMessage *)arg_msg
|
||||
completion:(void (^)(TestMessage *_Nullable, FlutterError *_Nullable))completion {
|
||||
FlutterBasicMessageChannel *channel = [FlutterBasicMessageChannel
|
||||
messageChannelWithName:@"dev.flutter.pigeon.FlutterSmallApi.echoWrappedList"
|
||||
binaryMessenger:self.binaryMessenger
|
||||
codec:FlutterSmallApiGetCodec()];
|
||||
[channel sendMessage:@[ arg_msg ?: [NSNull null] ]
|
||||
reply:^(id reply) {
|
||||
TestMessage *output = reply;
|
||||
completion(output, nil);
|
||||
}];
|
||||
}
|
||||
@end
|
||||
|
@ -199,6 +199,28 @@ class AllNullableTypesWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
/// A data class containing a List, used in unit tests.
|
||||
class TestMessage {
|
||||
TestMessage({
|
||||
this.testList,
|
||||
});
|
||||
|
||||
List<Object?>? testList;
|
||||
|
||||
Object encode() {
|
||||
return <Object?>[
|
||||
testList,
|
||||
];
|
||||
}
|
||||
|
||||
static TestMessage decode(Object result) {
|
||||
result as List<Object?>;
|
||||
return TestMessage(
|
||||
testList: result[0] as List<Object?>?,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _HostIntegrationCoreApiCodec extends StandardMessageCodec {
|
||||
const _HostIntegrationCoreApiCodec();
|
||||
@override
|
||||
@ -212,6 +234,9 @@ class _HostIntegrationCoreApiCodec extends StandardMessageCodec {
|
||||
} else if (value is AllTypes) {
|
||||
buffer.putUint8(130);
|
||||
writeValue(buffer, value.encode());
|
||||
} else if (value is TestMessage) {
|
||||
buffer.putUint8(131);
|
||||
writeValue(buffer, value.encode());
|
||||
} else {
|
||||
super.writeValue(buffer, value);
|
||||
}
|
||||
@ -226,6 +251,8 @@ class _HostIntegrationCoreApiCodec extends StandardMessageCodec {
|
||||
return AllNullableTypesWrapper.decode(readValue(buffer)!);
|
||||
case 130:
|
||||
return AllTypes.decode(readValue(buffer)!);
|
||||
case 131:
|
||||
return TestMessage.decode(readValue(buffer)!);
|
||||
default:
|
||||
return super.readValueOfType(type, buffer);
|
||||
}
|
||||
@ -1897,6 +1924,9 @@ class _FlutterIntegrationCoreApiCodec extends StandardMessageCodec {
|
||||
} else if (value is AllTypes) {
|
||||
buffer.putUint8(130);
|
||||
writeValue(buffer, value.encode());
|
||||
} else if (value is TestMessage) {
|
||||
buffer.putUint8(131);
|
||||
writeValue(buffer, value.encode());
|
||||
} else {
|
||||
super.writeValue(buffer, value);
|
||||
}
|
||||
@ -1911,6 +1941,8 @@ class _FlutterIntegrationCoreApiCodec extends StandardMessageCodec {
|
||||
return AllNullableTypesWrapper.decode(readValue(buffer)!);
|
||||
case 130:
|
||||
return AllTypes.decode(readValue(buffer)!);
|
||||
case 131:
|
||||
return TestMessage.decode(readValue(buffer)!);
|
||||
default:
|
||||
return super.readValueOfType(type, buffer);
|
||||
}
|
||||
@ -1986,6 +2018,13 @@ abstract class FlutterIntegrationCoreApi {
|
||||
/// Returns the passed map, to test serialization and deserialization.
|
||||
Map<String?, Object?>? echoNullableMap(Map<String?, Object?>? aMap);
|
||||
|
||||
/// A no-op function taking no arguments and returning no value, to sanity
|
||||
/// test basic asynchronous calling.
|
||||
Future<void> noopAsync();
|
||||
|
||||
/// Returns the passed in generic Object asynchronously.
|
||||
Future<String> echoAsyncString(String aString);
|
||||
|
||||
static void setup(FlutterIntegrationCoreApi? api,
|
||||
{BinaryMessenger? binaryMessenger}) {
|
||||
{
|
||||
@ -2354,6 +2393,39 @@ abstract class FlutterIntegrationCoreApi {
|
||||
});
|
||||
}
|
||||
}
|
||||
{
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.FlutterIntegrationCoreApi.noopAsync', codec,
|
||||
binaryMessenger: binaryMessenger);
|
||||
if (api == null) {
|
||||
channel.setMessageHandler(null);
|
||||
} else {
|
||||
channel.setMessageHandler((Object? message) async {
|
||||
// ignore message
|
||||
await api.noopAsync();
|
||||
return;
|
||||
});
|
||||
}
|
||||
}
|
||||
{
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAsyncString', codec,
|
||||
binaryMessenger: binaryMessenger);
|
||||
if (api == null) {
|
||||
channel.setMessageHandler(null);
|
||||
} else {
|
||||
channel.setMessageHandler((Object? message) async {
|
||||
assert(message != null,
|
||||
'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAsyncString was null.');
|
||||
final List<Object?> args = (message as List<Object?>?)!;
|
||||
final String? arg_aString = (args[0] as String?);
|
||||
assert(arg_aString != null,
|
||||
'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAsyncString was null, expected non-null String.');
|
||||
final String output = await api.echoAsyncString(arg_aString!);
|
||||
return output;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2389,3 +2461,115 @@ class HostTrivialApi {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A simple API implemented in some unit tests.
|
||||
class HostSmallApi {
|
||||
/// Constructor for [HostSmallApi]. The [binaryMessenger] named argument is
|
||||
/// available for dependency injection. If it is left null, the default
|
||||
/// BinaryMessenger will be used which routes to the host platform.
|
||||
HostSmallApi({BinaryMessenger? binaryMessenger})
|
||||
: _binaryMessenger = binaryMessenger;
|
||||
final BinaryMessenger? _binaryMessenger;
|
||||
|
||||
static const MessageCodec<Object?> codec = StandardMessageCodec();
|
||||
|
||||
Future<String> echo(String arg_aString) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.HostSmallApi.echo', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_aString]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
);
|
||||
} else if (replyList[0] == null) {
|
||||
throw PlatformException(
|
||||
code: 'null-error',
|
||||
message: 'Host platform returned null value for non-null return value.',
|
||||
);
|
||||
} else {
|
||||
return (replyList[0] as String?)!;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> voidVoid() async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.HostSmallApi.voidVoid', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList = await channel.send(null) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class _FlutterSmallApiCodec extends StandardMessageCodec {
|
||||
const _FlutterSmallApiCodec();
|
||||
@override
|
||||
void writeValue(WriteBuffer buffer, Object? value) {
|
||||
if (value is TestMessage) {
|
||||
buffer.putUint8(128);
|
||||
writeValue(buffer, value.encode());
|
||||
} else {
|
||||
super.writeValue(buffer, value);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Object? readValueOfType(int type, ReadBuffer buffer) {
|
||||
switch (type) {
|
||||
case 128:
|
||||
return TestMessage.decode(readValue(buffer)!);
|
||||
default:
|
||||
return super.readValueOfType(type, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A simple API called in some unit tests.
|
||||
abstract class FlutterSmallApi {
|
||||
static const MessageCodec<Object?> codec = _FlutterSmallApiCodec();
|
||||
|
||||
TestMessage echoWrappedList(TestMessage msg);
|
||||
|
||||
static void setup(FlutterSmallApi? api, {BinaryMessenger? binaryMessenger}) {
|
||||
{
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.FlutterSmallApi.echoWrappedList', codec,
|
||||
binaryMessenger: binaryMessenger);
|
||||
if (api == null) {
|
||||
channel.setMessageHandler(null);
|
||||
} else {
|
||||
channel.setMessageHandler((Object? message) async {
|
||||
assert(message != null,
|
||||
'Argument for dev.flutter.pigeon.FlutterSmallApi.echoWrappedList was null.');
|
||||
final List<Object?> args = (message as List<Object?>?)!;
|
||||
final TestMessage? arg_msg = (args[0] as TestMessage?);
|
||||
assert(arg_msg != null,
|
||||
'Argument for dev.flutter.pigeon.FlutterSmallApi.echoWrappedList was null, expected non-null TestMessage.');
|
||||
final TestMessage output = api.echoWrappedList(arg_msg!);
|
||||
return output;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1368,4 +1368,12 @@ class _FlutterApiTestImplementation implements FlutterIntegrationCoreApi {
|
||||
|
||||
@override
|
||||
Uint8List? echoNullableUint8List(Uint8List? aList) => aList;
|
||||
|
||||
@override
|
||||
Future<void> noopAsync() async {}
|
||||
|
||||
@override
|
||||
Future<String> echoAsyncString(String aString) async {
|
||||
return aString;
|
||||
}
|
||||
}
|
||||
|
@ -199,6 +199,28 @@ class AllNullableTypesWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
/// A data class containing a List, used in unit tests.
|
||||
class TestMessage {
|
||||
TestMessage({
|
||||
this.testList,
|
||||
});
|
||||
|
||||
List<Object?>? testList;
|
||||
|
||||
Object encode() {
|
||||
return <Object?>[
|
||||
testList,
|
||||
];
|
||||
}
|
||||
|
||||
static TestMessage decode(Object result) {
|
||||
result as List<Object?>;
|
||||
return TestMessage(
|
||||
testList: result[0] as List<Object?>?,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _HostIntegrationCoreApiCodec extends StandardMessageCodec {
|
||||
const _HostIntegrationCoreApiCodec();
|
||||
@override
|
||||
@ -212,6 +234,9 @@ class _HostIntegrationCoreApiCodec extends StandardMessageCodec {
|
||||
} else if (value is AllTypes) {
|
||||
buffer.putUint8(130);
|
||||
writeValue(buffer, value.encode());
|
||||
} else if (value is TestMessage) {
|
||||
buffer.putUint8(131);
|
||||
writeValue(buffer, value.encode());
|
||||
} else {
|
||||
super.writeValue(buffer, value);
|
||||
}
|
||||
@ -226,6 +251,8 @@ class _HostIntegrationCoreApiCodec extends StandardMessageCodec {
|
||||
return AllNullableTypesWrapper.decode(readValue(buffer)!);
|
||||
case 130:
|
||||
return AllTypes.decode(readValue(buffer)!);
|
||||
case 131:
|
||||
return TestMessage.decode(readValue(buffer)!);
|
||||
default:
|
||||
return super.readValueOfType(type, buffer);
|
||||
}
|
||||
@ -1897,6 +1924,9 @@ class _FlutterIntegrationCoreApiCodec extends StandardMessageCodec {
|
||||
} else if (value is AllTypes) {
|
||||
buffer.putUint8(130);
|
||||
writeValue(buffer, value.encode());
|
||||
} else if (value is TestMessage) {
|
||||
buffer.putUint8(131);
|
||||
writeValue(buffer, value.encode());
|
||||
} else {
|
||||
super.writeValue(buffer, value);
|
||||
}
|
||||
@ -1911,6 +1941,8 @@ class _FlutterIntegrationCoreApiCodec extends StandardMessageCodec {
|
||||
return AllNullableTypesWrapper.decode(readValue(buffer)!);
|
||||
case 130:
|
||||
return AllTypes.decode(readValue(buffer)!);
|
||||
case 131:
|
||||
return TestMessage.decode(readValue(buffer)!);
|
||||
default:
|
||||
return super.readValueOfType(type, buffer);
|
||||
}
|
||||
@ -1986,6 +2018,13 @@ abstract class FlutterIntegrationCoreApi {
|
||||
/// Returns the passed map, to test serialization and deserialization.
|
||||
Map<String?, Object?>? echoNullableMap(Map<String?, Object?>? aMap);
|
||||
|
||||
/// A no-op function taking no arguments and returning no value, to sanity
|
||||
/// test basic asynchronous calling.
|
||||
Future<void> noopAsync();
|
||||
|
||||
/// Returns the passed in generic Object asynchronously.
|
||||
Future<String> echoAsyncString(String aString);
|
||||
|
||||
static void setup(FlutterIntegrationCoreApi? api,
|
||||
{BinaryMessenger? binaryMessenger}) {
|
||||
{
|
||||
@ -2354,6 +2393,39 @@ abstract class FlutterIntegrationCoreApi {
|
||||
});
|
||||
}
|
||||
}
|
||||
{
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.FlutterIntegrationCoreApi.noopAsync', codec,
|
||||
binaryMessenger: binaryMessenger);
|
||||
if (api == null) {
|
||||
channel.setMessageHandler(null);
|
||||
} else {
|
||||
channel.setMessageHandler((Object? message) async {
|
||||
// ignore message
|
||||
await api.noopAsync();
|
||||
return;
|
||||
});
|
||||
}
|
||||
}
|
||||
{
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAsyncString', codec,
|
||||
binaryMessenger: binaryMessenger);
|
||||
if (api == null) {
|
||||
channel.setMessageHandler(null);
|
||||
} else {
|
||||
channel.setMessageHandler((Object? message) async {
|
||||
assert(message != null,
|
||||
'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAsyncString was null.');
|
||||
final List<Object?> args = (message as List<Object?>?)!;
|
||||
final String? arg_aString = (args[0] as String?);
|
||||
assert(arg_aString != null,
|
||||
'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAsyncString was null, expected non-null String.');
|
||||
final String output = await api.echoAsyncString(arg_aString!);
|
||||
return output;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2389,3 +2461,115 @@ class HostTrivialApi {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A simple API implemented in some unit tests.
|
||||
class HostSmallApi {
|
||||
/// Constructor for [HostSmallApi]. The [binaryMessenger] named argument is
|
||||
/// available for dependency injection. If it is left null, the default
|
||||
/// BinaryMessenger will be used which routes to the host platform.
|
||||
HostSmallApi({BinaryMessenger? binaryMessenger})
|
||||
: _binaryMessenger = binaryMessenger;
|
||||
final BinaryMessenger? _binaryMessenger;
|
||||
|
||||
static const MessageCodec<Object?> codec = StandardMessageCodec();
|
||||
|
||||
Future<String> echo(String arg_aString) async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.HostSmallApi.echo', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList =
|
||||
await channel.send(<Object?>[arg_aString]) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
);
|
||||
} else if (replyList[0] == null) {
|
||||
throw PlatformException(
|
||||
code: 'null-error',
|
||||
message: 'Host platform returned null value for non-null return value.',
|
||||
);
|
||||
} else {
|
||||
return (replyList[0] as String?)!;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> voidVoid() async {
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.HostSmallApi.voidVoid', codec,
|
||||
binaryMessenger: _binaryMessenger);
|
||||
final List<Object?>? replyList = await channel.send(null) as List<Object?>?;
|
||||
if (replyList == null) {
|
||||
throw PlatformException(
|
||||
code: 'channel-error',
|
||||
message: 'Unable to establish connection on channel.',
|
||||
);
|
||||
} else if (replyList.length > 1) {
|
||||
throw PlatformException(
|
||||
code: replyList[0]! as String,
|
||||
message: replyList[1] as String?,
|
||||
details: replyList[2],
|
||||
);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class _FlutterSmallApiCodec extends StandardMessageCodec {
|
||||
const _FlutterSmallApiCodec();
|
||||
@override
|
||||
void writeValue(WriteBuffer buffer, Object? value) {
|
||||
if (value is TestMessage) {
|
||||
buffer.putUint8(128);
|
||||
writeValue(buffer, value.encode());
|
||||
} else {
|
||||
super.writeValue(buffer, value);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Object? readValueOfType(int type, ReadBuffer buffer) {
|
||||
switch (type) {
|
||||
case 128:
|
||||
return TestMessage.decode(readValue(buffer)!);
|
||||
default:
|
||||
return super.readValueOfType(type, buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A simple API called in some unit tests.
|
||||
abstract class FlutterSmallApi {
|
||||
static const MessageCodec<Object?> codec = _FlutterSmallApiCodec();
|
||||
|
||||
TestMessage echoWrappedList(TestMessage msg);
|
||||
|
||||
static void setup(FlutterSmallApi? api, {BinaryMessenger? binaryMessenger}) {
|
||||
{
|
||||
final BasicMessageChannel<Object?> channel = BasicMessageChannel<Object?>(
|
||||
'dev.flutter.pigeon.FlutterSmallApi.echoWrappedList', codec,
|
||||
binaryMessenger: binaryMessenger);
|
||||
if (api == null) {
|
||||
channel.setMessageHandler(null);
|
||||
} else {
|
||||
channel.setMessageHandler((Object? message) async {
|
||||
assert(message != null,
|
||||
'Argument for dev.flutter.pigeon.FlutterSmallApi.echoWrappedList was null.');
|
||||
final List<Object?> args = (message as List<Object?>?)!;
|
||||
final TestMessage? arg_msg = (args[0] as TestMessage?);
|
||||
assert(arg_msg != null,
|
||||
'Argument for dev.flutter.pigeon.FlutterSmallApi.echoWrappedList was null, expected non-null TestMessage.');
|
||||
final TestMessage output = api.echoWrappedList(arg_msg!);
|
||||
return output;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -167,6 +167,29 @@ data class AllNullableTypesWrapper (
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A data class containing a List, used in unit tests.
|
||||
*
|
||||
* Generated class from Pigeon that represents data sent in messages.
|
||||
*/
|
||||
data class TestMessage (
|
||||
val testList: List<Any?>? = null
|
||||
|
||||
) {
|
||||
companion object {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun fromList(list: List<Any?>): TestMessage {
|
||||
val testList = list[0] as? List<Any?>
|
||||
return TestMessage(testList)
|
||||
}
|
||||
}
|
||||
fun toList(): List<Any?> {
|
||||
return listOf<Any?>(
|
||||
testList,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private object HostIntegrationCoreApiCodec : StandardMessageCodec() {
|
||||
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
|
||||
@ -186,6 +209,11 @@ private object HostIntegrationCoreApiCodec : StandardMessageCodec() {
|
||||
AllTypes.fromList(it)
|
||||
}
|
||||
}
|
||||
131.toByte() -> {
|
||||
return (readValue(buffer) as? List<Any?>)?.let {
|
||||
TestMessage.fromList(it)
|
||||
}
|
||||
}
|
||||
else -> super.readValueOfType(type, buffer)
|
||||
}
|
||||
}
|
||||
@ -203,6 +231,10 @@ private object HostIntegrationCoreApiCodec : StandardMessageCodec() {
|
||||
stream.write(130)
|
||||
writeValue(stream, value.toList())
|
||||
}
|
||||
is TestMessage -> {
|
||||
stream.write(131)
|
||||
writeValue(stream, value.toList())
|
||||
}
|
||||
else -> super.writeValue(stream, value)
|
||||
}
|
||||
}
|
||||
@ -1623,6 +1655,11 @@ private object FlutterIntegrationCoreApiCodec : StandardMessageCodec() {
|
||||
AllTypes.fromList(it)
|
||||
}
|
||||
}
|
||||
131.toByte() -> {
|
||||
return (readValue(buffer) as? List<Any?>)?.let {
|
||||
TestMessage.fromList(it)
|
||||
}
|
||||
}
|
||||
else -> super.readValueOfType(type, buffer)
|
||||
}
|
||||
}
|
||||
@ -1640,6 +1677,10 @@ private object FlutterIntegrationCoreApiCodec : StandardMessageCodec() {
|
||||
stream.write(130)
|
||||
writeValue(stream, value.toList())
|
||||
}
|
||||
is TestMessage -> {
|
||||
stream.write(131)
|
||||
writeValue(stream, value.toList())
|
||||
}
|
||||
else -> super.writeValue(stream, value)
|
||||
}
|
||||
}
|
||||
@ -1824,6 +1865,24 @@ class FlutterIntegrationCoreApi(private val binaryMessenger: BinaryMessenger) {
|
||||
callback(result)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* A no-op function taking no arguments and returning no value, to sanity
|
||||
* test basic asynchronous calling.
|
||||
*/
|
||||
fun noopAsync(callback: () -> Unit) {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.noopAsync", codec)
|
||||
channel.send(null) {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
/** Returns the passed in generic Object asynchronously. */
|
||||
fun echoAsyncString(aStringArg: String, callback: (String) -> Unit) {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAsyncString", codec)
|
||||
channel.send(listOf(aStringArg)) {
|
||||
val result = it as String
|
||||
callback(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* An API that can be implemented for minimal, compile-only tests.
|
||||
@ -1861,3 +1920,106 @@ interface HostTrivialApi {
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* A simple API implemented in some unit tests.
|
||||
*
|
||||
* Generated interface from Pigeon that represents a handler of messages from Flutter.
|
||||
*/
|
||||
interface HostSmallApi {
|
||||
fun echo(aString: String, callback: (Result<String>) -> Unit)
|
||||
fun voidVoid(callback: (Result<Unit>) -> Unit)
|
||||
|
||||
companion object {
|
||||
/** The codec used by HostSmallApi. */
|
||||
val codec: MessageCodec<Any?> by lazy {
|
||||
StandardMessageCodec()
|
||||
}
|
||||
/** Sets up an instance of `HostSmallApi` to handle messages through the `binaryMessenger`. */
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun setUp(binaryMessenger: BinaryMessenger, api: HostSmallApi?) {
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostSmallApi.echo", codec)
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { message, reply ->
|
||||
var wrapped = listOf<Any?>()
|
||||
val args = message as List<Any?>
|
||||
val aStringArg = args[0] as String
|
||||
api.echo(aStringArg) { result: Result<String> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
reply.reply(wrapError(error))
|
||||
} else {
|
||||
val data = result.getOrNull()
|
||||
reply.reply(wrapResult(data))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
channel.setMessageHandler(null)
|
||||
}
|
||||
}
|
||||
run {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.HostSmallApi.voidVoid", codec)
|
||||
if (api != null) {
|
||||
channel.setMessageHandler { _, reply ->
|
||||
var wrapped = listOf<Any?>()
|
||||
api.voidVoid() { result: Result<Unit> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
reply.reply(wrapError(error))
|
||||
} else {
|
||||
reply.reply(wrapResult(null))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
channel.setMessageHandler(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private object FlutterSmallApiCodec : StandardMessageCodec() {
|
||||
override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? {
|
||||
return when (type) {
|
||||
128.toByte() -> {
|
||||
return (readValue(buffer) as? List<Any?>)?.let {
|
||||
TestMessage.fromList(it)
|
||||
}
|
||||
}
|
||||
else -> super.readValueOfType(type, buffer)
|
||||
}
|
||||
}
|
||||
override fun writeValue(stream: ByteArrayOutputStream, value: Any?) {
|
||||
when (value) {
|
||||
is TestMessage -> {
|
||||
stream.write(128)
|
||||
writeValue(stream, value.toList())
|
||||
}
|
||||
else -> super.writeValue(stream, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple API called in some unit tests.
|
||||
*
|
||||
* Generated class from Pigeon that represents Flutter messages that can be called from Kotlin.
|
||||
*/
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class FlutterSmallApi(private val binaryMessenger: BinaryMessenger) {
|
||||
companion object {
|
||||
/** The codec used by FlutterSmallApi. */
|
||||
val codec: MessageCodec<Any?> by lazy {
|
||||
FlutterSmallApiCodec
|
||||
}
|
||||
}
|
||||
fun echoWrappedList(msgArg: TestMessage, callback: (TestMessage) -> Unit) {
|
||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.FlutterSmallApi.echoWrappedList", codec)
|
||||
channel.send(listOf(msgArg)) {
|
||||
val result = it as TestMessage
|
||||
callback(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,53 +18,60 @@ internal class AsyncHandlersTest: TestCase() {
|
||||
@Test
|
||||
fun testAsyncHost2Flutter() {
|
||||
val binaryMessenger = mockk<BinaryMessenger>()
|
||||
val api = Api2Flutter(binaryMessenger)
|
||||
val api = FlutterIntegrationCoreApi(binaryMessenger)
|
||||
|
||||
val input = Value(1)
|
||||
val output = Value(2)
|
||||
val value = "Test"
|
||||
|
||||
every { binaryMessenger.send(any(), any(), any()) } answers {
|
||||
val codec = Api2Flutter.codec
|
||||
val codec = FlutterIntegrationCoreApi.codec
|
||||
val message = arg<ByteBuffer>(1)
|
||||
val reply = arg<BinaryMessenger.BinaryReply>(2)
|
||||
message.position(0)
|
||||
val replyData = codec.encodeMessage(output)
|
||||
val replyData = codec.encodeMessage(value)
|
||||
replyData?.position(0)
|
||||
reply.reply(replyData)
|
||||
}
|
||||
|
||||
var didCall = false
|
||||
api.calculate(input) {
|
||||
api.echoAsyncString(value) {
|
||||
didCall = true
|
||||
assertEquals(it, output)
|
||||
assertEquals(it, value)
|
||||
}
|
||||
|
||||
assertTrue(didCall)
|
||||
|
||||
verify { binaryMessenger.send("dev.flutter.pigeon.Api2Flutter.calculate", any(), any()) }
|
||||
verify {
|
||||
binaryMessenger.send(
|
||||
"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAsyncString",
|
||||
any(),
|
||||
any()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAsyncFlutter2HostCalculate() {
|
||||
fun testAsyncFlutter2HostEcho() {
|
||||
val binaryMessenger = mockk<BinaryMessenger>()
|
||||
val api = mockk<Api2Host>()
|
||||
val api = mockk<HostSmallApi>()
|
||||
|
||||
val handlerSlot = slot<BinaryMessenger.BinaryMessageHandler>()
|
||||
|
||||
val input = Value(1)
|
||||
val output = Value(2)
|
||||
val channelName = "dev.flutter.pigeon.Api2Host.calculate"
|
||||
val input = "Test"
|
||||
val output = input
|
||||
val channelName = "dev.flutter.pigeon.HostSmallApi.echo"
|
||||
|
||||
every { binaryMessenger.setMessageHandler("dev.flutter.pigeon.Api2Host.voidVoid", any()) } returns Unit
|
||||
every {
|
||||
binaryMessenger.setMessageHandler("dev.flutter.pigeon.HostSmallApi.voidVoid", any())
|
||||
} returns Unit
|
||||
every { binaryMessenger.setMessageHandler(channelName, capture(handlerSlot)) } returns Unit
|
||||
every { api.calculate(any(), any()) } answers {
|
||||
val callback = arg<(Result<Value>) -> Unit>(1)
|
||||
every { api.echo(any(), any()) } answers {
|
||||
val callback = arg<(Result<String>) -> Unit>(1)
|
||||
callback(Result.success(output))
|
||||
}
|
||||
|
||||
Api2Host.setUp(binaryMessenger, api)
|
||||
HostSmallApi.setUp(binaryMessenger, api)
|
||||
|
||||
val codec = Api2Host.codec
|
||||
val codec = HostSmallApi.codec
|
||||
val message = codec.encodeMessage(listOf(input))
|
||||
message?.rewind()
|
||||
handlerSlot.captured.onMessage(message) {
|
||||
@ -79,28 +86,30 @@ internal class AsyncHandlersTest: TestCase() {
|
||||
}
|
||||
|
||||
verify { binaryMessenger.setMessageHandler(channelName, handlerSlot.captured) }
|
||||
verify { api.calculate(input, any()) }
|
||||
verify { api.echo(input, any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun asyncFlutter2HostVoidVoid() {
|
||||
val binaryMessenger = mockk<BinaryMessenger>()
|
||||
val api = mockk<Api2Host>()
|
||||
val api = mockk<HostSmallApi>()
|
||||
|
||||
val handlerSlot = slot<BinaryMessenger.BinaryMessageHandler>()
|
||||
|
||||
val channelName = "dev.flutter.pigeon.Api2Host.voidVoid"
|
||||
val channelName = "dev.flutter.pigeon.HostSmallApi.voidVoid"
|
||||
|
||||
every { binaryMessenger.setMessageHandler(channelName, capture(handlerSlot)) } returns Unit
|
||||
every { binaryMessenger.setMessageHandler("dev.flutter.pigeon.Api2Host.calculate", any()) } returns Unit
|
||||
every {
|
||||
binaryMessenger.setMessageHandler("dev.flutter.pigeon.HostSmallApi.echo", any())
|
||||
} returns Unit
|
||||
every { api.voidVoid(any()) } answers {
|
||||
val callback = arg<() -> Unit>(0)
|
||||
callback()
|
||||
}
|
||||
|
||||
Api2Host.setUp(binaryMessenger, api)
|
||||
HostSmallApi.setUp(binaryMessenger, api)
|
||||
|
||||
val codec = Api2Host.codec
|
||||
val codec = HostSmallApi.codec
|
||||
val message = codec.encodeMessage(null)
|
||||
handlerSlot.captured.onMessage(message) {
|
||||
it?.rewind()
|
||||
|
@ -16,13 +16,13 @@ class ListTest: TestCase() {
|
||||
@Test
|
||||
fun testListInList() {
|
||||
val binaryMessenger = mockk<BinaryMessenger>()
|
||||
val api = EchoApi(binaryMessenger)
|
||||
val api = FlutterSmallApi(binaryMessenger)
|
||||
|
||||
val inside = TestMessage(listOf(1, 2, 3))
|
||||
val input = TestMessage(listOf(inside))
|
||||
|
||||
every { binaryMessenger.send(any(), any(), any()) } answers {
|
||||
val codec = EchoApi.codec
|
||||
val codec = FlutterSmallApi.codec
|
||||
val message = arg<ByteBuffer>(1)
|
||||
val reply = arg<BinaryMessenger.BinaryReply>(2)
|
||||
message.position(0)
|
||||
@ -33,7 +33,7 @@ class ListTest: TestCase() {
|
||||
}
|
||||
|
||||
var didCall = false
|
||||
api.echo(input) {
|
||||
api.echoWrappedList(input) {
|
||||
didCall = true
|
||||
assertEquals(input, it)
|
||||
}
|
||||
|
@ -1,14 +1,15 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
import Flutter
|
||||
import XCTest
|
||||
@testable import test_plugin
|
||||
|
||||
class MockApi2Host: Api2Host {
|
||||
var output: Int32?
|
||||
class MockHostSmallApi: HostSmallApi {
|
||||
var output: String?
|
||||
|
||||
func calculate(value: Value, completion: @escaping (Result<Value, Error>) -> Void) {
|
||||
completion(.success(Value(number: output)))
|
||||
func echo(aString: String, completion: @escaping (Result<String, Error>) -> Void) {
|
||||
completion(.success(output!))
|
||||
}
|
||||
|
||||
func voidVoid(completion: @escaping (Result<Void, Error>) -> Void) {
|
||||
@ -19,25 +20,24 @@ class MockApi2Host: Api2Host {
|
||||
class AsyncHandlersTest: XCTestCase {
|
||||
|
||||
func testAsyncHost2Flutter() throws {
|
||||
let binaryMessenger = MockBinaryMessenger<Value>(codec: Api2FlutterCodec.shared)
|
||||
binaryMessenger.result = Value(number: 2)
|
||||
let api2Flutter = Api2Flutter(binaryMessenger: binaryMessenger)
|
||||
let input = Value(number: 1)
|
||||
let value = "Test"
|
||||
let binaryMessenger = MockBinaryMessenger<String>(codec: FlutterIntegrationCoreApiCodec.shared)
|
||||
binaryMessenger.result = value
|
||||
let flutterApi = FlutterIntegrationCoreApi(binaryMessenger: binaryMessenger)
|
||||
|
||||
let expectation = XCTestExpectation(description: "calculate callback")
|
||||
api2Flutter.calculate(value: input) { output in
|
||||
XCTAssertEqual(output.number, 2)
|
||||
let expectation = XCTestExpectation(description: "callback")
|
||||
flutterApi.echo(value) { output in
|
||||
XCTAssertEqual(output, value)
|
||||
expectation.fulfill()
|
||||
}
|
||||
wait(for: [expectation], timeout: 1.0)
|
||||
}
|
||||
|
||||
func testAsyncFlutter2HostVoidVoid() throws {
|
||||
let binaryMessenger = MockBinaryMessenger<Value>(codec: Api2HostCodec.shared)
|
||||
let mockApi2Host = MockApi2Host()
|
||||
mockApi2Host.output = 2
|
||||
Api2HostSetup.setUp(binaryMessenger: binaryMessenger, api: mockApi2Host)
|
||||
let channelName = "dev.flutter.pigeon.Api2Host.voidVoid"
|
||||
let binaryMessenger = MockBinaryMessenger<String>(codec: FlutterStandardMessageCodec.sharedInstance())
|
||||
let mockHostSmallApi = MockHostSmallApi()
|
||||
HostSmallApiSetup.setUp(binaryMessenger: binaryMessenger, api: mockHostSmallApi)
|
||||
let channelName = "dev.flutter.pigeon.HostSmallApi.voidVoid"
|
||||
XCTAssertNotNil(binaryMessenger.handlers[channelName])
|
||||
|
||||
let expectation = XCTestExpectation(description: "voidvoid callback")
|
||||
@ -50,21 +50,21 @@ class AsyncHandlersTest: XCTestCase {
|
||||
}
|
||||
|
||||
func testAsyncFlutter2Host() throws {
|
||||
let binaryMessenger = MockBinaryMessenger<Value>(codec: Api2HostCodec.shared)
|
||||
let mockApi2Host = MockApi2Host()
|
||||
mockApi2Host.output = 2
|
||||
Api2HostSetup.setUp(binaryMessenger: binaryMessenger, api: mockApi2Host)
|
||||
let channelName = "dev.flutter.pigeon.Api2Host.calculate"
|
||||
let binaryMessenger = MockBinaryMessenger<String>(codec: FlutterStandardMessageCodec.sharedInstance())
|
||||
let mockHostSmallApi = MockHostSmallApi()
|
||||
let value = "Test"
|
||||
mockHostSmallApi.output = value
|
||||
HostSmallApiSetup.setUp(binaryMessenger: binaryMessenger, api: mockHostSmallApi)
|
||||
let channelName = "dev.flutter.pigeon.HostSmallApi.echo"
|
||||
XCTAssertNotNil(binaryMessenger.handlers[channelName])
|
||||
|
||||
let input = Value(number: 1)
|
||||
let inputEncoded = binaryMessenger.codec.encode([input])
|
||||
let inputEncoded = binaryMessenger.codec.encode([value])
|
||||
|
||||
let expectation = XCTestExpectation(description: "calculate callback")
|
||||
let expectation = XCTestExpectation(description: "echo callback")
|
||||
binaryMessenger.handlers[channelName]?(inputEncoded) { data in
|
||||
let outputList = binaryMessenger.codec.decode(data) as? [Any]
|
||||
let output = outputList?.first as? Value
|
||||
XCTAssertEqual(output?.number, 2)
|
||||
let output = outputList?.first as? String
|
||||
XCTAssertEqual(output, value)
|
||||
expectation.fulfill()
|
||||
}
|
||||
wait(for: [expectation], timeout: 1.0)
|
||||
|
@ -10,11 +10,11 @@ class ListTests: XCTestCase {
|
||||
func testListInList() throws {
|
||||
let inside = TestMessage(testList: [1, 2, 3])
|
||||
let top = TestMessage(testList: [inside])
|
||||
let binaryMessenger = EchoBinaryMessenger(codec: EchoApiCodec.shared)
|
||||
let api = EchoApi(binaryMessenger: binaryMessenger)
|
||||
let binaryMessenger = EchoBinaryMessenger(codec: FlutterSmallApiCodec.shared)
|
||||
let api = FlutterSmallApi(binaryMessenger: binaryMessenger)
|
||||
|
||||
let expectation = XCTestExpectation(description: "callback")
|
||||
api.echo(msg: top) { result in
|
||||
api.echo(top) { result in
|
||||
XCTAssertEqual(1, result.testList?.count)
|
||||
XCTAssertTrue(result.testList?[0] is TestMessage)
|
||||
XCTAssert(equalsList(inside.testList, (result.testList?[0] as! TestMessage).testList))
|
||||
|
@ -190,6 +190,26 @@ struct AllNullableTypesWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
/// A data class containing a List, used in unit tests.
|
||||
///
|
||||
/// Generated class from Pigeon that represents data sent in messages.
|
||||
struct TestMessage {
|
||||
var testList: [Any?]? = nil
|
||||
|
||||
static func fromList(_ list: [Any?]) -> TestMessage? {
|
||||
let testList = list[0] as? [Any?]
|
||||
|
||||
return TestMessage(
|
||||
testList: testList
|
||||
)
|
||||
}
|
||||
func toList() -> [Any?] {
|
||||
return [
|
||||
testList,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
private class HostIntegrationCoreApiCodecReader: FlutterStandardReader {
|
||||
override func readValue(ofType type: UInt8) -> Any? {
|
||||
switch type {
|
||||
@ -199,6 +219,8 @@ private class HostIntegrationCoreApiCodecReader: FlutterStandardReader {
|
||||
return AllNullableTypesWrapper.fromList(self.readValue() as! [Any])
|
||||
case 130:
|
||||
return AllTypes.fromList(self.readValue() as! [Any])
|
||||
case 131:
|
||||
return TestMessage.fromList(self.readValue() as! [Any])
|
||||
default:
|
||||
return super.readValue(ofType: type)
|
||||
}
|
||||
@ -216,6 +238,9 @@ private class HostIntegrationCoreApiCodecWriter: FlutterStandardWriter {
|
||||
} else if let value = value as? AllTypes {
|
||||
super.writeByte(130)
|
||||
super.writeValue(value.toList())
|
||||
} else if let value = value as? TestMessage {
|
||||
super.writeByte(131)
|
||||
super.writeValue(value.toList())
|
||||
} else {
|
||||
super.writeValue(value)
|
||||
}
|
||||
@ -1448,6 +1473,8 @@ private class FlutterIntegrationCoreApiCodecReader: FlutterStandardReader {
|
||||
return AllNullableTypesWrapper.fromList(self.readValue() as! [Any])
|
||||
case 130:
|
||||
return AllTypes.fromList(self.readValue() as! [Any])
|
||||
case 131:
|
||||
return TestMessage.fromList(self.readValue() as! [Any])
|
||||
default:
|
||||
return super.readValue(ofType: type)
|
||||
}
|
||||
@ -1465,6 +1492,9 @@ private class FlutterIntegrationCoreApiCodecWriter: FlutterStandardWriter {
|
||||
} else if let value = value as? AllTypes {
|
||||
super.writeByte(130)
|
||||
super.writeValue(value.toList())
|
||||
} else if let value = value as? TestMessage {
|
||||
super.writeByte(131)
|
||||
super.writeValue(value.toList())
|
||||
} else {
|
||||
super.writeValue(value)
|
||||
}
|
||||
@ -1658,6 +1688,22 @@ class FlutterIntegrationCoreApi {
|
||||
completion(result)
|
||||
}
|
||||
}
|
||||
/// A no-op function taking no arguments and returning no value, to sanity
|
||||
/// test basic asynchronous calling.
|
||||
func noopAsync(completion: @escaping () -> Void) {
|
||||
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.noopAsync", binaryMessenger: binaryMessenger, codec: codec)
|
||||
channel.sendMessage(nil) { _ in
|
||||
completion()
|
||||
}
|
||||
}
|
||||
/// Returns the passed in generic Object asynchronously.
|
||||
func echoAsync(_ aStringArg: String, completion: @escaping (String) -> Void) {
|
||||
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAsyncString", binaryMessenger: binaryMessenger, codec: codec)
|
||||
channel.sendMessage([aStringArg] as [Any?]) { response in
|
||||
let result = response as! String
|
||||
completion(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
/// An API that can be implemented for minimal, compile-only tests.
|
||||
///
|
||||
@ -1686,3 +1732,105 @@ class HostTrivialApiSetup {
|
||||
}
|
||||
}
|
||||
}
|
||||
/// A simple API implemented in some unit tests.
|
||||
///
|
||||
/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
|
||||
protocol HostSmallApi {
|
||||
func echo(aString: String, completion: @escaping (Result<String, Error>) -> Void)
|
||||
func voidVoid(completion: @escaping (Result<Void, Error>) -> Void)
|
||||
}
|
||||
|
||||
/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
|
||||
class HostSmallApiSetup {
|
||||
/// The codec used by HostSmallApi.
|
||||
/// Sets up an instance of `HostSmallApi` to handle messages through the `binaryMessenger`.
|
||||
static func setUp(binaryMessenger: FlutterBinaryMessenger, api: HostSmallApi?) {
|
||||
let echoChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostSmallApi.echo", binaryMessenger: binaryMessenger)
|
||||
if let api = api {
|
||||
echoChannel.setMessageHandler { message, reply in
|
||||
let args = message as! [Any?]
|
||||
let aStringArg = args[0] as! String
|
||||
api.echo(aString: aStringArg) { result in
|
||||
switch result {
|
||||
case .success(let res):
|
||||
reply(wrapResult(res))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
echoChannel.setMessageHandler(nil)
|
||||
}
|
||||
let voidVoidChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostSmallApi.voidVoid", binaryMessenger: binaryMessenger)
|
||||
if let api = api {
|
||||
voidVoidChannel.setMessageHandler { _, reply in
|
||||
api.voidVoid() { result in
|
||||
switch result {
|
||||
case .success:
|
||||
reply(wrapResult(nil))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
voidVoidChannel.setMessageHandler(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
private class FlutterSmallApiCodecReader: FlutterStandardReader {
|
||||
override func readValue(ofType type: UInt8) -> Any? {
|
||||
switch type {
|
||||
case 128:
|
||||
return TestMessage.fromList(self.readValue() as! [Any])
|
||||
default:
|
||||
return super.readValue(ofType: type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class FlutterSmallApiCodecWriter: FlutterStandardWriter {
|
||||
override func writeValue(_ value: Any) {
|
||||
if let value = value as? TestMessage {
|
||||
super.writeByte(128)
|
||||
super.writeValue(value.toList())
|
||||
} else {
|
||||
super.writeValue(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class FlutterSmallApiCodecReaderWriter: FlutterStandardReaderWriter {
|
||||
override func reader(with data: Data) -> FlutterStandardReader {
|
||||
return FlutterSmallApiCodecReader(data: data)
|
||||
}
|
||||
|
||||
override func writer(with data: NSMutableData) -> FlutterStandardWriter {
|
||||
return FlutterSmallApiCodecWriter(data: data)
|
||||
}
|
||||
}
|
||||
|
||||
class FlutterSmallApiCodec: FlutterStandardMessageCodec {
|
||||
static let shared = FlutterSmallApiCodec(readerWriter: FlutterSmallApiCodecReaderWriter())
|
||||
}
|
||||
|
||||
/// A simple API called in some unit tests.
|
||||
///
|
||||
/// Generated class from Pigeon that represents Flutter messages that can be called from Swift.
|
||||
class FlutterSmallApi {
|
||||
private let binaryMessenger: FlutterBinaryMessenger
|
||||
init(binaryMessenger: FlutterBinaryMessenger){
|
||||
self.binaryMessenger = binaryMessenger
|
||||
}
|
||||
var codec: FlutterStandardMessageCodec {
|
||||
return FlutterSmallApiCodec.shared
|
||||
}
|
||||
func echo(_ msgArg: TestMessage, completion: @escaping (TestMessage) -> Void) {
|
||||
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterSmallApi.echoWrappedList", binaryMessenger: binaryMessenger, codec: codec)
|
||||
channel.sendMessage([msgArg] as [Any?]) { response in
|
||||
let result = response as! TestMessage
|
||||
completion(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -190,6 +190,26 @@ struct AllNullableTypesWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
/// A data class containing a List, used in unit tests.
|
||||
///
|
||||
/// Generated class from Pigeon that represents data sent in messages.
|
||||
struct TestMessage {
|
||||
var testList: [Any?]? = nil
|
||||
|
||||
static func fromList(_ list: [Any?]) -> TestMessage? {
|
||||
let testList = list[0] as? [Any?]
|
||||
|
||||
return TestMessage(
|
||||
testList: testList
|
||||
)
|
||||
}
|
||||
func toList() -> [Any?] {
|
||||
return [
|
||||
testList,
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
private class HostIntegrationCoreApiCodecReader: FlutterStandardReader {
|
||||
override func readValue(ofType type: UInt8) -> Any? {
|
||||
switch type {
|
||||
@ -199,6 +219,8 @@ private class HostIntegrationCoreApiCodecReader: FlutterStandardReader {
|
||||
return AllNullableTypesWrapper.fromList(self.readValue() as! [Any])
|
||||
case 130:
|
||||
return AllTypes.fromList(self.readValue() as! [Any])
|
||||
case 131:
|
||||
return TestMessage.fromList(self.readValue() as! [Any])
|
||||
default:
|
||||
return super.readValue(ofType: type)
|
||||
}
|
||||
@ -216,6 +238,9 @@ private class HostIntegrationCoreApiCodecWriter: FlutterStandardWriter {
|
||||
} else if let value = value as? AllTypes {
|
||||
super.writeByte(130)
|
||||
super.writeValue(value.toList())
|
||||
} else if let value = value as? TestMessage {
|
||||
super.writeByte(131)
|
||||
super.writeValue(value.toList())
|
||||
} else {
|
||||
super.writeValue(value)
|
||||
}
|
||||
@ -1448,6 +1473,8 @@ private class FlutterIntegrationCoreApiCodecReader: FlutterStandardReader {
|
||||
return AllNullableTypesWrapper.fromList(self.readValue() as! [Any])
|
||||
case 130:
|
||||
return AllTypes.fromList(self.readValue() as! [Any])
|
||||
case 131:
|
||||
return TestMessage.fromList(self.readValue() as! [Any])
|
||||
default:
|
||||
return super.readValue(ofType: type)
|
||||
}
|
||||
@ -1465,6 +1492,9 @@ private class FlutterIntegrationCoreApiCodecWriter: FlutterStandardWriter {
|
||||
} else if let value = value as? AllTypes {
|
||||
super.writeByte(130)
|
||||
super.writeValue(value.toList())
|
||||
} else if let value = value as? TestMessage {
|
||||
super.writeByte(131)
|
||||
super.writeValue(value.toList())
|
||||
} else {
|
||||
super.writeValue(value)
|
||||
}
|
||||
@ -1658,6 +1688,22 @@ class FlutterIntegrationCoreApi {
|
||||
completion(result)
|
||||
}
|
||||
}
|
||||
/// A no-op function taking no arguments and returning no value, to sanity
|
||||
/// test basic asynchronous calling.
|
||||
func noopAsync(completion: @escaping () -> Void) {
|
||||
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.noopAsync", binaryMessenger: binaryMessenger, codec: codec)
|
||||
channel.sendMessage(nil) { _ in
|
||||
completion()
|
||||
}
|
||||
}
|
||||
/// Returns the passed in generic Object asynchronously.
|
||||
func echoAsync(_ aStringArg: String, completion: @escaping (String) -> Void) {
|
||||
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAsyncString", binaryMessenger: binaryMessenger, codec: codec)
|
||||
channel.sendMessage([aStringArg] as [Any?]) { response in
|
||||
let result = response as! String
|
||||
completion(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
/// An API that can be implemented for minimal, compile-only tests.
|
||||
///
|
||||
@ -1686,3 +1732,105 @@ class HostTrivialApiSetup {
|
||||
}
|
||||
}
|
||||
}
|
||||
/// A simple API implemented in some unit tests.
|
||||
///
|
||||
/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
|
||||
protocol HostSmallApi {
|
||||
func echo(aString: String, completion: @escaping (Result<String, Error>) -> Void)
|
||||
func voidVoid(completion: @escaping (Result<Void, Error>) -> Void)
|
||||
}
|
||||
|
||||
/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`.
|
||||
class HostSmallApiSetup {
|
||||
/// The codec used by HostSmallApi.
|
||||
/// Sets up an instance of `HostSmallApi` to handle messages through the `binaryMessenger`.
|
||||
static func setUp(binaryMessenger: FlutterBinaryMessenger, api: HostSmallApi?) {
|
||||
let echoChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostSmallApi.echo", binaryMessenger: binaryMessenger)
|
||||
if let api = api {
|
||||
echoChannel.setMessageHandler { message, reply in
|
||||
let args = message as! [Any?]
|
||||
let aStringArg = args[0] as! String
|
||||
api.echo(aString: aStringArg) { result in
|
||||
switch result {
|
||||
case .success(let res):
|
||||
reply(wrapResult(res))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
echoChannel.setMessageHandler(nil)
|
||||
}
|
||||
let voidVoidChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.HostSmallApi.voidVoid", binaryMessenger: binaryMessenger)
|
||||
if let api = api {
|
||||
voidVoidChannel.setMessageHandler { _, reply in
|
||||
api.voidVoid() { result in
|
||||
switch result {
|
||||
case .success:
|
||||
reply(wrapResult(nil))
|
||||
case .failure(let error):
|
||||
reply(wrapError(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
voidVoidChannel.setMessageHandler(nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
private class FlutterSmallApiCodecReader: FlutterStandardReader {
|
||||
override func readValue(ofType type: UInt8) -> Any? {
|
||||
switch type {
|
||||
case 128:
|
||||
return TestMessage.fromList(self.readValue() as! [Any])
|
||||
default:
|
||||
return super.readValue(ofType: type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class FlutterSmallApiCodecWriter: FlutterStandardWriter {
|
||||
override func writeValue(_ value: Any) {
|
||||
if let value = value as? TestMessage {
|
||||
super.writeByte(128)
|
||||
super.writeValue(value.toList())
|
||||
} else {
|
||||
super.writeValue(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class FlutterSmallApiCodecReaderWriter: FlutterStandardReaderWriter {
|
||||
override func reader(with data: Data) -> FlutterStandardReader {
|
||||
return FlutterSmallApiCodecReader(data: data)
|
||||
}
|
||||
|
||||
override func writer(with data: NSMutableData) -> FlutterStandardWriter {
|
||||
return FlutterSmallApiCodecWriter(data: data)
|
||||
}
|
||||
}
|
||||
|
||||
class FlutterSmallApiCodec: FlutterStandardMessageCodec {
|
||||
static let shared = FlutterSmallApiCodec(readerWriter: FlutterSmallApiCodecReaderWriter())
|
||||
}
|
||||
|
||||
/// A simple API called in some unit tests.
|
||||
///
|
||||
/// Generated class from Pigeon that represents Flutter messages that can be called from Swift.
|
||||
class FlutterSmallApi {
|
||||
private let binaryMessenger: FlutterBinaryMessenger
|
||||
init(binaryMessenger: FlutterBinaryMessenger){
|
||||
self.binaryMessenger = binaryMessenger
|
||||
}
|
||||
var codec: FlutterStandardMessageCodec {
|
||||
return FlutterSmallApiCodec.shared
|
||||
}
|
||||
func echo(_ msgArg: TestMessage, completion: @escaping (TestMessage) -> Void) {
|
||||
let channel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.FlutterSmallApi.echoWrappedList", binaryMessenger: binaryMessenger, codec: codec)
|
||||
channel.sendMessage([msgArg] as [Any?]) { response in
|
||||
let result = response as! TestMessage
|
||||
completion(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,16 +17,10 @@ list(APPEND PLUGIN_SOURCES
|
||||
"test_plugin.cpp"
|
||||
"test_plugin.h"
|
||||
# Generated sources.
|
||||
"pigeon/async_handlers.gen.cpp"
|
||||
"pigeon/async_handlers.gen.h"
|
||||
"pigeon/core_tests.gen.cpp"
|
||||
"pigeon/core_tests.gen.h"
|
||||
"pigeon/enum.gen.cpp"
|
||||
"pigeon/enum.gen.h"
|
||||
"pigeon/host2flutter.gen.cpp"
|
||||
"pigeon/host2flutter.gen.h"
|
||||
"pigeon/list.gen.cpp"
|
||||
"pigeon/list.gen.h"
|
||||
"pigeon/message.gen.cpp"
|
||||
"pigeon/message.gen.h"
|
||||
"pigeon/multiple_arity.gen.cpp"
|
||||
@ -39,14 +33,6 @@ list(APPEND PLUGIN_SOURCES
|
||||
"pigeon/nullable_returns.gen.h"
|
||||
"pigeon/primitive.gen.cpp"
|
||||
"pigeon/primitive.gen.h"
|
||||
"pigeon/void_arg_flutter.gen.cpp"
|
||||
"pigeon/void_arg_flutter.gen.h"
|
||||
"pigeon/void_arg_host.gen.cpp"
|
||||
"pigeon/void_arg_host.gen.h"
|
||||
"pigeon/voidflutter.gen.cpp"
|
||||
"pigeon/voidflutter.gen.h"
|
||||
"pigeon/voidhost.gen.cpp"
|
||||
"pigeon/voidhost.gen.h"
|
||||
)
|
||||
|
||||
# Define the plugin library target. Its name must not be changed (see comment
|
||||
|
@ -473,6 +473,36 @@ AllNullableTypesWrapper::AllNullableTypesWrapper(const EncodableList& list) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestMessage
|
||||
|
||||
const EncodableList* TestMessage::test_list() const {
|
||||
return test_list_ ? &(*test_list_) : nullptr;
|
||||
}
|
||||
void TestMessage::set_test_list(const EncodableList* value_arg) {
|
||||
test_list_ =
|
||||
value_arg ? std::optional<EncodableList>(*value_arg) : std::nullopt;
|
||||
}
|
||||
void TestMessage::set_test_list(const EncodableList& value_arg) {
|
||||
test_list_ = value_arg;
|
||||
}
|
||||
|
||||
EncodableList TestMessage::ToEncodableList() const {
|
||||
EncodableList list;
|
||||
list.reserve(1);
|
||||
list.push_back(test_list_ ? EncodableValue(*test_list_) : EncodableValue());
|
||||
return list;
|
||||
}
|
||||
|
||||
TestMessage::TestMessage() {}
|
||||
|
||||
TestMessage::TestMessage(const EncodableList& list) {
|
||||
auto& encodable_test_list = list[0];
|
||||
if (const EncodableList* pointer_test_list =
|
||||
std::get_if<EncodableList>(&encodable_test_list)) {
|
||||
test_list_ = *pointer_test_list;
|
||||
}
|
||||
}
|
||||
|
||||
HostIntegrationCoreApiCodecSerializer::HostIntegrationCoreApiCodecSerializer() {
|
||||
}
|
||||
EncodableValue HostIntegrationCoreApiCodecSerializer::ReadValueOfType(
|
||||
@ -487,6 +517,9 @@ EncodableValue HostIntegrationCoreApiCodecSerializer::ReadValueOfType(
|
||||
case 130:
|
||||
return CustomEncodableValue(
|
||||
AllTypes(std::get<EncodableList>(ReadValue(stream))));
|
||||
case 131:
|
||||
return CustomEncodableValue(
|
||||
TestMessage(std::get<EncodableList>(ReadValue(stream))));
|
||||
default:
|
||||
return flutter::StandardCodecSerializer::ReadValueOfType(type, stream);
|
||||
}
|
||||
@ -519,6 +552,14 @@ void HostIntegrationCoreApiCodecSerializer::WriteValue(
|
||||
stream);
|
||||
return;
|
||||
}
|
||||
if (custom_value->type() == typeid(TestMessage)) {
|
||||
stream->WriteByte(131);
|
||||
WriteValue(
|
||||
EncodableValue(
|
||||
std::any_cast<TestMessage>(*custom_value).ToEncodableList()),
|
||||
stream);
|
||||
return;
|
||||
}
|
||||
}
|
||||
flutter::StandardCodecSerializer::WriteValue(value, stream);
|
||||
}
|
||||
@ -2881,6 +2922,9 @@ EncodableValue FlutterIntegrationCoreApiCodecSerializer::ReadValueOfType(
|
||||
case 130:
|
||||
return CustomEncodableValue(
|
||||
AllTypes(std::get<EncodableList>(ReadValue(stream))));
|
||||
case 131:
|
||||
return CustomEncodableValue(
|
||||
TestMessage(std::get<EncodableList>(ReadValue(stream))));
|
||||
default:
|
||||
return flutter::StandardCodecSerializer::ReadValueOfType(type, stream);
|
||||
}
|
||||
@ -2913,6 +2957,14 @@ void FlutterIntegrationCoreApiCodecSerializer::WriteValue(
|
||||
stream);
|
||||
return;
|
||||
}
|
||||
if (custom_value->type() == typeid(TestMessage)) {
|
||||
stream->WriteByte(131);
|
||||
WriteValue(
|
||||
EncodableValue(
|
||||
std::any_cast<TestMessage>(*custom_value).ToEncodableList()),
|
||||
stream);
|
||||
return;
|
||||
}
|
||||
}
|
||||
flutter::StandardCodecSerializer::WriteValue(value, stream);
|
||||
}
|
||||
@ -3355,6 +3407,41 @@ void FlutterIntegrationCoreApi::EchoNullableMap(
|
||||
on_success(return_value);
|
||||
});
|
||||
}
|
||||
void FlutterIntegrationCoreApi::NoopAsync(
|
||||
std::function<void(void)>&& on_success,
|
||||
std::function<void(const FlutterError&)>&& on_error) {
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(
|
||||
binary_messenger_,
|
||||
"dev.flutter.pigeon.FlutterIntegrationCoreApi.noopAsync", &GetCodec());
|
||||
EncodableValue encoded_api_arguments = EncodableValue();
|
||||
channel->Send(
|
||||
encoded_api_arguments,
|
||||
[on_success = std::move(on_success), on_error = std::move(on_error)](
|
||||
const uint8_t* reply, size_t reply_size) { on_success(); });
|
||||
}
|
||||
void FlutterIntegrationCoreApi::EchoAsyncString(
|
||||
const std::string& a_string_arg,
|
||||
std::function<void(const std::string&)>&& on_success,
|
||||
std::function<void(const FlutterError&)>&& on_error) {
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(
|
||||
binary_messenger_,
|
||||
"dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAsyncString",
|
||||
&GetCodec());
|
||||
EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
|
||||
EncodableValue(a_string_arg),
|
||||
});
|
||||
channel->Send(
|
||||
encoded_api_arguments,
|
||||
[on_success = std::move(on_success), on_error = std::move(on_error)](
|
||||
const uint8_t* reply, size_t reply_size) {
|
||||
std::unique_ptr<EncodableValue> response =
|
||||
GetCodec().DecodeMessage(reply, reply_size);
|
||||
const auto& encodable_return_value = *response;
|
||||
const auto& return_value =
|
||||
std::get<std::string>(encodable_return_value);
|
||||
on_success(return_value);
|
||||
});
|
||||
}
|
||||
/// The codec used by HostTrivialApi.
|
||||
const flutter::StandardMessageCodec& HostTrivialApi::GetCodec() {
|
||||
return flutter::StandardMessageCodec::GetInstance(
|
||||
@ -3403,4 +3490,148 @@ EncodableValue HostTrivialApi::WrapError(const FlutterError& error) {
|
||||
error.details()});
|
||||
}
|
||||
|
||||
/// The codec used by HostSmallApi.
|
||||
const flutter::StandardMessageCodec& HostSmallApi::GetCodec() {
|
||||
return flutter::StandardMessageCodec::GetInstance(
|
||||
&flutter::StandardCodecSerializer::GetInstance());
|
||||
}
|
||||
|
||||
// Sets up an instance of `HostSmallApi` to handle messages through the
|
||||
// `binary_messenger`.
|
||||
void HostSmallApi::SetUp(flutter::BinaryMessenger* binary_messenger,
|
||||
HostSmallApi* api) {
|
||||
{
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(
|
||||
binary_messenger, "dev.flutter.pigeon.HostSmallApi.echo", &GetCodec());
|
||||
if (api != nullptr) {
|
||||
channel->SetMessageHandler(
|
||||
[api](const EncodableValue& message,
|
||||
const flutter::MessageReply<EncodableValue>& reply) {
|
||||
try {
|
||||
const auto& args = std::get<EncodableList>(message);
|
||||
const auto& encodable_a_string_arg = args.at(0);
|
||||
if (encodable_a_string_arg.IsNull()) {
|
||||
reply(WrapError("a_string_arg unexpectedly null."));
|
||||
return;
|
||||
}
|
||||
const auto& a_string_arg =
|
||||
std::get<std::string>(encodable_a_string_arg);
|
||||
api->Echo(a_string_arg, [reply](ErrorOr<std::string>&& output) {
|
||||
if (output.has_error()) {
|
||||
reply(WrapError(output.error()));
|
||||
return;
|
||||
}
|
||||
EncodableList wrapped;
|
||||
wrapped.push_back(
|
||||
EncodableValue(std::move(output).TakeValue()));
|
||||
reply(EncodableValue(std::move(wrapped)));
|
||||
});
|
||||
} catch (const std::exception& exception) {
|
||||
reply(WrapError(exception.what()));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel->SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
{
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(
|
||||
binary_messenger, "dev.flutter.pigeon.HostSmallApi.voidVoid",
|
||||
&GetCodec());
|
||||
if (api != nullptr) {
|
||||
channel->SetMessageHandler(
|
||||
[api](const EncodableValue& message,
|
||||
const flutter::MessageReply<EncodableValue>& reply) {
|
||||
try {
|
||||
api->VoidVoid([reply](std::optional<FlutterError>&& output) {
|
||||
if (output.has_value()) {
|
||||
reply(WrapError(output.value()));
|
||||
return;
|
||||
}
|
||||
EncodableList wrapped;
|
||||
wrapped.push_back(EncodableValue());
|
||||
reply(EncodableValue(std::move(wrapped)));
|
||||
});
|
||||
} catch (const std::exception& exception) {
|
||||
reply(WrapError(exception.what()));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
channel->SetMessageHandler(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EncodableValue HostSmallApi::WrapError(std::string_view error_message) {
|
||||
return EncodableValue(
|
||||
EncodableList{EncodableValue(std::string(error_message)),
|
||||
EncodableValue("Error"), EncodableValue()});
|
||||
}
|
||||
EncodableValue HostSmallApi::WrapError(const FlutterError& error) {
|
||||
return EncodableValue(EncodableList{EncodableValue(error.message()),
|
||||
EncodableValue(error.code()),
|
||||
error.details()});
|
||||
}
|
||||
|
||||
FlutterSmallApiCodecSerializer::FlutterSmallApiCodecSerializer() {}
|
||||
EncodableValue FlutterSmallApiCodecSerializer::ReadValueOfType(
|
||||
uint8_t type, flutter::ByteStreamReader* stream) const {
|
||||
switch (type) {
|
||||
case 128:
|
||||
return CustomEncodableValue(
|
||||
TestMessage(std::get<EncodableList>(ReadValue(stream))));
|
||||
default:
|
||||
return flutter::StandardCodecSerializer::ReadValueOfType(type, stream);
|
||||
}
|
||||
}
|
||||
|
||||
void FlutterSmallApiCodecSerializer::WriteValue(
|
||||
const EncodableValue& value, flutter::ByteStreamWriter* stream) const {
|
||||
if (const CustomEncodableValue* custom_value =
|
||||
std::get_if<CustomEncodableValue>(&value)) {
|
||||
if (custom_value->type() == typeid(TestMessage)) {
|
||||
stream->WriteByte(128);
|
||||
WriteValue(
|
||||
EncodableValue(
|
||||
std::any_cast<TestMessage>(*custom_value).ToEncodableList()),
|
||||
stream);
|
||||
return;
|
||||
}
|
||||
}
|
||||
flutter::StandardCodecSerializer::WriteValue(value, stream);
|
||||
}
|
||||
|
||||
// Generated class from Pigeon that represents Flutter messages that can be
|
||||
// called from C++.
|
||||
FlutterSmallApi::FlutterSmallApi(flutter::BinaryMessenger* binary_messenger) {
|
||||
this->binary_messenger_ = binary_messenger;
|
||||
}
|
||||
|
||||
const flutter::StandardMessageCodec& FlutterSmallApi::GetCodec() {
|
||||
return flutter::StandardMessageCodec::GetInstance(
|
||||
&FlutterSmallApiCodecSerializer::GetInstance());
|
||||
}
|
||||
|
||||
void FlutterSmallApi::EchoWrappedList(
|
||||
const TestMessage& msg_arg,
|
||||
std::function<void(const TestMessage&)>&& on_success,
|
||||
std::function<void(const FlutterError&)>&& on_error) {
|
||||
auto channel = std::make_unique<BasicMessageChannel<>>(
|
||||
binary_messenger_, "dev.flutter.pigeon.FlutterSmallApi.echoWrappedList",
|
||||
&GetCodec());
|
||||
EncodableValue encoded_api_arguments = EncodableValue(EncodableList{
|
||||
EncodableValue(msg_arg.ToEncodableList()),
|
||||
});
|
||||
channel->Send(
|
||||
encoded_api_arguments,
|
||||
[on_success = std::move(on_success), on_error = std::move(on_error)](
|
||||
const uint8_t* reply, size_t reply_size) {
|
||||
std::unique_ptr<EncodableValue> response =
|
||||
GetCodec().DecodeMessage(reply, reply_size);
|
||||
const auto& encodable_return_value = *response;
|
||||
const auto& return_value = std::any_cast<const TestMessage&>(
|
||||
std::get<CustomEncodableValue>(encodable_return_value));
|
||||
on_success(return_value);
|
||||
});
|
||||
}
|
||||
} // namespace core_tests_pigeontest
|
||||
|
@ -57,6 +57,8 @@ class ErrorOr {
|
||||
friend class HostIntegrationCoreApi;
|
||||
friend class FlutterIntegrationCoreApi;
|
||||
friend class HostTrivialApi;
|
||||
friend class HostSmallApi;
|
||||
friend class FlutterSmallApi;
|
||||
ErrorOr() = default;
|
||||
T TakeValue() && { return std::get<T>(std::move(v_)); }
|
||||
|
||||
@ -111,6 +113,10 @@ class AllTypes {
|
||||
friend class FlutterIntegrationCoreApiCodecSerializer;
|
||||
friend class HostTrivialApi;
|
||||
friend class HostTrivialApiCodecSerializer;
|
||||
friend class HostSmallApi;
|
||||
friend class HostSmallApiCodecSerializer;
|
||||
friend class FlutterSmallApi;
|
||||
friend class FlutterSmallApiCodecSerializer;
|
||||
friend class CoreTestsTest;
|
||||
bool a_bool_;
|
||||
int64_t an_int_;
|
||||
@ -197,6 +203,10 @@ class AllNullableTypes {
|
||||
friend class FlutterIntegrationCoreApiCodecSerializer;
|
||||
friend class HostTrivialApi;
|
||||
friend class HostTrivialApiCodecSerializer;
|
||||
friend class HostSmallApi;
|
||||
friend class HostSmallApiCodecSerializer;
|
||||
friend class FlutterSmallApi;
|
||||
friend class FlutterSmallApiCodecSerializer;
|
||||
friend class CoreTestsTest;
|
||||
std::optional<bool> a_nullable_bool_;
|
||||
std::optional<int64_t> a_nullable_int_;
|
||||
@ -230,10 +240,41 @@ class AllNullableTypesWrapper {
|
||||
friend class FlutterIntegrationCoreApiCodecSerializer;
|
||||
friend class HostTrivialApi;
|
||||
friend class HostTrivialApiCodecSerializer;
|
||||
friend class HostSmallApi;
|
||||
friend class HostSmallApiCodecSerializer;
|
||||
friend class FlutterSmallApi;
|
||||
friend class FlutterSmallApiCodecSerializer;
|
||||
friend class CoreTestsTest;
|
||||
AllNullableTypes values_;
|
||||
};
|
||||
|
||||
// A data class containing a List, used in unit tests.
|
||||
//
|
||||
// Generated class from Pigeon that represents data sent in messages.
|
||||
class TestMessage {
|
||||
public:
|
||||
TestMessage();
|
||||
const flutter::EncodableList* test_list() const;
|
||||
void set_test_list(const flutter::EncodableList* value_arg);
|
||||
void set_test_list(const flutter::EncodableList& value_arg);
|
||||
|
||||
private:
|
||||
TestMessage(const flutter::EncodableList& list);
|
||||
flutter::EncodableList ToEncodableList() const;
|
||||
friend class HostIntegrationCoreApi;
|
||||
friend class HostIntegrationCoreApiCodecSerializer;
|
||||
friend class FlutterIntegrationCoreApi;
|
||||
friend class FlutterIntegrationCoreApiCodecSerializer;
|
||||
friend class HostTrivialApi;
|
||||
friend class HostTrivialApiCodecSerializer;
|
||||
friend class HostSmallApi;
|
||||
friend class HostSmallApiCodecSerializer;
|
||||
friend class FlutterSmallApi;
|
||||
friend class FlutterSmallApiCodecSerializer;
|
||||
friend class CoreTestsTest;
|
||||
std::optional<flutter::EncodableList> test_list_;
|
||||
};
|
||||
|
||||
class HostIntegrationCoreApiCodecSerializer
|
||||
: public flutter::StandardCodecSerializer {
|
||||
public:
|
||||
@ -607,6 +648,14 @@ class FlutterIntegrationCoreApi {
|
||||
const flutter::EncodableMap* a_map,
|
||||
std::function<void(const flutter::EncodableMap*)>&& on_success,
|
||||
std::function<void(const FlutterError&)>&& on_error);
|
||||
// A no-op function taking no arguments and returning no value, to sanity
|
||||
// test basic asynchronous calling.
|
||||
void NoopAsync(std::function<void(void)>&& on_success,
|
||||
std::function<void(const FlutterError&)>&& on_error);
|
||||
// Returns the passed in generic Object asynchronously.
|
||||
void EchoAsyncString(const std::string& a_string,
|
||||
std::function<void(const std::string&)>&& on_success,
|
||||
std::function<void(const FlutterError&)>&& on_error);
|
||||
};
|
||||
|
||||
// An API that can be implemented for minimal, compile-only tests.
|
||||
@ -632,5 +681,65 @@ class HostTrivialApi {
|
||||
protected:
|
||||
HostTrivialApi() = default;
|
||||
};
|
||||
// A simple API implemented in some unit tests.
|
||||
//
|
||||
// Generated interface from Pigeon that represents a handler of messages from
|
||||
// Flutter.
|
||||
class HostSmallApi {
|
||||
public:
|
||||
HostSmallApi(const HostSmallApi&) = delete;
|
||||
HostSmallApi& operator=(const HostSmallApi&) = delete;
|
||||
virtual ~HostSmallApi() {}
|
||||
virtual void Echo(const std::string& a_string,
|
||||
std::function<void(ErrorOr<std::string> reply)> result) = 0;
|
||||
virtual void VoidVoid(
|
||||
std::function<void(std::optional<FlutterError> reply)> result) = 0;
|
||||
|
||||
// The codec used by HostSmallApi.
|
||||
static const flutter::StandardMessageCodec& GetCodec();
|
||||
// Sets up an instance of `HostSmallApi` to handle messages through the
|
||||
// `binary_messenger`.
|
||||
static void SetUp(flutter::BinaryMessenger* binary_messenger,
|
||||
HostSmallApi* api);
|
||||
static flutter::EncodableValue WrapError(std::string_view error_message);
|
||||
static flutter::EncodableValue WrapError(const FlutterError& error);
|
||||
|
||||
protected:
|
||||
HostSmallApi() = default;
|
||||
};
|
||||
class FlutterSmallApiCodecSerializer : public flutter::StandardCodecSerializer {
|
||||
public:
|
||||
inline static FlutterSmallApiCodecSerializer& GetInstance() {
|
||||
static FlutterSmallApiCodecSerializer sInstance;
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
FlutterSmallApiCodecSerializer();
|
||||
|
||||
public:
|
||||
void WriteValue(const flutter::EncodableValue& value,
|
||||
flutter::ByteStreamWriter* stream) const override;
|
||||
|
||||
protected:
|
||||
flutter::EncodableValue ReadValueOfType(
|
||||
uint8_t type, flutter::ByteStreamReader* stream) const override;
|
||||
};
|
||||
|
||||
// A simple API called in some unit tests.
|
||||
//
|
||||
// Generated class from Pigeon that represents Flutter messages that can be
|
||||
// called from C++.
|
||||
class FlutterSmallApi {
|
||||
private:
|
||||
flutter::BinaryMessenger* binary_messenger_;
|
||||
|
||||
public:
|
||||
FlutterSmallApi(flutter::BinaryMessenger* binary_messenger);
|
||||
static const flutter::StandardMessageCodec& GetCodec();
|
||||
void EchoWrappedList(const TestMessage& msg,
|
||||
std::function<void(const TestMessage&)>&& on_success,
|
||||
std::function<void(const FlutterError&)>&& on_error);
|
||||
};
|
||||
|
||||
} // namespace core_tests_pigeontest
|
||||
#endif // PIGEON_CORE_TESTS_GEN_H_
|
||||
|
@ -16,9 +16,7 @@ enum GeneratorLanguages {
|
||||
// A map of pigeons/ files to the languages that they can't yet be generated
|
||||
// for due to limitations of that generator.
|
||||
const Map<String, Set<GeneratorLanguages>> _unsupportedFiles =
|
||||
<String, Set<GeneratorLanguages>>{
|
||||
'enum_args': <GeneratorLanguages>{GeneratorLanguages.cpp},
|
||||
};
|
||||
<String, Set<GeneratorLanguages>>{};
|
||||
|
||||
String _snakeToPascalCase(String snake) {
|
||||
final List<String> parts = snake.split('_');
|
||||
@ -37,12 +35,7 @@ String _snakeToPascalCase(String snake) {
|
||||
// https://github.com/flutter/flutter/issues/115168.
|
||||
String _javaFilenameForName(String inputName) {
|
||||
const Map<String, String> specialCases = <String, String>{
|
||||
'android_unittests': 'Pigeon',
|
||||
'host2flutter': 'Host2Flutter',
|
||||
'list': 'PigeonList',
|
||||
'message': 'MessagePigeon',
|
||||
'voidflutter': 'VoidFlutter',
|
||||
'voidhost': 'VoidHost',
|
||||
};
|
||||
return specialCases[inputName] ?? _snakeToPascalCase(inputName);
|
||||
}
|
||||
@ -51,25 +44,15 @@ Future<int> generatePigeons({required String baseDir}) async {
|
||||
// TODO(stuartmorgan): Make this dynamic rather than hard-coded. Or eliminate
|
||||
// it entirely; see https://github.com/flutter/flutter/issues/115169.
|
||||
const List<String> inputs = <String>[
|
||||
'android_unittests',
|
||||
'async_handlers',
|
||||
'background_platform_channels',
|
||||
'core_tests',
|
||||
'enum_args',
|
||||
'enum',
|
||||
'host2flutter',
|
||||
'java_double_host_api',
|
||||
'list',
|
||||
'message',
|
||||
'multiple_arity',
|
||||
'non_null_fields',
|
||||
'null_fields',
|
||||
'nullable_returns',
|
||||
'primitive',
|
||||
'void_arg_flutter',
|
||||
'void_arg_host',
|
||||
'voidflutter',
|
||||
'voidhost',
|
||||
];
|
||||
|
||||
final String outputBase = p.join(baseDir, 'platform_tests', 'test_plugin');
|
||||
|
@ -216,18 +216,6 @@ Future<int> _runFlutterUnitTests() async {
|
||||
'non_null_fields',
|
||||
'null_fields',
|
||||
'nullable_returns',
|
||||
// TODO(stuartmorgan): Eliminate these files by ensuring that everything
|
||||
// they are intended to cover is in core_tests.dart (or, if necessary in
|
||||
// the short term due to limitations in non-Dart generators, a single other
|
||||
// file). They aren't being unit tested, only analyzed.
|
||||
'async_handlers',
|
||||
'host2flutter',
|
||||
'list',
|
||||
'message',
|
||||
'void_arg_flutter',
|
||||
'void_arg_host',
|
||||
'voidflutter',
|
||||
'voidhost',
|
||||
];
|
||||
final int generateCode = await _generateDart(<String, String>{
|
||||
for (final String name in inputPigeons)
|
||||
|
Reference in New Issue
Block a user