From c3db02099368f538e5361d812a07709cddaa813d Mon Sep 17 00:00:00 2001 From: Kostia Sokolovskyi Date: Wed, 20 Sep 2023 16:34:23 +0200 Subject: [PATCH] Cover more test/widgets tests with leak tracking #9 (#135054) --- .../widgets/selection_container_test.dart | 28 ++++-- .../test/widgets/semantics_10_test.dart | 3 +- .../test/widgets/semantics_11_test.dart | 3 +- .../test/widgets/semantics_1_test.dart | 3 +- .../test/widgets/semantics_2_test.dart | 3 +- .../test/widgets/semantics_3_test.dart | 3 +- .../test/widgets/semantics_4_test.dart | 3 +- .../test/widgets/semantics_5_test.dart | 3 +- .../test/widgets/semantics_6_test.dart | 3 +- .../test/widgets/semantics_7_test.dart | 3 +- .../test/widgets/semantics_8_test.dart | 3 +- .../test/widgets/semantics_9_test.dart | 7 +- ...semantics_child_configs_delegate_test.dart | 11 ++- .../test/widgets/semantics_clipping_test.dart | 5 +- .../test/widgets/semantics_debugger_test.dart | 27 ++--- .../semantics_keep_alive_offstage_test.dart | 4 +- .../test/widgets/semantics_merge_test.dart | 5 +- .../flutter/test/widgets/semantics_test.dart | 61 ++++++------ ...ssion_for_current_semantics_tree_test.dart | 5 +- .../test/widgets/semantics_tester_test.dart | 3 +- .../widgets/semantics_traversal_test.dart | 3 +- .../semantics_zero_surface_size_test.dart | 3 +- .../test/widgets/set_state_1_test.dart | 3 +- .../test/widgets/set_state_2_test.dart | 3 +- .../test/widgets/set_state_3_test.dart | 3 +- .../test/widgets/set_state_4_test.dart | 3 +- .../test/widgets/set_state_5_test.dart | 3 +- .../test/widgets/shader_mask_test.dart | 7 +- .../flutter/test/widgets/shadow_test.dart | 9 +- .../test/widgets/shape_decoration_test.dart | 11 ++- .../test/widgets/shared_app_data_test.dart | 7 +- .../flutter/test/widgets/shortcuts_test.dart | 92 +++++++++-------- .../test/widgets/simple_semantics_test.dart | 5 +- .../single_child_scroll_view_test.dart | 99 +++++++++++++------ ...size_changed_layout_notification_test.dart | 3 +- .../flutter/test/widgets/sized_box_test.dart | 9 +- .../widgets/sliver_appbar_opacity_test.dart | 31 ++++-- .../sliver_constrained_cross_axis_test.dart | 11 ++- .../test/widgets/sliver_constraints_test.dart | 3 +- .../widgets/sliver_cross_axis_group_test.dart | 57 ++++++----- .../widgets/sliver_fill_remaining_test.dart | 45 +++++---- 41 files changed, 366 insertions(+), 230 deletions(-) diff --git a/packages/flutter/test/widgets/selection_container_test.dart b/packages/flutter/test/widgets/selection_container_test.dart index 3c7648c9209c7..c6ceebf778106 100644 --- a/packages/flutter/test/widgets/selection_container_test.dart +++ b/packages/flutter/test/widgets/selection_container_test.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { @@ -20,9 +21,11 @@ void main() { ); } - testWidgets('updates its registrar and delegate based on the number of selectables', (WidgetTester tester) async { + testWidgetsWithLeakTracking('updates its registrar and delegate based on the number of selectables', (WidgetTester tester) async { final TestSelectionRegistrar registrar = TestSelectionRegistrar(); final TestContainerDelegate delegate = TestContainerDelegate(); + addTearDown(delegate.dispose); + await pumpContainer( tester, SelectionContainer( @@ -42,9 +45,11 @@ void main() { expect(delegate.selectables.length, 3); }); - testWidgets('disabled container', (WidgetTester tester) async { + testWidgetsWithLeakTracking('disabled container', (WidgetTester tester) async { final TestSelectionRegistrar registrar = TestSelectionRegistrar(); final TestContainerDelegate delegate = TestContainerDelegate(); + addTearDown(delegate.dispose); + await pumpContainer( tester, SelectionContainer( @@ -65,10 +70,13 @@ void main() { expect(delegate.selectables.length, 0); }); - testWidgets('Swapping out container delegate does not crash', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Swapping out container delegate does not crash', (WidgetTester tester) async { final TestSelectionRegistrar registrar = TestSelectionRegistrar(); final TestContainerDelegate delegate = TestContainerDelegate(); + addTearDown(delegate.dispose); final TestContainerDelegate childDelegate = TestContainerDelegate(); + addTearDown(childDelegate.dispose); + await pumpContainer( tester, SelectionContainer( @@ -90,6 +98,8 @@ void main() { expect(delegate.value.hasContent, isTrue); final TestContainerDelegate newDelegate = TestContainerDelegate(); + addTearDown(newDelegate.dispose); + await pumpContainer( tester, SelectionContainer( @@ -112,10 +122,13 @@ void main() { expect(tester.takeException(), isNull); }); - testWidgets('Can update within one frame', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can update within one frame', (WidgetTester tester) async { final TestSelectionRegistrar registrar = TestSelectionRegistrar(); final TestContainerDelegate delegate = TestContainerDelegate(); + addTearDown(delegate.dispose); final TestContainerDelegate childDelegate = TestContainerDelegate(); + addTearDown(childDelegate.dispose); + await pumpContainer( tester, SelectionContainer( @@ -139,9 +152,11 @@ void main() { expect(delegate.value.hasContent, isTrue); }); - testWidgets('selection container registers itself if there is a selectable child', (WidgetTester tester) async { + testWidgetsWithLeakTracking('selection container registers itself if there is a selectable child', (WidgetTester tester) async { final TestSelectionRegistrar registrar = TestSelectionRegistrar(); final TestContainerDelegate delegate = TestContainerDelegate(); + addTearDown(delegate.dispose); + await pumpContainer( tester, SelectionContainer( @@ -181,9 +196,10 @@ void main() { expect(registrar.selectables.length, 0); }); - testWidgets('selection container gets registrar from context if not provided', (WidgetTester tester) async { + testWidgetsWithLeakTracking('selection container gets registrar from context if not provided', (WidgetTester tester) async { final TestSelectionRegistrar registrar = TestSelectionRegistrar(); final TestContainerDelegate delegate = TestContainerDelegate(); + addTearDown(delegate.dispose); await pumpContainer( tester, diff --git a/packages/flutter/test/widgets/semantics_10_test.dart b/packages/flutter/test/widgets/semantics_10_test.dart index 0ef416efd64bf..d550253e9bbb9 100644 --- a/packages/flutter/test/widgets/semantics_10_test.dart +++ b/packages/flutter/test/widgets/semantics_10_test.dart @@ -6,11 +6,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { - testWidgets('can cease to be semantics boundary after markNeedsSemanticsUpdate() has already been called once', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can cease to be semantics boundary after markNeedsSemanticsUpdate() has already been called once', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget( diff --git a/packages/flutter/test/widgets/semantics_11_test.dart b/packages/flutter/test/widgets/semantics_11_test.dart index 7979f319d6075..05b1d572eda8f 100644 --- a/packages/flutter/test/widgets/semantics_11_test.dart +++ b/packages/flutter/test/widgets/semantics_11_test.dart @@ -6,11 +6,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { - testWidgets('markNeedsSemanticsUpdate() called on non-boundary with non-boundary parent', (WidgetTester tester) async { + testWidgetsWithLeakTracking('markNeedsSemanticsUpdate() called on non-boundary with non-boundary parent', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget( diff --git a/packages/flutter/test/widgets/semantics_1_test.dart b/packages/flutter/test/widgets/semantics_1_test.dart index 7d475627942f2..3631f73d2b2e3 100644 --- a/packages/flutter/test/widgets/semantics_1_test.dart +++ b/packages/flutter/test/widgets/semantics_1_test.dart @@ -5,11 +5,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { - testWidgets('Semantics 1', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics 1', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); // smoketest diff --git a/packages/flutter/test/widgets/semantics_2_test.dart b/packages/flutter/test/widgets/semantics_2_test.dart index 2a0c69bf357fe..e56248d3d827a 100644 --- a/packages/flutter/test/widgets/semantics_2_test.dart +++ b/packages/flutter/test/widgets/semantics_2_test.dart @@ -5,11 +5,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { - testWidgets('Semantics 2', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics 2', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); // this test is the same as the test in Semantics 1, but diff --git a/packages/flutter/test/widgets/semantics_3_test.dart b/packages/flutter/test/widgets/semantics_3_test.dart index 32c1ac218b13d..11757f5d5fda5 100644 --- a/packages/flutter/test/widgets/semantics_3_test.dart +++ b/packages/flutter/test/widgets/semantics_3_test.dart @@ -5,11 +5,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { - testWidgets('Semantics 3', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics 3', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); // implicit annotators diff --git a/packages/flutter/test/widgets/semantics_4_test.dart b/packages/flutter/test/widgets/semantics_4_test.dart index 084e1d30a20f6..34ee195838e6b 100644 --- a/packages/flutter/test/widgets/semantics_4_test.dart +++ b/packages/flutter/test/widgets/semantics_4_test.dart @@ -5,11 +5,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { - testWidgets('Semantics 4', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics 4', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); // O diff --git a/packages/flutter/test/widgets/semantics_5_test.dart b/packages/flutter/test/widgets/semantics_5_test.dart index 16859cb921c84..160c54303d334 100644 --- a/packages/flutter/test/widgets/semantics_5_test.dart +++ b/packages/flutter/test/widgets/semantics_5_test.dart @@ -5,11 +5,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { - testWidgets('Semantics 5', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics 5', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget( diff --git a/packages/flutter/test/widgets/semantics_6_test.dart b/packages/flutter/test/widgets/semantics_6_test.dart index 30c126126b726..88bd11fc1fb3c 100644 --- a/packages/flutter/test/widgets/semantics_6_test.dart +++ b/packages/flutter/test/widgets/semantics_6_test.dart @@ -5,11 +5,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { - testWidgets('can change semantics in a branch blocked by BlockSemantics', (WidgetTester tester) async { + testWidgetsWithLeakTracking('can change semantics in a branch blocked by BlockSemantics', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); final TestSemantics expectedSemantics = TestSemantics.root( diff --git a/packages/flutter/test/widgets/semantics_7_test.dart b/packages/flutter/test/widgets/semantics_7_test.dart index 2ad88a3c446bf..3f9af1cad843d 100644 --- a/packages/flutter/test/widgets/semantics_7_test.dart +++ b/packages/flutter/test/widgets/semantics_7_test.dart @@ -5,11 +5,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { - testWidgets('Semantics 7 - Merging', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics 7 - Merging', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); String label; diff --git a/packages/flutter/test/widgets/semantics_8_test.dart b/packages/flutter/test/widgets/semantics_8_test.dart index 4fe5cd885f1b2..ffea309d169df 100644 --- a/packages/flutter/test/widgets/semantics_8_test.dart +++ b/packages/flutter/test/widgets/semantics_8_test.dart @@ -5,11 +5,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { - testWidgets('Semantics 8 - Merging with reset', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics 8 - Merging with reset', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget( diff --git a/packages/flutter/test/widgets/semantics_9_test.dart b/packages/flutter/test/widgets/semantics_9_test.dart index 9152a13fce0e2..9d2ac510ef4ef 100644 --- a/packages/flutter/test/widgets/semantics_9_test.dart +++ b/packages/flutter/test/widgets/semantics_9_test.dart @@ -6,12 +6,13 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { group('BlockSemantics', () { - testWidgets('hides semantic nodes of siblings', (WidgetTester tester) async { + testWidgetsWithLeakTracking('hides semantic nodes of siblings', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget(Stack( @@ -49,7 +50,7 @@ void main() { semantics.dispose(); }); - testWidgets('does not hides semantic nodes of siblings outside the current semantic boundary', (WidgetTester tester) async { + testWidgetsWithLeakTracking('does not hides semantic nodes of siblings outside the current semantic boundary', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget(Directionality(textDirection: TextDirection.ltr, child: Stack( @@ -103,7 +104,7 @@ void main() { semantics.dispose(); }); - testWidgets('node is semantic boundary and blocking previously painted nodes', (WidgetTester tester) async { + testWidgetsWithLeakTracking('node is semantic boundary and blocking previously painted nodes', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); final GlobalKey stackKey = GlobalKey(); diff --git a/packages/flutter/test/widgets/semantics_child_configs_delegate_test.dart b/packages/flutter/test/widgets/semantics_child_configs_delegate_test.dart index a562a53891d6f..b2e67726b1cae 100644 --- a/packages/flutter/test/widgets/semantics_child_configs_delegate_test.dart +++ b/packages/flutter/test/widgets/semantics_child_configs_delegate_test.dart @@ -5,11 +5,12 @@ import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { - testWidgets('Semantics can merge sibling group', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics can merge sibling group', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); const SemanticsTag first = SemanticsTag('1'); const SemanticsTag second = SemanticsTag('2'); @@ -74,7 +75,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics can drop semantics config', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics can drop semantics config', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); const SemanticsTag first = SemanticsTag('1'); const SemanticsTag second = SemanticsTag('2'); @@ -132,7 +133,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics throws when mark the same config twice case 1', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics throws when mark the same config twice case 1', (WidgetTester tester) async { const SemanticsTag first = SemanticsTag('1'); const SemanticsTag second = SemanticsTag('2'); const SemanticsTag third = SemanticsTag('3'); @@ -178,7 +179,7 @@ void main() { expect(tester.takeException(), isAssertionError); }); - testWidgets('Semantics throws when mark the same config twice case 2', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics throws when mark the same config twice case 2', (WidgetTester tester) async { const SemanticsTag first = SemanticsTag('1'); const SemanticsTag second = SemanticsTag('2'); const SemanticsTag third = SemanticsTag('3'); @@ -224,7 +225,7 @@ void main() { expect(tester.takeException(), isAssertionError); }); - testWidgets('RenderObject with semantics child delegate will mark correct boundary dirty', (WidgetTester tester) async { + testWidgetsWithLeakTracking('RenderObject with semantics child delegate will mark correct boundary dirty', (WidgetTester tester) async { final UniqueKey inner = UniqueKey(); final UniqueKey boundaryParent = UniqueKey(); final UniqueKey grandBoundaryParent = UniqueKey(); diff --git a/packages/flutter/test/widgets/semantics_clipping_test.dart b/packages/flutter/test/widgets/semantics_clipping_test.dart index 73554422dceaf..8b63e86a08d25 100644 --- a/packages/flutter/test/widgets/semantics_clipping_test.dart +++ b/packages/flutter/test/widgets/semantics_clipping_test.dart @@ -5,11 +5,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { - testWidgets('SemanticNode.rect is clipped', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SemanticNode.rect is clipped', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget(const Directionality( @@ -67,7 +68,7 @@ void main() { semantics.dispose(); }); - testWidgets('SemanticsNode is not removed if out of bounds and merged into something within bounds', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SemanticsNode is not removed if out of bounds and merged into something within bounds', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget(const Directionality( diff --git a/packages/flutter/test/widgets/semantics_debugger_test.dart b/packages/flutter/test/widgets/semantics_debugger_test.dart index d5985b933d964..4c48e69664591 100644 --- a/packages/flutter/test/widgets/semantics_debugger_test.dart +++ b/packages/flutter/test/widgets/semantics_debugger_test.dart @@ -5,9 +5,10 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { - testWidgets('SemanticsDebugger will schedule a frame', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SemanticsDebugger will schedule a frame', (WidgetTester tester) async { await tester.pumpWidget( SemanticsDebugger( child: Container(), @@ -17,7 +18,7 @@ void main() { expect(tester.binding.hasScheduledFrame, isTrue); }); - testWidgets('SemanticsDebugger smoke test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SemanticsDebugger smoke test', (WidgetTester tester) async { // This is a smoketest to verify that adding a debugger doesn't crash. await tester.pumpWidget( @@ -61,7 +62,7 @@ void main() { expect(true, isTrue); // expect that we reach here without crashing }); - testWidgets('SemanticsDebugger reparents subtree', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SemanticsDebugger reparents subtree', (WidgetTester tester) async { final GlobalKey key = GlobalKey(); await tester.pumpWidget( @@ -147,7 +148,7 @@ void main() { expect(tester.takeException(), isNull); }); - testWidgets('SemanticsDebugger interaction test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SemanticsDebugger interaction test', (WidgetTester tester) async { final List log = []; await tester.pumpWidget( @@ -185,7 +186,7 @@ void main() { log.clear(); }); - testWidgets('SemanticsDebugger interaction test - negative', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SemanticsDebugger interaction test - negative', (WidgetTester tester) async { final List log = []; await tester.pumpWidget( @@ -225,7 +226,7 @@ void main() { log.clear(); }); - testWidgets('SemanticsDebugger scroll test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SemanticsDebugger scroll test', (WidgetTester tester) async { final Key childKey = UniqueKey(); await tester.pumpWidget( @@ -268,7 +269,7 @@ void main() { expect(tester.getTopLeft(find.byKey(childKey)).dy, equals(0.0)); }); - testWidgets('SemanticsDebugger long press', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SemanticsDebugger long press', (WidgetTester tester) async { bool didLongPress = false; await tester.pumpWidget( @@ -290,7 +291,7 @@ void main() { expect(didLongPress, isTrue); }); - testWidgets('SemanticsDebugger slider', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SemanticsDebugger slider', (WidgetTester tester) async { double value = 0.75; await tester.pumpWidget( @@ -337,7 +338,7 @@ void main() { } }, variant: TargetPlatformVariant.all()); - testWidgets('SemanticsDebugger checkbox', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SemanticsDebugger checkbox', (WidgetTester tester) async { final Key keyTop = UniqueKey(); final Key keyBottom = UniqueKey(); @@ -378,7 +379,7 @@ void main() { expect(valueTop, isFalse); }); - testWidgets('SemanticsDebugger checkbox message', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SemanticsDebugger checkbox message', (WidgetTester tester) async { final Key checkbox = UniqueKey(); final Key checkboxUnchecked = UniqueKey(); final Key checkboxDisabled = UniqueKey(); @@ -450,7 +451,7 @@ void main() { ); }); - testWidgets('SemanticsDebugger ignores duplicated label and tooltip for Android', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SemanticsDebugger ignores duplicated label and tooltip for Android', (WidgetTester tester) async { final Key child = UniqueKey(); final Key debugger = UniqueKey(); final bool isPlatformAndroid = defaultTargetPlatform == TargetPlatform.android; @@ -477,7 +478,7 @@ void main() { ); }, variant: TargetPlatformVariant.all()); - testWidgets('SemanticsDebugger textfield', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SemanticsDebugger textfield', (WidgetTester tester) async { final UniqueKey textField = UniqueKey(); final UniqueKey debugger = UniqueKey(); @@ -504,7 +505,7 @@ void main() { ); }); - testWidgets('SemanticsDebugger label style is used in the painter.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SemanticsDebugger label style is used in the painter.', (WidgetTester tester) async { final UniqueKey debugger = UniqueKey(); const TextStyle labelStyle = TextStyle(color: Colors.amber); await tester.pumpWidget( diff --git a/packages/flutter/test/widgets/semantics_keep_alive_offstage_test.dart b/packages/flutter/test/widgets/semantics_keep_alive_offstage_test.dart index 8cffc4eb5f1d7..915b7fc6c6485 100644 --- a/packages/flutter/test/widgets/semantics_keep_alive_offstage_test.dart +++ b/packages/flutter/test/widgets/semantics_keep_alive_offstage_test.dart @@ -5,11 +5,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { - testWidgets('Un-layouted RenderObject in keep alive offstage area do not crash semantics compiler', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Un-layouted RenderObject in keep alive offstage area do not crash semantics compiler', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/20313. final SemanticsTester semantics = SemanticsTester(tester); @@ -18,6 +19,7 @@ void main() { const double bottomScrollOffset = 3000.0; final ScrollController controller = ScrollController(initialScrollOffset: bottomScrollOffset); + addTearDown(controller.dispose); await tester.pumpWidget(_buildTestWidget( extraPadding: false, diff --git a/packages/flutter/test/widgets/semantics_merge_test.dart b/packages/flutter/test/widgets/semantics_merge_test.dart index a4a997d37b91e..82d3c8157aa4b 100644 --- a/packages/flutter/test/widgets/semantics_merge_test.dart +++ b/packages/flutter/test/widgets/semantics_merge_test.dart @@ -6,6 +6,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; @@ -14,7 +15,7 @@ void main() { debugResetSemanticsIdCounter(); }); - testWidgets('MergeSemantics', (WidgetTester tester) async { + testWidgetsWithLeakTracking('MergeSemantics', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); // not merged @@ -120,7 +121,7 @@ void main() { semantics.dispose(); }); - testWidgets('MergeSemantics works if other nodes are implicitly merged into its node', (WidgetTester tester) async { + testWidgetsWithLeakTracking('MergeSemantics works if other nodes are implicitly merged into its node', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget( diff --git a/packages/flutter/test/widgets/semantics_test.dart b/packages/flutter/test/widgets/semantics_test.dart index 8a95217212fcd..8ec5e33799432 100644 --- a/packages/flutter/test/widgets/semantics_test.dart +++ b/packages/flutter/test/widgets/semantics_test.dart @@ -7,6 +7,7 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; @@ -15,7 +16,7 @@ void main() { debugResetSemanticsIdCounter(); }); - testWidgets('Semantics shutdown and restart', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics shutdown and restart', (WidgetTester tester) async { SemanticsTester? semantics = SemanticsTester(tester); final TestSemantics expectedSemantics = TestSemantics.root( @@ -59,7 +60,7 @@ void main() { semantics.dispose(); }, semanticsEnabled: false); - testWidgets('Semantics tag only applies to immediate child', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics tag only applies to immediate child', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget( @@ -95,7 +96,7 @@ void main() { semantics.dispose(); }, semanticsEnabled: false); - testWidgets('Semantics tooltip', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics tooltip', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); final TestSemantics expectedSemantics = TestSemantics.root( @@ -123,7 +124,7 @@ void main() { semantics.dispose(); }); - testWidgets('Detach and reattach assert', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Detach and reattach assert', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); final GlobalKey key = GlobalKey(); @@ -201,7 +202,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics and Directionality - RTL', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics and Directionality - RTL', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget( @@ -218,7 +219,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics and Directionality - LTR', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics and Directionality - LTR', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget( @@ -235,7 +236,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics and Directionality - cannot override RTL with LTR', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics and Directionality - cannot override RTL with LTR', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); final TestSemantics expectedSemantics = TestSemantics.root( @@ -262,7 +263,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics and Directionality - cannot override LTR with RTL', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics and Directionality - cannot override LTR with RTL', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); final TestSemantics expectedSemantics = TestSemantics.root( @@ -289,7 +290,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics label and hint', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics label and hint', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget( @@ -319,7 +320,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics hints can merge', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics hints can merge', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget( @@ -355,7 +356,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics values do not merge', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics values do not merge', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget( @@ -406,7 +407,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics value and hint can merge', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics value and hint can merge', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget( @@ -442,7 +443,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics tagForChildren works', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics tagForChildren works', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget( @@ -490,7 +491,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics widget supports all actions', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics widget supports all actions', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); final List performedActions = []; @@ -580,7 +581,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics widget supports all flags', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics widget supports all flags', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); // Checked state and toggled state are mutually exclusive. await tester.pumpWidget( @@ -710,7 +711,7 @@ void main() { expect(semantics, hasSemantics(expectedSemantics, ignoreId: true)); }); - testWidgets('Actions can be replaced without triggering semantics update', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Actions can be replaced without triggering semantics update', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); int semanticsUpdateCount = 0; final SemanticsHandle handle = tester.binding.pipelineOwner.ensureSemantics( @@ -807,7 +808,7 @@ void main() { semantics.dispose(); }); - testWidgets('onTapHint and onLongPressHint create custom actions', (WidgetTester tester) async { + testWidgetsWithLeakTracking('onTapHint and onLongPressHint create custom actions', (WidgetTester tester) async { final SemanticsHandle semantics = tester.ensureSemantics(); await tester.pumpWidget(Semantics( container: true, @@ -833,7 +834,7 @@ void main() { semantics.dispose(); }); - testWidgets('CustomSemanticsActions can be added to a Semantics widget', (WidgetTester tester) async { + testWidgetsWithLeakTracking('CustomSemanticsActions can be added to a Semantics widget', (WidgetTester tester) async { final SemanticsHandle semantics = tester.ensureSemantics(); await tester.pumpWidget(Semantics( container: true, @@ -852,7 +853,7 @@ void main() { semantics.dispose(); }); - testWidgets('Increased/decreased values are annotated', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Increased/decreased values are annotated', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget( @@ -884,7 +885,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics widgets built in a widget tree are sorted properly', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics widgets built in a widget tree are sorted properly', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); int semanticsUpdateCount = 0; final SemanticsHandle handle = tester.binding.pipelineOwner.ensureSemantics( @@ -967,7 +968,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics widgets built with explicit sort orders are sorted properly', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics widgets built with explicit sort orders are sorted properly', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); int semanticsUpdateCount = 0; final SemanticsHandle handle = tester.binding.pipelineOwner.ensureSemantics( @@ -1025,7 +1026,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics widgets without sort orders are sorted properly', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics widgets without sort orders are sorted properly', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); int semanticsUpdateCount = 0; final SemanticsHandle handle = tester.binding.pipelineOwner.ensureSemantics( @@ -1086,7 +1087,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics widgets that are transformed are sorted properly', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics widgets that are transformed are sorted properly', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); int semanticsUpdateCount = 0; final SemanticsHandle handle = tester.binding.pipelineOwner.ensureSemantics( @@ -1150,7 +1151,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics widgets without sort orders are sorted properly when no Directionality is present', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics widgets without sort orders are sorted properly when no Directionality is present', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); int semanticsUpdateCount = 0; final SemanticsHandle handle = tester.binding.pipelineOwner.ensureSemantics(listener: () { @@ -1251,7 +1252,7 @@ void main() { semantics.dispose(); }); - testWidgets('Semantics excludeSemantics ignores children', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics excludeSemantics ignores children', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget(Semantics( label: 'label', @@ -1279,7 +1280,7 @@ void main() { semantics.dispose(); }); - testWidgets('Can change handlers', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can change handlers', (WidgetTester tester) async { await tester.pumpWidget(Semantics( container: true, label: 'foo', @@ -1666,7 +1667,7 @@ void main() { )); }); - testWidgets('Semantics with zero transform gets dropped', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics with zero transform gets dropped', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/110671. // Construct a widget tree that will end up with a fitted box that applies // a zero transform because it does not actually draw its children. @@ -1693,7 +1694,7 @@ void main() { expect(node.childrenCount, 0); }); - testWidgets('blocking user interaction works on explicit child node.', (WidgetTester tester) async { + testWidgetsWithLeakTracking('blocking user interaction works on explicit child node.', (WidgetTester tester) async { final UniqueKey key1 = UniqueKey(); final UniqueKey key2 = UniqueKey(); await tester.pumpWidget( @@ -1736,7 +1737,7 @@ void main() { ); }); - testWidgets('blocking user interaction on a merged child', (WidgetTester tester) async { + testWidgetsWithLeakTracking('blocking user interaction on a merged child', (WidgetTester tester) async { final UniqueKey key = UniqueKey(); await tester.pumpWidget( MaterialApp( @@ -1771,7 +1772,7 @@ void main() { ); }); - testWidgets('does not merge conflicting actions even if one of them is blocked', (WidgetTester tester) async { + testWidgetsWithLeakTracking('does not merge conflicting actions even if one of them is blocked', (WidgetTester tester) async { final UniqueKey key = UniqueKey(); await tester.pumpWidget( MaterialApp( diff --git a/packages/flutter/test/widgets/semantics_tester_generate_test_semantics_expression_for_current_semantics_tree_test.dart b/packages/flutter/test/widgets/semantics_tester_generate_test_semantics_expression_for_current_semantics_tree_test.dart index 1f7aec466cf97..479f20e6319c1 100644 --- a/packages/flutter/test/widgets/semantics_tester_generate_test_semantics_expression_for_current_semantics_tree_test.dart +++ b/packages/flutter/test/widgets/semantics_tester_generate_test_semantics_expression_for_current_semantics_tree_test.dart @@ -10,6 +10,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/semantics.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; @@ -52,7 +53,7 @@ void _tests() { // also update this code to reflect the new output. // // This test is flexible w.r.t. leading and trailing whitespace. - testWidgets('generates code', (WidgetTester tester) async { + testWidgetsWithLeakTracking('generates code', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await pumpTestWidget(tester); final String code = semantics @@ -91,7 +92,7 @@ void _tests() { expect('$code,', expectedCode); }); - testWidgets('generated code is correct', (WidgetTester tester) async { + testWidgetsWithLeakTracking('generated code is correct', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await pumpTestWidget(tester); expect( diff --git a/packages/flutter/test/widgets/semantics_tester_test.dart b/packages/flutter/test/widgets/semantics_tester_test.dart index c5a9de1763cb9..e8b8a1ea59493 100644 --- a/packages/flutter/test/widgets/semantics_tester_test.dart +++ b/packages/flutter/test/widgets/semantics_tester_test.dart @@ -5,11 +5,12 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { - testWidgets('Semantics tester visits last child', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Semantics tester visits last child', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); const TextStyle textStyle = TextStyle(); await tester.pumpWidget( diff --git a/packages/flutter/test/widgets/semantics_traversal_test.dart b/packages/flutter/test/widgets/semantics_traversal_test.dart index a509ab2d2cf4e..23247ad651380 100644 --- a/packages/flutter/test/widgets/semantics_traversal_test.dart +++ b/packages/flutter/test/widgets/semantics_traversal_test.dart @@ -9,6 +9,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; @@ -21,7 +22,7 @@ void main() { }); void testTraversal(String description, TraversalTestFunction testFunction) { - testWidgets(description, (WidgetTester tester) async { + testWidgetsWithLeakTracking(description, (WidgetTester tester) async { final TraversalTester traversalTester = TraversalTester(tester); await testFunction(traversalTester); traversalTester.dispose(); diff --git a/packages/flutter/test/widgets/semantics_zero_surface_size_test.dart b/packages/flutter/test/widgets/semantics_zero_surface_size_test.dart index 07c58cdafa4ef..273c437cca453 100644 --- a/packages/flutter/test/widgets/semantics_zero_surface_size_test.dart +++ b/packages/flutter/test/widgets/semantics_zero_surface_size_test.dart @@ -5,11 +5,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { - testWidgets('has only root node if surface size is 0x0', (WidgetTester tester) async { + testWidgetsWithLeakTracking('has only root node if surface size is 0x0', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget(Semantics( diff --git a/packages/flutter/test/widgets/set_state_1_test.dart b/packages/flutter/test/widgets/set_state_1_test.dart index ca29a40b26fc6..dc85b46e470c3 100644 --- a/packages/flutter/test/widgets/set_state_1_test.dart +++ b/packages/flutter/test/widgets/set_state_1_test.dart @@ -4,6 +4,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; class Inside extends StatefulWidget { const Inside({ super.key }); @@ -65,7 +66,7 @@ class OutsideState extends State { } void main() { - testWidgets('setState() smoke test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('setState() smoke test', (WidgetTester tester) async { await tester.pumpWidget(const Outside()); final Offset location = tester.getCenter(find.text('INSIDE')); final TestGesture gesture = await tester.startGesture(location); diff --git a/packages/flutter/test/widgets/set_state_2_test.dart b/packages/flutter/test/widgets/set_state_2_test.dart index 4df03006cff66..1894cea871bae 100644 --- a/packages/flutter/test/widgets/set_state_2_test.dart +++ b/packages/flutter/test/widgets/set_state_2_test.dart @@ -4,9 +4,10 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { - testWidgets('setState() overbuild test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('setState() overbuild test', (WidgetTester tester) async { final List log = []; final Builder inner = Builder( builder: (BuildContext context) { diff --git a/packages/flutter/test/widgets/set_state_3_test.dart b/packages/flutter/test/widgets/set_state_3_test.dart index 461746e98a122..534d9cb976646 100644 --- a/packages/flutter/test/widgets/set_state_3_test.dart +++ b/packages/flutter/test/widgets/set_state_3_test.dart @@ -4,6 +4,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; late ChangerState changer; @@ -52,7 +53,7 @@ class LeafState extends State { } void main() { - testWidgets('three-way setState() smoke test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('three-way setState() smoke test', (WidgetTester tester) async { await tester.pumpWidget(const Changer(Wrapper(Leaf()))); await tester.pumpWidget(const Changer(Wrapper(Leaf()))); changer.test(); diff --git a/packages/flutter/test/widgets/set_state_4_test.dart b/packages/flutter/test/widgets/set_state_4_test.dart index e0fc2e7ee0693..2349f8151a3eb 100644 --- a/packages/flutter/test/widgets/set_state_4_test.dart +++ b/packages/flutter/test/widgets/set_state_4_test.dart @@ -4,6 +4,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; class Changer extends StatefulWidget { const Changer({ super.key }); @@ -21,7 +22,7 @@ class ChangerState extends State { } void main() { - testWidgets('setState() catches being used with an async callback', (WidgetTester tester) async { + testWidgetsWithLeakTracking('setState() catches being used with an async callback', (WidgetTester tester) async { await tester.pumpWidget(const Changer()); final ChangerState s = tester.state(find.byType(Changer)); expect(s.test0, isNot(throwsFlutterError)); diff --git a/packages/flutter/test/widgets/set_state_5_test.dart b/packages/flutter/test/widgets/set_state_5_test.dart index fd7bdaccd73f1..335d427d643c0 100644 --- a/packages/flutter/test/widgets/set_state_5_test.dart +++ b/packages/flutter/test/widgets/set_state_5_test.dart @@ -4,6 +4,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; class BadWidget extends StatefulWidget { const BadWidget({ super.key }); @@ -27,7 +28,7 @@ class BadWidgetState extends State { } void main() { - testWidgets('setState() catches being used inside a constructor', (WidgetTester tester) async { + testWidgetsWithLeakTracking('setState() catches being used inside a constructor', (WidgetTester tester) async { await tester.pumpWidget(const BadWidget()); expect(tester.takeException(), isFlutterError); }); diff --git a/packages/flutter/test/widgets/shader_mask_test.dart b/packages/flutter/test/widgets/shader_mask_test.dart index 018950f20bc8b..7b941c06d4903 100644 --- a/packages/flutter/test/widgets/shader_mask_test.dart +++ b/packages/flutter/test/widgets/shader_mask_test.dart @@ -9,6 +9,7 @@ library; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; Shader createShader(Rect bounds) { return const LinearGradient( @@ -21,12 +22,12 @@ Shader createShader(Rect bounds) { void main() { - testWidgets('Can be constructed', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Can be constructed', (WidgetTester tester) async { const Widget child = SizedBox(width: 100.0, height: 100.0); await tester.pumpWidget(const ShaderMask(shaderCallback: createShader, child: child)); }); - testWidgets('Bounds rect includes offset', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Bounds rect includes offset', (WidgetTester tester) async { late Rect shaderBounds; Shader recordShaderBounds(Rect bounds) { shaderBounds = bounds; @@ -50,7 +51,7 @@ void main() { }); - testWidgets('Bounds rect includes offset visual inspection', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Bounds rect includes offset visual inspection', (WidgetTester tester) async { final Widget widgetBottomRight = Container( width: 400, height: 400, diff --git a/packages/flutter/test/widgets/shadow_test.dart b/packages/flutter/test/widgets/shadow_test.dart index eb97b9af2d9ae..f2d5f93b429e5 100644 --- a/packages/flutter/test/widgets/shadow_test.dart +++ b/packages/flutter/test/widgets/shadow_test.dart @@ -9,13 +9,14 @@ library; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { tearDown(() { debugDisableShadows = true; }); - testWidgets('Shadows on BoxDecoration', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Shadows on BoxDecoration', (WidgetTester tester) async { await tester.pumpWidget( Center( child: RepaintBoundary( @@ -61,7 +62,7 @@ void main() { ); } for (final int elevation in kElevationToShadow.keys) { - testWidgets('elevation $elevation', (WidgetTester tester) async { + testWidgetsWithLeakTracking('elevation $elevation', (WidgetTester tester) async { debugDisableShadows = false; await tester.pumpWidget(build(elevation)); await expectLater( @@ -73,7 +74,7 @@ void main() { } }); - testWidgets('Shadows with PhysicalLayer', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Shadows with PhysicalLayer', (WidgetTester tester) async { await tester.pumpWidget( Center( child: RepaintBoundary( @@ -132,7 +133,7 @@ void main() { } for (final int elevation in kElevationToShadow.keys) { - testWidgets('elevation $elevation', (WidgetTester tester) async { + testWidgetsWithLeakTracking('elevation $elevation', (WidgetTester tester) async { debugDisableShadows = false; await tester.pumpWidget(build(elevation.toDouble())); await expectLater( diff --git a/packages/flutter/test/widgets/shape_decoration_test.dart b/packages/flutter/test/widgets/shape_decoration_test.dart index 1926745869c43..0db118ad09d3c 100644 --- a/packages/flutter/test/widgets/shape_decoration_test.dart +++ b/packages/flutter/test/widgets/shape_decoration_test.dart @@ -7,6 +7,7 @@ import 'dart:ui' as ui show Image; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import '../image_data.dart'; import '../painting/mocks_for_image_cache.dart'; @@ -16,7 +17,7 @@ Future main() async { AutomatedTestWidgetsFlutterBinding(); final ui.Image rawImage = await decodeImageFromList(Uint8List.fromList(kTransparentImage)); final ImageProvider image = TestImageProvider(0, 0, image: rawImage); - testWidgets('ShapeDecoration.image', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ShapeDecoration.image', (WidgetTester tester) async { await tester.pumpWidget( MaterialApp( home: DecoratedBox( @@ -39,7 +40,7 @@ Future main() async { ); }); - testWidgets('ShapeDecoration.color', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ShapeDecoration.color', (WidgetTester tester) async { await tester.pumpWidget( MaterialApp( home: DecoratedBox( @@ -68,7 +69,7 @@ Future main() async { expect(decoration.padding, isA()); }); - testWidgets('TestBorder and Directionality - 1', (WidgetTester tester) async { + testWidgetsWithLeakTracking('TestBorder and Directionality - 1', (WidgetTester tester) async { final List log = []; await tester.pumpWidget( MaterialApp( @@ -89,7 +90,7 @@ Future main() async { ); }); - testWidgets('TestBorder and Directionality - 2', (WidgetTester tester) async { + testWidgetsWithLeakTracking('TestBorder and Directionality - 2', (WidgetTester tester) async { final List log = []; await tester.pumpWidget( Directionality( @@ -113,7 +114,7 @@ Future main() async { ); }); - testWidgets('Does not crash with directional gradient', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Does not crash with directional gradient', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/76967. await tester.pumpWidget( diff --git a/packages/flutter/test/widgets/shared_app_data_test.dart b/packages/flutter/test/widgets/shared_app_data_test.dart index 6d57734d4b1b3..db9ec5d3a02f7 100644 --- a/packages/flutter/test/widgets/shared_app_data_test.dart +++ b/packages/flutter/test/widgets/shared_app_data_test.dart @@ -4,9 +4,10 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { - testWidgets('SharedAppData basics', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SharedAppData basics', (WidgetTester tester) async { int columnBuildCount = 0; int child1BuildCount = 0; int child2BuildCount = 0; @@ -116,7 +117,7 @@ void main() { expect(find.text('null').evaluate().length, 2); }); - testWidgets('WidgetsApp SharedAppData ', (WidgetTester tester) async { + testWidgetsWithLeakTracking('WidgetsApp SharedAppData ', (WidgetTester tester) async { int parentBuildCount = 0; int childBuildCount = 0; @@ -154,7 +155,7 @@ void main() { expect(find.text('child'), findsOneWidget); }); - testWidgets('WidgetsApp SharedAppData Shadowing', (WidgetTester tester) async { + testWidgetsWithLeakTracking('WidgetsApp SharedAppData Shadowing', (WidgetTester tester) async { int innerTapCount = 0; int outerTapCount = 0; diff --git a/packages/flutter/test/widgets/shortcuts_test.dart b/packages/flutter/test/widgets/shortcuts_test.dart index a73bb38e803fe..ed2d5ad99e919 100644 --- a/packages/flutter/test/widgets/shortcuts_test.dart +++ b/packages/flutter/test/widgets/shortcuts_test.dart @@ -112,7 +112,7 @@ void main() { ); }); - testWidgets('handles two keys', (WidgetTester tester) async { + testWidgetsWithLeakTracking('handles two keys', (WidgetTester tester) async { int invoked = 0; await tester.pumpWidget(activatorTester( LogicalKeySet( @@ -211,7 +211,7 @@ void main() { ); }); - testWidgets('isActivatedBy works as expected', (WidgetTester tester) async { + testWidgetsWithLeakTracking('isActivatedBy works as expected', (WidgetTester tester) async { // Collect some key events to use for testing. final List events = []; await tester.pumpWidget( @@ -253,7 +253,7 @@ void main() { }); group(SingleActivator, () { - testWidgets('handles Ctrl-C', (WidgetTester tester) async { + testWidgetsWithLeakTracking('handles Ctrl-C', (WidgetTester tester) async { int invoked = 0; await tester.pumpWidget(activatorTester( const SingleActivator( @@ -352,7 +352,7 @@ void main() { expect(RawKeyboard.instance.keysPressed, isEmpty); }, variant: KeySimulatorTransitModeVariant.all()); - testWidgets('handles repeated events', (WidgetTester tester) async { + testWidgetsWithLeakTracking('handles repeated events', (WidgetTester tester) async { int invoked = 0; await tester.pumpWidget(activatorTester( const SingleActivator( @@ -378,7 +378,7 @@ void main() { expect(RawKeyboard.instance.keysPressed, isEmpty); }, variant: KeySimulatorTransitModeVariant.all()); - testWidgets('rejects repeated events if requested', (WidgetTester tester) async { + testWidgetsWithLeakTracking('rejects repeated events if requested', (WidgetTester tester) async { int invoked = 0; await tester.pumpWidget(activatorTester( const SingleActivator( @@ -405,7 +405,7 @@ void main() { expect(RawKeyboard.instance.keysPressed, isEmpty); }, variant: KeySimulatorTransitModeVariant.all()); - testWidgets('handles Shift-Ctrl-C', (WidgetTester tester) async { + testWidgetsWithLeakTracking('handles Shift-Ctrl-C', (WidgetTester tester) async { int invoked = 0; await tester.pumpWidget(activatorTester( const SingleActivator( @@ -455,7 +455,7 @@ void main() { expect(RawKeyboard.instance.keysPressed, isEmpty); }); - testWidgets('isActivatedBy works as expected', (WidgetTester tester) async { + testWidgetsWithLeakTracking('isActivatedBy works as expected', (WidgetTester tester) async { // Collect some key events to use for testing. final List events = []; await tester.pumpWidget( @@ -534,15 +534,16 @@ void main() { }); group(Shortcuts, () { - testWidgets('Default constructed Shortcuts has empty shortcuts', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Default constructed Shortcuts has empty shortcuts', (WidgetTester tester) async { const Shortcuts shortcuts = Shortcuts(shortcuts: {}, child: SizedBox()); await tester.pumpWidget(shortcuts); expect(shortcuts.shortcuts, isNotNull); expect(shortcuts.shortcuts, isEmpty); }); - testWidgets('Default constructed Shortcuts.manager has empty shortcuts', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Default constructed Shortcuts.manager has empty shortcuts', (WidgetTester tester) async { final ShortcutManager manager = ShortcutManager(); + addTearDown(manager.dispose); expect(manager.shortcuts, isNotNull); expect(manager.shortcuts, isEmpty); final Shortcuts shortcuts = Shortcuts.manager(manager: manager, child: const SizedBox()); @@ -551,11 +552,12 @@ void main() { expect(shortcuts.shortcuts, isEmpty); }); - testWidgets('Shortcuts.manager passes on shortcuts', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Shortcuts.manager passes on shortcuts', (WidgetTester tester) async { final Map testShortcuts = { LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(), }; final ShortcutManager manager = ShortcutManager(shortcuts: testShortcuts); + addTearDown(manager.dispose); expect(manager.shortcuts, isNotNull); expect(manager.shortcuts, equals(testShortcuts)); final Shortcuts shortcuts = Shortcuts.manager(manager: manager, child: const SizedBox()); @@ -564,7 +566,7 @@ void main() { expect(shortcuts.shortcuts, equals(testShortcuts)); }); - testWidgets('ShortcutManager handles shortcuts', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ShortcutManager handles shortcuts', (WidgetTester tester) async { final GlobalKey containerKey = GlobalKey(); final List pressedKeys = []; final TestShortcutManager testManager = TestShortcutManager( @@ -573,6 +575,7 @@ void main() { LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(), }, ); + addTearDown(testManager.dispose); bool invoked = false; await tester.pumpWidget( Actions( @@ -599,7 +602,7 @@ void main() { expect(pressedKeys, equals([LogicalKeyboardKey.shiftLeft])); }); - testWidgets('Shortcuts.manager lets manager handle shortcuts', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Shortcuts.manager lets manager handle shortcuts', (WidgetTester tester) async { final GlobalKey containerKey = GlobalKey(); final List pressedKeys = []; final TestShortcutManager testManager = TestShortcutManager( @@ -608,6 +611,7 @@ void main() { LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(), }, ); + addTearDown(testManager.dispose); bool invoked = false; await tester.pumpWidget( Actions( @@ -634,7 +638,7 @@ void main() { expect(pressedKeys, equals([LogicalKeyboardKey.shiftLeft])); }); - testWidgets('ShortcutManager ignores key presses with no primary focus', (WidgetTester tester) async { + testWidgetsWithLeakTracking('ShortcutManager ignores key presses with no primary focus', (WidgetTester tester) async { final GlobalKey containerKey = GlobalKey(); final List pressedKeys = []; final TestShortcutManager testManager = TestShortcutManager( @@ -643,6 +647,7 @@ void main() { LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(), }, ); + addTearDown(testManager.dispose); bool invoked = false; await tester.pumpWidget( Actions( @@ -671,7 +676,7 @@ void main() { expect(()=> ShortcutManager().dispose(), dispatchesMemoryEvents(ShortcutManager)); }); - testWidgets("Shortcuts passes to the next Shortcuts widget if it doesn't map the key", (WidgetTester tester) async { + testWidgetsWithLeakTracking("Shortcuts passes to the next Shortcuts widget if it doesn't map the key", (WidgetTester tester) async { final GlobalKey containerKey = GlobalKey(); final List pressedKeys = []; final TestShortcutManager testManager = TestShortcutManager( @@ -680,6 +685,7 @@ void main() { LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(), }, ); + addTearDown(testManager.dispose); bool invoked = false; await tester.pumpWidget( Shortcuts.manager( @@ -711,7 +717,7 @@ void main() { expect(pressedKeys, equals([LogicalKeyboardKey.shiftLeft])); }); - testWidgets('Shortcuts can disable a shortcut with Intent.doNothing', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Shortcuts can disable a shortcut with Intent.doNothing', (WidgetTester tester) async { final GlobalKey containerKey = GlobalKey(); final List pressedKeys = []; final TestShortcutManager testManager = TestShortcutManager( @@ -720,6 +726,7 @@ void main() { LogicalKeySet(LogicalKeyboardKey.shift): const TestIntent(), }, ); + addTearDown(testManager.dispose); bool invoked = false; await tester.pumpWidget( MaterialApp( @@ -753,7 +760,7 @@ void main() { expect(pressedKeys, isEmpty); }); - testWidgets("Shortcuts that aren't bound to an action don't absorb keys meant for text fields", (WidgetTester tester) async { + testWidgetsWithLeakTracking("Shortcuts that aren't bound to an action don't absorb keys meant for text fields", (WidgetTester tester) async { final GlobalKey textFieldKey = GlobalKey(); final List pressedKeys = []; final TestShortcutManager testManager = TestShortcutManager( @@ -762,6 +769,7 @@ void main() { LogicalKeySet(LogicalKeyboardKey.keyA): const TestIntent(), }, ); + addTearDown(testManager.dispose); await tester.pumpWidget( MaterialApp( home: Material( @@ -778,7 +786,7 @@ void main() { expect(pressedKeys, equals([LogicalKeyboardKey.keyA])); }); - testWidgets('Shortcuts that are bound to an action do override text fields', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Shortcuts that are bound to an action do override text fields', (WidgetTester tester) async { final GlobalKey textFieldKey = GlobalKey(); final List pressedKeys = []; final TestShortcutManager testManager = TestShortcutManager( @@ -787,6 +795,7 @@ void main() { LogicalKeySet(LogicalKeyboardKey.keyA): const TestIntent(), }, ); + addTearDown(testManager.dispose); bool invoked = false; await tester.pumpWidget( MaterialApp( @@ -815,7 +824,7 @@ void main() { expect(invoked, isTrue); }); - testWidgets('Shortcuts can override intents that apply to text fields', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Shortcuts can override intents that apply to text fields', (WidgetTester tester) async { final GlobalKey textFieldKey = GlobalKey(); final List pressedKeys = []; final TestShortcutManager testManager = TestShortcutManager( @@ -824,6 +833,7 @@ void main() { LogicalKeySet(LogicalKeyboardKey.keyA): const TestIntent(), }, ); + addTearDown(testManager.dispose); bool invoked = false; await tester.pumpWidget( MaterialApp( @@ -856,7 +866,7 @@ void main() { expect(invoked, isFalse); }); - testWidgets('Shortcuts can override intents that apply to text fields with DoNothingAndStopPropagationIntent', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Shortcuts can override intents that apply to text fields with DoNothingAndStopPropagationIntent', (WidgetTester tester) async { final GlobalKey textFieldKey = GlobalKey(); final List pressedKeys = []; final TestShortcutManager testManager = TestShortcutManager( @@ -865,6 +875,7 @@ void main() { LogicalKeySet(LogicalKeyboardKey.keyA): const TestIntent(), }, ); + addTearDown(testManager.dispose); bool invoked = false; await tester.pumpWidget( MaterialApp( @@ -982,6 +993,7 @@ void main() { ): const ActivateIntent(), }, ); + addTearDown(testManager.dispose); Shortcuts.manager( manager: testManager, @@ -997,7 +1009,7 @@ void main() { expect(description[1], equalsIgnoringHashCodes('shortcuts: {{Key A + Key B}: ActivateIntent#00000}')); }); - testWidgets('Shortcuts support multiple intents', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Shortcuts support multiple intents', (WidgetTester tester) async { tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; bool? value = true; Widget buildApp() { @@ -1078,7 +1090,7 @@ void main() { expect(controller.position.pixels, 0.0); }); - testWidgets('Shortcuts support activators that returns null in triggers', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Shortcuts support activators that returns null in triggers', (WidgetTester tester) async { int invoked = 0; await tester.pumpWidget(activatorTester( const DumbLogicalActivator(LogicalKeyboardKey.keyC), @@ -1120,7 +1132,7 @@ void main() { }); group('CharacterActivator', () { - testWidgets('is triggered on events with correct character', (WidgetTester tester) async { + testWidgetsWithLeakTracking('is triggered on events with correct character', (WidgetTester tester) async { int invoked = 0; await tester.pumpWidget(activatorTester( const CharacterActivator('?'), @@ -1138,7 +1150,7 @@ void main() { invoked = 0; }, variant: KeySimulatorTransitModeVariant.all()); - testWidgets('handles repeated events', (WidgetTester tester) async { + testWidgetsWithLeakTracking('handles repeated events', (WidgetTester tester) async { int invoked = 0; await tester.pumpWidget(activatorTester( const CharacterActivator('?'), @@ -1158,7 +1170,7 @@ void main() { invoked = 0; }, variant: KeySimulatorTransitModeVariant.all()); - testWidgets('rejects repeated events if requested', (WidgetTester tester) async { + testWidgetsWithLeakTracking('rejects repeated events if requested', (WidgetTester tester) async { int invoked = 0; await tester.pumpWidget(activatorTester( const CharacterActivator('?', includeRepeats: false), @@ -1178,7 +1190,7 @@ void main() { invoked = 0; }, variant: KeySimulatorTransitModeVariant.all()); - testWidgets('handles Alt, Ctrl and Meta', (WidgetTester tester) async { + testWidgetsWithLeakTracking('handles Alt, Ctrl and Meta', (WidgetTester tester) async { int invoked = 0; await tester.pumpWidget(activatorTester( const CharacterActivator('?', alt: true, meta: true, control: true), @@ -1224,7 +1236,7 @@ void main() { invoked = 0; }, variant: KeySimulatorTransitModeVariant.all()); - testWidgets('isActivatedBy works as expected', (WidgetTester tester) async { + testWidgetsWithLeakTracking('isActivatedBy works as expected', (WidgetTester tester) async { // Collect some key events to use for testing. final List events = []; await tester.pumpWidget( @@ -1293,7 +1305,7 @@ void main() { }); group('CallbackShortcuts', () { - testWidgets('trigger on key events', (WidgetTester tester) async { + testWidgetsWithLeakTracking('trigger on key events', (WidgetTester tester) async { int invokedA = 0; int invokedB = 0; await tester.pumpWidget( @@ -1331,7 +1343,7 @@ void main() { expect(invokedB, equals(1)); }); - testWidgets('nested CallbackShortcuts stop propagation', (WidgetTester tester) async { + testWidgetsWithLeakTracking('nested CallbackShortcuts stop propagation', (WidgetTester tester) async { int invokedOuter = 0; int invokedInner = 0; await tester.pumpWidget( @@ -1364,7 +1376,7 @@ void main() { expect(invokedInner, equals(1)); }); - testWidgets('non-overlapping nested CallbackShortcuts fire appropriately', (WidgetTester tester) async { + testWidgetsWithLeakTracking('non-overlapping nested CallbackShortcuts fire appropriately', (WidgetTester tester) async { int invokedOuter = 0; int invokedInner = 0; await tester.pumpWidget( @@ -1401,7 +1413,7 @@ void main() { expect(invokedInner, equals(1)); }); - testWidgets('Works correctly with Shortcuts too', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Works correctly with Shortcuts too', (WidgetTester tester) async { int invokedCallbackA = 0; int invokedCallbackB = 0; int invokedActionA = 0; @@ -1475,7 +1487,7 @@ void main() { }); group('ShortcutRegistrar', () { - testWidgets('trigger ShortcutRegistrar on key events', (WidgetTester tester) async { + testWidgetsWithLeakTracking('trigger ShortcutRegistrar on key events', (WidgetTester tester) async { int invokedA = 0; int invokedB = 0; await tester.pumpWidget( @@ -1520,7 +1532,7 @@ void main() { expect(invokedB, equals(1)); }); - testWidgets('MaterialApp has a ShortcutRegistrar listening', (WidgetTester tester) async { + testWidgetsWithLeakTracking('MaterialApp has a ShortcutRegistrar listening', (WidgetTester tester) async { int invokedA = 0; int invokedB = 0; await tester.pumpWidget( @@ -1565,7 +1577,7 @@ void main() { expect(invokedB, equals(1)); }); - testWidgets("doesn't override text field shortcuts", (WidgetTester tester) async { + testWidgetsWithLeakTracking("doesn't override text field shortcuts", (WidgetTester tester) async { final TextEditingController controller = TextEditingController(); await tester.pumpWidget( MaterialApp( @@ -1597,7 +1609,7 @@ void main() { expect(controller.selection.extentOffset, equals(7)); }); - testWidgets('nested ShortcutRegistrars stop propagation', (WidgetTester tester) async { + testWidgetsWithLeakTracking('nested ShortcutRegistrars stop propagation', (WidgetTester tester) async { int invokedOuter = 0; int invokedInner = 0; await tester.pumpWidget( @@ -1638,7 +1650,7 @@ void main() { expect(invokedInner, equals(1)); }); - testWidgets('non-overlapping nested ShortcutRegistrars fire appropriately', (WidgetTester tester) async { + testWidgetsWithLeakTracking('non-overlapping nested ShortcutRegistrars fire appropriately', (WidgetTester tester) async { int invokedOuter = 0; int invokedInner = 0; await tester.pumpWidget( @@ -1684,7 +1696,7 @@ void main() { expect(invokedInner, equals(1)); }); - testWidgets('Works correctly with Shortcuts too', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Works correctly with Shortcuts too', (WidgetTester tester) async { int invokedCallbackA = 0; int invokedCallbackB = 0; int invokedActionA = 0; @@ -1761,7 +1773,7 @@ void main() { await tester.sendKeyUpEvent(LogicalKeyboardKey.keyB); }); - testWidgets('Updating shortcuts triggers dependency rebuild', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Updating shortcuts triggers dependency rebuild', (WidgetTester tester) async { final List> shortcutsChanged = >[]; void dependenciesUpdated(Map shortcuts) { shortcutsChanged.add(shortcuts); @@ -1835,8 +1847,9 @@ void main() { })); }); - testWidgets('using a disposed token asserts', (WidgetTester tester) async { + testWidgetsWithLeakTracking('using a disposed token asserts', (WidgetTester tester) async { final ShortcutRegistry registry = ShortcutRegistry(); + addTearDown(registry.dispose); final ShortcutRegistryEntry token = registry.addAll(const { SingleActivator(LogicalKeyboardKey.keyA): DoNothingIntent(), }); @@ -1844,8 +1857,9 @@ void main() { expect(() {token.replaceAll({}); }, throwsFlutterError); }); - testWidgets('setting duplicate bindings asserts', (WidgetTester tester) async { + testWidgetsWithLeakTracking('setting duplicate bindings asserts', (WidgetTester tester) async { final ShortcutRegistry registry = ShortcutRegistry(); + addTearDown(registry.dispose); final ShortcutRegistryEntry token = registry.addAll(const { SingleActivator(LogicalKeyboardKey.keyA): DoNothingIntent(), }); diff --git a/packages/flutter/test/widgets/simple_semantics_test.dart b/packages/flutter/test/widgets/simple_semantics_test.dart index 4b5729ea5d461..34b0733a94855 100644 --- a/packages/flutter/test/widgets/simple_semantics_test.dart +++ b/packages/flutter/test/widgets/simple_semantics_test.dart @@ -6,11 +6,12 @@ import 'dart:ui'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import 'semantics_tester.dart'; void main() { - testWidgets('Simple tree is simple', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Simple tree is simple', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); await tester.pumpWidget( @@ -34,7 +35,7 @@ void main() { semantics.dispose(); }); - testWidgets('Simple tree is simple - material', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Simple tree is simple - material', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); // Not using Text widget because of https://github.com/flutter/flutter/issues/12357. diff --git a/packages/flutter/test/widgets/single_child_scroll_view_test.dart b/packages/flutter/test/widgets/single_child_scroll_view_test.dart index 83b8df226f8ad..2cc8708215436 100644 --- a/packages/flutter/test/widgets/single_child_scroll_view_test.dart +++ b/packages/flutter/test/widgets/single_child_scroll_view_test.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import '../rendering/rendering_tester.dart' show TestClipPaintingContext; import 'semantics_tester.dart'; @@ -144,7 +145,7 @@ void main() { ); }); - testWidgets('SingleChildScrollView control test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SingleChildScrollView control test', (WidgetTester tester) async { await tester.pumpWidget(SingleChildScrollView( child: Container( height: 2000.0, @@ -160,8 +161,9 @@ void main() { expect(box.localToGlobal(Offset.zero), equals(const Offset(0.0, -200.0))); }); - testWidgets('Changing controllers changes scroll position', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Changing controllers changes scroll position', (WidgetTester tester) async { final TestScrollController controller = TestScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget(SingleChildScrollView( child: Container( @@ -182,8 +184,9 @@ void main() { expect(scrollable.position, isA()); }); - testWidgets('Sets PrimaryScrollController when primary', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Sets PrimaryScrollController when primary', (WidgetTester tester) async { final ScrollController primaryScrollController = ScrollController(); + addTearDown(primaryScrollController.dispose); await tester.pumpWidget(PrimaryScrollController( controller: primaryScrollController, child: SingleChildScrollView( @@ -200,8 +203,9 @@ void main() { }); - testWidgets('Changing scroll controller inside dirty layout builder does not assert', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Changing scroll controller inside dirty layout builder does not assert', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget(Center( child: SizedBox( @@ -237,25 +241,28 @@ void main() { )); }); - testWidgets('Vertical SingleChildScrollViews are not primary by default', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Vertical SingleChildScrollViews are not primary by default', (WidgetTester tester) async { const SingleChildScrollView view = SingleChildScrollView(); expect(view.primary, isNull); }); - testWidgets('Horizontal SingleChildScrollViews are not primary by default', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Horizontal SingleChildScrollViews are not primary by default', (WidgetTester tester) async { const SingleChildScrollView view = SingleChildScrollView(scrollDirection: Axis.horizontal); expect(view.primary, isNull); }); - testWidgets('SingleChildScrollViews with controllers are not primary by default', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SingleChildScrollViews with controllers are not primary by default', (WidgetTester tester) async { + final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); final SingleChildScrollView view = SingleChildScrollView( - controller: ScrollController(), + controller: controller, ); expect(view.primary, isNull); }); - testWidgets('Vertical SingleChildScrollViews use PrimaryScrollController by default on mobile', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Vertical SingleChildScrollViews use PrimaryScrollController by default on mobile', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget(primaryScrollControllerBoilerplate( child: const SingleChildScrollView(), controller: controller, @@ -263,8 +270,9 @@ void main() { expect(controller.hasClients, isTrue); }, variant: TargetPlatformVariant.mobile()); - testWidgets("Vertical SingleChildScrollViews don't use PrimaryScrollController by default on desktop", (WidgetTester tester) async { + testWidgetsWithLeakTracking("Vertical SingleChildScrollViews don't use PrimaryScrollController by default on desktop", (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget(primaryScrollControllerBoilerplate( child: const SingleChildScrollView(), controller: controller, @@ -272,9 +280,10 @@ void main() { expect(controller.hasClients, isFalse); }, variant: TargetPlatformVariant.desktop()); - testWidgets('Nested scrollables have a null PrimaryScrollController', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Nested scrollables have a null PrimaryScrollController', (WidgetTester tester) async { const Key innerKey = Key('inner'); final ScrollController primaryScrollController = ScrollController(); + addTearDown(primaryScrollController.dispose); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -300,9 +309,10 @@ void main() { expect(innerScrollable.controller, isNull); }); - testWidgets('SingleChildScrollView semantics', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SingleChildScrollView semantics', (WidgetTester tester) async { final SemanticsTester semantics = SemanticsTester(tester); final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget( Directionality( @@ -395,8 +405,9 @@ void main() { semantics.dispose(); }); - testWidgets('SingleChildScrollView semantics clips cover entire child vertical', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SingleChildScrollView semantics clips cover entire child vertical', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); final UniqueKey scrollView = UniqueKey(); final UniqueKey childBox = UniqueKey(); const double length = 10000; @@ -434,8 +445,9 @@ void main() { expect(semanticsClip.size.height, length); }); - testWidgets('SingleChildScrollView semantics clips cover entire child', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SingleChildScrollView semantics clips cover entire child', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); final UniqueKey scrollView = UniqueKey(); final UniqueKey childBox = UniqueKey(); const double length = 10000; @@ -474,7 +486,9 @@ void main() { expect(semanticsClip.size.width, length); }); - testWidgets('SingleChildScrollView getOffsetToReveal - down', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SingleChildScrollView getOffsetToReveal - down', (WidgetTester tester) async { + final ScrollController controller = ScrollController(initialScrollOffset: 300.0); + addTearDown(controller.dispose); List children; await tester.pumpWidget( Directionality( @@ -484,7 +498,7 @@ void main() { height: 200.0, width: 300.0, child: SingleChildScrollView( - controller: ScrollController(initialScrollOffset: 300.0), + controller: controller, child: Column( children: children = List.generate(20, (int i) { return SizedBox( @@ -520,7 +534,9 @@ void main() { expect(revealed.rect, const Rect.fromLTWH(40.0, 190.0, 10.0, 10.0)); }); - testWidgets('SingleChildScrollView getOffsetToReveal - up', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SingleChildScrollView getOffsetToReveal - up', (WidgetTester tester) async { + final ScrollController controller = ScrollController(initialScrollOffset: 300.0); + addTearDown(controller.dispose); final List children = List.generate(20, (int i) { return SizedBox( height: 100.0, @@ -536,7 +552,7 @@ void main() { height: 200.0, width: 300.0, child: SingleChildScrollView( - controller: ScrollController(initialScrollOffset: 300.0), + controller: controller, reverse: true, child: Column( children: children.reversed.toList(), @@ -567,7 +583,9 @@ void main() { expect(revealed.rect, const Rect.fromLTWH(40.0, 0.0, 10.0, 10.0)); }); - testWidgets('SingleChildScrollView getOffsetToReveal - right', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SingleChildScrollView getOffsetToReveal - right', (WidgetTester tester) async { + final ScrollController controller = ScrollController(initialScrollOffset: 300.0); + addTearDown(controller.dispose); List children; await tester.pumpWidget( @@ -579,7 +597,7 @@ void main() { width: 200.0, child: SingleChildScrollView( scrollDirection: Axis.horizontal, - controller: ScrollController(initialScrollOffset: 300.0), + controller: controller, child: Row( children: children = List.generate(20, (int i) { return SizedBox( @@ -615,7 +633,9 @@ void main() { expect(revealed.rect, const Rect.fromLTWH(190.0, 40.0, 10.0, 10.0)); }); - testWidgets('SingleChildScrollView getOffsetToReveal - left', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SingleChildScrollView getOffsetToReveal - left', (WidgetTester tester) async { + final ScrollController controller = ScrollController(initialScrollOffset: 300.0); + addTearDown(controller.dispose); final List children = List.generate(20, (int i) { return SizedBox( height: 300.0, @@ -634,7 +654,7 @@ void main() { child: SingleChildScrollView( scrollDirection: Axis.horizontal, reverse: true, - controller: ScrollController(initialScrollOffset: 300.0), + controller: controller, child: Row( children: children.reversed.toList(), ), @@ -664,7 +684,7 @@ void main() { expect(revealed.rect, const Rect.fromLTWH(0.0, 40.0, 10.0, 10.0)); }); - testWidgets('Nested SingleChildScrollView showOnScreen', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Nested SingleChildScrollView showOnScreen', (WidgetTester tester) async { final List> children = List>.generate(10, (int x) { return List.generate(10, (int y) { return SizedBox( @@ -674,8 +694,10 @@ void main() { ); }); }); - ScrollController controllerX; - ScrollController controllerY; + late ScrollController controllerX; + addTearDown(() => controllerX.dispose()); + late ScrollController controllerY; + addTearDown(() => controllerY.dispose()); /// Builds a gird: /// @@ -874,9 +896,11 @@ void main() { ); } - testWidgets('in view in inner, but not in outer', (WidgetTester tester) async { + testWidgetsWithLeakTracking('in view in inner, but not in outer', (WidgetTester tester) async { final ScrollController inner = ScrollController(); + addTearDown(inner.dispose); final ScrollController outer = ScrollController(); + addTearDown(outer.dispose); await buildNestedScroller( tester: tester, inner: inner, @@ -891,9 +915,11 @@ void main() { expect(outer.offset, 100.0); }); - testWidgets('not in view of neither inner nor outer', (WidgetTester tester) async { + testWidgetsWithLeakTracking('not in view of neither inner nor outer', (WidgetTester tester) async { final ScrollController inner = ScrollController(); + addTearDown(inner.dispose); final ScrollController outer = ScrollController(); + addTearDown(outer.dispose); await buildNestedScroller( tester: tester, inner: inner, @@ -908,9 +934,11 @@ void main() { expect(outer.offset, 200.0); }); - testWidgets('in view in inner and outer', (WidgetTester tester) async { + testWidgetsWithLeakTracking('in view in inner and outer', (WidgetTester tester) async { final ScrollController inner = ScrollController(initialScrollOffset: 200.0); + addTearDown(inner.dispose); final ScrollController outer = ScrollController(initialScrollOffset: 200.0); + addTearDown(outer.dispose); await buildNestedScroller( tester: tester, inner: inner, @@ -925,9 +953,11 @@ void main() { expect(inner.offset, 200.0); }); - testWidgets('inner shown in outer, but item not visible', (WidgetTester tester) async { + testWidgetsWithLeakTracking('inner shown in outer, but item not visible', (WidgetTester tester) async { final ScrollController inner = ScrollController(initialScrollOffset: 200.0); + addTearDown(inner.dispose); final ScrollController outer = ScrollController(initialScrollOffset: 200.0); + addTearDown(outer.dispose); await buildNestedScroller( tester: tester, inner: inner, @@ -942,9 +972,11 @@ void main() { expect(inner.offset, 400.0); }); - testWidgets('inner half shown in outer, item only visible in inner', (WidgetTester tester) async { + testWidgetsWithLeakTracking('inner half shown in outer, item only visible in inner', (WidgetTester tester) async { final ScrollController inner = ScrollController(); + addTearDown(inner.dispose); final ScrollController outer = ScrollController(initialScrollOffset: 100.0); + addTearDown(outer.dispose); await buildNestedScroller( tester: tester, inner: inner, @@ -960,8 +992,13 @@ void main() { }); }); - testWidgets('keyboardDismissBehavior tests', (WidgetTester tester) async { + testWidgetsWithLeakTracking('keyboardDismissBehavior tests', (WidgetTester tester) async { final List focusNodes = List.generate(50, (int i) => FocusNode()); + addTearDown(() { + for (final FocusNode node in focusNodes) { + node.dispose(); + } + }); Future boilerplate(ScrollViewKeyboardDismissBehavior behavior) { return tester.pumpWidget( diff --git a/packages/flutter/test/widgets/size_changed_layout_notification_test.dart b/packages/flutter/test/widgets/size_changed_layout_notification_test.dart index 6f8c8c83c1759..f4b1e8862057a 100644 --- a/packages/flutter/test/widgets/size_changed_layout_notification_test.dart +++ b/packages/flutter/test/widgets/size_changed_layout_notification_test.dart @@ -4,9 +4,10 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { - testWidgets('SizeChangedLayoutNotification test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SizeChangedLayoutNotification test', (WidgetTester tester) async { bool notified = false; await tester.pumpWidget( diff --git a/packages/flutter/test/widgets/sized_box_test.dart b/packages/flutter/test/widgets/sized_box_test.dart index 4d1d5094e1a59..60822a1e31b56 100644 --- a/packages/flutter/test/widgets/sized_box_test.dart +++ b/packages/flutter/test/widgets/sized_box_test.dart @@ -5,9 +5,10 @@ import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { - testWidgets('SizedBox constructors', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SizedBox constructors', (WidgetTester tester) async { const SizedBox a = SizedBox(); expect(a.width, isNull); expect(a.height, isNull); @@ -37,7 +38,7 @@ void main() { expect(g.height, 0.0); }); - testWidgets('SizedBox - no child', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SizedBox - no child', (WidgetTester tester) async { final GlobalKey patient = GlobalKey(); await tester.pumpWidget( @@ -109,7 +110,7 @@ void main() { expect(patient.currentContext!.size, equals(Size.zero)); }); - testWidgets('SizedBox - container child', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SizedBox - container child', (WidgetTester tester) async { final GlobalKey patient = GlobalKey(); await tester.pumpWidget( @@ -188,7 +189,7 @@ void main() { expect(patient.currentContext!.size, equals(Size.zero)); }); - testWidgets('SizedBox.square tests', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SizedBox.square tests', (WidgetTester tester) async { await tester.pumpWidget( const SizedBox.square( dimension: 100, diff --git a/packages/flutter/test/widgets/sliver_appbar_opacity_test.dart b/packages/flutter/test/widgets/sliver_appbar_opacity_test.dart index 474af5272cbe8..41d222c353c1e 100644 --- a/packages/flutter/test/widgets/sliver_appbar_opacity_test.dart +++ b/packages/flutter/test/widgets/sliver_appbar_opacity_test.dart @@ -5,10 +5,12 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { - testWidgets('!pinned && !floating && !bottom ==> fade opacity', (WidgetTester tester) async { + testWidgetsWithLeakTracking('!pinned && !floating && !bottom ==> fade opacity', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget( _TestWidget( pinned: false, @@ -26,8 +28,9 @@ void main() { expect(render.text.style!.color!.opacity, 0.0); }); - testWidgets('!pinned && !floating && bottom ==> fade opacity', (WidgetTester tester) async { + testWidgetsWithLeakTracking('!pinned && !floating && bottom ==> fade opacity', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget( _TestWidget( pinned: false, @@ -45,8 +48,9 @@ void main() { expect(render.text.style!.color!.opacity, 0.0); }); - testWidgets('!pinned && floating && !bottom ==> fade opacity', (WidgetTester tester) async { + testWidgetsWithLeakTracking('!pinned && floating && !bottom ==> fade opacity', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget( _TestWidget( pinned: false, @@ -64,8 +68,9 @@ void main() { expect(render.text.style!.color!.opacity, 0.0); }); - testWidgets('!pinned && floating && bottom ==> fade opacity', (WidgetTester tester) async { + testWidgetsWithLeakTracking('!pinned && floating && bottom ==> fade opacity', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget( _TestWidget( pinned: false, @@ -83,8 +88,9 @@ void main() { expect(render.text.style!.color!.opacity, 0.0); }); - testWidgets('pinned && !floating && !bottom ==> 1.0 opacity', (WidgetTester tester) async { + testWidgetsWithLeakTracking('pinned && !floating && !bottom ==> 1.0 opacity', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget( _TestWidget( pinned: true, @@ -102,8 +108,9 @@ void main() { expect(render.text.style!.color!.opacity, 1.0); }); - testWidgets('pinned && !floating && bottom ==> 1.0 opacity', (WidgetTester tester) async { + testWidgetsWithLeakTracking('pinned && !floating && bottom ==> 1.0 opacity', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget( _TestWidget( pinned: true, @@ -121,10 +128,11 @@ void main() { expect(render.text.style!.color!.opacity, 1.0); }); - testWidgets('pinned && floating && !bottom ==> 1.0 opacity', (WidgetTester tester) async { + testWidgetsWithLeakTracking('pinned && floating && !bottom ==> 1.0 opacity', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/25000. final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget( _TestWidget( pinned: true, @@ -142,10 +150,11 @@ void main() { expect(render.text.style!.color!.opacity, 1.0); }); - testWidgets('pinned && floating && bottom && extraToolbarHeight == 0.0 ==> fade opacity', (WidgetTester tester) async { + testWidgetsWithLeakTracking('pinned && floating && bottom && extraToolbarHeight == 0.0 ==> fade opacity', (WidgetTester tester) async { // Regression test for https://github.com/flutter/flutter/issues/25993. final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget( _TestWidget( pinned: true, @@ -163,8 +172,9 @@ void main() { expect(render.text.style!.color!.opacity, 0.0); }); - testWidgets('pinned && floating && bottom && extraToolbarHeight != 0.0 ==> 1.0 opacity', (WidgetTester tester) async { + testWidgetsWithLeakTracking('pinned && floating && bottom && extraToolbarHeight != 0.0 ==> 1.0 opacity', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget( _TestWidget( pinned: true, @@ -183,8 +193,9 @@ void main() { expect(render.text.style!.color!.opacity, 1.0); }); - testWidgets('!pinned && !floating && !bottom && extraToolbarHeight != 0.0 ==> fade opacity', (WidgetTester tester) async { + testWidgetsWithLeakTracking('!pinned && !floating && !bottom && extraToolbarHeight != 0.0 ==> fade opacity', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); const double collapsedHeight = 100.0; await tester.pumpWidget( _TestWidget( diff --git a/packages/flutter/test/widgets/sliver_constrained_cross_axis_test.dart b/packages/flutter/test/widgets/sliver_constrained_cross_axis_test.dart index 0fa6bf5eff40e..6cf42bd9cb92c 100644 --- a/packages/flutter/test/widgets/sliver_constrained_cross_axis_test.dart +++ b/packages/flutter/test/widgets/sliver_constrained_cross_axis_test.dart @@ -5,12 +5,13 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; const double VIEWPORT_HEIGHT = 500; const double VIEWPORT_WIDTH = 300; void main() { - testWidgets('SliverConstrainedCrossAxis basic test', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SliverConstrainedCrossAxis basic test', (WidgetTester tester) async { await tester.pumpWidget(_buildSliverConstrainedCrossAxis(maxExtent: 50)); final RenderBox box = tester.renderObject(find.byType(Container)); @@ -21,7 +22,7 @@ void main() { expect(sliver.geometry!.paintExtent, equals(100)); }); - testWidgets('SliverConstrainedCrossAxis updates correctly', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SliverConstrainedCrossAxis updates correctly', (WidgetTester tester) async { await tester.pumpWidget(_buildSliverConstrainedCrossAxis(maxExtent: 50)); final RenderBox box1 = tester.renderObject(find.byType(Container)); @@ -35,7 +36,7 @@ void main() { expect(box2.size.width, 80); }); - testWidgets('SliverConstrainedCrossAxis uses parent extent if maxExtent is greater', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SliverConstrainedCrossAxis uses parent extent if maxExtent is greater', (WidgetTester tester) async { await tester.pumpWidget(_buildSliverConstrainedCrossAxis(maxExtent: 400)); final RenderBox box = tester.renderObject(find.byType(Container)); @@ -43,7 +44,7 @@ void main() { expect(box.size.width, VIEWPORT_WIDTH); }); - testWidgets('SliverConstrainedCrossAxis constrains the height when direction is horizontal', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SliverConstrainedCrossAxis constrains the height when direction is horizontal', (WidgetTester tester) async { await tester.pumpWidget(_buildSliverConstrainedCrossAxis( maxExtent: 50, scrollDirection: Axis.horizontal, @@ -53,7 +54,7 @@ void main() { expect(box.size.height, 50); }); - testWidgets('SliverConstrainedCrossAxis sets its own flex to 0', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SliverConstrainedCrossAxis sets its own flex to 0', (WidgetTester tester) async { await tester.pumpWidget(_buildSliverConstrainedCrossAxis( maxExtent: 50, )); diff --git a/packages/flutter/test/widgets/sliver_constraints_test.dart b/packages/flutter/test/widgets/sliver_constraints_test.dart index 56565b69ebb5d..e2ac47afe7d98 100644 --- a/packages/flutter/test/widgets/sliver_constraints_test.dart +++ b/packages/flutter/test/widgets/sliver_constraints_test.dart @@ -5,9 +5,10 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { - testWidgets('precedingScrollExtent is reported as infinity for Sliver of unknown size', (WidgetTester tester) async { + testWidgetsWithLeakTracking('precedingScrollExtent is reported as infinity for Sliver of unknown size', (WidgetTester tester) async { await tester.pumpWidget( MaterialApp( home: CustomScrollView( diff --git a/packages/flutter/test/widgets/sliver_cross_axis_group_test.dart b/packages/flutter/test/widgets/sliver_cross_axis_group_test.dart index a3d4dc8fd906b..8755d358e8ea4 100644 --- a/packages/flutter/test/widgets/sliver_cross_axis_group_test.dart +++ b/packages/flutter/test/widgets/sliver_cross_axis_group_test.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; import '../rendering/sliver_utils.dart'; @@ -13,9 +14,10 @@ const double VIEWPORT_HEIGHT = 600; const double VIEWPORT_WIDTH = 300; void main() { - testWidgets('SliverCrossAxisGroup is laid out properly', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SliverCrossAxisGroup is laid out properly', (WidgetTester tester) async { final List items = List.generate(20, (int i) => i); final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget(_buildSliverCrossAxisGroup( controller: controller, @@ -60,7 +62,7 @@ void main() { expect(renderGroup.geometry!.scrollExtent, equals(300 * 20)); }); - testWidgets('SliverExpanded is laid out properly', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SliverExpanded is laid out properly', (WidgetTester tester) async { final List items = List.generate(20, (int i) => i); await tester.pumpWidget(_buildSliverCrossAxisGroup( slivers: [ @@ -98,7 +100,7 @@ void main() { expect(renderGroup.geometry!.scrollExtent, equals(300 * 20)); }); - testWidgets('SliverConstrainedCrossAxis is laid out properly', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SliverConstrainedCrossAxis is laid out properly', (WidgetTester tester) async { final List items = List.generate(20, (int i) => i); await tester.pumpWidget(_buildSliverCrossAxisGroup( slivers: [ @@ -127,7 +129,7 @@ void main() { expect(renderGroup.geometry!.scrollExtent, equals(300 * 20)); }); - testWidgets('Mix of slivers is laid out properly', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Mix of slivers is laid out properly', (WidgetTester tester) async { final List items = List.generate(20, (int i) => i); await tester.pumpWidget(_buildSliverCrossAxisGroup( slivers: [ @@ -160,7 +162,7 @@ void main() { expect(renderGroup.geometry!.scrollExtent, equals(300 * 20)); }); - testWidgets('Mix of slivers is laid out properly when horizontal', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Mix of slivers is laid out properly when horizontal', (WidgetTester tester) async { final List items = List.generate(20, (int i) => i); await tester.pumpWidget(_buildSliverCrossAxisGroup( scrollDirection: Axis.horizontal, @@ -215,7 +217,7 @@ void main() { expect(renderGroup.geometry!.scrollExtent, equals(300 * 20)); }); - testWidgets('Mix of slivers is laid out properly when reversed horizontal', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Mix of slivers is laid out properly when reversed horizontal', (WidgetTester tester) async { final List items = List.generate(20, (int i) => i); await tester.pumpWidget(_buildSliverCrossAxisGroup( scrollDirection: Axis.horizontal, @@ -271,7 +273,7 @@ void main() { expect(renderGroup.geometry!.scrollExtent, equals(300 * 20)); }); - testWidgets('Mix of slivers is laid out properly when reversed vertical', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Mix of slivers is laid out properly when reversed vertical', (WidgetTester tester) async { final List items = List.generate(20, (int i) => i); await tester.pumpWidget(_buildSliverCrossAxisGroup( reverse: true, @@ -354,9 +356,10 @@ void main() { ); }); - testWidgets('Hit test works properly on various parts of SliverCrossAxisGroup', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Hit test works properly on various parts of SliverCrossAxisGroup', (WidgetTester tester) async { final List items = List.generate(20, (int i) => i); final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); String? clickedTile; @@ -425,7 +428,7 @@ void main() { expect(clickedTile, equals('Group 1 Tile 2')); }); - testWidgets('Constrained sliver takes up remaining space', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Constrained sliver takes up remaining space', (WidgetTester tester) async { final List items = List.generate(20, (int i) => i); await tester.pumpWidget(_buildSliverCrossAxisGroup( slivers: [ @@ -454,7 +457,7 @@ void main() { expect(renderGroup.geometry!.scrollExtent, equals(300 * 20)); }); - testWidgets('Assertion error when constrained widget runs out of cross axis extent', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Assertion error when constrained widget runs out of cross axis extent', (WidgetTester tester) async { final List errors = []; final Function(FlutterErrorDetails)? oldHandler = FlutterError.onError; FlutterError.onError = (FlutterErrorDetails error) => errors.add(error); @@ -476,7 +479,7 @@ void main() { ); }); - testWidgets('Assertion error when expanded widget runs out of cross axis extent', (WidgetTester tester) async { + testWidgetsWithLeakTracking('Assertion error when expanded widget runs out of cross axis extent', (WidgetTester tester) async { final List errors = []; final Function(FlutterErrorDetails)? oldHandler = FlutterError.onError; FlutterError.onError = (FlutterErrorDetails error) => errors.add(error); @@ -499,7 +502,7 @@ void main() { ); }); - testWidgets('applyPaintTransform is implemented properly', (WidgetTester tester) async { + testWidgetsWithLeakTracking('applyPaintTransform is implemented properly', (WidgetTester tester) async { await tester.pumpWidget(_buildSliverCrossAxisGroup( slivers: [ const SliverToBoxAdapter(child: Text('first box')), @@ -515,8 +518,9 @@ void main() { expect(second.localToGlobal(Offset.zero), const Offset(VIEWPORT_WIDTH / 2, 0)); }); - testWidgets('SliverPinnedPersistentHeader is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SliverPinnedPersistentHeader is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget(_buildSliverCrossAxisGroup( controller: controller, slivers: [ @@ -540,8 +544,9 @@ void main() { expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(-20.0)); }); - testWidgets('SliverFloatingPersistentHeader is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SliverFloatingPersistentHeader is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget(_buildSliverCrossAxisGroup( controller: controller, slivers: [ @@ -569,8 +574,9 @@ void main() { expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(0.0)); }); - testWidgets('SliverPinnedPersistentHeader is painted within bounds of SliverCrossAxisGroup with different minExtent/maxExtent', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SliverPinnedPersistentHeader is painted within bounds of SliverCrossAxisGroup with different minExtent/maxExtent', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget(_buildSliverCrossAxisGroup( controller: controller, slivers: [ @@ -599,8 +605,9 @@ void main() { expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(0.0)); }); - testWidgets('SliverFloatingPersistentHeader is painted within bounds of SliverCrossAxisGroup with different minExtent/maxExtent', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SliverFloatingPersistentHeader is painted within bounds of SliverCrossAxisGroup with different minExtent/maxExtent', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget(_buildSliverCrossAxisGroup( controller: controller, slivers: [ @@ -635,8 +642,9 @@ void main() { expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(0.0)); }); - testWidgets('SliverPinnedFloatingPersistentHeader is painted within bounds of SliverCrossAxisGroup with different minExtent/maxExtent', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SliverPinnedFloatingPersistentHeader is painted within bounds of SliverCrossAxisGroup with different minExtent/maxExtent', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget(_buildSliverCrossAxisGroup( controller: controller, slivers: [ @@ -672,8 +680,9 @@ void main() { expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(0.0)); }); - testWidgets('SliverAppBar with floating: false, pinned: false, snap: false is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SliverAppBar with floating: false, pinned: false, snap: false is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget(_buildSliverCrossAxisGroup( controller: controller, slivers: [ @@ -701,8 +710,9 @@ void main() { expect(renderHeader.geometry!.paintExtent, equals(0.0)); }); - testWidgets('SliverAppBar with floating: true, pinned: false, snap: true is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SliverAppBar with floating: true, pinned: false, snap: true is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget(_buildSliverCrossAxisGroup( controller: controller, slivers: [ @@ -741,8 +751,9 @@ void main() { expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(-50.0)); }); - testWidgets('SliverAppBar with floating: true, pinned: true, snap: true is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SliverAppBar with floating: true, pinned: true, snap: true is painted within bounds of SliverCrossAxisGroup', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget(_buildSliverCrossAxisGroup( controller: controller, slivers: [ @@ -781,8 +792,9 @@ void main() { expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(-50.0)); }); - testWidgets('SliverFloatingPersistentHeader scroll direction is not affected by controller.jumpTo', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SliverFloatingPersistentHeader scroll direction is not affected by controller.jumpTo', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget(_buildSliverCrossAxisGroup( controller: controller, slivers: [ @@ -810,8 +822,9 @@ void main() { expect((renderHeader.parentData! as SliverPhysicalParentData).paintOffset.dy, equals(0.0)); }); - testWidgets('SliverCrossAxisGroup skips painting invisible children', (WidgetTester tester) async { + testWidgetsWithLeakTracking('SliverCrossAxisGroup skips painting invisible children', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); int counter = 0; void incrementCounter() { diff --git a/packages/flutter/test/widgets/sliver_fill_remaining_test.dart b/packages/flutter/test/widgets/sliver_fill_remaining_test.dart index f0279e27437fc..a1965c49f76e9 100644 --- a/packages/flutter/test/widgets/sliver_fill_remaining_test.dart +++ b/packages/flutter/test/widgets/sliver_fill_remaining_test.dart @@ -6,6 +6,7 @@ import 'dart:math' as math; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart'; void main() { @@ -39,8 +40,9 @@ void main() { group('SliverFillRemaining', () { group('hasScrollBody: true, default', () { - testWidgets('no siblings', (WidgetTester tester) async { + testWidgetsWithLeakTracking('no siblings', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -79,8 +81,9 @@ void main() { ); }); - testWidgets('one sibling', (WidgetTester tester) async { + testWidgetsWithLeakTracking('one sibling', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); await tester.pumpWidget( Directionality( textDirection: TextDirection.ltr, @@ -120,8 +123,9 @@ void main() { ); }); - testWidgets('scrolls beyond viewportMainAxisExtent', (WidgetTester tester) async { + testWidgetsWithLeakTracking('scrolls beyond viewportMainAxisExtent', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); final List slivers = [ sliverBox, SliverFillRemaining( @@ -139,8 +143,9 @@ void main() { }); group('hasScrollBody: false', () { - testWidgets('does not extend past viewportMainAxisExtent', (WidgetTester tester) async { + testWidgetsWithLeakTracking('does not extend past viewportMainAxisExtent', (WidgetTester tester) async { final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); final List slivers = [ sliverBox, SliverFillRemaining( @@ -158,7 +163,7 @@ void main() { expect(find.byType(Container), findsNWidgets(2)); }); - testWidgets('child without size is sized by extent', (WidgetTester tester) async { + testWidgetsWithLeakTracking('child without size is sized by extent', (WidgetTester tester) async { final List slivers = [ sliverBox, SliverFillRemaining( @@ -179,7 +184,7 @@ void main() { expect(box.size.width, equals(650)); }); - testWidgets('child with smaller size is sized by extent', (WidgetTester tester) async { + testWidgetsWithLeakTracking('child with smaller size is sized by extent', (WidgetTester tester) async { final GlobalKey key = GlobalKey(); final List slivers = [ sliverBox, @@ -220,7 +225,7 @@ void main() { ); }); - testWidgets('extent is overridden by child with larger size', (WidgetTester tester) async { + testWidgetsWithLeakTracking('extent is overridden by child with larger size', (WidgetTester tester) async { final List slivers = [ sliverBox, SliverFillRemaining( @@ -244,7 +249,7 @@ void main() { expect(box.size.width, equals(1000)); }); - testWidgets('extent is overridden by child size if precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async { + testWidgetsWithLeakTracking('extent is overridden by child size if precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async { final GlobalKey key = GlobalKey(); final List slivers = [ SliverFixedExtentList( @@ -285,7 +290,7 @@ void main() { expect(tester.getCenter(button).dx, equals(400.0)); }); - testWidgets('alignment with a flexible works', (WidgetTester tester) async { + testWidgetsWithLeakTracking('alignment with a flexible works', (WidgetTester tester) async { final GlobalKey key = GlobalKey(); final List slivers = [ sliverBox, @@ -354,7 +359,7 @@ void main() { }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); group('fillOverscroll: true, relevant platforms', () { - testWidgets('child without size is sized by extent and overscroll', (WidgetTester tester) async { + testWidgetsWithLeakTracking('child without size is sized by extent and overscroll', (WidgetTester tester) async { final List slivers = [ sliverBox, SliverFillRemaining( @@ -381,7 +386,7 @@ void main() { expect(box3.size.height, equals(450)); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets('child with smaller size is overridden and sized by extent and overscroll', (WidgetTester tester) async { + testWidgetsWithLeakTracking('child with smaller size is overridden and sized by extent and overscroll', (WidgetTester tester) async { final GlobalKey key = GlobalKey(); final List slivers = [ sliverBox, @@ -428,9 +433,10 @@ void main() { ); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets('extent is overridden by child size and overscroll if precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async { + testWidgetsWithLeakTracking('extent is overridden by child size and overscroll if precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async { final GlobalKey key = GlobalKey(); final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); final List slivers = [ SliverFixedExtentList( itemExtent: 150, @@ -492,9 +498,10 @@ void main() { ); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets('fillOverscroll works when child has no size and precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async { + testWidgetsWithLeakTracking('fillOverscroll works when child has no size and precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async { final GlobalKey key = GlobalKey(); final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); final List slivers = [ SliverFixedExtentList( itemExtent: 150, @@ -554,7 +561,7 @@ void main() { ); }, variant: const TargetPlatformVariant({ TargetPlatform.iOS, TargetPlatform.macOS })); - testWidgets('alignment with a flexible works with fillOverscroll', (WidgetTester tester) async { + testWidgetsWithLeakTracking('alignment with a flexible works with fillOverscroll', (WidgetTester tester) async { final GlobalKey key = GlobalKey(); final List slivers = [ sliverBox, @@ -648,7 +655,7 @@ void main() { group('fillOverscroll: true, is ignored on irrelevant platforms', () { // Android/Other scroll physics when hasScrollBody: false, ignores fillOverscroll: true - testWidgets('child without size is sized by extent', (WidgetTester tester) async { + testWidgetsWithLeakTracking('child without size is sized by extent', (WidgetTester tester) async { final List slivers = [ sliverBox, SliverFillRemaining( @@ -667,7 +674,7 @@ void main() { expect(box2.size.height, equals(450)); }); - testWidgets('child with size is overridden and sized by extent', (WidgetTester tester) async { + testWidgetsWithLeakTracking('child with size is overridden and sized by extent', (WidgetTester tester) async { final GlobalKey key = GlobalKey(); final List slivers = [ sliverBox, @@ -706,9 +713,10 @@ void main() { expect(tester.getCenter(button).dx, equals(400.0)); }); - testWidgets('extent is overridden by child size if precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async { + testWidgetsWithLeakTracking('extent is overridden by child size if precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async { final GlobalKey key = GlobalKey(); final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); final List slivers = [ SliverFixedExtentList( itemExtent: 150, @@ -763,9 +771,10 @@ void main() { expect(tester.getCenter(button).dx, equals(400.0)); }); - testWidgets('child has no size and precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async { + testWidgetsWithLeakTracking('child has no size and precedingScrollExtent > viewportMainAxisExtent', (WidgetTester tester) async { final GlobalKey key = GlobalKey(); final ScrollController controller = ScrollController(); + addTearDown(controller.dispose); final List slivers = [ SliverFixedExtentList( itemExtent: 150,