blob: 4e68c3a60cea4e86ecc4955d0f398e758f106c68 [file] [log] [blame]
// 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() {}
}