diff --git a/packages/pigeon/lib/cpp_generator.dart b/packages/pigeon/lib/cpp_generator.dart index 9c369a5125..f893f5733c 100644 --- a/packages/pigeon/lib/cpp_generator.dart +++ b/packages/pigeon/lib/cpp_generator.dart @@ -148,11 +148,11 @@ void _writeErrorOr(Indent indent, indent.format(''' class FlutterError { public: -\tFlutterError(const std::string& code) +\texplicit FlutterError(const std::string& code) \t\t: code_(code) {} -\tFlutterError(const std::string& code, const std::string& message) +\texplicit FlutterError(const std::string& code, const std::string& message) \t\t: code_(code), message_(message) {} -\tFlutterError(const std::string& code, const std::string& message, const flutter::EncodableValue& details) +\texplicit FlutterError(const std::string& code, const std::string& message, const flutter::EncodableValue& details) \t\t: code_(code), message_(message), details_(details) {} \tconst std::string& code() const { return code_; } diff --git a/packages/pigeon/pigeons/core_tests.dart b/packages/pigeon/pigeons/core_tests.dart index 730eabc2e3..4006d95c13 100644 --- a/packages/pigeon/pigeons/core_tests.dart +++ b/packages/pigeon/pigeons/core_tests.dart @@ -12,28 +12,76 @@ enum AnEnum { // A class containing all supported types. class AllTypes { - bool? aBool; - int? anInt; - double? aDouble; - String? aString; - Uint8List? aByteArray; - Int32List? a4ByteArray; - Int64List? a8ByteArray; - Float64List? aFloatArray; + AllTypes({ + this.aBool = false, + this.anInt = 0, + this.aDouble = 0, + this.aString = '', + required this.aByteArray, + required this.a4ByteArray, + required this.a8ByteArray, + required this.aFloatArray, + this.aList = const [], + this.aMap = const {}, + this.anEnum = AnEnum.one, + }); + + bool aBool; + int anInt; + double aDouble; + String aString; + Uint8List aByteArray; + Int32List a4ByteArray; + Int64List a8ByteArray; + Float64List aFloatArray; // ignore: always_specify_types, strict_raw_type - List? aList; + List aList; // ignore: always_specify_types, strict_raw_type - Map? aMap; - List?>? nestedList; - Map? mapWithAnnotations; - Map? mapWithObject; - AnEnum? anEnum; + Map aMap; + AnEnum anEnum; +} + +// A class containing all supported nullable types. +class AllNullableTypes { + AllNullableTypes( + this.aNullableBool, + this.aNullableInt, + this.aNullableDouble, + this.aNullableString, + this.aNullableByteArray, + this.aNullable4ByteArray, + this.aNullable8ByteArray, + this.aNullableFloatArray, + this.aNullableList, + this.aNullableMap, + this.nullableNestedList, + this.nullableMapWithAnnotations, + this.nullableMapWithObject, + this.aNullableEnum, + ); + + bool? aNullableBool; + int? aNullableInt; + double? aNullableDouble; + String? aNullableString; + Uint8List? aNullableByteArray; + Int32List? aNullable4ByteArray; + Int64List? aNullable8ByteArray; + Float64List? aNullableFloatArray; + // ignore: always_specify_types, strict_raw_type + List? aNullableList; + // ignore: always_specify_types, strict_raw_type + Map? aNullableMap; + List?>? nullableNestedList; + Map? nullableMapWithAnnotations; + Map? nullableMapWithObject; + AnEnum? aNullableEnum; } // A class for testing nested object handling. -class AllTypesWrapper { - AllTypesWrapper(this.values); - AllTypes values; +class AllNullableTypesWrapper { + AllNullableTypesWrapper(this.values); + AllNullableTypes values; } /// The core interface that each host language plugin must implement in @@ -50,23 +98,13 @@ abstract class HostIntegrationCoreApi { @ObjCSelector('echoAllTypes:') AllTypes echoAllTypes(AllTypes everything); + /// Returns the passed object, to test serialization and deserialization. + @ObjCSelector('echoAllNullableTypes:') + AllNullableTypes? echoAllNullableTypes(AllNullableTypes? everything); + /// Returns an error, to test error handling. void throwError(); - /// Returns the inner `aString` value from the wrapped object, to test - /// sending of nested objects. - @ObjCSelector('extractNestedStringFrom:') - String? extractNestedString(AllTypesWrapper wrapper); - - /// Returns the inner `aString` value from the wrapped object, to test - /// sending of nested objects. - @ObjCSelector('createNestedObjectWithString:') - AllTypesWrapper createNestedString(String string); - - /// Returns passed in arguments of multiple types. - @ObjCSelector('sendMultipleTypesABool:anInt:aString:') - AllTypes sendMultipleTypes(bool aBool, int anInt, String aString); - /// Returns passed in int. @ObjCSelector('echoInt:') int echoInt(int anInt); @@ -87,6 +125,43 @@ abstract class HostIntegrationCoreApi { @ObjCSelector('echoUint8List:') Uint8List echoUint8List(Uint8List aUint8List); + // ========== Syncronous nullable method tests ========== + + /// Returns the inner `aString` value from the wrapped object, to test + /// sending of nested objects. + @ObjCSelector('extractNestedNullableStringFrom:') + String? extractNestedNullableString(AllNullableTypesWrapper wrapper); + + /// Returns the inner `aString` value from the wrapped object, to test + /// sending of nested objects. + @ObjCSelector('createNestedObjectWithNullableString:') + AllNullableTypesWrapper createNestedNullableString(String? nullableString); + + /// Returns passed in arguments of multiple types. + @ObjCSelector('sendMultipleNullableTypesABool:anInt:aString:') + AllNullableTypes sendMultipleNullableTypes( + bool? aNullableBool, int? aNullableInt, String? aNullableString); + + /// Returns passed in int. + @ObjCSelector('echoNullableInt:') + int? echoNullableInt(int? aNullableInt); + + /// Returns passed in double. + @ObjCSelector('echoNullableDouble:') + double? echoNullableDouble(double? aNullableDouble); + + /// Returns the passed in boolean. + @ObjCSelector('echoNullableBool:') + bool? echoNullableBool(bool? aNullableBool); + + /// Returns the passed in string. + @ObjCSelector('echoNullableString:') + String? echoNullableString(String? aNullableString); + + /// Returns the passed in Uint8List. + @ObjCSelector('echoNullableUint8List:') + Uint8List? echoNullableUint8List(Uint8List? aNullableUint8List); + // ========== Asyncronous method tests ========== /// A no-op function taking no arguments and returning no value, to sanity @@ -126,6 +201,10 @@ abstract class FlutterIntegrationCoreApi { @ObjCSelector('echoAllTypes:') AllTypes echoAllTypes(AllTypes everything); + /// Returns the passed object, to test serialization and deserialization. + @ObjCSelector('echoAllNullableTypes:') + AllNullableTypes echoAllNullableTypes(AllNullableTypes everything); + /// Returns the passed string, to test serialization and deserialization. @ObjCSelector('echoString:') String echoString(String aString); diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java index 838db5348b..69910b5137 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java @@ -6,8 +6,9 @@ package com.example.alternate_language_test_plugin; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.example.alternate_language_test_plugin.CoreTests.AllNullableTypes; +import com.example.alternate_language_test_plugin.CoreTests.AllNullableTypesWrapper; import com.example.alternate_language_test_plugin.CoreTests.AllTypes; -import com.example.alternate_language_test_plugin.CoreTests.AllTypesWrapper; import com.example.alternate_language_test_plugin.CoreTests.FlutterIntegrationCoreApi; import com.example.alternate_language_test_plugin.CoreTests.HostIntegrationCoreApi; import com.example.alternate_language_test_plugin.CoreTests.Result; @@ -36,30 +37,16 @@ public class AlternateLanguageTestPlugin implements FlutterPlugin, HostIntegrati return everything; } + @Override + public @Nullable AllNullableTypes echoAllNullableTypes(@Nullable AllNullableTypes everything) { + return everything; + } + @Override public void throwError() { throw new RuntimeException("An error"); } - @Override - public @Nullable String extractNestedString(@NonNull AllTypesWrapper wrapper) { - return wrapper.getValues().getAString(); - } - - @Override - public @NonNull AllTypesWrapper createNestedString(@NonNull String string) { - AllTypes innerObject = new AllTypes.Builder().setAString(string).build(); - return new AllTypesWrapper.Builder().setValues(innerObject).build(); - } - - @Override - public @NonNull AllTypes sendMultipleTypes( - @NonNull Boolean aBool, @NonNull Long anInt, @NonNull String aString) { - AllTypes someThings = - new AllTypes.Builder().setABool(aBool).setAnInt(anInt).setAString(aString).build(); - return someThings; - } - @Override public Long echoInt(@NonNull Long anInt) { return anInt; @@ -85,6 +72,58 @@ public class AlternateLanguageTestPlugin implements FlutterPlugin, HostIntegrati return aUint8List; } + @Override + public @Nullable String extractNestedNullableString(@NonNull AllNullableTypesWrapper wrapper) { + return wrapper.getValues().getANullableString(); + } + + @Override + public @NonNull AllNullableTypesWrapper createNestedNullableString( + @Nullable String nullableString) { + AllNullableTypes innerObject = + new AllNullableTypes.Builder().setANullableString(nullableString).build(); + return new AllNullableTypesWrapper.Builder().setValues(innerObject).build(); + } + + @Override + public @NonNull AllNullableTypes sendMultipleNullableTypes( + @Nullable Boolean aNullableBool, + @Nullable Long aNullableInt, + @Nullable String aNullableString) { + AllNullableTypes someThings = + new AllNullableTypes.Builder() + .setANullableBool(aNullableBool) + .setANullableInt(aNullableInt) + .setANullableString(aNullableString) + .build(); + return someThings; + } + + @Override + public @Nullable Long echoNullableInt(@Nullable Long aNullableInt) { + return aNullableInt; + } + + @Override + public @Nullable Double echoNullableDouble(@Nullable Double aNullableDouble) { + return aNullableDouble; + } + + @Override + public @Nullable Boolean echoNullableBool(@Nullable Boolean aNullableBool) { + return aNullableBool; + } + + @Override + public @Nullable String echoNullableString(@Nullable String aNullableString) { + return aNullableString; + } + + @Override + public @Nullable byte[] echoNullableUint8List(@Nullable byte[] aNullableUint8List) { + return aNullableUint8List; + } + @Override public void noopAsync(Result result) { result.success(null); diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AllDatatypesTest.java b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AllDatatypesTest.java index f0531bd3c3..e4aea7c300 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AllDatatypesTest.java +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/test/java/com/example/alternate_language_test_plugin/AllDatatypesTest.java @@ -7,7 +7,7 @@ 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.AllTypes; +import com.example.alternate_language_test_plugin.CoreTests.AllNullableTypes; import com.example.alternate_language_test_plugin.CoreTests.FlutterIntegrationCoreApi; import io.flutter.plugin.common.BinaryMessenger; import java.nio.ByteBuffer; @@ -20,7 +20,7 @@ import org.junit.Test; public class AllDatatypesTest { @Test public void nullValues() { - AllTypes everything = new AllTypes(); + AllNullableTypes everything = new AllNullableTypes(); BinaryMessenger binaryMessenger = mock(BinaryMessenger.class); doAnswer( invocation -> { @@ -39,21 +39,21 @@ public class AllDatatypesTest { .send(anyString(), any(), any()); FlutterIntegrationCoreApi api = new FlutterIntegrationCoreApi(binaryMessenger); boolean[] didCall = {false}; - api.echoAllTypes( + api.echoAllNullableTypes( everything, (result) -> { didCall[0] = true; - assertNull(everything.getABool()); - assertNull(everything.getAnInt()); - assertNull(everything.getADouble()); - assertNull(everything.getAString()); - assertNull(everything.getAByteArray()); - assertNull(everything.getA4ByteArray()); - assertNull(everything.getA8ByteArray()); - assertNull(everything.getAFloatArray()); - assertNull(everything.getAList()); - assertNull(everything.getAMap()); - assertNull(everything.getMapWithObject()); + assertNull(everything.getANullableBool()); + assertNull(everything.getANullableInt()); + assertNull(everything.getANullableDouble()); + assertNull(everything.getANullableString()); + assertNull(everything.getANullableByteArray()); + assertNull(everything.getANullable4ByteArray()); + assertNull(everything.getANullable8ByteArray()); + assertNull(everything.getANullableFloatArray()); + assertNull(everything.getANullableList()); + assertNull(everything.getANullableMap()); + assertNull(everything.getNullableMapWithObject()); }); assertTrue(didCall[0]); } @@ -84,18 +84,18 @@ public class AllDatatypesTest { @Test public void hasValues() { - AllTypes everything = new AllTypes(); - everything.setABool(false); - everything.setAnInt(1234L); - everything.setADouble(2.0); - everything.setAString("hello"); - everything.setAByteArray(new byte[] {1, 2, 3, 4}); - everything.setA4ByteArray(new int[] {1, 2, 3, 4}); - everything.setA8ByteArray(new long[] {1, 2, 3, 4}); - everything.setAFloatArray(new double[] {0.5, 0.25, 1.5, 1.25}); - everything.setAList(Arrays.asList(new int[] {1, 2, 3})); - everything.setAMap(makeMap("hello", 1234)); - everything.setMapWithObject(makeStringMap("hello", 1234)); + AllNullableTypes everything = new AllNullableTypes(); + everything.setANullableBool(false); + everything.setANullableInt(1234L); + everything.setANullableDouble(2.0); + everything.setANullableString("hello"); + everything.setANullableByteArray(new byte[] {1, 2, 3, 4}); + everything.setANullable4ByteArray(new int[] {1, 2, 3, 4}); + everything.setANullable8ByteArray(new long[] {1, 2, 3, 4}); + everything.setANullableFloatArray(new double[] {0.5, 0.25, 1.5, 1.25}); + everything.setANullableList(Arrays.asList(new int[] {1, 2, 3})); + everything.setANullableMap(makeMap("hello", 1234)); + everything.setNullableMapWithObject(makeStringMap("hello", 1234)); BinaryMessenger binaryMessenger = mock(BinaryMessenger.class); doAnswer( invocation -> { @@ -114,38 +114,43 @@ public class AllDatatypesTest { .send(anyString(), any(), any()); FlutterIntegrationCoreApi api = new FlutterIntegrationCoreApi(binaryMessenger); boolean[] didCall = {false}; - api.echoAllTypes( + api.echoAllNullableTypes( everything, (result) -> { didCall[0] = true; - assertEquals(everything.getABool(), result.getABool()); - assertEquals(everything.getAnInt(), result.getAnInt()); - assertEquals(everything.getADouble(), result.getADouble()); - assertEquals(everything.getAString(), result.getAString()); - assertArrayEquals(everything.getAByteArray(), result.getAByteArray()); - assertArrayEquals(everything.getA4ByteArray(), result.getA4ByteArray()); - assertArrayEquals(everything.getA8ByteArray(), result.getA8ByteArray()); - assertTrue(floatArraysEqual(everything.getAFloatArray(), result.getAFloatArray())); - assertArrayEquals(everything.getAList().toArray(), result.getAList().toArray()); + assertEquals(everything.getANullableBool(), result.getANullableBool()); + assertEquals(everything.getANullableInt(), result.getANullableInt()); + assertEquals(everything.getANullableDouble(), result.getANullableDouble()); + assertEquals(everything.getANullableString(), result.getANullableString()); + assertArrayEquals(everything.getANullableByteArray(), result.getANullableByteArray()); + assertArrayEquals(everything.getANullable4ByteArray(), result.getANullable4ByteArray()); + assertArrayEquals(everything.getANullable8ByteArray(), result.getANullable8ByteArray()); + assertTrue( + floatArraysEqual( + everything.getANullableFloatArray(), result.getANullableFloatArray())); assertArrayEquals( - everything.getAMap().keySet().toArray(), result.getAMap().keySet().toArray()); + everything.getANullableList().toArray(), result.getANullableList().toArray()); assertArrayEquals( - everything.getAMap().values().toArray(), result.getAMap().values().toArray()); + everything.getANullableMap().keySet().toArray(), + result.getANullableMap().keySet().toArray()); assertArrayEquals( - everything.getMapWithObject().values().toArray(), - result.getMapWithObject().values().toArray()); + everything.getANullableMap().values().toArray(), + result.getANullableMap().values().toArray()); + assertArrayEquals( + everything.getNullableMapWithObject().values().toArray(), + result.getNullableMapWithObject().values().toArray()); }); assertTrue(didCall[0]); } @Test public void integerToLong() { - AllTypes everything = new AllTypes(); - everything.setAnInt(123L); + AllNullableTypes everything = new AllNullableTypes(); + everything.setANullableInt(123L); Map map = everything.toMap(); - assertTrue(map.containsKey("anInt")); - map.put("anInt", 123); - AllTypes readEverything = AllTypes.fromMap(map); - assertEquals(readEverything.getAnInt(), everything.getAnInt()); + assertTrue(map.containsKey("aNullableInt")); + map.put("aNullableInt", 123); + AllNullableTypes readEverything = AllNullableTypes.fromMap(map); + assertEquals(readEverything.getANullableInt(), everything.getANullableInt()); } } diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/ios/RunnerTests/AllDatatypesTest.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/ios/RunnerTests/AllDatatypesTest.m index 6355e2bfd7..c6355ae187 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/example/ios/RunnerTests/AllDatatypesTest.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/example/ios/RunnerTests/AllDatatypesTest.m @@ -21,66 +21,71 @@ @implementation AllDatatypesTest - (void)testAllNull { - AllTypes *everything = [[AllTypes alloc] init]; + AllNullableTypes *everything = [[AllNullableTypes alloc] init]; EchoBinaryMessenger *binaryMessenger = [[EchoBinaryMessenger alloc] initWithCodec:FlutterIntegrationCoreApiGetCodec()]; FlutterIntegrationCoreApi *api = [[FlutterIntegrationCoreApi alloc] initWithBinaryMessenger:binaryMessenger]; XCTestExpectation *expectation = [self expectationWithDescription:@"callback"]; - [api echoAllTypes:everything - completion:^(AllTypes *_Nonnull result, NSError *_Nullable error) { - XCTAssertNil(result.aBool); - XCTAssertNil(result.anInt); - XCTAssertNil(result.aDouble); - XCTAssertNil(result.aString); - XCTAssertNil(result.aByteArray); - XCTAssertNil(result.a4ByteArray); - XCTAssertNil(result.a8ByteArray); - XCTAssertNil(result.aFloatArray); - XCTAssertNil(result.aList); - XCTAssertNil(result.aMap); - [expectation fulfill]; - }]; + [api echoAllNullableTypes:everything + completion:^(AllNullableTypes *_Nonnull result, NSError *_Nullable error) { + XCTAssertNil(result.aNullableBool); + XCTAssertNil(result.aNullableInt); + XCTAssertNil(result.aNullableDouble); + XCTAssertNil(result.aNullableString); + XCTAssertNil(result.aNullableByteArray); + XCTAssertNil(result.aNullable4ByteArray); + XCTAssertNil(result.aNullable8ByteArray); + XCTAssertNil(result.aNullableFloatArray); + XCTAssertNil(result.aNullableList); + XCTAssertNil(result.aNullableMap); + [expectation fulfill]; + }]; [self waitForExpectations:@[ expectation ] timeout:1.0]; } - (void)testAllEquals { - AllTypes *everything = [[AllTypes alloc] init]; - everything.aBool = @NO; - everything.anInt = @(1); - everything.aDouble = @(2.0); - everything.aString = @"123"; - everything.aByteArray = [FlutterStandardTypedData + AllNullableTypes *everything = [[AllNullableTypes alloc] init]; + everything.aNullableBool = @NO; + everything.aNullableInt = @(1); + everything.aNullableDouble = @(2.0); + everything.aNullableString = @"123"; + everything.aNullableByteArray = [FlutterStandardTypedData typedDataWithBytes:[@"1234" dataUsingEncoding:NSUTF8StringEncoding]]; - everything.a4ByteArray = [FlutterStandardTypedData + everything.aNullable4ByteArray = [FlutterStandardTypedData typedDataWithInt32:[@"1234" dataUsingEncoding:NSUTF8StringEncoding]]; - everything.a8ByteArray = [FlutterStandardTypedData + everything.aNullable8ByteArray = [FlutterStandardTypedData typedDataWithInt64:[@"12345678" dataUsingEncoding:NSUTF8StringEncoding]]; - everything.aFloatArray = [FlutterStandardTypedData + everything.aNullableFloatArray = [FlutterStandardTypedData typedDataWithFloat64:[@"12345678" dataUsingEncoding:NSUTF8StringEncoding]]; - everything.aList = @[ @(1), @(2) ]; - everything.aMap = @{@"hello" : @(1234)}; - everything.mapWithObject = @{@"hello" : @(1234), @"goodbye" : @"world"}; + everything.aNullableList = @[ @(1), @(2) ]; + everything.aNullableMap = @{@"hello" : @(1234)}; + everything.nullableMapWithObject = @{@"hello" : @(1234), @"goodbye" : @"world"}; EchoBinaryMessenger *binaryMessenger = [[EchoBinaryMessenger alloc] initWithCodec:FlutterIntegrationCoreApiGetCodec()]; FlutterIntegrationCoreApi *api = [[FlutterIntegrationCoreApi alloc] initWithBinaryMessenger:binaryMessenger]; XCTestExpectation *expectation = [self expectationWithDescription:@"callback"]; - [api echoAllTypes:everything - completion:^(AllTypes *_Nonnull result, NSError *_Nullable error) { - XCTAssertEqual(result.aBool, everything.aBool); - XCTAssertEqual(result.anInt, everything.anInt); - XCTAssertEqual(result.aDouble, everything.aDouble); - XCTAssertEqualObjects(result.aString, everything.aString); - XCTAssertEqualObjects(result.aByteArray.data, everything.aByteArray.data); - XCTAssertEqualObjects(result.a4ByteArray.data, everything.a4ByteArray.data); - XCTAssertEqualObjects(result.a8ByteArray.data, everything.a8ByteArray.data); - XCTAssertEqualObjects(result.aFloatArray.data, everything.aFloatArray.data); - XCTAssertEqualObjects(result.aList, everything.aList); - XCTAssertEqualObjects(result.aMap, everything.aMap); - XCTAssertEqualObjects(result.mapWithObject, everything.mapWithObject); - [expectation fulfill]; - }]; + [api echoAllNullableTypes:everything + completion:^(AllNullableTypes *_Nonnull result, NSError *_Nullable error) { + XCTAssertEqual(result.aNullableBool, everything.aNullableBool); + XCTAssertEqual(result.aNullableInt, everything.aNullableInt); + XCTAssertEqual(result.aNullableDouble, everything.aNullableDouble); + XCTAssertEqualObjects(result.aNullableString, everything.aNullableString); + XCTAssertEqualObjects(result.aNullableByteArray.data, + everything.aNullableByteArray.data); + XCTAssertEqualObjects(result.aNullable4ByteArray.data, + everything.aNullable4ByteArray.data); + XCTAssertEqualObjects(result.aNullable8ByteArray.data, + everything.aNullable8ByteArray.data); + XCTAssertEqualObjects(result.aNullableFloatArray.data, + everything.aNullableFloatArray.data); + XCTAssertEqualObjects(result.aNullableList, everything.aNullableList); + XCTAssertEqualObjects(result.aNullableMap, everything.aNullableMap); + XCTAssertEqualObjects(result.nullableMapWithObject, + everything.nullableMapWithObject); + [expectation fulfill]; + }]; [self waitForExpectations:@[ expectation ] timeout:1.0]; } diff --git a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/AlternateLanguageTestPlugin.m b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/AlternateLanguageTestPlugin.m index cbe1bda260..ee3e247062 100644 --- a/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/AlternateLanguageTestPlugin.m +++ b/packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/AlternateLanguageTestPlugin.m @@ -31,41 +31,22 @@ return everything; } +- (nullable AllNullableTypes *)echoAllNullableTypes:(nullable AllNullableTypes *)everything + error:(FlutterError *_Nullable *_Nonnull)error { + return everything; +} + - (void)throwErrorWithError:(FlutterError *_Nullable *_Nonnull)error { *error = [FlutterError errorWithCode:@"An error" message:nil details:nil]; } -- (nullable NSString *)extractNestedStringFrom:(AllTypesWrapper *)wrapper - error:(FlutterError *_Nullable *_Nonnull)error { - return wrapper.values.aString; -} - -- (nullable AllTypesWrapper *)createNestedObjectWithString:(NSString *)string - error: - (FlutterError *_Nullable *_Nonnull)error { - AllTypes *innerObject = [[AllTypes alloc] init]; - innerObject.aString = string; - return [AllTypesWrapper makeWithValues:innerObject]; -} - -- (nullable AllTypes *)sendMultipleTypesABool:(NSNumber *)aBool - anInt:(NSNumber *)anInt - aString:(NSString *)aString - error:(FlutterError *_Nullable *_Nonnull)error { - AllTypes *someTypes = [[AllTypes alloc] init]; - someTypes.aBool = aBool; - someTypes.anInt = anInt; - someTypes.aString = aString; - return someTypes; -} - - (nullable NSNumber *)echoInt:(NSNumber *)anInt error:(FlutterError *_Nullable *_Nonnull)error { return anInt; } - (nullable NSNumber *)echoDouble:(NSNumber *)aDouble error:(FlutterError *_Nullable *_Nonnull)error { - return aDouble + return aDouble; } - (nullable NSNumber *)echoBool:(NSNumber *)aBool error:(FlutterError *_Nullable *_Nonnull)error { @@ -82,6 +63,57 @@ return aUint8List; } +- (nullable NSString *)extractNestedNullableStringFrom:(AllNullableTypesWrapper *)wrapper + error:(FlutterError *_Nullable *_Nonnull)error { + return wrapper.values.aNullableString; +} + +- (nullable AllNullableTypesWrapper *) + createNestedObjectWithNullableString:(nullable NSString *)nullableString + error:(FlutterError *_Nullable *_Nonnull)error { + AllNullableTypes *innerObject = [[AllNullableTypes alloc] init]; + innerObject.aNullableString = nullableString; + return [AllNullableTypesWrapper makeWithValues:innerObject]; +} + +- (nullable AllNullableTypes *)sendMultipleNullableTypesABool:(nullable NSNumber *)aNullableBool + anInt:(nullable NSNumber *)aNullableInt + aString:(nullable NSString *)aNullableString + error:(FlutterError *_Nullable *_Nonnull) + error { + AllNullableTypes *someTypes = [[AllNullableTypes alloc] init]; + someTypes.aNullableBool = aNullableBool; + someTypes.aNullableInt = aNullableInt; + someTypes.aNullableString = aNullableString; + return someTypes; +} + +- (nullable NSNumber *)echoNullableInt:(nullable NSNumber *)aNullableInt + error:(FlutterError *_Nullable *_Nonnull)error { + return aNullableInt; +} + +- (nullable NSNumber *)echoNullableDouble:(nullable NSNumber *)aNullableDouble + error:(FlutterError *_Nullable *_Nonnull)error { + return aNullableDouble; +} + +- (nullable NSNumber *)echoNullableBool:(nullable NSNumber *)aNullableBool + error:(FlutterError *_Nullable *_Nonnull)error { + return aNullableBool; +} + +- (nullable NSString *)echoNullableString:(nullable NSString *)aNullableString + error:(FlutterError *_Nullable *_Nonnull)error { + return aNullableString; +} + +- (nullable FlutterStandardTypedData *) + echoNullableUint8List:(nullable FlutterStandardTypedData *)aNullableUint8List + error:(FlutterError *_Nullable *_Nonnull)error { + return aNullableUint8List; +} + - (void)noopAsyncWithCompletion:(void (^)(FlutterError *_Nullable))completion { completion(nil); } diff --git a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart index b701c66101..048415138b 100644 --- a/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart +++ b/packages/pigeon/platform_tests/flutter_null_safe_unit_tests/lib/core_tests.gen.dart @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // -// Autogenerated from Pigeon (v4.2.10), do not edit directly. +// Autogenerated from Pigeon (v4.2.11), do not edit directly. // See also: https://pub.dev/packages/pigeon // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import import 'dart:async'; @@ -19,36 +19,30 @@ enum AnEnum { class AllTypes { AllTypes({ - this.aBool, - this.anInt, - this.aDouble, - this.aString, - this.aByteArray, - this.a4ByteArray, - this.a8ByteArray, - this.aFloatArray, - this.aList, - this.aMap, - this.nestedList, - this.mapWithAnnotations, - this.mapWithObject, - this.anEnum, + required this.aBool, + required this.anInt, + required this.aDouble, + required this.aString, + required this.aByteArray, + required this.a4ByteArray, + required this.a8ByteArray, + required this.aFloatArray, + required this.aList, + required this.aMap, + required this.anEnum, }); - bool? aBool; - int? anInt; - double? aDouble; - String? aString; - Uint8List? aByteArray; - Int32List? a4ByteArray; - Int64List? a8ByteArray; - Float64List? aFloatArray; - List? aList; - Map? aMap; - List?>? nestedList; - Map? mapWithAnnotations; - Map? mapWithObject; - AnEnum? anEnum; + bool aBool; + int anInt; + double aDouble; + String aString; + Uint8List aByteArray; + Int32List a4ByteArray; + Int64List a8ByteArray; + Float64List aFloatArray; + List aList; + Map aMap; + AnEnum anEnum; Object encode() { final Map pigeonMap = {}; @@ -62,46 +56,114 @@ class AllTypes { pigeonMap['aFloatArray'] = aFloatArray; pigeonMap['aList'] = aList; pigeonMap['aMap'] = aMap; - pigeonMap['nestedList'] = nestedList; - pigeonMap['mapWithAnnotations'] = mapWithAnnotations; - pigeonMap['mapWithObject'] = mapWithObject; - pigeonMap['anEnum'] = anEnum?.index; + pigeonMap['anEnum'] = anEnum.index; return pigeonMap; } static AllTypes decode(Object message) { final Map pigeonMap = message as Map; return AllTypes( - aBool: pigeonMap['aBool'] as bool?, - anInt: pigeonMap['anInt'] as int?, - aDouble: pigeonMap['aDouble'] as double?, - aString: pigeonMap['aString'] as String?, - aByteArray: pigeonMap['aByteArray'] as Uint8List?, - a4ByteArray: pigeonMap['a4ByteArray'] as Int32List?, - a8ByteArray: pigeonMap['a8ByteArray'] as Int64List?, - aFloatArray: pigeonMap['aFloatArray'] as Float64List?, - aList: pigeonMap['aList'] as List?, - aMap: pigeonMap['aMap'] as Map?, - nestedList: - (pigeonMap['nestedList'] as List?)?.cast?>(), - mapWithAnnotations: - (pigeonMap['mapWithAnnotations'] as Map?) + aBool: pigeonMap['aBool']! as bool, + anInt: pigeonMap['anInt']! as int, + aDouble: pigeonMap['aDouble']! as double, + aString: pigeonMap['aString']! as String, + aByteArray: pigeonMap['aByteArray']! as Uint8List, + a4ByteArray: pigeonMap['a4ByteArray']! as Int32List, + a8ByteArray: pigeonMap['a8ByteArray']! as Int64List, + aFloatArray: pigeonMap['aFloatArray']! as Float64List, + aList: pigeonMap['aList']! as List, + aMap: pigeonMap['aMap']! as Map, + anEnum: AnEnum.values[pigeonMap['anEnum']! as int], + ); + } +} + +class AllNullableTypes { + AllNullableTypes({ + this.aNullableBool, + this.aNullableInt, + this.aNullableDouble, + this.aNullableString, + this.aNullableByteArray, + this.aNullable4ByteArray, + this.aNullable8ByteArray, + this.aNullableFloatArray, + this.aNullableList, + this.aNullableMap, + this.nullableNestedList, + this.nullableMapWithAnnotations, + this.nullableMapWithObject, + this.aNullableEnum, + }); + + bool? aNullableBool; + int? aNullableInt; + double? aNullableDouble; + String? aNullableString; + Uint8List? aNullableByteArray; + Int32List? aNullable4ByteArray; + Int64List? aNullable8ByteArray; + Float64List? aNullableFloatArray; + List? aNullableList; + Map? aNullableMap; + List?>? nullableNestedList; + Map? nullableMapWithAnnotations; + Map? nullableMapWithObject; + AnEnum? aNullableEnum; + + Object encode() { + final Map pigeonMap = {}; + pigeonMap['aNullableBool'] = aNullableBool; + pigeonMap['aNullableInt'] = aNullableInt; + pigeonMap['aNullableDouble'] = aNullableDouble; + pigeonMap['aNullableString'] = aNullableString; + pigeonMap['aNullableByteArray'] = aNullableByteArray; + pigeonMap['aNullable4ByteArray'] = aNullable4ByteArray; + pigeonMap['aNullable8ByteArray'] = aNullable8ByteArray; + pigeonMap['aNullableFloatArray'] = aNullableFloatArray; + pigeonMap['aNullableList'] = aNullableList; + pigeonMap['aNullableMap'] = aNullableMap; + pigeonMap['nullableNestedList'] = nullableNestedList; + pigeonMap['nullableMapWithAnnotations'] = nullableMapWithAnnotations; + pigeonMap['nullableMapWithObject'] = nullableMapWithObject; + pigeonMap['aNullableEnum'] = aNullableEnum?.index; + return pigeonMap; + } + + static AllNullableTypes decode(Object message) { + final Map pigeonMap = message as Map; + return AllNullableTypes( + aNullableBool: pigeonMap['aNullableBool'] as bool?, + aNullableInt: pigeonMap['aNullableInt'] as int?, + aNullableDouble: pigeonMap['aNullableDouble'] as double?, + aNullableString: pigeonMap['aNullableString'] as String?, + aNullableByteArray: pigeonMap['aNullableByteArray'] as Uint8List?, + aNullable4ByteArray: pigeonMap['aNullable4ByteArray'] as Int32List?, + aNullable8ByteArray: pigeonMap['aNullable8ByteArray'] as Int64List?, + aNullableFloatArray: pigeonMap['aNullableFloatArray'] as Float64List?, + aNullableList: pigeonMap['aNullableList'] as List?, + aNullableMap: pigeonMap['aNullableMap'] as Map?, + nullableNestedList: (pigeonMap['nullableNestedList'] as List?) + ?.cast?>(), + nullableMapWithAnnotations: + (pigeonMap['nullableMapWithAnnotations'] as Map?) ?.cast(), - mapWithObject: (pigeonMap['mapWithObject'] as Map?) - ?.cast(), - anEnum: pigeonMap['anEnum'] != null - ? AnEnum.values[pigeonMap['anEnum']! as int] + nullableMapWithObject: + (pigeonMap['nullableMapWithObject'] as Map?) + ?.cast(), + aNullableEnum: pigeonMap['aNullableEnum'] != null + ? AnEnum.values[pigeonMap['aNullableEnum']! as int] : null, ); } } -class AllTypesWrapper { - AllTypesWrapper({ +class AllNullableTypesWrapper { + AllNullableTypesWrapper({ required this.values, }); - AllTypes values; + AllNullableTypes values; Object encode() { final Map pigeonMap = {}; @@ -109,10 +171,10 @@ class AllTypesWrapper { return pigeonMap; } - static AllTypesWrapper decode(Object message) { + static AllNullableTypesWrapper decode(Object message) { final Map pigeonMap = message as Map; - return AllTypesWrapper( - values: AllTypes.decode(pigeonMap['values']!), + return AllNullableTypesWrapper( + values: AllNullableTypes.decode(pigeonMap['values']!), ); } } @@ -121,12 +183,18 @@ class _HostIntegrationCoreApiCodec extends StandardMessageCodec { const _HostIntegrationCoreApiCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is AllTypes) { + if (value is AllNullableTypes) { buffer.putUint8(128); writeValue(buffer, value.encode()); - } else if (value is AllTypesWrapper) { + } else if (value is AllNullableTypes) { buffer.putUint8(129); writeValue(buffer, value.encode()); + } else if (value is AllNullableTypesWrapper) { + buffer.putUint8(130); + writeValue(buffer, value.encode()); + } else if (value is AllTypes) { + buffer.putUint8(131); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -136,10 +204,16 @@ class _HostIntegrationCoreApiCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 128: - return AllTypes.decode(readValue(buffer)!); + return AllNullableTypes.decode(readValue(buffer)!); case 129: - return AllTypesWrapper.decode(readValue(buffer)!); + return AllNullableTypes.decode(readValue(buffer)!); + + case 130: + return AllNullableTypesWrapper.decode(readValue(buffer)!); + + case 131: + return AllTypes.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -215,6 +289,32 @@ class HostIntegrationCoreApi { } } + /// Returns the passed object, to test serialization and deserialization. + Future echoAllNullableTypes( + AllNullableTypes? arg_everything) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_everything]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as AllNullableTypes?); + } + } + /// Returns an error, to test error handling. Future throwError() async { final BasicMessageChannel channel = BasicMessageChannel( @@ -240,95 +340,6 @@ class HostIntegrationCoreApi { } } - /// Returns the inner `aString` value from the wrapped object, to test - /// sending of nested objects. - Future extractNestedString(AllTypesWrapper arg_wrapper) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedString', codec, - binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_wrapper]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = - (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else { - return (replyMap['result'] as String?); - } - } - - /// Returns the inner `aString` value from the wrapped object, to test - /// sending of nested objects. - Future createNestedString(String arg_string) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.HostIntegrationCoreApi.createNestedString', codec, - binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_string]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = - (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else if (replyMap['result'] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyMap['result'] as AllTypesWrapper?)!; - } - } - - /// Returns passed in arguments of multiple types. - Future sendMultipleTypes( - bool arg_aBool, int arg_anInt, String arg_aString) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.HostIntegrationCoreApi.sendMultipleTypes', codec, - binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_aBool, arg_anInt, arg_aString]) - as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = - (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else if (replyMap['result'] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyMap['result'] as AllTypes?)!; - } - } - /// Returns passed in int. Future echoInt(int arg_anInt) async { final BasicMessageChannel channel = BasicMessageChannel( @@ -479,6 +490,227 @@ class HostIntegrationCoreApi { } } + /// Returns the inner `aString` value from the wrapped object, to test + /// sending of nested objects. + Future extractNestedNullableString( + AllNullableTypesWrapper arg_wrapper) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString', + codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_wrapper]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as String?); + } + } + + /// Returns the inner `aString` value from the wrapped object, to test + /// sending of nested objects. + Future createNestedNullableString( + String? arg_nullableString) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.createNestedNullableString', + codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_nullableString]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else if (replyMap['result'] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyMap['result'] as AllNullableTypesWrapper?)!; + } + } + + /// Returns passed in arguments of multiple types. + Future sendMultipleNullableTypes(bool? arg_aNullableBool, + int? arg_aNullableInt, String? arg_aNullableString) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.sendMultipleNullableTypes', + codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel.send( + [arg_aNullableBool, arg_aNullableInt, arg_aNullableString]) + as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else if (replyMap['result'] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyMap['result'] as AllNullableTypes?)!; + } + } + + /// Returns passed in int. + Future echoNullableInt(int? arg_aNullableInt) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableInt', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_aNullableInt]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as int?); + } + } + + /// Returns passed in double. + Future echoNullableDouble(double? arg_aNullableDouble) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableDouble', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_aNullableDouble]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as double?); + } + } + + /// Returns the passed in boolean. + Future echoNullableBool(bool? arg_aNullableBool) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableBool', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_aNullableBool]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as bool?); + } + } + + /// Returns the passed in string. + Future echoNullableString(String? arg_aNullableString) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableString', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_aNullableString]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as String?); + } + } + + /// Returns the passed in Uint8List. + Future echoNullableUint8List( + Uint8List? arg_aNullableUint8List) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableUint8List', + codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_aNullableUint8List]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as Uint8List?); + } + } + /// A no-op function taking no arguments and returning no value, to sanity /// test basic asynchronous calling. Future noopAsync() async { @@ -594,9 +826,12 @@ class _FlutterIntegrationCoreApiCodec extends StandardMessageCodec { const _FlutterIntegrationCoreApiCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is AllTypes) { + if (value is AllNullableTypes) { buffer.putUint8(128); writeValue(buffer, value.encode()); + } else if (value is AllTypes) { + buffer.putUint8(129); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -606,6 +841,9 @@ class _FlutterIntegrationCoreApiCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 128: + return AllNullableTypes.decode(readValue(buffer)!); + + case 129: return AllTypes.decode(readValue(buffer)!); default: @@ -626,6 +864,9 @@ abstract class FlutterIntegrationCoreApi { /// Returns the passed object, to test serialization and deserialization. AllTypes echoAllTypes(AllTypes everything); + /// Returns the passed object, to test serialization and deserialization. + AllNullableTypes echoAllNullableTypes(AllNullableTypes everything); + /// Returns the passed string, to test serialization and deserialization. String echoString(String aString); static void setup(FlutterIntegrationCoreApi? api, @@ -663,6 +904,28 @@ abstract class FlutterIntegrationCoreApi { }); } } + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes', + codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes was null.'); + final List args = (message as List?)!; + final AllNullableTypes? arg_everything = + (args[0] as AllNullableTypes?); + assert(arg_everything != null, + 'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes was null, expected non-null AllNullableTypes.'); + final AllNullableTypes output = + api.echoAllNullableTypes(arg_everything!); + return output; + }); + } + } { final BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoString', codec, diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart index 5346472a70..37b4bc843f 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/integration_tests.dart @@ -35,6 +35,45 @@ enum TargetGenerator { void runPigeonIntegrationTests(TargetGenerator targetGenerator) { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + final AllTypes genericAllTypes = AllTypes( + aBool: true, + anInt: 42, + aDouble: 3.14159, + aString: 'Hello host!', + aByteArray: Uint8List.fromList([1, 2, 3]), + a4ByteArray: Int32List.fromList([4, 5, 6]), + a8ByteArray: Int64List.fromList([7, 8, 9]), + aFloatArray: Float64List.fromList([2.71828, 3.14159]), + aList: ['Thing 1', 2, true, 3.14], + aMap: {'a': 1, 'b': 2.0, 'c': 'three', 'd': false}, + anEnum: AnEnum.two, + ); + + final AllNullableTypes genericAllNullableTypes = AllNullableTypes( + aNullableBool: true, + aNullableInt: 42, + aNullableDouble: 3.14159, + aNullableString: 'Hello host!', + aNullableByteArray: Uint8List.fromList([1, 2, 3]), + aNullable4ByteArray: Int32List.fromList([4, 5, 6]), + aNullable8ByteArray: Int64List.fromList([7, 8, 9]), + aNullableFloatArray: Float64List.fromList([2.71828, 3.14159]), + aNullableList: ['Thing 1', 2, true, 3.14], + aNullableMap: { + 'a': 1, + 'b': 2.0, + 'c': 'three', + 'd': false + }, + nullableNestedList: >[ + [true, false], + [false, true] + ], + nullableMapWithAnnotations: {}, + nullableMapWithObject: {}, + aNullableEnum: AnEnum.two, + ); + group('Host sync API tests', () { testWidgets('basic void->void call works', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); @@ -46,49 +85,154 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - final AllTypes sentObject = AllTypes( - aBool: true, - anInt: 42, - aDouble: 3.14159, - aString: 'Hello host!', - aByteArray: Uint8List.fromList([1, 2, 3]), - a4ByteArray: Int32List.fromList([4, 5, 6]), - a8ByteArray: Int64List.fromList([7, 8, 9]), - aFloatArray: Float64List.fromList([2.71828, 3.14159]), - aList: ['Thing 1', 2], - aMap: {'a': 1, 'b': 2.0}, - nestedList: >[ - [true, false], - [false, true] - ], - anEnum: AnEnum.two, - ); + final AllTypes echoObject = await api.echoAllTypes(genericAllTypes); - final AllTypes echoObject = await api.echoAllTypes(sentObject); - expect(echoObject.aBool, sentObject.aBool); - expect(echoObject.anInt, sentObject.anInt); - expect(echoObject.aDouble, sentObject.aDouble); - expect(echoObject.aString, sentObject.aString); - expect(echoObject.aByteArray, sentObject.aByteArray); - expect(echoObject.a4ByteArray, sentObject.a4ByteArray); - expect(echoObject.a8ByteArray, sentObject.a8ByteArray); - expect(echoObject.aFloatArray, sentObject.aFloatArray); - expect(listEquals(echoObject.aList, sentObject.aList), true); - expect(mapEquals(echoObject.aMap, sentObject.aMap), true); - expect(echoObject.nestedList?.length, sentObject.nestedList?.length); + expect(echoObject.aBool, genericAllTypes.aBool); + expect(echoObject.anInt, genericAllTypes.anInt); + expect(echoObject.aDouble, genericAllTypes.aDouble); + expect(echoObject.aString, genericAllTypes.aString); + expect(echoObject.aByteArray, genericAllTypes.aByteArray); + expect(echoObject.a4ByteArray, genericAllTypes.a4ByteArray); + expect(echoObject.a8ByteArray, genericAllTypes.a8ByteArray); + expect(echoObject.aFloatArray, genericAllTypes.aFloatArray); + expect(listEquals(echoObject.aList, genericAllTypes.aList), true); + expect(mapEquals(echoObject.aMap, genericAllTypes.aMap), true); // TODO(stuartmorgan): Enable this once the Dart types are fixed; see // https://github.com/flutter/flutter/issues/116117 + // expect(echoObject.nestedList.length, genericAllTypes.nestedList.length); //for (int i = 0; i < echoObject.nestedList!.length; i++) { - // expect(listEquals(echoObject.nestedList![i], sentObject.nestedList![i]), + // expect(listEquals(echoObject.nestedList![i], genericAllTypes.nestedList![i]), + // true); + //} + // expect( + // mapEquals( + // echoObject.mapWithAnnotations, genericAllTypes.mapWithAnnotations), + // true); + // expect( + // mapEquals(echoObject.mapWithObject, genericAllTypes.mapWithObject), true); + expect(echoObject.anEnum, genericAllTypes.anEnum); + }); + + testWidgets('all nullable datatypes serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final AllNullableTypes? echoObject = + await api.echoAllNullableTypes(genericAllNullableTypes); + expect(echoObject?.aNullableBool, genericAllNullableTypes.aNullableBool); + expect(echoObject?.aNullableInt, genericAllNullableTypes.aNullableInt); + expect( + echoObject?.aNullableDouble, genericAllNullableTypes.aNullableDouble); + expect( + echoObject?.aNullableString, genericAllNullableTypes.aNullableString); + expect(echoObject?.aNullableByteArray, + genericAllNullableTypes.aNullableByteArray); + expect(echoObject?.aNullable4ByteArray, + genericAllNullableTypes.aNullable4ByteArray); + expect(echoObject?.aNullable8ByteArray, + genericAllNullableTypes.aNullable8ByteArray); + expect(echoObject?.aNullableFloatArray, + genericAllNullableTypes.aNullableFloatArray); + expect( + listEquals( + echoObject?.aNullableList, genericAllNullableTypes.aNullableList), + true); + expect( + mapEquals( + echoObject?.aNullableMap, genericAllNullableTypes.aNullableMap), + true); + expect(echoObject?.nullableNestedList?.length, + genericAllNullableTypes.nullableNestedList?.length); + // TODO(stuartmorgan): Enable this once the Dart types are fixed; see + // https://github.com/flutter/flutter/issues/116117 + //for (int i = 0; i < echoObject?.nullableNestedList!.length; i++) { + // expect(listEquals(echoObject?.nullableNestedList![i], genericAllNullableTypes.nullableNestedList![i]), // true); //} expect( - mapEquals( - echoObject.mapWithAnnotations, sentObject.mapWithAnnotations), + mapEquals(echoObject?.nullableMapWithAnnotations, + genericAllNullableTypes.nullableMapWithAnnotations), true); expect( - mapEquals(echoObject.mapWithObject, sentObject.mapWithObject), true); - expect(echoObject.anEnum, sentObject.anEnum); + mapEquals(echoObject?.nullableMapWithObject, + genericAllNullableTypes.nullableMapWithObject), + true); + expect(echoObject?.aNullableEnum, genericAllNullableTypes.aNullableEnum); + }); + + testWidgets('all nulla datatypes serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final AllNullableTypes allTypesNull = AllNullableTypes(); + + final AllNullableTypes? echoNullFilledObject = + await api.echoAllNullableTypes(allTypesNull); + + expect(echoNullFilledObject?.aNullableBool, allTypesNull.aNullableBool); + expect(echoNullFilledObject?.aNullableBool, null); + + expect(echoNullFilledObject?.aNullableInt, allTypesNull.aNullableInt); + expect(echoNullFilledObject?.aNullableInt, null); + + expect( + echoNullFilledObject?.aNullableDouble, allTypesNull.aNullableDouble); + expect(echoNullFilledObject?.aNullableDouble, null); + + expect( + echoNullFilledObject?.aNullableString, allTypesNull.aNullableString); + expect(echoNullFilledObject?.aNullableString, null); + + expect(echoNullFilledObject?.aNullableByteArray, + allTypesNull.aNullableByteArray); + expect(echoNullFilledObject?.aNullableByteArray, null); + + expect(echoNullFilledObject?.aNullable4ByteArray, + allTypesNull.aNullable4ByteArray); + expect(echoNullFilledObject?.aNullable4ByteArray, null); + + expect(echoNullFilledObject?.aNullable8ByteArray, + allTypesNull.aNullable8ByteArray); + expect(echoNullFilledObject?.aNullable8ByteArray, null); + + expect(echoNullFilledObject?.aNullableFloatArray, + allTypesNull.aNullableFloatArray); + expect(echoNullFilledObject?.aNullableFloatArray, null); + + expect( + listEquals( + echoNullFilledObject?.aNullableList, allTypesNull.aNullableList), + true); + expect(echoNullFilledObject?.aNullableList, null); + + expect( + mapEquals( + echoNullFilledObject?.aNullableMap, allTypesNull.aNullableMap), + true); + expect(echoNullFilledObject?.aNullableMap, null); + + // TODO(stuartmorgan): Enable this once the Dart types are fixed; see + // https://github.com/flutter/flutter/issues/116117 + //for (int i = 0; i < echoNullFilledObject?.nullableNestedList!.length; i++) { + // expect(listEquals(echoNullFilledObject?.nullableNestedList![i], allTypesNull.nullableNestedList![i]), + // true); + //} + expect(echoNullFilledObject?.nullableNestedList, null); + + expect( + mapEquals(echoNullFilledObject?.nullableMapWithAnnotations, + allTypesNull.nullableMapWithAnnotations), + true); + expect(echoNullFilledObject?.nullableMapWithAnnotations, null); + + expect( + mapEquals(echoNullFilledObject?.nullableMapWithObject, + allTypesNull.nullableMapWithObject), + true); + expect(echoNullFilledObject?.nullableMapWithObject, null); + + expect(echoNullFilledObject?.aNullableEnum, allTypesNull.aNullableEnum); + expect(echoNullFilledObject?.aNullableEnum, null); }); testWidgets('errors are returned correctly', (WidgetTester _) async { @@ -105,12 +249,12 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { testWidgets('nested objects can be sent correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const String sentString = 'Some string'; - final AllTypesWrapper sentObject = - AllTypesWrapper(values: AllTypes(aString: sentString)); + final AllNullableTypesWrapper sentObject = + AllNullableTypesWrapper(values: genericAllNullableTypes); - final String? receivedString = await api.extractNestedString(sentObject); - expect(receivedString, sentString); + final String? receivedString = + await api.extractNestedNullableString(sentObject); + expect(receivedString, sentObject.values.aNullableString); }); testWidgets('nested objects can be received correctly', @@ -118,24 +262,36 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); const String sentString = 'Some string'; - final AllTypesWrapper receivedObject = - await api.createNestedString(sentString); - expect(receivedObject.values.aString, sentString); + final AllNullableTypesWrapper receivedObject = + await api.createNestedNullableString(sentString); + expect(receivedObject.values.aNullableString, sentString); }); testWidgets( 'Arguments of multiple types serialize and deserialize correctly', (WidgetTester _) async { final HostIntegrationCoreApi api = HostIntegrationCoreApi(); - const String aString = 'this is aString'; - const bool aBool = false; - const int anInt = 42; + const String aNullableString = 'this is a String'; + const bool aNullableBool = false; + const int aNullableInt = 42; - final AllTypes echoObject = - await api.sendMultipleTypes(aBool, anInt, aString); - expect(echoObject.anInt, anInt); - expect(echoObject.aBool, aBool); - expect(echoObject.aString, aString); + final AllNullableTypes echoObject = await api.sendMultipleNullableTypes( + aNullableBool, aNullableInt, aNullableString); + expect(echoObject.aNullableInt, aNullableInt); + expect(echoObject.aNullableBool, aNullableBool); + expect(echoObject.aNullableString, aNullableString); + }); + + testWidgets( + 'Arguments of multiple null types serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final AllNullableTypes echoNullFilledObject = + await api.sendMultipleNullableTypes(null, null, null); + expect(echoNullFilledObject.aNullableInt, null); + expect(echoNullFilledObject.aNullableBool, null); + expect(echoNullFilledObject.aNullableString, null); }); testWidgets('Ints serialize and deserialize correctly', @@ -194,6 +350,105 @@ void runPigeonIntegrationTests(TargetGenerator targetGenerator) { await api.echoUint8List(sentUint8List); expect(receivedUint8List, sentUint8List); }); + + testWidgets('Nullable Ints serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + const int sentInt = -13; + final int? receivedInt = await api.echoNullableInt(sentInt); + expect(receivedInt, sentInt); + }); + + testWidgets('Null Ints serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final int? receivedNullInt = await api.echoNullableInt(null); + expect(receivedNullInt, null); + }); + + testWidgets('Nullable Doubles serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + const double sentDouble = 2.0694; + final double? receivedDouble = await api.echoNullableDouble(sentDouble); + expect(receivedDouble, sentDouble); + }); + + testWidgets('Null Doubles serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final double? receivedNullDouble = await api.echoNullableDouble(null); + expect(receivedNullDouble, null); + }); + + testWidgets('Nullable booleans serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + for (final bool? sentBool in [true, false]) { + final bool? receivedBool = await api.echoNullableBool(sentBool); + expect(receivedBool, sentBool); + } + }); + + testWidgets('Null booleans serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + const bool? sentBool = null; + final bool? receivedBool = await api.echoNullableBool(sentBool); + expect(receivedBool, sentBool); + }); + + testWidgets('Nullable strings serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + const String sentString = "I'm a computer"; + final String? receivedString = await api.echoNullableString(sentString); + expect(receivedString, sentString); + }); + + testWidgets('Null strings serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final String? receivedNullString = await api.echoNullableString(null); + expect(receivedNullString, null); + }); + + testWidgets('Nullable Uint8List serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + final List data = [ + 102, + 111, + 114, + 116, + 121, + 45, + 116, + 119, + 111, + 0 + ]; + final Uint8List sentUint8List = Uint8List.fromList(data); + final Uint8List? receivedUint8List = + await api.echoNullableUint8List(sentUint8List); + expect(receivedUint8List, sentUint8List); + }); + + testWidgets('Null Uint8List serialize and deserialize correctly', + (WidgetTester _) async { + final HostIntegrationCoreApi api = HostIntegrationCoreApi(); + + final Uint8List? receivedNullUint8List = + await api.echoNullableUint8List(null); + expect(receivedNullUint8List, null); + }); }); group('Host async API tests', () { @@ -250,6 +505,11 @@ class _FlutterApiTestImplementation implements FlutterIntegrationCoreApi { return everything; } + @override + AllNullableTypes echoAllNullableTypes(AllNullableTypes everything) { + return everything; + } + @override String echoString(String aString) { return aString; diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart index 9b0f14bd83..048415138b 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/core_tests.gen.dart @@ -19,36 +19,30 @@ enum AnEnum { class AllTypes { AllTypes({ - this.aBool, - this.anInt, - this.aDouble, - this.aString, - this.aByteArray, - this.a4ByteArray, - this.a8ByteArray, - this.aFloatArray, - this.aList, - this.aMap, - this.nestedList, - this.mapWithAnnotations, - this.mapWithObject, - this.anEnum, + required this.aBool, + required this.anInt, + required this.aDouble, + required this.aString, + required this.aByteArray, + required this.a4ByteArray, + required this.a8ByteArray, + required this.aFloatArray, + required this.aList, + required this.aMap, + required this.anEnum, }); - bool? aBool; - int? anInt; - double? aDouble; - String? aString; - Uint8List? aByteArray; - Int32List? a4ByteArray; - Int64List? a8ByteArray; - Float64List? aFloatArray; - List? aList; - Map? aMap; - List?>? nestedList; - Map? mapWithAnnotations; - Map? mapWithObject; - AnEnum? anEnum; + bool aBool; + int anInt; + double aDouble; + String aString; + Uint8List aByteArray; + Int32List a4ByteArray; + Int64List a8ByteArray; + Float64List aFloatArray; + List aList; + Map aMap; + AnEnum anEnum; Object encode() { final Map pigeonMap = {}; @@ -62,46 +56,114 @@ class AllTypes { pigeonMap['aFloatArray'] = aFloatArray; pigeonMap['aList'] = aList; pigeonMap['aMap'] = aMap; - pigeonMap['nestedList'] = nestedList; - pigeonMap['mapWithAnnotations'] = mapWithAnnotations; - pigeonMap['mapWithObject'] = mapWithObject; - pigeonMap['anEnum'] = anEnum?.index; + pigeonMap['anEnum'] = anEnum.index; return pigeonMap; } static AllTypes decode(Object message) { final Map pigeonMap = message as Map; return AllTypes( - aBool: pigeonMap['aBool'] as bool?, - anInt: pigeonMap['anInt'] as int?, - aDouble: pigeonMap['aDouble'] as double?, - aString: pigeonMap['aString'] as String?, - aByteArray: pigeonMap['aByteArray'] as Uint8List?, - a4ByteArray: pigeonMap['a4ByteArray'] as Int32List?, - a8ByteArray: pigeonMap['a8ByteArray'] as Int64List?, - aFloatArray: pigeonMap['aFloatArray'] as Float64List?, - aList: pigeonMap['aList'] as List?, - aMap: pigeonMap['aMap'] as Map?, - nestedList: - (pigeonMap['nestedList'] as List?)?.cast?>(), - mapWithAnnotations: - (pigeonMap['mapWithAnnotations'] as Map?) + aBool: pigeonMap['aBool']! as bool, + anInt: pigeonMap['anInt']! as int, + aDouble: pigeonMap['aDouble']! as double, + aString: pigeonMap['aString']! as String, + aByteArray: pigeonMap['aByteArray']! as Uint8List, + a4ByteArray: pigeonMap['a4ByteArray']! as Int32List, + a8ByteArray: pigeonMap['a8ByteArray']! as Int64List, + aFloatArray: pigeonMap['aFloatArray']! as Float64List, + aList: pigeonMap['aList']! as List, + aMap: pigeonMap['aMap']! as Map, + anEnum: AnEnum.values[pigeonMap['anEnum']! as int], + ); + } +} + +class AllNullableTypes { + AllNullableTypes({ + this.aNullableBool, + this.aNullableInt, + this.aNullableDouble, + this.aNullableString, + this.aNullableByteArray, + this.aNullable4ByteArray, + this.aNullable8ByteArray, + this.aNullableFloatArray, + this.aNullableList, + this.aNullableMap, + this.nullableNestedList, + this.nullableMapWithAnnotations, + this.nullableMapWithObject, + this.aNullableEnum, + }); + + bool? aNullableBool; + int? aNullableInt; + double? aNullableDouble; + String? aNullableString; + Uint8List? aNullableByteArray; + Int32List? aNullable4ByteArray; + Int64List? aNullable8ByteArray; + Float64List? aNullableFloatArray; + List? aNullableList; + Map? aNullableMap; + List?>? nullableNestedList; + Map? nullableMapWithAnnotations; + Map? nullableMapWithObject; + AnEnum? aNullableEnum; + + Object encode() { + final Map pigeonMap = {}; + pigeonMap['aNullableBool'] = aNullableBool; + pigeonMap['aNullableInt'] = aNullableInt; + pigeonMap['aNullableDouble'] = aNullableDouble; + pigeonMap['aNullableString'] = aNullableString; + pigeonMap['aNullableByteArray'] = aNullableByteArray; + pigeonMap['aNullable4ByteArray'] = aNullable4ByteArray; + pigeonMap['aNullable8ByteArray'] = aNullable8ByteArray; + pigeonMap['aNullableFloatArray'] = aNullableFloatArray; + pigeonMap['aNullableList'] = aNullableList; + pigeonMap['aNullableMap'] = aNullableMap; + pigeonMap['nullableNestedList'] = nullableNestedList; + pigeonMap['nullableMapWithAnnotations'] = nullableMapWithAnnotations; + pigeonMap['nullableMapWithObject'] = nullableMapWithObject; + pigeonMap['aNullableEnum'] = aNullableEnum?.index; + return pigeonMap; + } + + static AllNullableTypes decode(Object message) { + final Map pigeonMap = message as Map; + return AllNullableTypes( + aNullableBool: pigeonMap['aNullableBool'] as bool?, + aNullableInt: pigeonMap['aNullableInt'] as int?, + aNullableDouble: pigeonMap['aNullableDouble'] as double?, + aNullableString: pigeonMap['aNullableString'] as String?, + aNullableByteArray: pigeonMap['aNullableByteArray'] as Uint8List?, + aNullable4ByteArray: pigeonMap['aNullable4ByteArray'] as Int32List?, + aNullable8ByteArray: pigeonMap['aNullable8ByteArray'] as Int64List?, + aNullableFloatArray: pigeonMap['aNullableFloatArray'] as Float64List?, + aNullableList: pigeonMap['aNullableList'] as List?, + aNullableMap: pigeonMap['aNullableMap'] as Map?, + nullableNestedList: (pigeonMap['nullableNestedList'] as List?) + ?.cast?>(), + nullableMapWithAnnotations: + (pigeonMap['nullableMapWithAnnotations'] as Map?) ?.cast(), - mapWithObject: (pigeonMap['mapWithObject'] as Map?) - ?.cast(), - anEnum: pigeonMap['anEnum'] != null - ? AnEnum.values[pigeonMap['anEnum']! as int] + nullableMapWithObject: + (pigeonMap['nullableMapWithObject'] as Map?) + ?.cast(), + aNullableEnum: pigeonMap['aNullableEnum'] != null + ? AnEnum.values[pigeonMap['aNullableEnum']! as int] : null, ); } } -class AllTypesWrapper { - AllTypesWrapper({ +class AllNullableTypesWrapper { + AllNullableTypesWrapper({ required this.values, }); - AllTypes values; + AllNullableTypes values; Object encode() { final Map pigeonMap = {}; @@ -109,10 +171,10 @@ class AllTypesWrapper { return pigeonMap; } - static AllTypesWrapper decode(Object message) { + static AllNullableTypesWrapper decode(Object message) { final Map pigeonMap = message as Map; - return AllTypesWrapper( - values: AllTypes.decode(pigeonMap['values']!), + return AllNullableTypesWrapper( + values: AllNullableTypes.decode(pigeonMap['values']!), ); } } @@ -121,12 +183,18 @@ class _HostIntegrationCoreApiCodec extends StandardMessageCodec { const _HostIntegrationCoreApiCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is AllTypes) { + if (value is AllNullableTypes) { buffer.putUint8(128); writeValue(buffer, value.encode()); - } else if (value is AllTypesWrapper) { + } else if (value is AllNullableTypes) { buffer.putUint8(129); writeValue(buffer, value.encode()); + } else if (value is AllNullableTypesWrapper) { + buffer.putUint8(130); + writeValue(buffer, value.encode()); + } else if (value is AllTypes) { + buffer.putUint8(131); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -136,10 +204,16 @@ class _HostIntegrationCoreApiCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 128: - return AllTypes.decode(readValue(buffer)!); + return AllNullableTypes.decode(readValue(buffer)!); case 129: - return AllTypesWrapper.decode(readValue(buffer)!); + return AllNullableTypes.decode(readValue(buffer)!); + + case 130: + return AllNullableTypesWrapper.decode(readValue(buffer)!); + + case 131: + return AllTypes.decode(readValue(buffer)!); default: return super.readValueOfType(type, buffer); @@ -215,6 +289,32 @@ class HostIntegrationCoreApi { } } + /// Returns the passed object, to test serialization and deserialization. + Future echoAllNullableTypes( + AllNullableTypes? arg_everything) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.echoAllNullableTypes', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_everything]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as AllNullableTypes?); + } + } + /// Returns an error, to test error handling. Future throwError() async { final BasicMessageChannel channel = BasicMessageChannel( @@ -240,95 +340,6 @@ class HostIntegrationCoreApi { } } - /// Returns the inner `aString` value from the wrapped object, to test - /// sending of nested objects. - Future extractNestedString(AllTypesWrapper arg_wrapper) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedString', codec, - binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_wrapper]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = - (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else { - return (replyMap['result'] as String?); - } - } - - /// Returns the inner `aString` value from the wrapped object, to test - /// sending of nested objects. - Future createNestedString(String arg_string) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.HostIntegrationCoreApi.createNestedString', codec, - binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_string]) as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = - (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else if (replyMap['result'] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyMap['result'] as AllTypesWrapper?)!; - } - } - - /// Returns passed in arguments of multiple types. - Future sendMultipleTypes( - bool arg_aBool, int arg_anInt, String arg_aString) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.pigeon.HostIntegrationCoreApi.sendMultipleTypes', codec, - binaryMessenger: _binaryMessenger); - final Map? replyMap = - await channel.send([arg_aBool, arg_anInt, arg_aString]) - as Map?; - if (replyMap == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyMap['error'] != null) { - final Map error = - (replyMap['error'] as Map?)!; - throw PlatformException( - code: (error['code'] as String?)!, - message: error['message'] as String?, - details: error['details'], - ); - } else if (replyMap['result'] == null) { - throw PlatformException( - code: 'null-error', - message: 'Host platform returned null value for non-null return value.', - ); - } else { - return (replyMap['result'] as AllTypes?)!; - } - } - /// Returns passed in int. Future echoInt(int arg_anInt) async { final BasicMessageChannel channel = BasicMessageChannel( @@ -479,6 +490,227 @@ class HostIntegrationCoreApi { } } + /// Returns the inner `aString` value from the wrapped object, to test + /// sending of nested objects. + Future extractNestedNullableString( + AllNullableTypesWrapper arg_wrapper) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.extractNestedNullableString', + codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = + await channel.send([arg_wrapper]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as String?); + } + } + + /// Returns the inner `aString` value from the wrapped object, to test + /// sending of nested objects. + Future createNestedNullableString( + String? arg_nullableString) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.createNestedNullableString', + codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_nullableString]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else if (replyMap['result'] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyMap['result'] as AllNullableTypesWrapper?)!; + } + } + + /// Returns passed in arguments of multiple types. + Future sendMultipleNullableTypes(bool? arg_aNullableBool, + int? arg_aNullableInt, String? arg_aNullableString) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.sendMultipleNullableTypes', + codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel.send( + [arg_aNullableBool, arg_aNullableInt, arg_aNullableString]) + as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else if (replyMap['result'] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyMap['result'] as AllNullableTypes?)!; + } + } + + /// Returns passed in int. + Future echoNullableInt(int? arg_aNullableInt) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableInt', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_aNullableInt]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as int?); + } + } + + /// Returns passed in double. + Future echoNullableDouble(double? arg_aNullableDouble) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableDouble', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_aNullableDouble]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as double?); + } + } + + /// Returns the passed in boolean. + Future echoNullableBool(bool? arg_aNullableBool) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableBool', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_aNullableBool]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as bool?); + } + } + + /// Returns the passed in string. + Future echoNullableString(String? arg_aNullableString) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableString', codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_aNullableString]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as String?); + } + } + + /// Returns the passed in Uint8List. + Future echoNullableUint8List( + Uint8List? arg_aNullableUint8List) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.HostIntegrationCoreApi.echoNullableUint8List', + codec, + binaryMessenger: _binaryMessenger); + final Map? replyMap = await channel + .send([arg_aNullableUint8List]) as Map?; + if (replyMap == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyMap['error'] != null) { + final Map error = + (replyMap['error'] as Map?)!; + throw PlatformException( + code: (error['code'] as String?)!, + message: error['message'] as String?, + details: error['details'], + ); + } else { + return (replyMap['result'] as Uint8List?); + } + } + /// A no-op function taking no arguments and returning no value, to sanity /// test basic asynchronous calling. Future noopAsync() async { @@ -594,9 +826,12 @@ class _FlutterIntegrationCoreApiCodec extends StandardMessageCodec { const _FlutterIntegrationCoreApiCodec(); @override void writeValue(WriteBuffer buffer, Object? value) { - if (value is AllTypes) { + if (value is AllNullableTypes) { buffer.putUint8(128); writeValue(buffer, value.encode()); + } else if (value is AllTypes) { + buffer.putUint8(129); + writeValue(buffer, value.encode()); } else { super.writeValue(buffer, value); } @@ -606,6 +841,9 @@ class _FlutterIntegrationCoreApiCodec extends StandardMessageCodec { Object? readValueOfType(int type, ReadBuffer buffer) { switch (type) { case 128: + return AllNullableTypes.decode(readValue(buffer)!); + + case 129: return AllTypes.decode(readValue(buffer)!); default: @@ -626,6 +864,9 @@ abstract class FlutterIntegrationCoreApi { /// Returns the passed object, to test serialization and deserialization. AllTypes echoAllTypes(AllTypes everything); + /// Returns the passed object, to test serialization and deserialization. + AllNullableTypes echoAllNullableTypes(AllNullableTypes everything); + /// Returns the passed string, to test serialization and deserialization. String echoString(String aString); static void setup(FlutterIntegrationCoreApi? api, @@ -663,6 +904,28 @@ abstract class FlutterIntegrationCoreApi { }); } } + { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes', + codec, + binaryMessenger: binaryMessenger); + if (api == null) { + channel.setMessageHandler(null); + } else { + channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes was null.'); + final List args = (message as List?)!; + final AllNullableTypes? arg_everything = + (args[0] as AllNullableTypes?); + assert(arg_everything != null, + 'Argument for dev.flutter.pigeon.FlutterIntegrationCoreApi.echoAllNullableTypes was null, expected non-null AllNullableTypes.'); + final AllNullableTypes output = + api.echoAllNullableTypes(arg_everything!); + return output; + }); + } + } { final BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.FlutterIntegrationCoreApi.echoString', codec, diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/TestPlugin.kt b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/TestPlugin.kt index 2b8843b6e9..c5ea2ff461 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/TestPlugin.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/main/kotlin/com/example/test_plugin/TestPlugin.kt @@ -36,23 +36,14 @@ class TestPlugin: FlutterPlugin, HostIntegrationCoreApi { return everything } + override fun echoAllNullableTypes(everything: AllNullableTypes?): AllNullableTypes? { + return everything + } + override fun throwError() { throw Exception("An error"); } - override fun extractNestedString(wrapper: AllTypesWrapper): String? { - return wrapper.values.aString; - } - - override fun createNestedString(string: String): AllTypesWrapper { - return AllTypesWrapper(AllTypes(aString = string)) - } - - override fun sendMultipleTypes(aBool: Boolean, anInt: Long, aString: String): AllTypes { - var someThings = AllTypes(aBool = aBool, anInt = anInt, aString = aString) - return someThings - } - override fun echoInt(anInt: Long): Long { return anInt } @@ -73,6 +64,33 @@ class TestPlugin: FlutterPlugin, HostIntegrationCoreApi { return aUint8List } + override fun extractNestedNullableString(wrapper: AllNullableTypesWrapper): String? { + return wrapper.values.aNullableString + } + + override fun createNestedNullableString(nullableString: String?): AllNullableTypesWrapper { + return AllNullableTypesWrapper(AllNullableTypes(aNullableString = nullableString)) + } + + override fun sendMultipleNullableTypes(aNullableBool: Boolean?, aNullableInt: Long?, aNullableString: String?): AllNullableTypes { + return AllNullableTypes(aNullableBool = aNullableBool, aNullableInt = aNullableInt, aNullableString = aNullableString) + } + override fun echoNullableInt(aNullableInt: Long?): Long? { + return aNullableInt + } + override fun echoNullableDouble(aNullableDouble: Double?): Double? { + return aNullableDouble + } + override fun echoNullableBool(aNullableBool: Boolean?): Boolean? { + return aNullableBool + } + override fun echoNullableString(aNullableString: String?): String? { + return aNullableString + } + override fun echoNullableUint8List(aNullableUint8List: ByteArray?): ByteArray? { + return aNullableUint8List + } + override fun noopAsync(callback: () -> Unit) { callback() } diff --git a/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/AllDatatypesTest.kt b/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/AllDatatypesTest.kt index 5c072cbdfc..ceba13b671 100644 --- a/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/AllDatatypesTest.kt +++ b/packages/pigeon/platform_tests/test_plugin/android/src/test/kotlin/com/example/test_plugin/AllDatatypesTest.kt @@ -16,7 +16,7 @@ import java.util.ArrayList internal class AllDatatypesTest: TestCase() { @Test fun testNullValues() { - val everything = AllTypes() + val everything = AllNullableTypes() val binaryMessenger = mockk() val api = FlutterIntegrationCoreApi(binaryMessenger) @@ -32,19 +32,19 @@ internal class AllDatatypesTest: TestCase() { } var didCall = false - api.echoAllTypes(everything) { + api.echoAllNullableTypes(everything) { didCall = true - assertNull(it.aBool) - assertNull(it.anInt) - assertNull(it.aDouble) - assertNull(it.aString) - assertNull(it.aByteArray) - assertNull(it.a4ByteArray) - assertNull(it.a8ByteArray) - assertNull(it.aFloatArray) - assertNull(it.aList) - assertNull(it.aMap) - assertNull(it.mapWithObject) + assertNull(it.aNullableBool) + assertNull(it.aNullableInt) + assertNull(it.aNullableDouble) + assertNull(it.aNullableString) + assertNull(it.aNullableByteArray) + assertNull(it.aNullable4ByteArray) + assertNull(it.aNullable8ByteArray) + assertNull(it.aNullableFloatArray) + assertNull(it.aNullableList) + assertNull(it.aNullableMap) + assertNull(it.nullableMapWithObject) } assertTrue(didCall) @@ -52,18 +52,18 @@ internal class AllDatatypesTest: TestCase() { @Test fun testHasValues() { - val everything = AllTypes( - aBool = false, - anInt = 1234L, - aDouble = 2.0, - aString = "hello", - aByteArray = byteArrayOf(1, 2, 3, 4), - a4ByteArray = intArrayOf(1, 2, 3, 4), - a8ByteArray = longArrayOf(1, 2, 3, 4), - aFloatArray = doubleArrayOf(0.5, 0.25, 1.5, 1.25), - aList = listOf(1, 2, 3), - aMap = mapOf("hello" to 1234), - mapWithObject = mapOf("hello" to 1234) + val everything = AllNullableTypes( + aNullableBool = false, + aNullableInt = 1234L, + aNullableDouble = 2.0, + aNullableString = "hello", + aNullableByteArray = byteArrayOf(1, 2, 3, 4), + aNullable4ByteArray = intArrayOf(1, 2, 3, 4), + aNullable8ByteArray = longArrayOf(1, 2, 3, 4), + aNullableFloatArray = doubleArrayOf(0.5, 0.25, 1.5, 1.25), + aNullableList = listOf(1, 2, 3), + aNullableMap = mapOf("hello" to 1234), + nullableMapWithObject = mapOf("hello" to 1234) ) val binaryMessenger = mockk() val api = FlutterIntegrationCoreApi(binaryMessenger) @@ -80,19 +80,19 @@ internal class AllDatatypesTest: TestCase() { } var didCall = false - api.echoAllTypes(everything) { + api.echoAllNullableTypes(everything) { didCall = true - assertEquals(everything.aBool, it.aBool) - assertEquals(everything.anInt, it.anInt) - assertEquals(everything.aDouble, it.aDouble) - assertEquals(everything.aString, it.aString) - assertTrue(everything.aByteArray.contentEquals(it.aByteArray)) - assertTrue(everything.a4ByteArray.contentEquals(it.a4ByteArray)) - assertTrue(everything.a8ByteArray.contentEquals(it.a8ByteArray)) - assertTrue(everything.aFloatArray.contentEquals(it.aFloatArray)) - assertEquals(everything.aList, it.aList) - assertEquals(everything.aMap, it.aMap) - assertEquals(everything.mapWithObject, it.mapWithObject) + assertEquals(everything.aNullableBool, it.aNullableBool) + assertEquals(everything.aNullableInt, it.aNullableInt) + assertEquals(everything.aNullableDouble, it.aNullableDouble) + assertEquals(everything.aNullableString, it.aNullableString) + assertTrue(everything.aNullableByteArray.contentEquals(it.aNullableByteArray)) + assertTrue(everything.aNullable4ByteArray.contentEquals(it.aNullable4ByteArray)) + assertTrue(everything.aNullable8ByteArray.contentEquals(it.aNullable8ByteArray)) + assertTrue(everything.aNullableFloatArray.contentEquals(it.aNullableFloatArray)) + assertEquals(everything.aNullableList, it.aNullableList) + assertEquals(everything.aNullableMap, it.aNullableMap) + assertEquals(everything.nullableMapWithObject, it.nullableMapWithObject) } assertTrue(didCall) @@ -100,13 +100,13 @@ internal class AllDatatypesTest: TestCase() { @Test fun testIntegerToLong() { - val everything = AllTypes(anInt = 123L) + val everything = AllNullableTypes(aNullableInt = 123L) val map = everything.toMap() - assertTrue(map.containsKey("anInt")) + assertTrue(map.containsKey("aNullableInt")) - val map2 = hashMapOf("anInt" to 123) - val everything2 = AllTypes.fromMap(map2) + val map2 = hashMapOf("aNullableInt" to 123) + val everything2 = AllNullableTypes.fromMap(map2) - assertEquals(everything.anInt, everything2.anInt) + assertEquals(everything.aNullableInt, everything2.aNullableInt) } } diff --git a/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/AllDatatypesTests.swift b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/AllDatatypesTests.swift index df69d27e62..ac439ca871 100644 --- a/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/AllDatatypesTests.swift +++ b/packages/pigeon/platform_tests/test_plugin/example/ios/RunnerTests/AllDatatypesTests.swift @@ -9,26 +9,26 @@ import XCTest class AllDatatypesTests: XCTestCase { func testAllNull() throws { - let everything = AllTypes() + let everything = AllNullableTypes() let binaryMessenger = EchoBinaryMessenger(codec: FlutterIntegrationCoreApiCodec.shared) let api = FlutterIntegrationCoreApi(binaryMessenger: binaryMessenger) let expectation = XCTestExpectation(description: "callback") - api.echoAllTypes(everything: everything) { result in - XCTAssertNil(result.aBool) - XCTAssertNil(result.anInt) - XCTAssertNil(result.aDouble) - XCTAssertNil(result.aString) - XCTAssertNil(result.aByteArray) - XCTAssertNil(result.a4ByteArray) - XCTAssertNil(result.a8ByteArray) - XCTAssertNil(result.aFloatArray) - XCTAssertNil(result.aList) - XCTAssertNil(result.aMap) - XCTAssertNil(result.nestedList) - XCTAssertNil(result.mapWithAnnotations) - XCTAssertNil(result.mapWithObject) + api.echoAllNullableTypes(everything: everything) { result in + XCTAssertNil(result.aNullableBool) + XCTAssertNil(result.aNullableInt) + XCTAssertNil(result.aNullableDouble) + XCTAssertNil(result.aNullableString) + XCTAssertNil(result.aNullableByteArray) + XCTAssertNil(result.aNullable4ByteArray) + XCTAssertNil(result.aNullable8ByteArray) + XCTAssertNil(result.aNullableFloatArray) + XCTAssertNil(result.aNullableList) + XCTAssertNil(result.aNullableMap) + XCTAssertNil(result.nullableNestedList) + XCTAssertNil(result.nullableMapWithAnnotations) + XCTAssertNil(result.nullableMapWithObject) expectation.fulfill() } @@ -36,41 +36,41 @@ class AllDatatypesTests: XCTestCase { } func testAllEquals() throws { - let everything = AllTypes( - aBool: false, - anInt: 1, - aDouble: 2.0, - aString: "123", - aByteArray: FlutterStandardTypedData(bytes: "1234".data(using: .utf8)!), - a4ByteArray: FlutterStandardTypedData(int32: "1234".data(using: .utf8)!), - a8ByteArray: FlutterStandardTypedData(int64: "12345678".data(using: .utf8)!), - aFloatArray: FlutterStandardTypedData(float64: "12345678".data(using: .utf8)!), - - aList: [1, 2], - aMap: ["hello": 1234], - nestedList: [[true, false], [true]], - mapWithAnnotations: ["hello": "world"], - mapWithObject: ["hello": 1234, "goodbye" : "world"] + let everything = AllNullableTypes( + aNullableBool: false, + aNullableInt: 1, + aNullableDouble: 2.0, + aNullableString: "123", + aNullableByteArray: FlutterStandardTypedData(bytes: "1234".data(using: .utf8)!), + aNullable4ByteArray: FlutterStandardTypedData(int32: "1234".data(using: .utf8)!), + aNullable8ByteArray: FlutterStandardTypedData(int64: "12345678".data(using: .utf8)!), + aNullableFloatArray: FlutterStandardTypedData(float64: "12345678".data(using: .utf8)!), + aNullableList: [1, 2], + aNullableMap: ["hello": 1234], + nullableNestedList: [[true, false], [true]], + nullableMapWithAnnotations: ["hello": "world"], + nullableMapWithObject: ["hello": 1234, "goodbye" : "world"] ) + let binaryMessenger = EchoBinaryMessenger(codec: FlutterIntegrationCoreApiCodec.shared) let api = FlutterIntegrationCoreApi(binaryMessenger: binaryMessenger) let expectation = XCTestExpectation(description: "callback") - api.echoAllTypes(everything: everything) { result in - XCTAssertEqual(result.aBool, everything.aBool) - XCTAssertEqual(result.anInt, everything.anInt) - XCTAssertEqual(result.aDouble, everything.aDouble) - XCTAssertEqual(result.aString, everything.aString) - XCTAssertEqual(result.aByteArray, everything.aByteArray) - XCTAssertEqual(result.a4ByteArray, everything.a4ByteArray) - XCTAssertEqual(result.a8ByteArray, everything.a8ByteArray) - XCTAssertEqual(result.aFloatArray, everything.aFloatArray) - XCTAssert(equalsList(result.aList, everything.aList)) - XCTAssert(equalsDictionary(result.aMap, everything.aMap)) - XCTAssertEqual(result.nestedList, everything.nestedList) - XCTAssertEqual(result.mapWithAnnotations, everything.mapWithAnnotations) - XCTAssert(equalsDictionary(result.mapWithObject, everything.mapWithObject)) + api.echoAllNullableTypes(everything: everything) { result in + XCTAssertEqual(result.aNullableBool, everything.aNullableBool) + XCTAssertEqual(result.aNullableInt, everything.aNullableInt) + XCTAssertEqual(result.aNullableDouble, everything.aNullableDouble) + XCTAssertEqual(result.aNullableString, everything.aNullableString) + XCTAssertEqual(result.aNullableByteArray, everything.aNullableByteArray) + XCTAssertEqual(result.aNullable4ByteArray, everything.aNullable4ByteArray) + XCTAssertEqual(result.aNullable8ByteArray, everything.aNullable8ByteArray) + XCTAssertEqual(result.aNullableFloatArray, everything.aNullableFloatArray) + XCTAssert(equalsList(result.aNullableList, everything.aNullableList)) + XCTAssert(equalsDictionary(result.aNullableMap, everything.aNullableMap)) + XCTAssertEqual(result.nullableNestedList, everything.nullableNestedList) + XCTAssertEqual(result.nullableMapWithAnnotations, everything.nullableMapWithAnnotations) + XCTAssert(equalsDictionary(result.nullableMapWithObject, everything.nullableMapWithObject)) expectation.fulfill() } diff --git a/packages/pigeon/platform_tests/test_plugin/ios/Classes/TestPlugin.swift b/packages/pigeon/platform_tests/test_plugin/ios/Classes/TestPlugin.swift index fdb4f354b9..305627b789 100644 --- a/packages/pigeon/platform_tests/test_plugin/ios/Classes/TestPlugin.swift +++ b/packages/pigeon/platform_tests/test_plugin/ios/Classes/TestPlugin.swift @@ -30,24 +30,15 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { return everything } + func echoAllNullableTypes(everything: AllNullableTypes?) -> AllNullableTypes? { + return everything + } + func throwError() { // TODO(stuartmorgan): Implement this. See // https://github.com/flutter/flutter/issues/112483 } - func extractNestedString(wrapper: AllTypesWrapper) -> String? { - return wrapper.values.aString; - } - - func createNestedString(string: String) -> AllTypesWrapper { - return AllTypesWrapper(values: AllTypes(aString: string)) - } - - func sendMultipleTypes(aBool: Bool, anInt: Int32, aString: String) -> AllTypes { - let someThings = AllTypes(aBool: aBool, anInt: anInt, aString: aString) - return someThings - } - func echoInt(anInt: Int32) -> Int32 { return anInt } @@ -68,6 +59,39 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { return aUint8List } + func extractNestedNullableString(wrapper: AllNullableTypesWrapper) -> String? { + return wrapper.values.aNullableString; + } + + func createNestedNullableString(nullableString: String?) -> AllNullableTypesWrapper { + return AllNullableTypesWrapper(values: AllNullableTypes(aNullableString: nullableString)) + } + + func sendMultipleNullableTypes(aNullableBool: Bool?, aNullableInt: Int32?, aNullableString: String?) -> AllNullableTypes { + let someThings = AllNullableTypes(aNullableBool: aNullableBool, aNullableInt: aNullableInt, aNullableString: aNullableString) + return someThings + } + + func echoNullableInt(aNullableInt: Int32?) -> Int32? { + return aNullableInt + } + + func echoNullableDouble(aNullableDouble: Double?) -> Double? { + return aNullableDouble + } + + func echoNullableBool(aNullableBool: Bool?) -> Bool? { + return aNullableBool + } + + func echoNullableString(aNullableString: String?) -> String? { + return aNullableString + } + + func echoNullableUint8List(aNullableUint8List: FlutterStandardTypedData?) -> FlutterStandardTypedData? { + return aNullableUint8List + } + func noopAsync(completion: @escaping () -> Void) { completion() } diff --git a/packages/pigeon/platform_tests/test_plugin/macos/Classes/TestPlugin.swift b/packages/pigeon/platform_tests/test_plugin/macos/Classes/TestPlugin.swift index d40fcb8f74..85a0f62890 100644 --- a/packages/pigeon/platform_tests/test_plugin/macos/Classes/TestPlugin.swift +++ b/packages/pigeon/platform_tests/test_plugin/macos/Classes/TestPlugin.swift @@ -23,31 +23,22 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { // MARK: HostIntegrationCoreApi implementation - func noop() { + func noop() { } func echoAllTypes(everything: AllTypes) -> AllTypes { return everything } + func echoAllNullableTypes(everything: AllNullableTypes?) -> AllNullableTypes? { + return everything + } + func throwError() { // TODO(stuartmorgan): Implement this. See // https://github.com/flutter/flutter/issues/112483 } - func extractNestedString(wrapper: AllTypesWrapper) -> String? { - return wrapper.values.aString; - } - - func createNestedString(string: String) -> AllTypesWrapper { - return AllTypesWrapper(values: AllTypes(aString: string)) - } - - func sendMultipleTypes(aBool: Bool, anInt: Int32, aString: String) -> AllTypes { - let someThings = AllTypes(aBool: aBool, anInt: anInt, aString: aString) - return someThings - } - func echoInt(anInt: Int32) -> Int32 { return anInt } @@ -68,6 +59,39 @@ public class TestPlugin: NSObject, FlutterPlugin, HostIntegrationCoreApi { return aUint8List } + func extractNestedNullableString(wrapper: AllNullableTypesWrapper) -> String? { + return wrapper.values.aNullableString; + } + + func createNestedNullableString(nullableString: String?) -> AllNullableTypesWrapper { + return AllNullableTypesWrapper(values: AllNullableTypes(aNullableString: nullableString)) + } + + func sendMultipleNullableTypes(aNullableBool: Bool?, aNullableInt: Int32?, aNullableString: String?) -> AllNullableTypes { + let someThings = AllNullableTypes(aNullableBool: aNullableBool, aNullableInt: aNullableInt, aNullableString: aNullableString) + return someThings + } + + func echoNullableInt(aNullableInt: Int32?) -> Int32? { + return aNullableInt + } + + func echoNullableDouble(aNullableDouble: Double?) -> Double? { + return aNullableDouble + } + + func echoNullableBool(aNullableBool: Bool?) -> Bool? { + return aNullableBool + } + + func echoNullableString(aNullableString: String?) -> String? { + return aNullableString + } + + func echoNullableUint8List(aNullableUint8List: FlutterStandardTypedData?) -> FlutterStandardTypedData? { + return aNullableUint8List + } + func noopAsync(completion: @escaping () -> Void) { completion() } diff --git a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp index 6e1a25c559..b3a3bb110b 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp +++ b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.cpp @@ -16,8 +16,9 @@ namespace test_plugin { +using core_tests_pigeontest::AllNullableTypes; +using core_tests_pigeontest::AllNullableTypesWrapper; using core_tests_pigeontest::AllTypes; -using core_tests_pigeontest::AllTypesWrapper; using core_tests_pigeontest::ErrorOr; using core_tests_pigeontest::FlutterError; using core_tests_pigeontest::FlutterIntegrationCoreApi; @@ -45,35 +46,18 @@ ErrorOr TestPlugin::EchoAllTypes(const AllTypes& everything) { return everything; } +ErrorOr> TestPlugin::EchoAllNullableTypes( + const AllNullableTypes* everything) { + if (!everything) { + return std::nullopt; + } + return *everything; +} + std::optional TestPlugin::ThrowError() { return FlutterError("An error"); } -ErrorOr> TestPlugin::ExtractNestedString( - const AllTypesWrapper& wrapper) { - const std::string* inner_string = wrapper.values().a_string(); - return inner_string ? std::optional(*inner_string) - : std::nullopt; -} - -ErrorOr TestPlugin::CreateNestedString( - const std::string& string) { - AllTypes inner_object; - inner_object.set_a_string(string); - AllTypesWrapper wrapper; - wrapper.set_values(inner_object); - return wrapper; -} - -ErrorOr TestPlugin::SendMultipleTypes(bool a_bool, int64_t an_int, - const std::string& a_string) { - AllTypes someTypes; - someTypes.set_a_bool(a_bool); - someTypes.set_an_int(an_int); - someTypes.set_a_string(a_string); - return someTypes; -}; - ErrorOr TestPlugin::EchoInt(int64_t an_int) { return an_int; } ErrorOr TestPlugin::EchoDouble(double a_double) { return a_double; } @@ -88,6 +72,87 @@ ErrorOr> TestPlugin::EchoUint8List( const std::vector& a_uint8_list) { return a_uint8_list; } + +ErrorOr> TestPlugin::ExtractNestedNullableString( + const AllNullableTypesWrapper& wrapper) { + const std::string* inner_string = wrapper.values().a_nullable_string(); + return inner_string ? std::optional(*inner_string) + : std::nullopt; +} + +ErrorOr TestPlugin::CreateNestedNullableString( + const std::string* nullable_string) { + AllNullableTypes inner_object; + // The string pointer can't be passed through directly since the setter for + // a string takes a std::string_view rather than std::string so the pointer + // types don't match. + if (nullable_string) { + inner_object.set_a_nullable_string(*nullable_string); + } else { + inner_object.set_a_nullable_string(nullptr); + } + AllNullableTypesWrapper wrapper; + wrapper.set_values(inner_object); + return wrapper; +} + +ErrorOr TestPlugin::SendMultipleNullableTypes( + const bool* a_nullable_bool, const int64_t* a_nullable_int, + const std::string* a_nullable_string) { + AllNullableTypes someTypes; + someTypes.set_a_nullable_bool(a_nullable_bool); + someTypes.set_a_nullable_int(a_nullable_int); + // The string pointer can't be passed through directly since the setter for + // a string takes a std::string_view rather than std::string so the pointer + // types don't match. + if (a_nullable_string) { + someTypes.set_a_nullable_string(*a_nullable_string); + } else { + someTypes.set_a_nullable_string(nullptr); + } + return someTypes; +}; + +ErrorOr> TestPlugin::EchoNullableInt( + const int64_t* a_nullable_int) { + if (!a_nullable_int) { + return std::nullopt; + } + return *a_nullable_int; +}; + +ErrorOr> TestPlugin::EchoNullableDouble( + const double* a_nullable_double) { + if (!a_nullable_double) { + return std::nullopt; + } + return *a_nullable_double; +}; + +ErrorOr> TestPlugin::EchoNullableBool( + const bool* a_nullable_bool) { + if (!a_nullable_bool) { + return std::nullopt; + } + return *a_nullable_bool; +}; + +ErrorOr> TestPlugin::EchoNullableString( + const std::string* a_nullable_string) { + if (!a_nullable_string) { + return std::nullopt; + } + return *a_nullable_string; +}; + +ErrorOr>> TestPlugin::EchoNullableUint8List( + const std::vector* a_nullable_uint8_list) { + if (!a_nullable_uint8_list) { + return std::nullopt; + } + return *a_nullable_uint8_list; +}; + void TestPlugin::NoopAsync( std::function reply)> result) { result(std::nullopt); diff --git a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.h b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.h index 20b6d50a05..d5d1e1bd60 100644 --- a/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.h +++ b/packages/pigeon/platform_tests/test_plugin/windows/test_plugin.h @@ -35,15 +35,11 @@ class TestPlugin : public flutter::Plugin, std::optional Noop() override; core_tests_pigeontest::ErrorOr EchoAllTypes( const core_tests_pigeontest::AllTypes& everything) override; + core_tests_pigeontest::ErrorOr< + std::optional> + EchoAllNullableTypes( + const core_tests_pigeontest::AllNullableTypes* everything) override; std::optional ThrowError() override; - core_tests_pigeontest::ErrorOr> - ExtractNestedString( - const core_tests_pigeontest::AllTypesWrapper& wrapper) override; - core_tests_pigeontest::ErrorOr - CreateNestedString(const std::string& string) override; - core_tests_pigeontest::ErrorOr - SendMultipleTypes(bool a_bool, int64_t an_int, - const std::string& a_string) override; core_tests_pigeontest::ErrorOr EchoInt(int64_t an_int) override; core_tests_pigeontest::ErrorOr EchoDouble(double a_double) override; core_tests_pigeontest::ErrorOr EchoBool(bool a_bool) override; @@ -51,6 +47,27 @@ class TestPlugin : public flutter::Plugin, const std::string& a_string) override; core_tests_pigeontest::ErrorOr> EchoUint8List( const std::vector& a_uint8_list) override; + core_tests_pigeontest::ErrorOr> + ExtractNestedNullableString( + const core_tests_pigeontest::AllNullableTypesWrapper& wrapper) override; + core_tests_pigeontest::ErrorOr + CreateNestedNullableString(const std::string* nullable_string) override; + core_tests_pigeontest::ErrorOr + SendMultipleNullableTypes(const bool* a_nullable_bool, + const int64_t* a_nullable_int, + const std::string* a_nullable_string) override; + core_tests_pigeontest::ErrorOr> EchoNullableInt( + const int64_t* a_nullable_int) override; + core_tests_pigeontest::ErrorOr> EchoNullableDouble( + const double* a_nullable_double) override; + core_tests_pigeontest::ErrorOr> EchoNullableBool( + const bool* a_nullable_bool) override; + core_tests_pigeontest::ErrorOr> EchoNullableString( + const std::string* a_nullable_string) override; + core_tests_pigeontest::ErrorOr>> + EchoNullableUint8List( + const std::vector* a_nullable_uint8_list) override; + void NoopAsync(std::function< void(std::optional reply)> result) override;