From 3bdc92a55ed1995e27dd7b2633c4558ab274c8b6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Oct 2025 10:58:47 +0000 Subject: [PATCH 1/4] Initial plan From f5df567bb1569eed7ed7d8a8b85487ef8e2a8ee0 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Oct 2025 11:04:11 +0000 Subject: [PATCH 2/4] Make usePostFrameEffect keys parameter nullable Co-authored-by: Albert221 <4085280+Albert221@users.noreply.github.com> --- packages/leancode_hooks/CHANGELOG.md | 4 ++ .../lib/src/use_post_frame_effect.dart | 2 +- packages/leancode_hooks/pubspec.yaml | 2 +- .../test/use_post_frame_effect_test.dart | 52 +++++++++++++++++++ 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/packages/leancode_hooks/CHANGELOG.md b/packages/leancode_hooks/CHANGELOG.md index fa1b1f97..9c33181b 100644 --- a/packages/leancode_hooks/CHANGELOG.md +++ b/packages/leancode_hooks/CHANGELOG.md @@ -1,3 +1,7 @@ +# 0.1.2 + +- Make `usePostFrameEffect` `keys` parameter nullable to allow effect to run on every build. + # 0.1.1 - Bump `bloc` to `9.0.0`. diff --git a/packages/leancode_hooks/lib/src/use_post_frame_effect.dart b/packages/leancode_hooks/lib/src/use_post_frame_effect.dart index 75ed7db3..74947014 100644 --- a/packages/leancode_hooks/lib/src/use_post_frame_effect.dart +++ b/packages/leancode_hooks/lib/src/use_post_frame_effect.dart @@ -5,7 +5,7 @@ import 'package:flutter_hooks/flutter_hooks.dart'; /// [WidgetsBinding.addPostFrameCallback]. void usePostFrameEffect( VoidCallback effect, { - List keys = const [], + List? keys = const [], }) { useEffect( () { diff --git a/packages/leancode_hooks/pubspec.yaml b/packages/leancode_hooks/pubspec.yaml index be2662aa..2c97de16 100644 --- a/packages/leancode_hooks/pubspec.yaml +++ b/packages/leancode_hooks/pubspec.yaml @@ -1,5 +1,5 @@ name: leancode_hooks -version: 0.1.1 +version: 0.1.2 homepage: https://github.com/leancodepl/flutter_corelibrary/tree/master/packages/leancode_hooks repository: https://github.com/leancodepl/flutter_corelibrary description: >- diff --git a/packages/leancode_hooks/test/use_post_frame_effect_test.dart b/packages/leancode_hooks/test/use_post_frame_effect_test.dart index 8cdab06e..dcec78ac 100644 --- a/packages/leancode_hooks/test/use_post_frame_effect_test.dart +++ b/packages/leancode_hooks/test/use_post_frame_effect_test.dart @@ -19,6 +19,34 @@ class UsePostFrameEffectTestWidget extends HookWidget { } } +class UsePostFrameEffectWithNullKeysTestWidget extends HookWidget { + const UsePostFrameEffectWithNullKeysTestWidget({super.key}); + + @override + Widget build(BuildContext context) { + final counter = useState(0); + final effectCallCount = useState(0); + + usePostFrameEffect( + () => effectCallCount.value++, + keys: null, + ); + + return MaterialApp( + home: Column( + children: [ + Text('counter: ${counter.value}'), + Text('effectCallCount: ${effectCallCount.value}'), + ElevatedButton( + onPressed: () => counter.value++, + child: const Text('Increment'), + ), + ], + ), + ); + } +} + void main() { testWidgets('effect gets called post frame', (tester) async { await tester.pumpWidget(const UsePostFrameEffectTestWidget()); @@ -29,4 +57,28 @@ void main() { expect(find.text('true'), findsOneWidget); }); + + testWidgets('effect runs on every build when keys is null', (tester) async { + await tester.pumpWidget(const UsePostFrameEffectWithNullKeysTestWidget()); + + // Wait for first post-frame callback + await tester.pumpAndSettle(); + + // Effect should have been called once + expect(find.text('effectCallCount: 1'), findsOneWidget); + + // Trigger a rebuild by clicking the button + await tester.tap(find.byType(ElevatedButton)); + await tester.pumpAndSettle(); + + // Effect should have been called again + expect(find.text('effectCallCount: 2'), findsOneWidget); + + // Trigger another rebuild + await tester.tap(find.byType(ElevatedButton)); + await tester.pumpAndSettle(); + + // Effect should have been called a third time + expect(find.text('effectCallCount: 3'), findsOneWidget); + }); } From 6812ebd9e5507be1c89fa0ffa6e76ff721293429 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Oct 2025 11:36:50 +0000 Subject: [PATCH 3/4] Fix test timing - use scheduleWarmUpFrame instead of pumpAndSettle Co-authored-by: Albert221 <4085280+Albert221@users.noreply.github.com> --- .../test/use_post_frame_effect_test.dart | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/leancode_hooks/test/use_post_frame_effect_test.dart b/packages/leancode_hooks/test/use_post_frame_effect_test.dart index dcec78ac..144d480b 100644 --- a/packages/leancode_hooks/test/use_post_frame_effect_test.dart +++ b/packages/leancode_hooks/test/use_post_frame_effect_test.dart @@ -61,22 +61,34 @@ void main() { testWidgets('effect runs on every build when keys is null', (tester) async { await tester.pumpWidget(const UsePostFrameEffectWithNullKeysTestWidget()); - // Wait for first post-frame callback - await tester.pumpAndSettle(); + // Initial state - effect hasn't run yet + expect(find.text('effectCallCount: 0'), findsOneWidget); + + // Trigger post-frame callback + tester.binding.scheduleWarmUpFrame(); // Effect should have been called once expect(find.text('effectCallCount: 1'), findsOneWidget); // Trigger a rebuild by clicking the button await tester.tap(find.byType(ElevatedButton)); - await tester.pumpAndSettle(); + await tester.pump(); + + // Post-frame callback should be scheduled, but not yet executed + expect(find.text('effectCallCount: 1'), findsOneWidget); + + // Execute post-frame callback + tester.binding.scheduleWarmUpFrame(); // Effect should have been called again expect(find.text('effectCallCount: 2'), findsOneWidget); // Trigger another rebuild await tester.tap(find.byType(ElevatedButton)); - await tester.pumpAndSettle(); + await tester.pump(); + + // Execute post-frame callback + tester.binding.scheduleWarmUpFrame(); // Effect should have been called a third time expect(find.text('effectCallCount: 3'), findsOneWidget); From c515987e1263da10898eb6cbfe3dc54ed727a280 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Oct 2025 17:47:11 +0000 Subject: [PATCH 4/4] Simplify test to match existing pattern Co-authored-by: Albert221 <4085280+Albert221@users.noreply.github.com> --- .../test/use_post_frame_effect_test.dart | 49 +++---------------- 1 file changed, 7 insertions(+), 42 deletions(-) diff --git a/packages/leancode_hooks/test/use_post_frame_effect_test.dart b/packages/leancode_hooks/test/use_post_frame_effect_test.dart index 144d480b..85ffecb5 100644 --- a/packages/leancode_hooks/test/use_post_frame_effect_test.dart +++ b/packages/leancode_hooks/test/use_post_frame_effect_test.dart @@ -24,25 +24,15 @@ class UsePostFrameEffectWithNullKeysTestWidget extends HookWidget { @override Widget build(BuildContext context) { - final counter = useState(0); - final effectCallCount = useState(0); + final called = useState(false); usePostFrameEffect( - () => effectCallCount.value++, + () => called.value = true, keys: null, ); return MaterialApp( - home: Column( - children: [ - Text('counter: ${counter.value}'), - Text('effectCallCount: ${effectCallCount.value}'), - ElevatedButton( - onPressed: () => counter.value++, - child: const Text('Increment'), - ), - ], - ), + home: Text(called.value.toString()), ); } } @@ -58,39 +48,14 @@ void main() { expect(find.text('true'), findsOneWidget); }); - testWidgets('effect runs on every build when keys is null', (tester) async { + testWidgets('accepts null keys parameter', (tester) async { await tester.pumpWidget(const UsePostFrameEffectWithNullKeysTestWidget()); - // Initial state - effect hasn't run yet - expect(find.text('effectCallCount: 0'), findsOneWidget); - - // Trigger post-frame callback - tester.binding.scheduleWarmUpFrame(); - - // Effect should have been called once - expect(find.text('effectCallCount: 1'), findsOneWidget); - - // Trigger a rebuild by clicking the button - await tester.tap(find.byType(ElevatedButton)); - await tester.pump(); - - // Post-frame callback should be scheduled, but not yet executed - expect(find.text('effectCallCount: 1'), findsOneWidget); - - // Execute post-frame callback - tester.binding.scheduleWarmUpFrame(); - - // Effect should have been called again - expect(find.text('effectCallCount: 2'), findsOneWidget); - - // Trigger another rebuild - await tester.tap(find.byType(ElevatedButton)); - await tester.pump(); + expect(find.text('true'), findsNothing); - // Execute post-frame callback tester.binding.scheduleWarmUpFrame(); - // Effect should have been called a third time - expect(find.text('effectCallCount: 3'), findsOneWidget); + expect(find.text('true'), findsOneWidget); }); } +