| // Copyright 2013 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // TODO(a14n): remove this import once Flutter 3.1 or later reaches stable (including flutter/flutter#104231) |
| // ignore: unnecessary_import |
| import 'dart:typed_data'; |
| |
| import 'package:flutter/foundation.dart'; |
| import 'package:flutter/services.dart'; |
| import 'package:flutter_test/flutter_test.dart'; |
| import 'package:integration_test/integration_test.dart'; |
| |
| import 'generated.dart'; |
| |
| /// Possible host languages that test can target. |
| enum TargetGenerator { |
| /// The Windows C++ generator. |
| cpp, |
| |
| /// The Android Java generator. |
| java, |
| |
| /// The Android Kotlin generator. |
| kotlin, |
| |
| /// The iOS Objective-C generator. |
| objc, |
| |
| /// The iOS or macOS Swift generator. |
| swift, |
| } |
| |
| /// Sets up and runs the integration tests. |
| void runPigeonIntegrationTests(TargetGenerator targetGenerator) { |
| IntegrationTestWidgetsFlutterBinding.ensureInitialized(); |
| |
| group('Host sync API tests', () { |
| testWidgets('basic void->void call works', (WidgetTester _) async { |
| final HostIntegrationCoreApi api = HostIntegrationCoreApi(); |
| |
| expect(api.noop(), completes); |
| }); |
| |
| testWidgets('all datatypes serialize and deserialize correctly', |
| (WidgetTester _) async { |
| final HostIntegrationCoreApi api = HostIntegrationCoreApi(); |
| |
| final AllTypes sentObject = AllTypes( |
| aBool: true, |
| anInt: 42, |
| aDouble: 3.14159, |
| aString: 'Hello host!', |
| aByteArray: Uint8List.fromList(<int>[1, 2, 3]), |
| a4ByteArray: Int32List.fromList(<int>[4, 5, 6]), |
| a8ByteArray: Int64List.fromList(<int>[7, 8, 9]), |
| aFloatArray: Float64List.fromList(<double>[2.71828, 3.14159]), |
| aList: <Object?>['Thing 1', 2], |
| aMap: <Object?, Object?>{'a': 1, 'b': 2.0}, |
| nestedList: <List<bool>>[ |
| <bool>[true, false], |
| <bool>[false, true] |
| ], |
| anEnum: AnEnum.two, |
| ); |
| |
| 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); |
| // TODO(stuartmorgan): Enable these once they work for all generators; |
| // currently at least Swift is broken. |
| // See https://github.com/flutter/flutter/issues/115906 |
| //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); |
| // TODO(stuartmorgan): Enable this once the Dart types are fixed; see |
| // https://github.com/flutter/flutter/issues/116117 |
| //for (int i = 0; i < echoObject.nestedList!.length; i++) { |
| // expect(listEquals(echoObject.nestedList![i], sentObject.nestedList![i]), |
| // true); |
| //} |
| expect( |
| mapEquals( |
| echoObject.mapWithAnnotations, sentObject.mapWithAnnotations), |
| true); |
| expect( |
| mapEquals(echoObject.mapWithObject, sentObject.mapWithObject), true); |
| expect(echoObject.anEnum, sentObject.anEnum); |
| }); |
| |
| testWidgets('errors are returned correctly', (WidgetTester _) async { |
| final HostIntegrationCoreApi api = HostIntegrationCoreApi(); |
| |
| expect(() async { |
| await api.throwError(); |
| }, throwsA(isA<PlatformException>())); |
| }, |
| // Currently unimplementable for Swift: |
| // https://github.com/flutter/flutter/issues/112483 |
| skip: targetGenerator == TargetGenerator.swift); |
| |
| 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 String? receivedString = await api.extractNestedString(sentObject); |
| expect(receivedString, sentString); |
| }); |
| |
| testWidgets('nested objects can be received correctly', |
| (WidgetTester _) async { |
| final HostIntegrationCoreApi api = HostIntegrationCoreApi(); |
| |
| const String sentString = 'Some string'; |
| final AllTypesWrapper receivedObject = |
| await api.createNestedString(sentString); |
| expect(receivedObject.values.aString, 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; |
| |
| final AllTypes echoObject = |
| await api.sendMultipleTypes(aBool, anInt, aString); |
| expect(echoObject.anInt, anInt); |
| expect(echoObject.aBool, aBool); |
| expect(echoObject.aString, aString); |
| }); |
| |
| testWidgets('Ints serialize and deserialize correctly', |
| (WidgetTester _) async { |
| final HostIntegrationCoreApi api = HostIntegrationCoreApi(); |
| |
| const int sentInt = -13; |
| final int receivedInt = await api.echoInt(sentInt); |
| expect(receivedInt, sentInt); |
| }); |
| |
| testWidgets('Doubles serialize and deserialize correctly', |
| (WidgetTester _) async { |
| final HostIntegrationCoreApi api = HostIntegrationCoreApi(); |
| |
| const double sentDouble = 2.0694; |
| final double receivedDouble = await api.echoDouble(sentDouble); |
| expect(receivedDouble, sentDouble); |
| }); |
| |
| testWidgets('booleans serialize and deserialize correctly', |
| (WidgetTester _) async { |
| final HostIntegrationCoreApi api = HostIntegrationCoreApi(); |
| |
| for (final bool sentBool in <bool>[true, false]) { |
| final bool receivedBool = await api.echoBool(sentBool); |
| expect(receivedBool, sentBool); |
| } |
| }); |
| |
| testWidgets('strings serialize and deserialize correctly', |
| (WidgetTester _) async { |
| final HostIntegrationCoreApi api = HostIntegrationCoreApi(); |
| const String sentString = "I'm a computer"; |
| final String receivedString = await api.echoString(sentString); |
| expect(receivedString, sentString); |
| }); |
| |
| // TODO(stuartmorgan): Enable these once they work for all generators; |
| // currently at least Swift is broken. |
| // TODO(tarrinneal): Finish tests for int lists once issue solved. |
| // See https://github.com/flutter/flutter/issues/115906 |
| // testWidgets('Uint8List serialize and deserialize correctly', |
| // (WidgetTester _) async { |
| // final HostIntegrationCoreApi api = HostIntegrationCoreApi(); |
| // final List<int> data = [102, 111, 114, 116, 121, 45, 116, 119, 111, 0]; |
| // final Uint8List sentUint8List = Uint8List.fromList(data); |
| // final Uint8List receivedUint8List = |
| // await api.echoUint8List(sentUint8List); |
| // expect(receivedUint8List, sentUint8List); |
| // }); |
| }); |
| |
| group('Host async API tests', () { |
| testWidgets('basic void->void call works', (WidgetTester _) async { |
| final HostIntegrationCoreApi api = HostIntegrationCoreApi(); |
| |
| expect(api.noopAsync(), completes); |
| }); |
| |
| testWidgets('strings serialize and deserialize correctly', |
| (WidgetTester _) async { |
| final HostIntegrationCoreApi api = HostIntegrationCoreApi(); |
| |
| const String sentObject = 'Hello, asyncronously!'; |
| |
| final String echoObject = await api.echoAsyncString(sentObject); |
| expect(echoObject, sentObject); |
| }); |
| }); |
| |
| // These tests rely on the ansync Dart->host calls to work correctly, since |
| // the host->Dart call is wrapped in a driving Dart->host call, so any test |
| // added to this group should have coverage of the relevant arguments and |
| // return value in the "Host async API tests" group. |
| group('Flutter API tests', () { |
| setUp(() { |
| FlutterIntegrationCoreApi.setup(_FlutterApiTestImplementation()); |
| }); |
| |
| testWidgets('basic void->void call works', (WidgetTester _) async { |
| final HostIntegrationCoreApi api = HostIntegrationCoreApi(); |
| |
| expect(api.callFlutterNoop(), completes); |
| }); |
| |
| testWidgets('strings serialize and deserialize correctly', |
| (WidgetTester _) async { |
| final HostIntegrationCoreApi api = HostIntegrationCoreApi(); |
| |
| const String sentObject = 'Hello Dart!'; |
| |
| final String echoObject = await api.callFlutterEchoString(sentObject); |
| expect(echoObject, sentObject); |
| }); |
| }, |
| // TODO(stuartmorgan): Enable when FlutterApi generation is fixed for |
| // C++. See https://github.com/flutter/flutter/issues/108682. |
| skip: targetGenerator == TargetGenerator.cpp); |
| } |
| |
| class _FlutterApiTestImplementation implements FlutterIntegrationCoreApi { |
| @override |
| AllTypes echoAllTypes(AllTypes everything) { |
| return everything; |
| } |
| |
| @override |
| String echoString(String aString) { |
| return aString; |
| } |
| |
| @override |
| void noop() {} |
| } |