From 9db15969066ae1413dd0b8eb11a3445a8879652b Mon Sep 17 00:00:00 2001 From: Maurice Parrish <10687576+bparrishMines@users.noreply.github.com> Date: Thu, 5 Jun 2025 20:19:47 -0400 Subject: [PATCH 01/10] set test default instance manager --- packages/pigeon/CHANGELOG.md | 4 +- .../pigeon/lib/src/dart/dart_generator.dart | 3 ++ packages/pigeon/lib/src/dart/templates.dart | 3 ++ packages/pigeon/lib/src/generator_tools.dart | 2 +- .../src/generated/proxy_api_tests.gen.dart | 4 ++ .../test/instance_manager_test.dart | 38 +++++++++++++++++++ packages/pigeon/pubspec.yaml | 2 +- 7 files changed, 53 insertions(+), 3 deletions(-) diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index be954b5a5b1..7df51e8f87c 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,5 +1,7 @@ -## NEXT +## 25.4.0 +* [dart] Changes the default InstanceManager and its initialization to no longer make a method calls + when used in a Flutter unit test. * Updates minimum supported SDK version to Flutter 3.27/Dart 3.6. ## 25.3.2 diff --git a/packages/pigeon/lib/src/dart/dart_generator.dart b/packages/pigeon/lib/src/dart/dart_generator.dart index 4ce527e292a..2dcb9b2efad 100644 --- a/packages/pigeon/lib/src/dart/dart_generator.dart +++ b/packages/pigeon/lib/src/dart/dart_generator.dart @@ -146,6 +146,9 @@ class DartGenerator extends StructuredGenerator { required String dartPackageName, }) { indent.writeln("import 'dart:async';"); + if (root.containsProxyApi) { + indent.writeln("import 'dart:io' show Platform;"); + } indent.writeln( "import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;", ); diff --git a/packages/pigeon/lib/src/dart/templates.dart b/packages/pigeon/lib/src/dart/templates.dart index 78b8e20ef26..a945c5776ba 100644 --- a/packages/pigeon/lib/src/dart/templates.dart +++ b/packages/pigeon/lib/src/dart/templates.dart @@ -87,6 +87,9 @@ class $dartInstanceManagerClassName { late final void Function(int) onWeakReferenceRemoved; static $dartInstanceManagerClassName _initInstance() { + if (Platform.environment.containsKey('FLUTTER_TEST')) { + return $dartInstanceManagerClassName(onWeakReferenceRemoved: (_) {}); + } WidgetsFlutterBinding.ensureInitialized(); final $dartInstanceManagerApiClassName api = $dartInstanceManagerApiClassName(); // Clears the native `$dartInstanceManagerClassName` on the initial use of the Dart one. diff --git a/packages/pigeon/lib/src/generator_tools.dart b/packages/pigeon/lib/src/generator_tools.dart index f706ecc1703..19b38e36d2e 100644 --- a/packages/pigeon/lib/src/generator_tools.dart +++ b/packages/pigeon/lib/src/generator_tools.dart @@ -15,7 +15,7 @@ import 'generator.dart'; /// The current version of pigeon. /// /// This must match the version in pubspec.yaml. -const String pigeonVersion = '25.3.2'; +const String pigeonVersion = '25.4.0'; /// Read all the content from [stdin] to a String. String readStdin() { diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart index 559b4d12ee2..26b567e233f 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart @@ -7,6 +7,7 @@ // 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, no_leading_underscores_for_local_identifiers import 'dart:async'; +import 'dart:io' show Platform; import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; import 'package:flutter/foundation.dart' @@ -126,6 +127,9 @@ class PigeonInstanceManager { late final void Function(int) onWeakReferenceRemoved; static PigeonInstanceManager _initInstance() { + if (Platform.environment.containsKey('FLUTTER_TEST')) { + return PigeonInstanceManager(onWeakReferenceRemoved: (_) {}); + } WidgetsFlutterBinding.ensureInitialized(); final _PigeonInternalInstanceManagerApi api = _PigeonInternalInstanceManagerApi(); diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart index 66f9d955202..a49cf2f6364 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart @@ -192,6 +192,44 @@ void main() { expect(weakReferencedRemovedCalled, isFalse); }); + + testWidgets( + 'instantiating default InstanceManager in a Flutter test does not set handlers or make a message call', + (WidgetTester tester) async { + // Initialize default InstanceManager + // ignore: unnecessary_statements + PigeonInstanceManager.instance; + + final TestDefaultBinaryMessenger testBinaryMessenger = + TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger; + expect(testBinaryMessenger.allMessagesHandler, isNull); + + await expectLater( + testBinaryMessenger.platformMessagesFinished, + completes, + ); + }, + ); + + testWidgets( + 'default InstanceManager does not make message call when weak reference is removed', + (WidgetTester tester) async { + // Initialize default InstanceManager + // ignore: unnecessary_statements + final PigeonInstanceManager instanceManager = + PigeonInstanceManager.instance; + + final int identifier = + instanceManager.addDartCreatedInstance(CopyableObject()); + instanceManager.onWeakReferenceRemoved(identifier); + + await expectLater( + TestDefaultBinaryMessengerBinding + .instance.defaultBinaryMessenger.platformMessagesFinished, + completes, + ); + }, + ); }); } diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index 65e6b0c48c7..bcc34f39bec 100644 --- a/packages/pigeon/pubspec.yaml +++ b/packages/pigeon/pubspec.yaml @@ -2,7 +2,7 @@ name: pigeon description: Code generator tool to make communication between Flutter and the host platform type-safe and easier. repository: https://github.com/flutter/packages/tree/main/packages/pigeon issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+pigeon%22 -version: 25.3.2 # This must match the version in lib/src/generator_tools.dart +version: 25.4.0 # This must match the version in lib/src/generator_tools.dart environment: sdk: ^3.6.0 From 37d94beac3b6dbf7c9d34a932bf24ff0ae1d5939 Mon Sep 17 00:00:00 2001 From: Maurice Parrish <10687576+bparrishMines@users.noreply.github.com> Date: Thu, 5 Jun 2025 20:27:07 -0400 Subject: [PATCH 02/10] fix changelog --- packages/pigeon/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 7df51e8f87c..d117c92cd19 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,6 +1,6 @@ ## 25.4.0 -* [dart] Changes the default InstanceManager and its initialization to no longer make a method calls +* [dart] Changes the default InstanceManager and its initialization to no longer make a method call when used in a Flutter unit test. * Updates minimum supported SDK version to Flutter 3.27/Dart 3.6. From 7d3840c69f047b1ea7e7921757ccb1ba07133cc0 Mon Sep 17 00:00:00 2001 From: Maurice Parrish <10687576+bparrishMines@users.noreply.github.com> Date: Thu, 5 Jun 2025 20:38:06 -0400 Subject: [PATCH 03/10] better formatting --- .../shared_test_plugin_code/test/instance_manager_test.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart index a49cf2f6364..ef9fb7c0f61 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart @@ -202,8 +202,8 @@ void main() { final TestDefaultBinaryMessenger testBinaryMessenger = TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger; - expect(testBinaryMessenger.allMessagesHandler, isNull); + expect(testBinaryMessenger.allMessagesHandler, isNull); await expectLater( testBinaryMessenger.platformMessagesFinished, completes, @@ -214,8 +214,6 @@ void main() { testWidgets( 'default InstanceManager does not make message call when weak reference is removed', (WidgetTester tester) async { - // Initialize default InstanceManager - // ignore: unnecessary_statements final PigeonInstanceManager instanceManager = PigeonInstanceManager.instance; From a496abff9bd2c58274a3a9db5d391dfc7fb257d1 Mon Sep 17 00:00:00 2001 From: Maurice Parrish <10687576+bparrishMines@users.noreply.github.com> Date: Thu, 5 Jun 2025 20:43:33 -0400 Subject: [PATCH 04/10] improve test --- .../test/instance_manager_test.dart | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart index ef9fb7c0f61..3708d2a6b85 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart @@ -4,6 +4,7 @@ // This file specifically tests the test PigeonInstanceManager generated by core_tests. +import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:leak_tracker/leak_tracker.dart'; import 'package:shared_test_plugin_code/src/generated/proxy_api_tests.gen.dart'; @@ -194,26 +195,41 @@ void main() { }); testWidgets( - 'instantiating default InstanceManager in a Flutter test does not set handlers or make a message call', + 'instantiating default InstanceManager does not make a message call', (WidgetTester tester) async { + bool messageCallMade = false; + TestDefaultBinaryMessengerBinding + .instance.defaultBinaryMessenger.allMessagesHandler = ( + String channel, + MessageHandler? handler, + ByteData? message, + ) { + messageCallMade = true; + return null; + }; + // Initialize default InstanceManager // ignore: unnecessary_statements PigeonInstanceManager.instance; - final TestDefaultBinaryMessenger testBinaryMessenger = - TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger; - - expect(testBinaryMessenger.allMessagesHandler, isNull); - await expectLater( - testBinaryMessenger.platformMessagesFinished, - completes, - ); + expect(messageCallMade, isFalse); }, ); testWidgets( 'default InstanceManager does not make message call when weak reference is removed', (WidgetTester tester) async { + bool messageCallMade = false; + TestDefaultBinaryMessengerBinding + .instance.defaultBinaryMessenger.allMessagesHandler = ( + String channel, + MessageHandler? handler, + ByteData? message, + ) { + messageCallMade = true; + return null; + }; + final PigeonInstanceManager instanceManager = PigeonInstanceManager.instance; @@ -221,11 +237,7 @@ void main() { instanceManager.addDartCreatedInstance(CopyableObject()); instanceManager.onWeakReferenceRemoved(identifier); - await expectLater( - TestDefaultBinaryMessengerBinding - .instance.defaultBinaryMessenger.platformMessagesFinished, - completes, - ); + expect(messageCallMade, isFalse); }, ); }); From 7765204978eeab8058074b152201e23d3df96298 Mon Sep 17 00:00:00 2001 From: Maurice Parrish <10687576+bparrishMines@users.noreply.github.com> Date: Thu, 5 Jun 2025 20:45:22 -0400 Subject: [PATCH 05/10] unused params --- .../test/instance_manager_test.dart | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart index 3708d2a6b85..a539e8af992 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart @@ -199,11 +199,7 @@ void main() { (WidgetTester tester) async { bool messageCallMade = false; TestDefaultBinaryMessengerBinding - .instance.defaultBinaryMessenger.allMessagesHandler = ( - String channel, - MessageHandler? handler, - ByteData? message, - ) { + .instance.defaultBinaryMessenger.allMessagesHandler = (_, __, ___) { messageCallMade = true; return null; }; @@ -221,11 +217,7 @@ void main() { (WidgetTester tester) async { bool messageCallMade = false; TestDefaultBinaryMessengerBinding - .instance.defaultBinaryMessenger.allMessagesHandler = ( - String channel, - MessageHandler? handler, - ByteData? message, - ) { + .instance.defaultBinaryMessenger.allMessagesHandler = (_, __, ___) { messageCallMade = true; return null; }; From 6e60cc2ed5e159450df16cc5af755fc6c2396c69 Mon Sep 17 00:00:00 2001 From: Maurice Parrish <10687576+bparrishMines@users.noreply.github.com> Date: Thu, 5 Jun 2025 20:47:23 -0400 Subject: [PATCH 06/10] message instead of method --- packages/pigeon/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index d117c92cd19..7f37e9ce5fb 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,6 +1,6 @@ ## 25.4.0 -* [dart] Changes the default InstanceManager and its initialization to no longer make a method call +* [dart] Changes the default InstanceManager and its initialization to no longer make a message call when used in a Flutter unit test. * Updates minimum supported SDK version to Flutter 3.27/Dart 3.6. From f4d7d6fcc91a9f30c8d24f7b37d1db6b7ba64cca Mon Sep 17 00:00:00 2001 From: Maurice Parrish <10687576+bparrishMines@users.noreply.github.com> Date: Thu, 5 Jun 2025 20:53:29 -0400 Subject: [PATCH 07/10] unused import --- .../shared_test_plugin_code/test/instance_manager_test.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart index a539e8af992..43e1df3b9a2 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart @@ -4,7 +4,6 @@ // This file specifically tests the test PigeonInstanceManager generated by core_tests. -import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:leak_tracker/leak_tracker.dart'; import 'package:shared_test_plugin_code/src/generated/proxy_api_tests.gen.dart'; From de63935fb14fb471d79910bb1eb2a654da15e455 Mon Sep 17 00:00:00 2001 From: Maurice Parrish <10687576+bparrishMines@users.noreply.github.com> Date: Sat, 7 Jun 2025 13:34:06 -0400 Subject: [PATCH 08/10] use 2 full cycles --- .../shared_test_plugin_code/test/instance_manager_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart index 43e1df3b9a2..815277cf019 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart @@ -167,7 +167,7 @@ void main() { instanceManager.addDartCreatedInstance(object); object = null; - await forceGC(); + await forceGC(fullGcCycles: 2); expect(weakReferencedRemovedCalled, isTrue); }); From a10c8bc453fdd30577339aad3be937ad50e25e8e Mon Sep 17 00:00:00 2001 From: Maurice Parrish <10687576+bparrishMines@users.noreply.github.com> Date: Sat, 7 Jun 2025 13:50:05 -0400 Subject: [PATCH 09/10] add full cycle to the other test --- .../shared_test_plugin_code/test/instance_manager_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart index 815277cf019..2582ed27a02 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/test/instance_manager_test.dart @@ -188,7 +188,7 @@ void main() { instanceManager.addHostCreatedInstance(object, 0); object = null; - await forceGC(); + await forceGC(fullGcCycles: 2); expect(weakReferencedRemovedCalled, isFalse); }); From 20014bcb4913cbc54628c36625b96e68eb44ab55 Mon Sep 17 00:00:00 2001 From: Maurice Parrish <10687576+bparrishMines@users.noreply.github.com> Date: Sat, 7 Jun 2025 22:57:51 -0400 Subject: [PATCH 10/10] check for true instead --- packages/pigeon/lib/src/dart/templates.dart | 2 +- .../lib/src/generated/proxy_api_tests.gen.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/pigeon/lib/src/dart/templates.dart b/packages/pigeon/lib/src/dart/templates.dart index a945c5776ba..73fbf92035b 100644 --- a/packages/pigeon/lib/src/dart/templates.dart +++ b/packages/pigeon/lib/src/dart/templates.dart @@ -87,7 +87,7 @@ class $dartInstanceManagerClassName { late final void Function(int) onWeakReferenceRemoved; static $dartInstanceManagerClassName _initInstance() { - if (Platform.environment.containsKey('FLUTTER_TEST')) { + if (Platform.environment['FLUTTER_TEST'] == 'true') { return $dartInstanceManagerClassName(onWeakReferenceRemoved: (_) {}); } WidgetsFlutterBinding.ensureInitialized(); diff --git a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart index 26b567e233f..4f6b8593aed 100644 --- a/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart +++ b/packages/pigeon/platform_tests/shared_test_plugin_code/lib/src/generated/proxy_api_tests.gen.dart @@ -127,7 +127,7 @@ class PigeonInstanceManager { late final void Function(int) onWeakReferenceRemoved; static PigeonInstanceManager _initInstance() { - if (Platform.environment.containsKey('FLUTTER_TEST')) { + if (Platform.environment['FLUTTER_TEST'] == 'true') { return PigeonInstanceManager(onWeakReferenceRemoved: (_) {}); } WidgetsFlutterBinding.ensureInitialized();