Unverified Commit 7cd8b407 authored by Kostia Sokolovskyi's avatar Kostia Sokolovskyi Committed by GitHub

Cover more test/widgets tests with leak tracking #4 (#134663)

parent f38dcb12
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
class MockOnEndFunction { class MockOnEndFunction {
int called = 0; int called = 0;
...@@ -24,7 +25,7 @@ void main() { ...@@ -24,7 +25,7 @@ void main() {
mockOnEndFunction = MockOnEndFunction(); mockOnEndFunction = MockOnEndFunction();
}); });
testWidgets('BoxConstraintsTween control test', (WidgetTester tester) async { testWidgetsWithLeakTracking('BoxConstraintsTween control test', (WidgetTester tester) async {
final BoxConstraintsTween tween = BoxConstraintsTween( final BoxConstraintsTween tween = BoxConstraintsTween(
begin: BoxConstraints.tight(const Size(20.0, 50.0)), begin: BoxConstraints.tight(const Size(20.0, 50.0)),
end: BoxConstraints.tight(const Size(10.0, 30.0)), end: BoxConstraints.tight(const Size(10.0, 30.0)),
...@@ -36,7 +37,7 @@ void main() { ...@@ -36,7 +37,7 @@ void main() {
expect(result.maxHeight, 45.0); expect(result.maxHeight, 45.0);
}); });
testWidgets('DecorationTween control test', (WidgetTester tester) async { testWidgetsWithLeakTracking('DecorationTween control test', (WidgetTester tester) async {
final DecorationTween tween = DecorationTween( final DecorationTween tween = DecorationTween(
begin: const BoxDecoration(color: Color(0xFF00FF00)), begin: const BoxDecoration(color: Color(0xFF00FF00)),
end: const BoxDecoration(color: Color(0xFFFFFF00)), end: const BoxDecoration(color: Color(0xFFFFFF00)),
...@@ -45,7 +46,7 @@ void main() { ...@@ -45,7 +46,7 @@ void main() {
expect(result.color, const Color(0xFF3FFF00)); expect(result.color, const Color(0xFF3FFF00));
}); });
testWidgets('EdgeInsetsTween control test', (WidgetTester tester) async { testWidgetsWithLeakTracking('EdgeInsetsTween control test', (WidgetTester tester) async {
final EdgeInsetsTween tween = EdgeInsetsTween( final EdgeInsetsTween tween = EdgeInsetsTween(
begin: const EdgeInsets.symmetric(vertical: 50.0), begin: const EdgeInsets.symmetric(vertical: 50.0),
end: const EdgeInsets.only(top: 10.0, bottom: 30.0), end: const EdgeInsets.only(top: 10.0, bottom: 30.0),
...@@ -57,7 +58,7 @@ void main() { ...@@ -57,7 +58,7 @@ void main() {
expect(result.bottom, 45.0); expect(result.bottom, 45.0);
}); });
testWidgets('Matrix4Tween control test', (WidgetTester tester) async { testWidgetsWithLeakTracking('Matrix4Tween control test', (WidgetTester tester) async {
final Matrix4Tween tween = Matrix4Tween( final Matrix4Tween tween = Matrix4Tween(
begin: Matrix4.translationValues(10.0, 20.0, 30.0), begin: Matrix4.translationValues(10.0, 20.0, 30.0),
end: Matrix4.translationValues(14.0, 24.0, 34.0), end: Matrix4.translationValues(14.0, 24.0, 34.0),
...@@ -66,7 +67,7 @@ void main() { ...@@ -66,7 +67,7 @@ void main() {
expect(result, equals(Matrix4.translationValues(11.0, 21.0, 31.0))); expect(result, equals(Matrix4.translationValues(11.0, 21.0, 31.0)));
}); });
testWidgets('AnimatedContainer onEnd callback test', (WidgetTester tester) async { testWidgetsWithLeakTracking('AnimatedContainer onEnd callback test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
callback: mockOnEndFunction.handler, callback: mockOnEndFunction.handler,
...@@ -89,7 +90,7 @@ void main() { ...@@ -89,7 +90,7 @@ void main() {
await tapTest2and3(tester, widgetFinder, mockOnEndFunction); await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
}); });
testWidgets('AnimatedPadding onEnd callback test', (WidgetTester tester) async { testWidgetsWithLeakTracking('AnimatedPadding onEnd callback test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
callback: mockOnEndFunction.handler, callback: mockOnEndFunction.handler,
...@@ -112,7 +113,7 @@ void main() { ...@@ -112,7 +113,7 @@ void main() {
await tapTest2and3(tester, widgetFinder, mockOnEndFunction); await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
}); });
testWidgets('AnimatedAlign onEnd callback test', (WidgetTester tester) async { testWidgetsWithLeakTracking('AnimatedAlign onEnd callback test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
callback: mockOnEndFunction.handler, callback: mockOnEndFunction.handler,
...@@ -135,7 +136,7 @@ void main() { ...@@ -135,7 +136,7 @@ void main() {
await tapTest2and3(tester, widgetFinder, mockOnEndFunction); await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
}); });
testWidgets('AnimatedPositioned onEnd callback test', (WidgetTester tester) async { testWidgetsWithLeakTracking('AnimatedPositioned onEnd callback test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
callback: mockOnEndFunction.handler, callback: mockOnEndFunction.handler,
...@@ -158,7 +159,7 @@ void main() { ...@@ -158,7 +159,7 @@ void main() {
await tapTest2and3(tester, widgetFinder, mockOnEndFunction); await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
}); });
testWidgets('AnimatedPositionedDirectional onEnd callback test', (WidgetTester tester) async { testWidgetsWithLeakTracking('AnimatedPositionedDirectional onEnd callback test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
callback: mockOnEndFunction.handler, callback: mockOnEndFunction.handler,
...@@ -181,7 +182,7 @@ void main() { ...@@ -181,7 +182,7 @@ void main() {
await tapTest2and3(tester, widgetFinder, mockOnEndFunction); await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
}); });
testWidgets('AnimatedSlide onEnd callback test', (WidgetTester tester) async { testWidgetsWithLeakTracking('AnimatedSlide onEnd callback test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
callback: mockOnEndFunction.handler, callback: mockOnEndFunction.handler,
...@@ -203,7 +204,7 @@ void main() { ...@@ -203,7 +204,7 @@ void main() {
await tapTest2and3(tester, widgetFinder, mockOnEndFunction); await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
}); });
testWidgets('AnimatedSlide transition test', (WidgetTester tester) async { testWidgetsWithLeakTracking('AnimatedSlide transition test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
switchKey: switchKey, switchKey: switchKey,
...@@ -241,7 +242,7 @@ void main() { ...@@ -241,7 +242,7 @@ void main() {
expect(state.builds, equals(2)); expect(state.builds, equals(2));
}); });
testWidgets('AnimatedScale onEnd callback test', (WidgetTester tester) async { testWidgetsWithLeakTracking('AnimatedScale onEnd callback test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
callback: mockOnEndFunction.handler, callback: mockOnEndFunction.handler,
...@@ -263,7 +264,7 @@ void main() { ...@@ -263,7 +264,7 @@ void main() {
await tapTest2and3(tester, widgetFinder, mockOnEndFunction); await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
}); });
testWidgets('AnimatedScale transition test', (WidgetTester tester) async { testWidgetsWithLeakTracking('AnimatedScale transition test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
switchKey: switchKey, switchKey: switchKey,
...@@ -301,7 +302,7 @@ void main() { ...@@ -301,7 +302,7 @@ void main() {
expect(state.builds, equals(2)); expect(state.builds, equals(2));
}); });
testWidgets('AnimatedRotation onEnd callback test', (WidgetTester tester) async { testWidgetsWithLeakTracking('AnimatedRotation onEnd callback test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
callback: mockOnEndFunction.handler, callback: mockOnEndFunction.handler,
...@@ -323,7 +324,7 @@ void main() { ...@@ -323,7 +324,7 @@ void main() {
await tapTest2and3(tester, widgetFinder, mockOnEndFunction); await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
}); });
testWidgets('AnimatedRotation transition test', (WidgetTester tester) async { testWidgetsWithLeakTracking('AnimatedRotation transition test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
switchKey: switchKey, switchKey: switchKey,
...@@ -361,7 +362,7 @@ void main() { ...@@ -361,7 +362,7 @@ void main() {
expect(state.builds, equals(2)); expect(state.builds, equals(2));
}); });
testWidgets('AnimatedOpacity onEnd callback test', (WidgetTester tester) async { testWidgetsWithLeakTracking('AnimatedOpacity onEnd callback test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
callback: mockOnEndFunction.handler, callback: mockOnEndFunction.handler,
...@@ -383,7 +384,7 @@ void main() { ...@@ -383,7 +384,7 @@ void main() {
await tapTest2and3(tester, widgetFinder, mockOnEndFunction); await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
}); });
testWidgets('AnimatedOpacity transition test', (WidgetTester tester) async { testWidgetsWithLeakTracking('AnimatedOpacity transition test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
switchKey: switchKey, switchKey: switchKey,
...@@ -421,7 +422,7 @@ void main() { ...@@ -421,7 +422,7 @@ void main() {
expect(state.builds, equals(2)); expect(state.builds, equals(2));
}); });
testWidgets('AnimatedFractionallySizedBox onEnd callback test', (WidgetTester tester) async { testWidgetsWithLeakTracking('AnimatedFractionallySizedBox onEnd callback test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
callback: mockOnEndFunction.handler, callback: mockOnEndFunction.handler,
...@@ -443,7 +444,7 @@ void main() { ...@@ -443,7 +444,7 @@ void main() {
await tapTest2and3(tester, widgetFinder, mockOnEndFunction); await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
}); });
testWidgets('SliverAnimatedOpacity onEnd callback test', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverAnimatedOpacity onEnd callback test', (WidgetTester tester) async {
await tester.pumpWidget(TestAnimatedWidget( await tester.pumpWidget(TestAnimatedWidget(
callback: mockOnEndFunction.handler, callback: mockOnEndFunction.handler,
switchKey: switchKey, switchKey: switchKey,
...@@ -464,7 +465,7 @@ void main() { ...@@ -464,7 +465,7 @@ void main() {
await tapTest2and3(tester, widgetFinder, mockOnEndFunction); await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
}); });
testWidgets('SliverAnimatedOpacity transition test', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverAnimatedOpacity transition test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
switchKey: switchKey, switchKey: switchKey,
...@@ -502,7 +503,7 @@ void main() { ...@@ -502,7 +503,7 @@ void main() {
expect(state.builds, equals(2)); expect(state.builds, equals(2));
}); });
testWidgets('AnimatedDefaultTextStyle onEnd callback test', (WidgetTester tester) async { testWidgetsWithLeakTracking('AnimatedDefaultTextStyle onEnd callback test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
callback: mockOnEndFunction.handler, callback: mockOnEndFunction.handler,
...@@ -525,7 +526,7 @@ void main() { ...@@ -525,7 +526,7 @@ void main() {
await tapTest2and3(tester, widgetFinder, mockOnEndFunction); await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
}); });
testWidgets('AnimatedPhysicalModel onEnd callback test', (WidgetTester tester) async { testWidgetsWithLeakTracking('AnimatedPhysicalModel onEnd callback test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
callback: mockOnEndFunction.handler, callback: mockOnEndFunction.handler,
...@@ -548,7 +549,7 @@ void main() { ...@@ -548,7 +549,7 @@ void main() {
await tapTest2and3(tester, widgetFinder, mockOnEndFunction); await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
}); });
testWidgets('TweenAnimationBuilder onEnd callback test', (WidgetTester tester) async { testWidgetsWithLeakTracking('TweenAnimationBuilder onEnd callback test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
callback: mockOnEndFunction.handler, callback: mockOnEndFunction.handler,
...@@ -571,7 +572,7 @@ void main() { ...@@ -571,7 +572,7 @@ void main() {
await tapTest2and3(tester, widgetFinder, mockOnEndFunction); await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
}); });
testWidgets('AnimatedTheme onEnd callback test', (WidgetTester tester) async { testWidgetsWithLeakTracking('AnimatedTheme onEnd callback test', (WidgetTester tester) async {
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: TestAnimatedWidget( child: TestAnimatedWidget(
callback: mockOnEndFunction.handler, callback: mockOnEndFunction.handler,
...@@ -594,11 +595,12 @@ void main() { ...@@ -594,11 +595,12 @@ void main() {
await tapTest2and3(tester, widgetFinder, mockOnEndFunction); await tapTest2and3(tester, widgetFinder, mockOnEndFunction);
}); });
testWidgets('Ensure CurvedAnimations are disposed on widget change', testWidgetsWithLeakTracking('Ensure CurvedAnimations are disposed on widget change',
(WidgetTester tester) async { (WidgetTester tester) async {
final GlobalKey<ImplicitlyAnimatedWidgetState<AnimatedOpacity>> key = final GlobalKey<ImplicitlyAnimatedWidgetState<AnimatedOpacity>> key =
GlobalKey<ImplicitlyAnimatedWidgetState<AnimatedOpacity>>(); GlobalKey<ImplicitlyAnimatedWidgetState<AnimatedOpacity>>();
final ValueNotifier<Curve> curve = ValueNotifier<Curve>(const Interval(0.0, 0.5)); final ValueNotifier<Curve> curve = ValueNotifier<Curve>(const Interval(0.0, 0.5));
addTearDown(curve.dispose);
await tester.pumpWidget(wrap( await tester.pumpWidget(wrap(
child: ValueListenableBuilder<Curve>( child: ValueListenableBuilder<Curve>(
valueListenable: curve, valueListenable: curve,
......
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
void main() { void main() {
testWidgets('Implicit Semantics merge behavior', (WidgetTester tester) async { testWidgetsWithLeakTracking('Implicit Semantics merge behavior', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget( await tester.pumpWidget(
...@@ -172,7 +173,7 @@ void main() { ...@@ -172,7 +173,7 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('Do not merge with conflicts', (WidgetTester tester) async { testWidgetsWithLeakTracking('Do not merge with conflicts', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget( await tester.pumpWidget(
......
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
import 'package:flutter/src/widgets/basic.dart'; import 'package:flutter/src/widgets/basic.dart';
import 'package:flutter/src/widgets/framework.dart'; import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() { void main() {
testWidgets('InheritedWidget dependencies show up in diagnostic properties', (WidgetTester tester) async { testWidgetsWithLeakTracking('InheritedWidget dependencies show up in diagnostic properties', (WidgetTester tester) async {
final GlobalKey key = GlobalKey(); final GlobalKey key = GlobalKey();
await tester.pumpWidget(Directionality( await tester.pumpWidget(Directionality(
key: key, key: key,
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
// A simple "flat" InheritedModel: the data model is just 3 integer // A simple "flat" InheritedModel: the data model is just 3 integer
// valued fields: a, b, c. // valued fields: a, b, c.
...@@ -73,7 +74,7 @@ class _ShowABCFieldState extends State<ShowABCField> { ...@@ -73,7 +74,7 @@ class _ShowABCFieldState extends State<ShowABCField> {
} }
void main() { void main() {
testWidgets('InheritedModel basics', (WidgetTester tester) async { testWidgetsWithLeakTracking('InheritedModel basics', (WidgetTester tester) async {
int a = 0; int a = 0;
int b = 1; int b = 1;
int c = 2; int c = 2;
...@@ -189,7 +190,7 @@ void main() { ...@@ -189,7 +190,7 @@ void main() {
expect(find.text('a: 2 b: 2 c: 3'), findsOneWidget); expect(find.text('a: 2 b: 2 c: 3'), findsOneWidget);
}); });
testWidgets('Looking up an non existent InheritedModel ancestor returns null', (WidgetTester tester) async { testWidgetsWithLeakTracking('Looking up an non existent InheritedModel ancestor returns null', (WidgetTester tester) async {
ABCModel? inheritedModel; ABCModel? inheritedModel;
await tester.pumpWidget( await tester.pumpWidget(
...@@ -205,7 +206,7 @@ void main() { ...@@ -205,7 +206,7 @@ void main() {
expect(inheritedModel, null); expect(inheritedModel, null);
}); });
testWidgets('Inner InheritedModel shadows the outer one', (WidgetTester tester) async { testWidgetsWithLeakTracking('Inner InheritedModel shadows the outer one', (WidgetTester tester) async {
int a = 0; int a = 0;
int b = 1; int b = 1;
int c = 2; int c = 2;
...@@ -323,7 +324,7 @@ void main() { ...@@ -323,7 +324,7 @@ void main() {
expect(find.text('a: 102 b: 102 c: null'), findsOneWidget); expect(find.text('a: 102 b: 102 c: null'), findsOneWidget);
}); });
testWidgets('InheritedModel inner models supported aspect change', (WidgetTester tester) async { testWidgetsWithLeakTracking('InheritedModel inner models supported aspect change', (WidgetTester tester) async {
int a = 0; int a = 0;
int b = 1; int b = 1;
int c = 2; int c = 2;
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'test_widgets.dart'; import 'test_widgets.dart';
...@@ -55,7 +56,7 @@ class ChangeNotifierInherited extends InheritedNotifier<ChangeNotifier> { ...@@ -55,7 +56,7 @@ class ChangeNotifierInherited extends InheritedNotifier<ChangeNotifier> {
} }
void main() { void main() {
testWidgets('Inherited notifies dependents', (WidgetTester tester) async { testWidgetsWithLeakTracking('Inherited notifies dependents', (WidgetTester tester) async {
final List<TestInherited> log = <TestInherited>[]; final List<TestInherited> log = <TestInherited>[];
final Builder builder = Builder( final Builder builder = Builder(
...@@ -81,7 +82,7 @@ void main() { ...@@ -81,7 +82,7 @@ void main() {
expect(log, equals(<TestInherited>[first, third])); expect(log, equals(<TestInherited>[first, third]));
}); });
testWidgets('Update inherited when reparenting state', (WidgetTester tester) async { testWidgetsWithLeakTracking('Update inherited when reparenting state', (WidgetTester tester) async {
final GlobalKey globalKey = GlobalKey(); final GlobalKey globalKey = GlobalKey();
final List<TestInherited> log = <TestInherited>[]; final List<TestInherited> log = <TestInherited>[];
...@@ -111,7 +112,7 @@ void main() { ...@@ -111,7 +112,7 @@ void main() {
expect(log, equals(<TestInherited>[first, second])); expect(log, equals(<TestInherited>[first, second]));
}); });
testWidgets('Update inherited when removing node', (WidgetTester tester) async { testWidgetsWithLeakTracking('Update inherited when removing node', (WidgetTester tester) async {
final List<String> log = <String>[]; final List<String> log = <String>[];
await tester.pumpWidget( await tester.pumpWidget(
...@@ -166,7 +167,7 @@ void main() { ...@@ -166,7 +167,7 @@ void main() {
log.clear(); log.clear();
}); });
testWidgets('Update inherited when removing node and child has global key', (WidgetTester tester) async { testWidgetsWithLeakTracking('Update inherited when removing node and child has global key', (WidgetTester tester) async {
final List<String> log = <String>[]; final List<String> log = <String>[];
...@@ -230,7 +231,7 @@ void main() { ...@@ -230,7 +231,7 @@ void main() {
log.clear(); log.clear();
}); });
testWidgets('Update inherited when removing node and child has global key with constant child', (WidgetTester tester) async { testWidgetsWithLeakTracking('Update inherited when removing node and child has global key with constant child', (WidgetTester tester) async {
final List<int> log = <int>[]; final List<int> log = <int>[];
final Key key = GlobalKey(); final Key key = GlobalKey();
...@@ -289,7 +290,7 @@ void main() { ...@@ -289,7 +290,7 @@ void main() {
log.clear(); log.clear();
}); });
testWidgets('Update inherited when removing node and child has global key with constant child, minimised', (WidgetTester tester) async { testWidgetsWithLeakTracking('Update inherited when removing node and child has global key with constant child, minimised', (WidgetTester tester) async {
final List<int> log = <int>[]; final List<int> log = <int>[];
...@@ -336,7 +337,7 @@ void main() { ...@@ -336,7 +337,7 @@ void main() {
log.clear(); log.clear();
}); });
testWidgets('Inherited widget notifies descendants when descendant previously failed to find a match', (WidgetTester tester) async { testWidgetsWithLeakTracking('Inherited widget notifies descendants when descendant previously failed to find a match', (WidgetTester tester) async {
int? inheritedValue = -1; int? inheritedValue = -1;
final Widget inner = Container( final Widget inner = Container(
...@@ -365,7 +366,7 @@ void main() { ...@@ -365,7 +366,7 @@ void main() {
expect(inheritedValue, equals(3)); expect(inheritedValue, equals(3));
}); });
testWidgets("Inherited widget doesn't notify descendants when descendant did not previously fail to find a match and had no dependencies", (WidgetTester tester) async { testWidgetsWithLeakTracking("Inherited widget doesn't notify descendants when descendant did not previously fail to find a match and had no dependencies", (WidgetTester tester) async {
int buildCount = 0; int buildCount = 0;
final Widget inner = Container( final Widget inner = Container(
...@@ -392,7 +393,7 @@ void main() { ...@@ -392,7 +393,7 @@ void main() {
expect(buildCount, equals(1)); expect(buildCount, equals(1));
}); });
testWidgets('Inherited widget does notify descendants when descendant did not previously fail to find a match but did have other dependencies', (WidgetTester tester) async { testWidgetsWithLeakTracking('Inherited widget does notify descendants when descendant did not previously fail to find a match but did have other dependencies', (WidgetTester tester) async {
int buildCount = 0; int buildCount = 0;
final Widget inner = Container( final Widget inner = Container(
...@@ -423,10 +424,11 @@ void main() { ...@@ -423,10 +424,11 @@ void main() {
expect(buildCount, equals(2)); expect(buildCount, equals(2));
}); });
testWidgets("BuildContext.getInheritedWidgetOfExactType doesn't create a dependency", (WidgetTester tester) async { testWidgetsWithLeakTracking("BuildContext.getInheritedWidgetOfExactType doesn't create a dependency", (WidgetTester tester) async {
int buildCount = 0; int buildCount = 0;
final GlobalKey<void> inheritedKey = GlobalKey(); final GlobalKey<void> inheritedKey = GlobalKey();
final ChangeNotifier notifier = ChangeNotifier(); final ChangeNotifier notifier = ChangeNotifier();
addTearDown(notifier.dispose);
final Widget builder = Builder( final Widget builder = Builder(
builder: (BuildContext context) { builder: (BuildContext context) {
...@@ -449,7 +451,7 @@ void main() { ...@@ -449,7 +451,7 @@ void main() {
expect(buildCount, equals(1)); expect(buildCount, equals(1));
}); });
testWidgets('initState() dependency on Inherited asserts', (WidgetTester tester) async { testWidgetsWithLeakTracking('initState() dependency on Inherited asserts', (WidgetTester tester) async {
// This is a regression test for https://github.com/flutter/flutter/issues/5491 // This is a regression test for https://github.com/flutter/flutter/issues/5491
bool exceptionCaught = false; bool exceptionCaught = false;
...@@ -461,9 +463,10 @@ void main() { ...@@ -461,9 +463,10 @@ void main() {
expect(exceptionCaught, isTrue); expect(exceptionCaught, isTrue);
}); });
testWidgets('InheritedNotifier', (WidgetTester tester) async { testWidgetsWithLeakTracking('InheritedNotifier', (WidgetTester tester) async {
int buildCount = 0; int buildCount = 0;
final ChangeNotifier notifier = ChangeNotifier(); final ChangeNotifier notifier = ChangeNotifier();
addTearDown(notifier.dispose);
final Widget builder = Builder( final Widget builder = Builder(
builder: (BuildContext context) { builder: (BuildContext context) {
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
class TestRoute extends PageRouteBuilder<void> { class TestRoute extends PageRouteBuilder<void> {
TestRoute(Widget child) : super( TestRoute(Widget child) : super(
...@@ -26,7 +27,7 @@ class IconTextBox extends StatelessWidget { ...@@ -26,7 +27,7 @@ class IconTextBox extends StatelessWidget {
} }
void main() { void main() {
testWidgets('InheritedTheme.captureAll()', (WidgetTester tester) async { testWidgetsWithLeakTracking('InheritedTheme.captureAll()', (WidgetTester tester) async {
const double fontSize = 32; const double fontSize = 32;
const double iconSize = 48; const double iconSize = 48;
const Color textColor = Color(0xFF00FF00); const Color textColor = Color(0xFF00FF00);
...@@ -146,7 +147,7 @@ void main() { ...@@ -146,7 +147,7 @@ void main() {
expect(getIconStyle().fontSize, iconSize); expect(getIconStyle().fontSize, iconSize);
}); });
testWidgets('InheritedTheme.captureAll() multiple IconTheme ancestors', (WidgetTester tester) async { testWidgetsWithLeakTracking('InheritedTheme.captureAll() multiple IconTheme ancestors', (WidgetTester tester) async {
// This is a regression test for https://github.com/flutter/flutter/issues/39087 // This is a regression test for https://github.com/flutter/flutter/issues/39087
const Color outerColor = Color(0xFF0000FF); const Color outerColor = Color(0xFF0000FF);
...@@ -206,7 +207,7 @@ void main() { ...@@ -206,7 +207,7 @@ void main() {
expect(getIconStyle(icon2).fontSize, iconSize); expect(getIconStyle(icon2).fontSize, iconSize);
}); });
testWidgets('InheritedTheme.captureAll() multiple DefaultTextStyle ancestors', (WidgetTester tester) async { testWidgetsWithLeakTracking('InheritedTheme.captureAll() multiple DefaultTextStyle ancestors', (WidgetTester tester) async {
// This is a regression test for https://github.com/flutter/flutter/issues/39087 // This is a regression test for https://github.com/flutter/flutter/issues/39087
const Color textColor = Color(0xFF00FF00); const Color textColor = Color(0xFF00FF00);
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
List<String> ancestors = <String>[]; List<String> ancestors = <String>[];
...@@ -28,7 +29,7 @@ class TestWidgetState extends State<TestWidget> { ...@@ -28,7 +29,7 @@ class TestWidgetState extends State<TestWidget> {
} }
void main() { void main() {
testWidgets('initState() is called when we are in the tree', (WidgetTester tester) async { testWidgetsWithLeakTracking('initState() is called when we are in the tree', (WidgetTester tester) async {
await tester.pumpWidget(const Parent(child: TestWidget())); await tester.pumpWidget(const Parent(child: TestWidget()));
expect(ancestors, containsAllInOrder(<String>['Parent', 'View', 'RootWidget'])); expect(ancestors, containsAllInOrder(<String>['Parent', 'View', 'RootWidget']));
}); });
......
...@@ -8,14 +8,24 @@ import 'package:flutter/gestures.dart'; ...@@ -8,14 +8,24 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'package:vector_math/vector_math_64.dart' show Matrix4, Quad, Vector3; import 'package:vector_math/vector_math_64.dart' show Matrix4, Quad, Vector3;
import 'gesture_utils.dart'; import 'gesture_utils.dart';
void main() { void main() {
group('InteractiveViewer', () { group('InteractiveViewer', () {
testWidgets('child fits in viewport', (WidgetTester tester) async { late TransformationController transformationController;
final TransformationController transformationController = TransformationController();
setUp(() {
transformationController = TransformationController();
});
tearDown(() {
transformationController.dispose();
});
testWidgetsWithLeakTracking('child fits in viewport', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -65,8 +75,7 @@ void main() { ...@@ -65,8 +75,7 @@ void main() {
expect(transformationController.value, isNot(equals(Matrix4.identity()))); expect(transformationController.value, isNot(equals(Matrix4.identity())));
}); });
testWidgets('boundary slightly bigger than child', (WidgetTester tester) async { testWidgetsWithLeakTracking('boundary slightly bigger than child', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
const double boundaryMargin = 10.0; const double boundaryMargin = 10.0;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -121,8 +130,7 @@ void main() { ...@@ -121,8 +130,7 @@ void main() {
expect(transformationController.value.getMaxScaleOnAxis(), 200.0 / 220.0); expect(transformationController.value.getMaxScaleOnAxis(), 200.0 / 220.0);
}); });
testWidgets('child bigger than viewport', (WidgetTester tester) async { testWidgetsWithLeakTracking('child bigger than viewport', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -197,8 +205,7 @@ void main() { ...@@ -197,8 +205,7 @@ void main() {
expect(transformationController.value, isNot(equals(Matrix4.identity()))); expect(transformationController.value, isNot(equals(Matrix4.identity())));
}); });
testWidgets('child has no dimensions', (WidgetTester tester) async { testWidgetsWithLeakTracking('child has no dimensions', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -232,8 +239,7 @@ void main() { ...@@ -232,8 +239,7 @@ void main() {
expect(tester.takeException(), isAssertionError); expect(tester.takeException(), isAssertionError);
}); });
testWidgets('no boundary', (WidgetTester tester) async { testWidgetsWithLeakTracking('no boundary', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
const double minScale = 0.8; const double minScale = 0.8;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -288,8 +294,7 @@ void main() { ...@@ -288,8 +294,7 @@ void main() {
expect(transformationController.value.getMaxScaleOnAxis(), minScale); expect(transformationController.value.getMaxScaleOnAxis(), minScale);
}); });
testWidgets('PanAxis.free allows panning in all directions for diagonal gesture', (WidgetTester tester) async { testWidgetsWithLeakTracking('PanAxis.free allows panning in all directions for diagonal gesture', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -326,8 +331,7 @@ void main() { ...@@ -326,8 +331,7 @@ void main() {
expect(translation.y, childOffset.dy - childInterior.dy); expect(translation.y, childOffset.dy - childInterior.dy);
}); });
testWidgets('PanAxis.aligned allows panning in one direction only for diagonal gesture', (WidgetTester tester) async { testWidgetsWithLeakTracking('PanAxis.aligned allows panning in one direction only for diagonal gesture', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -365,8 +369,7 @@ void main() { ...@@ -365,8 +369,7 @@ void main() {
expect(translation.y, childOffset.dy - childInterior.dy); expect(translation.y, childOffset.dy - childInterior.dy);
}); });
testWidgets('PanAxis.aligned allows panning in one direction only for horizontal leaning gesture', (WidgetTester tester) async { testWidgetsWithLeakTracking('PanAxis.aligned allows panning in one direction only for horizontal leaning gesture', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -404,8 +407,7 @@ void main() { ...@@ -404,8 +407,7 @@ void main() {
expect(translation.y, 0.0); expect(translation.y, 0.0);
}); });
testWidgets('PanAxis.horizontal allows panning in the horizontal direction only for diagonal gesture', (WidgetTester tester) async { testWidgetsWithLeakTracking('PanAxis.horizontal allows panning in the horizontal direction only for diagonal gesture', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -443,8 +445,7 @@ void main() { ...@@ -443,8 +445,7 @@ void main() {
expect(translation.y, 0.0); expect(translation.y, 0.0);
}); });
testWidgets('PanAxis.horizontal allows panning in the horizontal direction only for horizontal leaning gesture', (WidgetTester tester) async { testWidgetsWithLeakTracking('PanAxis.horizontal allows panning in the horizontal direction only for horizontal leaning gesture', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -482,8 +483,7 @@ void main() { ...@@ -482,8 +483,7 @@ void main() {
expect(translation.y, 0.0); expect(translation.y, 0.0);
}); });
testWidgets('PanAxis.horizontal does not allow panning in vertical direction on vertical gesture', (WidgetTester tester) async { testWidgetsWithLeakTracking('PanAxis.horizontal does not allow panning in vertical direction on vertical gesture', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -521,8 +521,7 @@ void main() { ...@@ -521,8 +521,7 @@ void main() {
expect(translation.y, 0.0); expect(translation.y, 0.0);
}); });
testWidgets('PanAxis.vertical allows panning in the vertical direction only for diagonal gesture', (WidgetTester tester) async { testWidgetsWithLeakTracking('PanAxis.vertical allows panning in the vertical direction only for diagonal gesture', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -560,8 +559,7 @@ void main() { ...@@ -560,8 +559,7 @@ void main() {
expect(translation.x, 0.0); expect(translation.x, 0.0);
}); });
testWidgets('PanAxis.vertical allows panning in the vertical direction only for vertical leaning gesture', (WidgetTester tester) async { testWidgetsWithLeakTracking('PanAxis.vertical allows panning in the vertical direction only for vertical leaning gesture', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -599,8 +597,7 @@ void main() { ...@@ -599,8 +597,7 @@ void main() {
expect(translation.x, 0.0); expect(translation.x, 0.0);
}); });
testWidgets('PanAxis.vertical does not allow panning in horizontal direction on vertical gesture', (WidgetTester tester) async { testWidgetsWithLeakTracking('PanAxis.vertical does not allow panning in horizontal direction on vertical gesture', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -638,8 +635,7 @@ void main() { ...@@ -638,8 +635,7 @@ void main() {
expect(translation.y, 0.0); expect(translation.y, 0.0);
}); });
testWidgets('inertia fling and boundary sliding', (WidgetTester tester) async { testWidgetsWithLeakTracking('inertia fling and boundary sliding', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
const double boundaryMargin = 50.0; const double boundaryMargin = 50.0;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -697,8 +693,7 @@ void main() { ...@@ -697,8 +693,7 @@ void main() {
expect(translation.y, moreOrLessEquals(boundaryMargin, epsilon: 1e-9)); expect(translation.y, moreOrLessEquals(boundaryMargin, epsilon: 1e-9));
}); });
testWidgets('Scaling automatically causes a centering translation', (WidgetTester tester) async { testWidgetsWithLeakTracking('Scaling automatically causes a centering translation', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
const double boundaryMargin = 50.0; const double boundaryMargin = 50.0;
const double minScale = 0.1; const double minScale = 0.1;
await tester.pumpWidget( await tester.pumpWidget(
...@@ -782,8 +777,7 @@ void main() { ...@@ -782,8 +777,7 @@ void main() {
expect(newSceneFocalPoint.dy, moreOrLessEquals(sceneFocalPoint.dy, epsilon: 1.0)); expect(newSceneFocalPoint.dy, moreOrLessEquals(sceneFocalPoint.dy, epsilon: 1.0));
}); });
testWidgets('Scaling automatically causes a centering translation even when alignPanAxis is set', (WidgetTester tester) async { testWidgetsWithLeakTracking('Scaling automatically causes a centering translation even when alignPanAxis is set', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
const double boundaryMargin = 50.0; const double boundaryMargin = 50.0;
const double minScale = 0.1; const double minScale = 0.1;
await tester.pumpWidget( await tester.pumpWidget(
...@@ -874,8 +868,7 @@ void main() { ...@@ -874,8 +868,7 @@ void main() {
expect(newSceneFocalPoint.dy, moreOrLessEquals(sceneFocalPoint.dy, epsilon: 1.0)); expect(newSceneFocalPoint.dy, moreOrLessEquals(sceneFocalPoint.dy, epsilon: 1.0));
}); });
testWidgets('Can scale with mouse', (WidgetTester tester) async { testWidgetsWithLeakTracking('Can scale with mouse', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -896,8 +889,7 @@ void main() { ...@@ -896,8 +889,7 @@ void main() {
expect(transformationController.value.getMaxScaleOnAxis(), greaterThan(1.0)); expect(transformationController.value.getMaxScaleOnAxis(), greaterThan(1.0));
}); });
testWidgets('Cannot scale with mouse when scale is disabled', (WidgetTester tester) async { testWidgetsWithLeakTracking('Cannot scale with mouse when scale is disabled', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -919,8 +911,7 @@ void main() { ...@@ -919,8 +911,7 @@ void main() {
expect(transformationController.value.getMaxScaleOnAxis(), equals(1.0)); expect(transformationController.value.getMaxScaleOnAxis(), equals(1.0));
}); });
testWidgets('Scale with mouse returns onInteraction properties', (WidgetTester tester) async{ testWidgetsWithLeakTracking('Scale with mouse returns onInteraction properties', (WidgetTester tester) async{
final TransformationController transformationController = TransformationController();
late Offset focalPoint; late Offset focalPoint;
late Offset localFocalPoint; late Offset localFocalPoint;
late double scaleChange; late double scaleChange;
...@@ -971,8 +962,7 @@ void main() { ...@@ -971,8 +962,7 @@ void main() {
expect(scenePoint, const Offset(100, 100)); expect(scenePoint, const Offset(100, 100));
}); });
testWidgets('Scaling amount is equal forth and back with a mouse scroll', (WidgetTester tester) async { testWidgetsWithLeakTracking('Scaling amount is equal forth and back with a mouse scroll', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -1003,8 +993,7 @@ void main() { ...@@ -1003,8 +993,7 @@ void main() {
expect(transformationController.value.getMaxScaleOnAxis(), 1.0); expect(transformationController.value.getMaxScaleOnAxis(), 1.0);
}); });
testWidgets('onInteraction can be used to get scene point', (WidgetTester tester) async{ testWidgetsWithLeakTracking('onInteraction can be used to get scene point', (WidgetTester tester) async{
final TransformationController transformationController = TransformationController();
late Offset focalPoint; late Offset focalPoint;
late Offset localFocalPoint; late Offset localFocalPoint;
late double scaleChange; late double scaleChange;
...@@ -1057,8 +1046,7 @@ void main() { ...@@ -1057,8 +1046,7 @@ void main() {
expect(scenePoint.dy, greaterThan(0.0)); expect(scenePoint.dy, greaterThan(0.0));
}); });
testWidgets('onInteraction is called even when disabled (touch)', (WidgetTester tester) async { testWidgetsWithLeakTracking('onInteraction is called even when disabled (touch)', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
bool calledStart = false; bool calledStart = false;
bool calledUpdate = false; bool calledUpdate = false;
bool calledEnd = false; bool calledEnd = false;
...@@ -1129,8 +1117,7 @@ void main() { ...@@ -1129,8 +1117,7 @@ void main() {
expect(calledEnd, isTrue); expect(calledEnd, isTrue);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.iOS })); }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.iOS }));
testWidgets('onInteraction is called even when disabled (mouse)', (WidgetTester tester) async { testWidgetsWithLeakTracking('onInteraction is called even when disabled (mouse)', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
bool calledStart = false; bool calledStart = false;
bool calledUpdate = false; bool calledUpdate = false;
bool calledEnd = false; bool calledEnd = false;
...@@ -1189,10 +1176,9 @@ void main() { ...@@ -1189,10 +1176,9 @@ void main() {
expect(calledEnd, isTrue); expect(calledEnd, isTrue);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.macOS, TargetPlatform.linux, TargetPlatform.windows })); }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.macOS, TargetPlatform.linux, TargetPlatform.windows }));
testWidgets('viewport changes size', (WidgetTester tester) async { testWidgetsWithLeakTracking('viewport changes size', (WidgetTester tester) async {
addTearDown(tester.view.reset); addTearDown(tester.view.reset);
final TransformationController transformationController = TransformationController();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -1239,8 +1225,7 @@ void main() { ...@@ -1239,8 +1225,7 @@ void main() {
expect(transformationController.value, equals(Matrix4.identity())); expect(transformationController.value, equals(Matrix4.identity()));
}); });
testWidgets('gesture can start as pan and become scale', (WidgetTester tester) async { testWidgetsWithLeakTracking('gesture can start as pan and become scale', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
const double boundaryMargin = 50.0; const double boundaryMargin = 50.0;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -1297,8 +1282,7 @@ void main() { ...@@ -1297,8 +1282,7 @@ void main() {
}); });
// Regression test for https://github.com/flutter/flutter/issues/65304 // Regression test for https://github.com/flutter/flutter/issues/65304
testWidgets('can view beyond boundary when necessary for a small child', (WidgetTester tester) async { testWidgetsWithLeakTracking('can view beyond boundary when necessary for a small child', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -1337,8 +1321,7 @@ void main() { ...@@ -1337,8 +1321,7 @@ void main() {
expect(transformationController.value, equals(Matrix4.identity())); expect(transformationController.value, equals(Matrix4.identity()));
}); });
testWidgets('scale does not jump when wrapped in GestureDetector', (WidgetTester tester) async { testWidgetsWithLeakTracking('scale does not jump when wrapped in GestureDetector', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
double? initialScale; double? initialScale;
double? scale; double? scale;
await tester.pumpWidget( await tester.pumpWidget(
...@@ -1413,7 +1396,7 @@ void main() { ...@@ -1413,7 +1396,7 @@ void main() {
expect(transformationController.value.getMaxScaleOnAxis(), greaterThan(1.0)); expect(transformationController.value.getMaxScaleOnAxis(), greaterThan(1.0));
}); });
testWidgets('Check if ClipRect is present in the tree', (WidgetTester tester) async { testWidgetsWithLeakTracking('Check if ClipRect is present in the tree', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -1454,8 +1437,7 @@ void main() { ...@@ -1454,8 +1437,7 @@ void main() {
); );
}); });
testWidgets('builder can change widgets that are off-screen', (WidgetTester tester) async { testWidgetsWithLeakTracking('builder can change widgets that are off-screen', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
const double childHeight = 10.0; const double childHeight = 10.0;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -1539,7 +1521,7 @@ void main() { ...@@ -1539,7 +1521,7 @@ void main() {
// Accessing the intrinsic size of a LayoutBuilder throws an error, so // Accessing the intrinsic size of a LayoutBuilder throws an error, so
// InteractiveViewer only uses a LayoutBuilder when it's needed by // InteractiveViewer only uses a LayoutBuilder when it's needed by
// InteractiveViewer.builder. // InteractiveViewer.builder.
testWidgets('LayoutBuilder is only used for InteractiveViewer.builder', (WidgetTester tester) async { testWidgetsWithLeakTracking('LayoutBuilder is only used for InteractiveViewer.builder', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -1571,9 +1553,8 @@ void main() { ...@@ -1571,9 +1553,8 @@ void main() {
expect(find.byType(LayoutBuilder), findsOneWidget); expect(find.byType(LayoutBuilder), findsOneWidget);
}); });
testWidgets('scaleFactor', (WidgetTester tester) async { testWidgetsWithLeakTracking('scaleFactor', (WidgetTester tester) async {
const double scrollAmount = 30.0; const double scrollAmount = 30.0;
final TransformationController transformationController = TransformationController();
Future<void> pumpScaleFactor(double scaleFactor) { Future<void> pumpScaleFactor(double scaleFactor) {
return tester.pumpWidget( return tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -1651,7 +1632,7 @@ void main() { ...@@ -1651,7 +1632,7 @@ void main() {
expect(scaleHighZoomedIn - scaleHighZoomedOut, lessThan(scaleZoomedIn - scaleZoomedOut)); expect(scaleHighZoomedIn - scaleHighZoomedOut, lessThan(scaleZoomedIn - scaleZoomedOut));
}); });
testWidgets('alignment argument is used properly', (WidgetTester tester) async { testWidgetsWithLeakTracking('alignment argument is used properly', (WidgetTester tester) async {
const Alignment alignment = Alignment.center; const Alignment alignment = Alignment.center;
await tester.pumpWidget(MaterialApp( await tester.pumpWidget(MaterialApp(
...@@ -1667,9 +1648,10 @@ void main() { ...@@ -1667,9 +1648,10 @@ void main() {
expect(transform.alignment, alignment); expect(transform.alignment, alignment);
}); });
testWidgets('interactionEndFrictionCoefficient', (WidgetTester tester) async { testWidgetsWithLeakTracking('interactionEndFrictionCoefficient', (WidgetTester tester) async {
// Use the default interactionEndFrictionCoefficient. // Use the default interactionEndFrictionCoefficient.
final TransformationController transformationController1 = TransformationController(); final TransformationController transformationController1 = TransformationController();
addTearDown(transformationController1.dispose);
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -1695,6 +1677,7 @@ void main() { ...@@ -1695,6 +1677,7 @@ void main() {
// Next try a custom interactionEndFrictionCoefficient. // Next try a custom interactionEndFrictionCoefficient.
final TransformationController transformationController2 = TransformationController(); final TransformationController transformationController2 = TransformationController();
addTearDown(transformationController2.dispose);
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
...@@ -1723,8 +1706,7 @@ void main() { ...@@ -1723,8 +1706,7 @@ void main() {
expect(translation2.y, lessThan(translation1.y)); expect(translation2.y, lessThan(translation1.y));
}); });
testWidgets('discrete scroll pointer events', (WidgetTester tester) async { testWidgetsWithLeakTracking('discrete scroll pointer events', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
const double boundaryMargin = 50.0; const double boundaryMargin = 50.0;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -1767,8 +1749,7 @@ void main() { ...@@ -1767,8 +1749,7 @@ void main() {
expect(translation.y, -125); expect(translation.y, -125);
}); });
testWidgets('discrete scale pointer event', (WidgetTester tester) async { testWidgetsWithLeakTracking('discrete scale pointer event', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
const double boundaryMargin = 50.0; const double boundaryMargin = 50.0;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -1804,8 +1785,7 @@ void main() { ...@@ -1804,8 +1785,7 @@ void main() {
expect(transformationController.value.getMaxScaleOnAxis(), 2.5); // capped at maxScale (2.5) expect(transformationController.value.getMaxScaleOnAxis(), 2.5); // capped at maxScale (2.5)
}); });
testWidgets('trackpadScrollCausesScale', (WidgetTester tester) async { testWidgetsWithLeakTracking('trackpadScrollCausesScale', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
const double boundaryMargin = 50.0; const double boundaryMargin = 50.0;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -1840,8 +1820,7 @@ void main() { ...@@ -1840,8 +1820,7 @@ void main() {
expect(transformationController.value.getMaxScaleOnAxis(), moreOrLessEquals(1.499302500056767)); expect(transformationController.value.getMaxScaleOnAxis(), moreOrLessEquals(1.499302500056767));
}); });
testWidgets('trackpad pointer scroll events cause scale', (WidgetTester tester) async { testWidgetsWithLeakTracking('trackpad pointer scroll events cause scale', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
const double boundaryMargin = 50.0; const double boundaryMargin = 50.0;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
...@@ -1891,8 +1870,7 @@ void main() { ...@@ -1891,8 +1870,7 @@ void main() {
expect(translation.y, moreOrLessEquals(-99.37155332430822)); expect(translation.y, moreOrLessEquals(-99.37155332430822));
}); });
testWidgets('Scaling inertia', (WidgetTester tester) async { testWidgetsWithLeakTracking('Scaling inertia', (WidgetTester tester) async {
final TransformationController transformationController = TransformationController();
const double boundaryMargin = 50.0; const double boundaryMargin = 50.0;
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
......
...@@ -4,9 +4,10 @@ ...@@ -4,9 +4,10 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() { void main() {
testWidgets('Intrinsic stepWidth, stepHeight', (WidgetTester tester) async { testWidgetsWithLeakTracking('Intrinsic stepWidth, stepHeight', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/25224 // Regression test for https://github.com/flutter/flutter/issues/25224
Widget buildFrame(double? stepWidth, double? stepHeight) { Widget buildFrame(double? stepWidth, double? stepHeight) {
return Center( return Center(
......
...@@ -10,9 +10,10 @@ library; ...@@ -10,9 +10,10 @@ library;
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() { void main() {
testWidgets('InvertColors', (WidgetTester tester) async { testWidgetsWithLeakTracking('InvertColors', (WidgetTester tester) async {
await tester.pumpWidget(const RepaintBoundary( await tester.pumpWidget(const RepaintBoundary(
child: SizedBox( child: SizedBox(
width: 200.0, width: 200.0,
...@@ -29,7 +30,7 @@ void main() { ...@@ -29,7 +30,7 @@ void main() {
); );
}); });
testWidgets('InvertColors and ColorFilter', (WidgetTester tester) async { testWidgetsWithLeakTracking('InvertColors and ColorFilter', (WidgetTester tester) async {
await tester.pumpWidget(const RepaintBoundary( await tester.pumpWidget(const RepaintBoundary(
child: SizedBox( child: SizedBox(
width: 200.0, width: 200.0,
......
...@@ -7,6 +7,7 @@ import 'dart:io' show Platform; ...@@ -7,6 +7,7 @@ import 'dart:io' show Platform;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
class Leaf extends StatefulWidget { class Leaf extends StatefulWidget {
const Leaf({ const Leaf({
...@@ -46,7 +47,7 @@ List<Widget> generateList(Widget child) { ...@@ -46,7 +47,7 @@ List<Widget> generateList(Widget child) {
} }
void main() { void main() {
testWidgets('KeepAlive with ListView with itemExtent', (WidgetTester tester) async { testWidgetsWithLeakTracking('KeepAlive with ListView with itemExtent', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -94,7 +95,7 @@ void main() { ...@@ -94,7 +95,7 @@ void main() {
expect(find.byKey(const GlobalObjectKey<_LeafState>(90), skipOffstage: false), findsNothing); expect(find.byKey(const GlobalObjectKey<_LeafState>(90), skipOffstage: false), findsNothing);
}); });
testWidgets('KeepAlive with ListView without itemExtent', (WidgetTester tester) async { testWidgetsWithLeakTracking('KeepAlive with ListView without itemExtent', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -141,7 +142,7 @@ void main() { ...@@ -141,7 +142,7 @@ void main() {
expect(find.byKey(const GlobalObjectKey<_LeafState>(90), skipOffstage: false), findsNothing); expect(find.byKey(const GlobalObjectKey<_LeafState>(90), skipOffstage: false), findsNothing);
}); });
testWidgets('KeepAlive with GridView', (WidgetTester tester) async { testWidgetsWithLeakTracking('KeepAlive with GridView', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -190,7 +191,7 @@ void main() { ...@@ -190,7 +191,7 @@ void main() {
expect(find.byKey(const GlobalObjectKey<_LeafState>(90), skipOffstage: false), findsNothing); expect(find.byKey(const GlobalObjectKey<_LeafState>(90), skipOffstage: false), findsNothing);
}); });
testWidgets('KeepAlive render tree description', (WidgetTester tester) async { testWidgetsWithLeakTracking('KeepAlive render tree description', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
class TestValueKey<T> extends ValueKey<T> { class TestValueKey<T> extends ValueKey<T> {
const TestValueKey(super.value); const TestValueKey(super.value);
...@@ -19,7 +20,7 @@ class NotEquals { ...@@ -19,7 +20,7 @@ class NotEquals {
} }
void main() { void main() {
testWidgets('Keys', (WidgetTester tester) async { testWidgetsWithLeakTracking('Keys', (WidgetTester tester) async {
expect(ValueKey<int>(nonconst(3)) == ValueKey<int>(nonconst(3)), isTrue); expect(ValueKey<int>(nonconst(3)) == ValueKey<int>(nonconst(3)), isTrue);
expect(ValueKey<num>(nonconst(3)) == ValueKey<int>(nonconst(3)), isFalse); expect(ValueKey<num>(nonconst(3)) == ValueKey<int>(nonconst(3)), isFalse);
expect(ValueKey<int>(nonconst(3)) == ValueKey<int>(nonconst(2)), isFalse); expect(ValueKey<int>(nonconst(3)) == ValueKey<int>(nonconst(2)), isFalse);
......
...@@ -5,19 +5,22 @@ ...@@ -5,19 +5,22 @@
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() { void main() {
testWidgets('Can dispose without keyboard', (WidgetTester tester) async { testWidgetsWithLeakTracking('Can dispose without keyboard', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
await tester.pumpWidget(KeyboardListener(focusNode: focusNode, child: Container())); await tester.pumpWidget(KeyboardListener(focusNode: focusNode, child: Container()));
await tester.pumpWidget(KeyboardListener(focusNode: focusNode, child: Container())); await tester.pumpWidget(KeyboardListener(focusNode: focusNode, child: Container()));
await tester.pumpWidget(Container()); await tester.pumpWidget(Container());
}); });
testWidgets('Fuchsia key event', (WidgetTester tester) async { testWidgetsWithLeakTracking('Fuchsia key event', (WidgetTester tester) async {
final List<KeyEvent> events = <KeyEvent>[]; final List<KeyEvent> events = <KeyEvent>[];
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
await tester.pumpWidget( await tester.pumpWidget(
KeyboardListener( KeyboardListener(
...@@ -39,13 +42,13 @@ void main() { ...@@ -39,13 +42,13 @@ void main() {
expect(events[0].logicalKey, LogicalKeyboardKey.metaLeft); expect(events[0].logicalKey, LogicalKeyboardKey.metaLeft);
await tester.pumpWidget(Container()); await tester.pumpWidget(Container());
focusNode.dispose();
}, skip: isBrowser); // [intended] This is a Fuchsia-specific test. }, skip: isBrowser); // [intended] This is a Fuchsia-specific test.
testWidgets('Web key event', (WidgetTester tester) async { testWidgetsWithLeakTracking('Web key event', (WidgetTester tester) async {
final List<KeyEvent> events = <KeyEvent>[]; final List<KeyEvent> events = <KeyEvent>[];
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
await tester.pumpWidget( await tester.pumpWidget(
KeyboardListener( KeyboardListener(
...@@ -67,13 +70,13 @@ void main() { ...@@ -67,13 +70,13 @@ void main() {
expect(events[0].logicalKey, LogicalKeyboardKey.metaLeft); expect(events[0].logicalKey, LogicalKeyboardKey.metaLeft);
await tester.pumpWidget(Container()); await tester.pumpWidget(Container());
focusNode.dispose();
}); });
testWidgets('Defunct listeners do not receive events', (WidgetTester tester) async { testWidgetsWithLeakTracking('Defunct listeners do not receive events', (WidgetTester tester) async {
final List<KeyEvent> events = <KeyEvent>[]; final List<KeyEvent> events = <KeyEvent>[];
final FocusNode focusNode = FocusNode(); final FocusNode focusNode = FocusNode();
addTearDown(focusNode.dispose);
await tester.pumpWidget( await tester.pumpWidget(
KeyboardListener( KeyboardListener(
...@@ -101,6 +104,5 @@ void main() { ...@@ -101,6 +104,5 @@ void main() {
expect(events.length, 0); expect(events.length, 0);
await tester.pumpWidget(Container()); await tester.pumpWidget(Container());
focusNode.dispose();
}); });
} }
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import 'package:flutter/src/rendering/sliver.dart'; import 'package:flutter/src/rendering/sliver.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
class Wrapper extends StatelessWidget { class Wrapper extends StatelessWidget {
const Wrapper({ const Wrapper({
...@@ -41,7 +42,7 @@ class StatefulWrapperState extends State<StatefulWrapper> { ...@@ -41,7 +42,7 @@ class StatefulWrapperState extends State<StatefulWrapper> {
} }
void main() { void main() {
testWidgets('Moving global key inside a LayoutBuilder', (WidgetTester tester) async { testWidgetsWithLeakTracking('Moving global key inside a LayoutBuilder', (WidgetTester tester) async {
final GlobalKey<StatefulWrapperState> key = GlobalKey<StatefulWrapperState>(); final GlobalKey<StatefulWrapperState> key = GlobalKey<StatefulWrapperState>();
await tester.pumpWidget( await tester.pumpWidget(
LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) { LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
...@@ -60,7 +61,7 @@ void main() { ...@@ -60,7 +61,7 @@ void main() {
expect(tester.takeException(), null); expect(tester.takeException(), null);
}); });
testWidgets('Moving global key inside a SliverLayoutBuilder', (WidgetTester tester) async { testWidgetsWithLeakTracking('Moving global key inside a SliverLayoutBuilder', (WidgetTester tester) async {
final GlobalKey<StatefulWrapperState> key = GlobalKey<StatefulWrapperState>(); final GlobalKey<StatefulWrapperState> key = GlobalKey<StatefulWrapperState>();
await tester.pumpWidget( await tester.pumpWidget(
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
class SizeChanger extends StatefulWidget { class SizeChanger extends StatefulWidget {
const SizeChanger({ const SizeChanger({
...@@ -42,7 +43,7 @@ class SizeChangerState extends State<SizeChanger> { ...@@ -42,7 +43,7 @@ class SizeChangerState extends State<SizeChanger> {
} }
void main() { void main() {
testWidgets('Applying parent data inside a LayoutBuilder', (WidgetTester tester) async { testWidgetsWithLeakTracking('Applying parent data inside a LayoutBuilder', (WidgetTester tester) async {
int frame = 1; int frame = 1;
await tester.pumpWidget(SizeChanger( // when this is triggered, the child LayoutBuilder will build again await tester.pumpWidget(SizeChanger( // when this is triggered, the child LayoutBuilder will build again
child: LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) { child: LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) {
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'test_widgets.dart'; import 'test_widgets.dart';
...@@ -49,7 +50,7 @@ class Wrapper extends StatelessWidget { ...@@ -49,7 +50,7 @@ class Wrapper extends StatelessWidget {
} }
void main() { void main() {
testWidgets('Calling setState on a widget that moves into a LayoutBuilder in the same frame', (WidgetTester tester) async { testWidgetsWithLeakTracking('Calling setState on a widget that moves into a LayoutBuilder in the same frame', (WidgetTester tester) async {
StatefulWrapperState statefulWrapper; StatefulWrapperState statefulWrapper;
final Widget inner = Wrapper( final Widget inner = Wrapper(
child: StatefulWrapper( child: StatefulWrapper(
......
...@@ -11,6 +11,7 @@ import 'package:flutter/src/widgets/media_query.dart'; ...@@ -11,6 +11,7 @@ import 'package:flutter/src/widgets/media_query.dart';
import 'package:flutter/src/widgets/scroll_view.dart'; import 'package:flutter/src/widgets/scroll_view.dart';
import 'package:flutter/src/widgets/sliver_layout_builder.dart'; import 'package:flutter/src/widgets/sliver_layout_builder.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
class Wrapper extends StatelessWidget { class Wrapper extends StatelessWidget {
const Wrapper({ const Wrapper({
...@@ -25,7 +26,7 @@ class Wrapper extends StatelessWidget { ...@@ -25,7 +26,7 @@ class Wrapper extends StatelessWidget {
} }
void main() { void main() {
testWidgets('Moving a global key from another LayoutBuilder at layout time', (WidgetTester tester) async { testWidgetsWithLeakTracking('Moving a global key from another LayoutBuilder at layout time', (WidgetTester tester) async {
final GlobalKey victimKey = GlobalKey(); final GlobalKey victimKey = GlobalKey();
await tester.pumpWidget(Row( await tester.pumpWidget(Row(
...@@ -71,7 +72,7 @@ void main() { ...@@ -71,7 +72,7 @@ void main() {
expect(tester.takeException(), null); expect(tester.takeException(), null);
}); });
testWidgets('Moving a global key from another SliverLayoutBuilder at layout time', (WidgetTester tester) async { testWidgetsWithLeakTracking('Moving a global key from another SliverLayoutBuilder at layout time', (WidgetTester tester) async {
final GlobalKey victimKey1 = GlobalKey(); final GlobalKey victimKey1 = GlobalKey();
final GlobalKey victimKey2 = GlobalKey(); final GlobalKey victimKey2 = GlobalKey();
...@@ -128,7 +129,7 @@ void main() { ...@@ -128,7 +129,7 @@ void main() {
expect(tester.takeException(), null); expect(tester.takeException(), null);
}); });
testWidgets('LayoutBuilder does not layout twice', (WidgetTester tester) async { testWidgetsWithLeakTracking('LayoutBuilder does not layout twice', (WidgetTester tester) async {
// This widget marks itself dirty when the closest MediaQuery changes. // This widget marks itself dirty when the closest MediaQuery changes.
final _LayoutCount widget = _LayoutCount(); final _LayoutCount widget = _LayoutCount();
late StateSetter setState; late StateSetter setState;
......
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() { void main() {
testWidgets('LayoutBuilder parent size', (WidgetTester tester) async { testWidgetsWithLeakTracking('LayoutBuilder parent size', (WidgetTester tester) async {
late Size layoutBuilderSize; late Size layoutBuilderSize;
final Key childKey = UniqueKey(); final Key childKey = UniqueKey();
final Key parentKey = UniqueKey(); final Key parentKey = UniqueKey();
...@@ -38,7 +39,7 @@ void main() { ...@@ -38,7 +39,7 @@ void main() {
expect(childBox.size, equals(const Size(50.0, 100.0))); expect(childBox.size, equals(const Size(50.0, 100.0)));
}); });
testWidgets('SliverLayoutBuilder parent geometry', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverLayoutBuilder parent geometry', (WidgetTester tester) async {
late SliverConstraints parentConstraints1; late SliverConstraints parentConstraints1;
late SliverConstraints parentConstraints2; late SliverConstraints parentConstraints2;
final Key childKey1 = UniqueKey(); final Key childKey1 = UniqueKey();
...@@ -88,7 +89,7 @@ void main() { ...@@ -88,7 +89,7 @@ void main() {
expect(childSliver2.geometry, parentSliver2.geometry); expect(childSliver2.geometry, parentSliver2.geometry);
}); });
testWidgets('LayoutBuilder stateful child', (WidgetTester tester) async { testWidgetsWithLeakTracking('LayoutBuilder stateful child', (WidgetTester tester) async {
late Size layoutBuilderSize; late Size layoutBuilderSize;
late StateSetter setState; late StateSetter setState;
final Key childKey = UniqueKey(); final Key childKey = UniqueKey();
...@@ -134,7 +135,7 @@ void main() { ...@@ -134,7 +135,7 @@ void main() {
expect(childBox.size, equals(const Size(100.0, 200.0))); expect(childBox.size, equals(const Size(100.0, 200.0)));
}); });
testWidgets('SliverLayoutBuilder stateful descendants', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverLayoutBuilder stateful descendants', (WidgetTester tester) async {
late StateSetter setState; late StateSetter setState;
double childWidth = 10.0; double childWidth = 10.0;
double childHeight = 20.0; double childHeight = 20.0;
...@@ -203,7 +204,7 @@ void main() { ...@@ -203,7 +204,7 @@ void main() {
expect(parentSliver.geometry!.paintExtent, 600); expect(parentSliver.geometry!.paintExtent, 600);
}); });
testWidgets('LayoutBuilder stateful parent', (WidgetTester tester) async { testWidgetsWithLeakTracking('LayoutBuilder stateful parent', (WidgetTester tester) async {
late Size layoutBuilderSize; late Size layoutBuilderSize;
late StateSetter setState; late StateSetter setState;
final Key childKey = UniqueKey(); final Key childKey = UniqueKey();
...@@ -247,7 +248,7 @@ void main() { ...@@ -247,7 +248,7 @@ void main() {
expect(box.size, equals(const Size(100.0, 200.0))); expect(box.size, equals(const Size(100.0, 200.0)));
}); });
testWidgets('LayoutBuilder and Inherited -- do not rebuild when not using inherited', (WidgetTester tester) async { testWidgetsWithLeakTracking('LayoutBuilder and Inherited -- do not rebuild when not using inherited', (WidgetTester tester) async {
int built = 0; int built = 0;
final Widget target = LayoutBuilder( final Widget target = LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) { builder: (BuildContext context, BoxConstraints constraints) {
...@@ -270,7 +271,7 @@ void main() { ...@@ -270,7 +271,7 @@ void main() {
expect(built, 1); expect(built, 1);
}); });
testWidgets('LayoutBuilder and Inherited -- do rebuild when using inherited', (WidgetTester tester) async { testWidgetsWithLeakTracking('LayoutBuilder and Inherited -- do rebuild when using inherited', (WidgetTester tester) async {
int built = 0; int built = 0;
final Widget target = LayoutBuilder( final Widget target = LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) { builder: (BuildContext context, BoxConstraints constraints) {
...@@ -294,7 +295,7 @@ void main() { ...@@ -294,7 +295,7 @@ void main() {
expect(built, 2); expect(built, 2);
}); });
testWidgets('SliverLayoutBuilder and Inherited -- do not rebuild when not using inherited', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverLayoutBuilder and Inherited -- do not rebuild when not using inherited', (WidgetTester tester) async {
int built = 0; int built = 0;
final Widget target = Directionality( final Widget target = Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -325,7 +326,7 @@ void main() { ...@@ -325,7 +326,7 @@ void main() {
expect(built, 1); expect(built, 1);
}); });
testWidgets( testWidgetsWithLeakTracking(
'SliverLayoutBuilder and Inherited -- do rebuild when not using inherited', 'SliverLayoutBuilder and Inherited -- do rebuild when not using inherited',
(WidgetTester tester) async { (WidgetTester tester) async {
int built = 0; int built = 0;
...@@ -360,7 +361,7 @@ void main() { ...@@ -360,7 +361,7 @@ void main() {
}, },
); );
testWidgets('nested SliverLayoutBuilder', (WidgetTester tester) async { testWidgetsWithLeakTracking('nested SliverLayoutBuilder', (WidgetTester tester) async {
late SliverConstraints parentConstraints1; late SliverConstraints parentConstraints1;
late SliverConstraints parentConstraints2; late SliverConstraints parentConstraints2;
final Key childKey = UniqueKey(); final Key childKey = UniqueKey();
...@@ -405,10 +406,11 @@ void main() { ...@@ -405,10 +406,11 @@ void main() {
expect(parentSliver1.geometry, parentSliver2.geometry); expect(parentSliver1.geometry, parentSliver2.geometry);
}); });
testWidgets('localToGlobal works with SliverLayoutBuilder', (WidgetTester tester) async { testWidgetsWithLeakTracking('localToGlobal works with SliverLayoutBuilder', (WidgetTester tester) async {
final Key childKey1 = UniqueKey(); final Key childKey1 = UniqueKey();
final Key childKey2 = UniqueKey(); final Key childKey2 = UniqueKey();
final ScrollController scrollController = ScrollController(); final ScrollController scrollController = ScrollController();
addTearDown(scrollController.dispose);
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
...@@ -461,8 +463,9 @@ void main() { ...@@ -461,8 +463,9 @@ void main() {
); );
}); });
testWidgets('hitTest works within SliverLayoutBuilder', (WidgetTester tester) async { testWidgetsWithLeakTracking('hitTest works within SliverLayoutBuilder', (WidgetTester tester) async {
final ScrollController scrollController = ScrollController(); final ScrollController scrollController = ScrollController();
addTearDown(scrollController.dispose);
List<int> hitCounts = <int> [0, 0, 0]; List<int> hitCounts = <int> [0, 0, 0];
await tester.pumpWidget( await tester.pumpWidget(
...@@ -589,7 +592,7 @@ void main() { ...@@ -589,7 +592,7 @@ void main() {
expect(hitCounts, const <int> [0, 0, 0]); expect(hitCounts, const <int> [0, 0, 0]);
}); });
testWidgets('LayoutBuilder does not call builder when layout happens but layout constraints do not change', (WidgetTester tester) async { testWidgetsWithLeakTracking('LayoutBuilder does not call builder when layout happens but layout constraints do not change', (WidgetTester tester) async {
int builderInvocationCount = 0; int builderInvocationCount = 0;
Future<void> pumpTestWidget(Size size) async { Future<void> pumpTestWidget(Size size) async {
...@@ -665,7 +668,7 @@ void main() { ...@@ -665,7 +668,7 @@ void main() {
expect(spy.performResizeCount, 2); expect(spy.performResizeCount, 2);
}); });
testWidgets('LayoutBuilder descendant widget can access [RenderBox.size] when rebuilding during layout', (WidgetTester tester) async { testWidgetsWithLeakTracking('LayoutBuilder descendant widget can access [RenderBox.size] when rebuilding during layout', (WidgetTester tester) async {
Size? childSize; Size? childSize;
int buildCount = 0; int buildCount = 0;
......
...@@ -14,6 +14,7 @@ import 'dart:math' as math; ...@@ -14,6 +14,7 @@ import 'dart:math' as math;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
class LinkedScrollController extends ScrollController { class LinkedScrollController extends ScrollController {
LinkedScrollController({ this.before, this.after }); LinkedScrollController({ this.before, this.after });
...@@ -381,7 +382,7 @@ class _TestState extends State<Test> { ...@@ -381,7 +382,7 @@ class _TestState extends State<Test> {
} }
void main() { void main() {
testWidgets('LinkedScrollController - 1', (WidgetTester tester) async { testWidgetsWithLeakTracking('LinkedScrollController - 1', (WidgetTester tester) async {
await tester.pumpWidget(const Test()); await tester.pumpWidget(const Test());
expect(find.text('Hello A'), findsOneWidget); expect(find.text('Hello A'), findsOneWidget);
expect(find.text('Hello 1'), findsOneWidget); expect(find.text('Hello 1'), findsOneWidget);
...@@ -459,7 +460,7 @@ void main() { ...@@ -459,7 +460,7 @@ void main() {
expect(find.text('Hello D'), findsNothing); expect(find.text('Hello D'), findsNothing);
expect(find.text('Hello 4'), findsOneWidget); expect(find.text('Hello 4'), findsOneWidget);
}); });
testWidgets('LinkedScrollController - 2', (WidgetTester tester) async { testWidgetsWithLeakTracking('LinkedScrollController - 2', (WidgetTester tester) async {
await tester.pumpWidget(const Test()); await tester.pumpWidget(const Test());
expect(find.text('Hello A'), findsOneWidget); expect(find.text('Hello A'), findsOneWidget);
expect(find.text('Hello B'), findsOneWidget); expect(find.text('Hello B'), findsOneWidget);
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
import 'package:flutter/src/foundation/assertions.dart'; import 'package:flutter/src/foundation/assertions.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
const List<Widget> children = <Widget>[ const List<Widget> children = <Widget>[
SizedBox(width: 200.0, height: 150.0), SizedBox(width: 200.0, height: 150.0),
...@@ -29,7 +30,7 @@ void expectRects(WidgetTester tester, List<Rect> expected) { ...@@ -29,7 +30,7 @@ void expectRects(WidgetTester tester, List<Rect> expected) {
void main() { void main() {
testWidgets('ListBody down', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListBody down', (WidgetTester tester) async {
await tester.pumpWidget(const Flex( await tester.pumpWidget(const Flex(
direction: Axis.vertical, direction: Axis.vertical,
children: <Widget>[ ListBody(children: children) ], children: <Widget>[ ListBody(children: children) ],
...@@ -46,7 +47,7 @@ void main() { ...@@ -46,7 +47,7 @@ void main() {
); );
}); });
testWidgets('ListBody up', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListBody up', (WidgetTester tester) async {
await tester.pumpWidget(const Flex( await tester.pumpWidget(const Flex(
direction: Axis.vertical, direction: Axis.vertical,
children: <Widget>[ ListBody(reverse: true, children: children) ], children: <Widget>[ ListBody(reverse: true, children: children) ],
...@@ -63,7 +64,7 @@ void main() { ...@@ -63,7 +64,7 @@ void main() {
); );
}); });
testWidgets('ListBody right', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListBody right', (WidgetTester tester) async {
await tester.pumpWidget(const Flex( await tester.pumpWidget(const Flex(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
direction: Axis.horizontal, direction: Axis.horizontal,
...@@ -86,7 +87,7 @@ void main() { ...@@ -86,7 +87,7 @@ void main() {
); );
}); });
testWidgets('ListBody left', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListBody left', (WidgetTester tester) async {
await tester.pumpWidget(const Flex( await tester.pumpWidget(const Flex(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
direction: Axis.horizontal, direction: Axis.horizontal,
...@@ -109,7 +110,7 @@ void main() { ...@@ -109,7 +110,7 @@ void main() {
); );
}); });
testWidgets('Limited space along main axis error', (WidgetTester tester) async { testWidgetsWithLeakTracking('Limited space along main axis error', (WidgetTester tester) async {
final FlutterExceptionHandler oldHandler = FlutterError.onError!; final FlutterExceptionHandler oldHandler = FlutterError.onError!;
final List<FlutterErrorDetails> errors = <FlutterErrorDetails>[]; final List<FlutterErrorDetails> errors = <FlutterErrorDetails>[];
FlutterError.onError = (FlutterErrorDetails error) => errors.add(error); FlutterError.onError = (FlutterErrorDetails error) => errors.add(error);
...@@ -142,7 +143,7 @@ void main() { ...@@ -142,7 +143,7 @@ void main() {
)); ));
}); });
testWidgets('Nested ListBody unbounded cross axis error', (WidgetTester tester) async { testWidgetsWithLeakTracking('Nested ListBody unbounded cross axis error', (WidgetTester tester) async {
final FlutterExceptionHandler oldHandler = FlutterError.onError!; final FlutterExceptionHandler oldHandler = FlutterError.onError!;
final List<FlutterErrorDetails> errors = <FlutterErrorDetails>[]; final List<FlutterErrorDetails> errors = <FlutterErrorDetails>[];
FlutterError.onError = (FlutterErrorDetails error) => errors.add(error); FlutterError.onError = (FlutterErrorDetails error) => errors.add(error);
......
...@@ -4,11 +4,12 @@ ...@@ -4,11 +4,12 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'test_widgets.dart'; import 'test_widgets.dart';
void main() { void main() {
testWidgets('ListView.builder mount/dismount smoke test', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView.builder mount/dismount smoke test', (WidgetTester tester) async {
final List<int> callbackTracker = <int>[]; final List<int> callbackTracker = <int>[];
// the root view is 800x600 in the test environment // the root view is 800x600 in the test environment
...@@ -61,7 +62,7 @@ void main() { ...@@ -61,7 +62,7 @@ void main() {
check(visible: <int>[0, 1, 2, 3, 4, 5], hidden: <int>[ 6, 7, 8]); check(visible: <int>[0, 1, 2, 3, 4, 5], hidden: <int>[ 6, 7, 8]);
}); });
testWidgets('ListView.builder vertical', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView.builder vertical', (WidgetTester tester) async {
final List<int> callbackTracker = <int>[]; final List<int> callbackTracker = <int>[];
// the root view is 800x600 in the test environment // the root view is 800x600 in the test environment
...@@ -79,11 +80,14 @@ void main() { ...@@ -79,11 +80,14 @@ void main() {
} }
Widget buildWidget() { Widget buildWidget() {
final ScrollController controller = ScrollController(initialScrollOffset: 300.0);
addTearDown(controller.dispose);
return Directionality( return Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: FlipWidget( child: FlipWidget(
left: ListView.builder( left: ListView.builder(
controller: ScrollController(initialScrollOffset: 300.0), controller: controller,
itemExtent: 200.0, itemExtent: 200.0,
itemBuilder: itemBuilder, itemBuilder: itemBuilder,
), ),
...@@ -134,7 +138,7 @@ void main() { ...@@ -134,7 +138,7 @@ void main() {
callbackTracker.clear(); callbackTracker.clear();
}); });
testWidgets('ListView.builder horizontal', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView.builder horizontal', (WidgetTester tester) async {
final List<int> callbackTracker = <int>[]; final List<int> callbackTracker = <int>[];
// the root view is 800x600 in the test environment // the root view is 800x600 in the test environment
...@@ -152,11 +156,14 @@ void main() { ...@@ -152,11 +156,14 @@ void main() {
} }
Widget buildWidget() { Widget buildWidget() {
final ScrollController controller = ScrollController(initialScrollOffset: 300.0);
addTearDown(controller.dispose);
return Directionality( return Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: FlipWidget( child: FlipWidget(
left: ListView.builder( left: ListView.builder(
controller: ScrollController(initialScrollOffset: 300.0), controller: controller,
itemBuilder: itemBuilder, itemBuilder: itemBuilder,
itemExtent: 200.0, itemExtent: 200.0,
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
...@@ -208,7 +215,7 @@ void main() { ...@@ -208,7 +215,7 @@ void main() {
callbackTracker.clear(); callbackTracker.clear();
}); });
testWidgets('ListView.builder 10 items, 2-3 items visible', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView.builder 10 items, 2-3 items visible', (WidgetTester tester) async {
final List<int> callbackTracker = <int>[]; final List<int> callbackTracker = <int>[];
// The root view is 800x600 in the test environment and our list // The root view is 800x600 in the test environment and our list
...@@ -261,7 +268,7 @@ void main() { ...@@ -261,7 +268,7 @@ void main() {
callbackTracker.clear(); callbackTracker.clear();
}); });
testWidgets('ListView.builder 30 items with big jump, using prototypeItem', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView.builder 30 items with big jump, using prototypeItem', (WidgetTester tester) async {
final List<int> callbackTracker = <int>[]; final List<int> callbackTracker = <int>[];
// The root view is 800x600 in the test environment and our list // The root view is 800x600 in the test environment and our list
...@@ -309,7 +316,7 @@ void main() { ...@@ -309,7 +316,7 @@ void main() {
callbackTracker.clear(); callbackTracker.clear();
}); });
testWidgets('ListView.separated', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView.separated', (WidgetTester tester) async {
Widget buildFrame({ required int itemCount }) { Widget buildFrame({ required int itemCount }) {
return Directionality( return Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -355,7 +362,7 @@ void main() { ...@@ -355,7 +362,7 @@ void main() {
}); });
testWidgets('ListView.separated uses correct semanticChildCount', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView.separated uses correct semanticChildCount', (WidgetTester tester) async {
Widget buildFrame({ required int itemCount}) { Widget buildFrame({ required int itemCount}) {
return Directionality( return Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -403,7 +410,7 @@ void main() { ...@@ -403,7 +410,7 @@ void main() {
}); });
// Regression test for https://github.com/flutter/flutter/issues/72292 // Regression test for https://github.com/flutter/flutter/issues/72292
testWidgets('ListView.builder and SingleChildScrollView can work well together', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView.builder and SingleChildScrollView can work well together', (WidgetTester tester) async {
Widget builder(int itemCount) { Widget builder(int itemCount) {
return Directionality( return Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
......
...@@ -4,10 +4,13 @@ ...@@ -4,10 +4,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() { void main() {
testWidgets('ListView can handle shrinking top elements', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView can handle shrinking top elements', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -65,8 +68,10 @@ void main() { ...@@ -65,8 +68,10 @@ void main() {
expect(tester.getTopLeft(find.text('2')).dy, equals(200.0)); expect(tester.getTopLeft(find.text('2')).dy, equals(200.0));
}); });
testWidgets('ListView can handle shrinking top elements with cache extent', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView can handle shrinking top elements with cache extent', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -122,8 +127,10 @@ void main() { ...@@ -122,8 +127,10 @@ void main() {
expect(tester.getTopLeft(find.text('2')).dy, equals(150.0)); expect(tester.getTopLeft(find.text('2')).dy, equals(150.0));
}); });
testWidgets('ListView can handle inserts at 0', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView can handle inserts at 0', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
......
...@@ -4,12 +4,13 @@ ...@@ -4,12 +4,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
const double kHeight = 10.0; const double kHeight = 10.0;
const double kFlingOffset = kHeight * 20.0; const double kFlingOffset = kHeight * 20.0;
void main() { void main() {
testWidgets("Flings don't stutter", (WidgetTester tester) async { testWidgetsWithLeakTracking("Flings don't stutter", (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
const List<int> items = <int>[0, 1, 2, 3, 4, 5]; const List<int> items = <int>[0, 1, 2, 3, 4, 5];
...@@ -28,7 +29,7 @@ Widget buildFrame({ bool reverse = false, required TextDirection textDirection } ...@@ -28,7 +29,7 @@ Widget buildFrame({ bool reverse = false, required TextDirection textDirection }
} }
void main() { void main() {
testWidgets('Drag horizontally with scroll anchor at start (LTR)', (WidgetTester tester) async { testWidgetsWithLeakTracking('Drag horizontally with scroll anchor at start (LTR)', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(textDirection: TextDirection.ltr)); await tester.pumpWidget(buildFrame(textDirection: TextDirection.ltr));
await tester.pump(const Duration(seconds: 1)); await tester.pump(const Duration(seconds: 1));
...@@ -147,7 +148,7 @@ void main() { ...@@ -147,7 +148,7 @@ void main() {
expect(find.text('5'), findsNothing); expect(find.text('5'), findsNothing);
}); });
testWidgets('Drag horizontally with scroll anchor at end (LTR)', (WidgetTester tester) async { testWidgetsWithLeakTracking('Drag horizontally with scroll anchor at end (LTR)', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(reverse: true, textDirection: TextDirection.ltr)); await tester.pumpWidget(buildFrame(reverse: true, textDirection: TextDirection.ltr));
await tester.pump(const Duration(seconds: 1)); await tester.pump(const Duration(seconds: 1));
...@@ -247,7 +248,7 @@ void main() { ...@@ -247,7 +248,7 @@ void main() {
expect(find.text('5'), findsOneWidget); expect(find.text('5'), findsOneWidget);
}); });
testWidgets('Drag horizontally with scroll anchor at start (RTL)', (WidgetTester tester) async { testWidgetsWithLeakTracking('Drag horizontally with scroll anchor at start (RTL)', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(textDirection: TextDirection.rtl)); await tester.pumpWidget(buildFrame(textDirection: TextDirection.rtl));
await tester.pump(const Duration(seconds: 1)); await tester.pump(const Duration(seconds: 1));
...@@ -347,7 +348,7 @@ void main() { ...@@ -347,7 +348,7 @@ void main() {
expect(find.text('5'), findsOneWidget); expect(find.text('5'), findsOneWidget);
}); });
testWidgets('Drag horizontally with scroll anchor at end (LTR)', (WidgetTester tester) async { testWidgetsWithLeakTracking('Drag horizontally with scroll anchor at end (LTR)', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame(reverse: true, textDirection: TextDirection.rtl)); await tester.pumpWidget(buildFrame(reverse: true, textDirection: TextDirection.rtl));
await tester.pump(const Duration(seconds: 1)); await tester.pump(const Duration(seconds: 1));
......
...@@ -4,11 +4,12 @@ ...@@ -4,11 +4,12 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
const Key blockKey = Key('test'); const Key blockKey = Key('test');
void main() { void main() {
testWidgets('Cannot scroll a non-overflowing block', (WidgetTester tester) async { testWidgetsWithLeakTracking('Cannot scroll a non-overflowing block', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -36,7 +37,7 @@ void main() { ...@@ -36,7 +37,7 @@ void main() {
await gesture.up(); await gesture.up();
}); });
testWidgets('Can scroll an overflowing block', (WidgetTester tester) async { testWidgetsWithLeakTracking('Can scroll an overflowing block', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -67,7 +68,7 @@ void main() { ...@@ -67,7 +68,7 @@ void main() {
await gesture.up(); await gesture.up();
}); });
testWidgets('ListView reverse', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView reverse', (WidgetTester tester) async {
int first = 0; int first = 0;
int second = 0; int second = 0;
...@@ -111,8 +112,9 @@ void main() { ...@@ -111,8 +112,9 @@ void main() {
expect(second, equals(1)); expect(second, equals(1));
}); });
testWidgets('ListView controller', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView controller', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
Widget buildBlock() { Widget buildBlock() {
return Directionality( return Directionality(
...@@ -127,7 +129,7 @@ void main() { ...@@ -127,7 +129,7 @@ void main() {
expect(controller.offset, equals(0.0)); expect(controller.offset, equals(0.0));
}); });
testWidgets('SliverBlockChildListDelegate.estimateMaxScrollOffset hits end', (WidgetTester tester) async { testWidgetsWithLeakTracking('SliverBlockChildListDelegate.estimateMaxScrollOffset hits end', (WidgetTester tester) async {
final SliverChildListDelegate delegate = SliverChildListDelegate(<Widget>[ final SliverChildListDelegate delegate = SliverChildListDelegate(<Widget>[
Container(), Container(),
Container(), Container(),
...@@ -161,7 +163,7 @@ void main() { ...@@ -161,7 +163,7 @@ void main() {
expect(maxScrollOffset, equals(26.0)); expect(maxScrollOffset, equals(26.0));
}); });
testWidgets('Resizing a ListView child restores scroll offset', (WidgetTester tester) async { testWidgetsWithLeakTracking('Resizing a ListView child restores scroll offset', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/9221 // Regression test for https://github.com/flutter/flutter/issues/9221
final AnimationController controller = AnimationController( final AnimationController controller = AnimationController(
vsync: const TestVSync(), vsync: const TestVSync(),
......
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() { void main() {
testWidgets('Nested ListView with shrinkWrap', (WidgetTester tester) async { testWidgetsWithLeakTracking('Nested ListView with shrinkWrap', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -36,7 +37,7 @@ void main() { ...@@ -36,7 +37,7 @@ void main() {
); );
}); });
testWidgets('Underflowing ListView should relayout for additional children', (WidgetTester tester) async { testWidgetsWithLeakTracking('Underflowing ListView should relayout for additional children', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/5950 // Regression test for https://github.com/flutter/flutter/issues/5950
await tester.pumpWidget( await tester.pumpWidget(
...@@ -65,7 +66,7 @@ void main() { ...@@ -65,7 +66,7 @@ void main() {
expect(find.text('200'), findsOneWidget); expect(find.text('200'), findsOneWidget);
}); });
testWidgets('Underflowing ListView contentExtent should track additional children', (WidgetTester tester) async { testWidgetsWithLeakTracking('Underflowing ListView contentExtent should track additional children', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -102,7 +103,7 @@ void main() { ...@@ -102,7 +103,7 @@ void main() {
expect(list.geometry!.scrollExtent, equals(0.0)); expect(list.geometry!.scrollExtent, equals(0.0));
}); });
testWidgets('Overflowing ListView should relayout for missing children', (WidgetTester tester) async { testWidgetsWithLeakTracking('Overflowing ListView should relayout for missing children', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -143,7 +144,7 @@ void main() { ...@@ -143,7 +144,7 @@ void main() {
expect(find.text('400'), findsNothing); expect(find.text('400'), findsNothing);
}); });
testWidgets('Overflowing ListView should not relayout for additional children', (WidgetTester tester) async { testWidgetsWithLeakTracking('Overflowing ListView should not relayout for additional children', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -177,7 +178,7 @@ void main() { ...@@ -177,7 +178,7 @@ void main() {
expect(find.text('100'), findsNothing); expect(find.text('100'), findsNothing);
}); });
testWidgets('Overflowing ListView should become scrollable', (WidgetTester tester) async { testWidgetsWithLeakTracking('Overflowing ListView should become scrollable', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/5920 // Regression test for https://github.com/flutter/flutter/issues/5920
// When a ListView's viewport hasn't overflowed, scrolling is disabled. // When a ListView's viewport hasn't overflowed, scrolling is disabled.
// When children are added that cause it to overflow, scrolling should // When children are added that cause it to overflow, scrolling should
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'semantics_tester.dart'; import 'semantics_tester.dart';
...@@ -14,9 +15,10 @@ void main() { ...@@ -14,9 +15,10 @@ void main() {
const int itemCount = 10; const int itemCount = 10;
const double itemHeight = 150.0; const double itemHeight = 150.0;
testWidgets('forward vertical', (WidgetTester tester) async { testWidgetsWithLeakTracking('forward vertical', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
...@@ -44,9 +46,10 @@ void main() { ...@@ -44,9 +46,10 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('reverse vertical', (WidgetTester tester) async { testWidgetsWithLeakTracking('reverse vertical', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
...@@ -75,9 +78,10 @@ void main() { ...@@ -75,9 +78,10 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('forward horizontal', (WidgetTester tester) async { testWidgetsWithLeakTracking('forward horizontal', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
...@@ -106,9 +110,10 @@ void main() { ...@@ -106,9 +110,10 @@ void main() {
semantics.dispose(); semantics.dispose();
}); });
testWidgets('reverse horizontal', (WidgetTester tester) async { testWidgetsWithLeakTracking('reverse horizontal', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester); final SemanticsTester semantics = SemanticsTester(tester);
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
......
...@@ -6,6 +6,7 @@ import 'package:collection/collection.dart'; ...@@ -6,6 +6,7 @@ import 'package:collection/collection.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.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 '../rendering/rendering_tester.dart' show TestClipPaintingContext;
...@@ -77,7 +78,7 @@ class _StatefulListViewState extends State<_StatefulListView> { ...@@ -77,7 +78,7 @@ class _StatefulListViewState extends State<_StatefulListView> {
void main() { void main() {
// Regression test for https://github.com/flutter/flutter/issues/100451 // Regression test for https://github.com/flutter/flutter/issues/100451
testWidgets('ListView.builder respects findChildIndexCallback', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView.builder respects findChildIndexCallback', (WidgetTester tester) async {
bool finderCalled = false; bool finderCalled = false;
int itemCount = 7; int itemCount = 7;
late StateSetter stateSetter; late StateSetter stateSetter;
...@@ -113,7 +114,7 @@ void main() { ...@@ -113,7 +114,7 @@ void main() {
}); });
// Regression test for https://github.com/flutter/flutter/issues/100451 // Regression test for https://github.com/flutter/flutter/issues/100451
testWidgets('ListView.separator respects findChildIndexCallback', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView.separator respects findChildIndexCallback', (WidgetTester tester) async {
bool finderCalled = false; bool finderCalled = false;
int itemCount = 7; int itemCount = 7;
late StateSetter stateSetter; late StateSetter stateSetter;
...@@ -149,7 +150,7 @@ void main() { ...@@ -149,7 +150,7 @@ void main() {
expect(finderCalled, true); expect(finderCalled, true);
}); });
testWidgets('ListView default control', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView default control', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -160,7 +161,7 @@ void main() { ...@@ -160,7 +161,7 @@ void main() {
); );
}); });
testWidgets('ListView itemExtent control test', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView itemExtent control test', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -207,7 +208,7 @@ void main() { ...@@ -207,7 +208,7 @@ void main() {
expect(find.text('5'), findsNothing); expect(find.text('5'), findsNothing);
}); });
testWidgets('ListView large scroll jump', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView large scroll jump', (WidgetTester tester) async {
final List<int> log = <int>[]; final List<int> log = <int>[];
await tester.pumpWidget( await tester.pumpWidget(
...@@ -249,7 +250,7 @@ void main() { ...@@ -249,7 +250,7 @@ void main() {
log.clear(); log.clear();
}); });
testWidgets('ListView large scroll jump and keepAlive first child not keepAlive', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView large scroll jump and keepAlive first child not keepAlive', (WidgetTester tester) async {
Future<void> checkAndScroll([ String zero = '0:false' ]) async { Future<void> checkAndScroll([ String zero = '0:false' ]) async {
expect(find.text(zero), findsOneWidget); expect(find.text(zero), findsOneWidget);
expect(find.text('1:false'), findsOneWidget); expect(find.text('1:false'), findsOneWidget);
...@@ -286,7 +287,7 @@ void main() { ...@@ -286,7 +287,7 @@ void main() {
await checkAndScroll('0:true'); await checkAndScroll('0:true');
}); });
testWidgets('ListView can build out of underflow', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView can build out of underflow', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -342,7 +343,7 @@ void main() { ...@@ -342,7 +343,7 @@ void main() {
expect(find.text('5'), findsNothing); expect(find.text('5'), findsNothing);
}); });
testWidgets('ListView can build out of overflow padding', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView can build out of overflow padding', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -361,7 +362,7 @@ void main() { ...@@ -361,7 +362,7 @@ void main() {
expect(find.text('padded', skipOffstage: false), findsOneWidget); expect(find.text('padded', skipOffstage: false), findsOneWidget);
}); });
testWidgets('ListView with itemExtent in unbounded context', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView with itemExtent in unbounded context', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -381,7 +382,7 @@ void main() { ...@@ -381,7 +382,7 @@ void main() {
expect(find.text('19'), findsOneWidget); expect(find.text('19'), findsOneWidget);
}); });
testWidgets('ListView with shrink wrap in bounded context correctly uses cache extent', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView with shrink wrap in bounded context correctly uses cache extent', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
...@@ -405,7 +406,7 @@ void main() { ...@@ -405,7 +406,7 @@ void main() {
handle.dispose(); handle.dispose();
}); });
testWidgets('ListView hidden items should stay hidden if their semantics are updated', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView hidden items should stay hidden if their semantics are updated', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
...@@ -440,7 +441,7 @@ void main() { ...@@ -440,7 +441,7 @@ void main() {
handle.dispose(); handle.dispose();
}); });
testWidgets('didFinishLayout has correct indices', (WidgetTester tester) async { testWidgetsWithLeakTracking('didFinishLayout has correct indices', (WidgetTester tester) async {
final TestSliverChildListDelegate delegate = TestSliverChildListDelegate( final TestSliverChildListDelegate delegate = TestSliverChildListDelegate(
List<Widget>.generate( List<Widget>.generate(
20, 20,
...@@ -486,7 +487,7 @@ void main() { ...@@ -486,7 +487,7 @@ void main() {
delegate.log.clear(); delegate.log.clear();
}); });
testWidgets('ListView automatically pad MediaQuery on axis', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView automatically pad MediaQuery on axis', (WidgetTester tester) async {
EdgeInsets? innerMediaQueryPadding; EdgeInsets? innerMediaQueryPadding;
await tester.pumpWidget( await tester.pumpWidget(
...@@ -514,7 +515,7 @@ void main() { ...@@ -514,7 +515,7 @@ void main() {
expect(innerMediaQueryPadding, const EdgeInsets.symmetric(horizontal: 30.0)); expect(innerMediaQueryPadding, const EdgeInsets.symmetric(horizontal: 30.0));
}); });
testWidgets('ListView clips if overflow is smaller than cacheExtent', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView clips if overflow is smaller than cacheExtent', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/17426. // Regression test for https://github.com/flutter/flutter/issues/17426.
await tester.pumpWidget( await tester.pumpWidget(
...@@ -545,7 +546,7 @@ void main() { ...@@ -545,7 +546,7 @@ void main() {
expect(find.byType(Viewport), paints..clipRect()); expect(find.byType(Viewport), paints..clipRect());
}); });
testWidgets('ListView does not clips if no overflow', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView does not clips if no overflow', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -568,7 +569,7 @@ void main() { ...@@ -568,7 +569,7 @@ void main() {
expect(find.byType(Viewport), isNot(paints..clipRect())); expect(find.byType(Viewport), isNot(paints..clipRect()));
}); });
testWidgets('ListView (fixed extent) clips if overflow is smaller than cacheExtent', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView (fixed extent) clips if overflow is smaller than cacheExtent', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/17426. // Regression test for https://github.com/flutter/flutter/issues/17426.
await tester.pumpWidget( await tester.pumpWidget(
...@@ -600,7 +601,7 @@ void main() { ...@@ -600,7 +601,7 @@ void main() {
expect(find.byType(Viewport), paints..clipRect()); expect(find.byType(Viewport), paints..clipRect());
}); });
testWidgets('ListView (fixed extent) does not clips if no overflow', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView (fixed extent) does not clips if no overflow', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -624,7 +625,7 @@ void main() { ...@@ -624,7 +625,7 @@ void main() {
expect(find.byType(Viewport), isNot(paints..clipRect())); expect(find.byType(Viewport), isNot(paints..clipRect()));
}); });
testWidgets('ListView.horizontal has implicit scrolling by default', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView.horizontal has implicit scrolling by default', (WidgetTester tester) async {
final SemanticsHandle handle = tester.ensureSemantics(); final SemanticsHandle handle = tester.ensureSemantics();
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
...@@ -657,9 +658,10 @@ void main() { ...@@ -657,9 +658,10 @@ void main() {
handle.dispose(); handle.dispose();
}); });
testWidgets('Updates viewport dimensions when scroll direction changes', (WidgetTester tester) async { testWidgetsWithLeakTracking('Updates viewport dimensions when scroll direction changes', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/43380. // Regression test for https://github.com/flutter/flutter/issues/43380.
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
Widget buildListView({ required Axis scrollDirection }) { Widget buildListView({ required Axis scrollDirection }) {
return Directionality( return Directionality(
...@@ -694,7 +696,7 @@ void main() { ...@@ -694,7 +696,7 @@ void main() {
expect(controller.position.viewportDimension, 100.0); expect(controller.position.viewportDimension, 100.0);
}); });
testWidgets('ListView respects clipBehavior', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView respects clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -728,9 +730,14 @@ void main() { ...@@ -728,9 +730,14 @@ void main() {
// 4th, check that a non-default clip behavior can be sent to the painting context. // 4th, check that a non-default clip behavior can be sent to the painting context.
renderObject.paint(context, Offset.zero); renderObject.paint(context, Offset.zero);
expect(context.clipBehavior, equals(Clip.antiAlias)); expect(context.clipBehavior, equals(Clip.antiAlias));
}); },
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134572
notDisposedAllowList: <String, int?> {'ContainerLayer': 1},
));
testWidgets('ListView.builder respects clipBehavior', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView.builder respects clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -745,7 +752,7 @@ void main() { ...@@ -745,7 +752,7 @@ void main() {
expect(renderObject.clipBehavior, equals(Clip.antiAlias)); expect(renderObject.clipBehavior, equals(Clip.antiAlias));
}); });
testWidgets('ListView.custom respects clipBehavior', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView.custom respects clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -762,7 +769,7 @@ void main() { ...@@ -762,7 +769,7 @@ void main() {
expect(renderObject.clipBehavior, equals(Clip.antiAlias)); expect(renderObject.clipBehavior, equals(Clip.antiAlias));
}); });
testWidgets('ListView.separated respects clipBehavior', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView.separated respects clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -779,8 +786,9 @@ void main() { ...@@ -779,8 +786,9 @@ void main() {
}); });
// Regression test for https://github.com/flutter/flutter/pull/131393 // Regression test for https://github.com/flutter/flutter/pull/131393
testWidgets('itemExtentBuilder test', (WidgetTester tester) async { testWidgetsWithLeakTracking('itemExtentBuilder test', (WidgetTester tester) async {
final ScrollController controller = ScrollController(); final ScrollController controller = ScrollController();
addTearDown(controller.dispose);
final List<int> buildLog = <int>[]; final List<int> buildLog = <int>[];
late SliverLayoutDimensions sliverLayoutDimensions; late SliverLayoutDimensions sliverLayoutDimensions;
await tester.pumpWidget( await tester.pumpWidget(
...@@ -909,7 +917,7 @@ void main() { ...@@ -909,7 +917,7 @@ void main() {
expect(buildLog.max, 61); expect(buildLog.max, 61);
}); });
testWidgets('itemExtent, prototypeItem and itemExtentBuilder conflicts test', (WidgetTester tester) async { testWidgetsWithLeakTracking('itemExtent, prototypeItem and itemExtentBuilder conflicts test', (WidgetTester tester) async {
Object? error; Object? error;
try { try {
await tester.pumpWidget( await tester.pumpWidget(
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
const List<int> items = <int>[0, 1, 2, 3, 4, 5]; const List<int> items = <int>[0, 1, 2, 3, 4, 5];
...@@ -20,7 +21,7 @@ Widget buildFrame() { ...@@ -20,7 +21,7 @@ Widget buildFrame() {
} }
void main() { void main() {
testWidgets('Drag vertically', (WidgetTester tester) async { testWidgetsWithLeakTracking('Drag vertically', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame()); await tester.pumpWidget(buildFrame());
await tester.pump(); await tester.pump();
...@@ -63,7 +64,7 @@ void main() { ...@@ -63,7 +64,7 @@ void main() {
expect(find.text('5'), findsNothing); expect(find.text('5'), findsNothing);
}); });
testWidgets('Drag vertically', (WidgetTester tester) async { testWidgetsWithLeakTracking('Drag vertically', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
......
...@@ -5,11 +5,12 @@ ...@@ -5,11 +5,12 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart'; import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import 'test_widgets.dart'; import 'test_widgets.dart';
void main() { void main() {
testWidgets('ListView mount/dismount smoke test', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView mount/dismount smoke test', (WidgetTester tester) async {
final List<int> callbackTracker = <int>[]; final List<int> callbackTracker = <int>[];
// the root view is 800x600 in the test environment // the root view is 800x600 in the test environment
...@@ -59,7 +60,7 @@ void main() { ...@@ -59,7 +60,7 @@ void main() {
])); ]));
}); });
testWidgets('ListView vertical', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView vertical', (WidgetTester tester) async {
final List<int> callbackTracker = <int>[]; final List<int> callbackTracker = <int>[];
// the root view is 800x600 in the test environment // the root view is 800x600 in the test environment
...@@ -77,11 +78,14 @@ void main() { ...@@ -77,11 +78,14 @@ void main() {
} }
Widget builder() { Widget builder() {
final ScrollController controller = ScrollController(initialScrollOffset: 300.0);
addTearDown(controller.dispose);
return Directionality( return Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: FlipWidget( child: FlipWidget(
left: ListView.builder( left: ListView.builder(
controller: ScrollController(initialScrollOffset: 300.0), controller: controller,
itemBuilder: itemBuilder, itemBuilder: itemBuilder,
), ),
right: const Text('Not Today'), right: const Text('Not Today'),
...@@ -122,7 +126,7 @@ void main() { ...@@ -122,7 +126,7 @@ void main() {
callbackTracker.clear(); callbackTracker.clear();
}); });
testWidgets('ListView horizontal', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView horizontal', (WidgetTester tester) async {
final List<int> callbackTracker = <int>[]; final List<int> callbackTracker = <int>[];
// the root view is 800x600 in the test environment // the root view is 800x600 in the test environment
...@@ -140,12 +144,15 @@ void main() { ...@@ -140,12 +144,15 @@ void main() {
} }
Widget builder() { Widget builder() {
final ScrollController controller = ScrollController(initialScrollOffset: 500.0);
addTearDown(controller.dispose);
return Directionality( return Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
child: FlipWidget( child: FlipWidget(
left: ListView.builder( left: ListView.builder(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
controller: ScrollController(initialScrollOffset: 500.0), controller: controller,
itemBuilder: itemBuilder, itemBuilder: itemBuilder,
), ),
right: const Text('Not Today'), right: const Text('Not Today'),
...@@ -176,7 +183,7 @@ void main() { ...@@ -176,7 +183,7 @@ void main() {
callbackTracker.clear(); callbackTracker.clear();
}); });
testWidgets('ListView reinvoke builders', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView reinvoke builders', (WidgetTester tester) async {
final List<int> callbackTracker = <int>[]; final List<int> callbackTracker = <int>[];
final List<String?> text = <String?>[]; final List<String?> text = <String?>[];
...@@ -228,7 +235,7 @@ void main() { ...@@ -228,7 +235,7 @@ void main() {
text.clear(); text.clear();
}); });
testWidgets('ListView reinvoke builders', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView reinvoke builders', (WidgetTester tester) async {
late StateSetter setState; late StateSetter setState;
ThemeData themeData = ThemeData.light(useMaterial3: false); ThemeData themeData = ThemeData.light(useMaterial3: false);
...@@ -271,7 +278,7 @@ void main() { ...@@ -271,7 +278,7 @@ void main() {
expect(widget.color, equals(Colors.green)); expect(widget.color, equals(Colors.green));
}); });
testWidgets('ListView padding', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView padding', (WidgetTester tester) async {
Widget itemBuilder(BuildContext context, int index) { Widget itemBuilder(BuildContext context, int index) {
return Container( return Container(
key: ValueKey<int>(index), key: ValueKey<int>(index),
...@@ -298,7 +305,7 @@ void main() { ...@@ -298,7 +305,7 @@ void main() {
expect(firstBox.size.width, equals(800.0 - 12.0)); expect(firstBox.size.width, equals(800.0 - 12.0));
}); });
testWidgets('ListView underflow extents', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView underflow extents', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -433,8 +440,11 @@ void main() { ...@@ -433,8 +440,11 @@ void main() {
expect(position.minScrollExtent, equals(0.0)); expect(position.minScrollExtent, equals(0.0));
}); });
testWidgets('ListView should not paint hidden children', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView should not paint hidden children', (WidgetTester tester) async {
const Text text = Text('test'); const Text text = Text('test');
final ScrollController controller = ScrollController(initialScrollOffset: 300.0);
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.ltr, textDirection: TextDirection.ltr,
...@@ -443,7 +453,7 @@ void main() { ...@@ -443,7 +453,7 @@ void main() {
height: 200.0, height: 200.0,
child: ListView( child: ListView(
cacheExtent: 500.0, cacheExtent: 500.0,
controller: ScrollController(initialScrollOffset: 300.0), controller: controller,
children: const <Widget>[ children: const <Widget>[
SizedBox(height: 140.0, child: text), SizedBox(height: 140.0, child: text),
SizedBox(height: 160.0, child: text), SizedBox(height: 160.0, child: text),
...@@ -462,14 +472,17 @@ void main() { ...@@ -462,14 +472,17 @@ void main() {
expect(list, paintsExactlyCountTimes(#drawParagraph, 2)); expect(list, paintsExactlyCountTimes(#drawParagraph, 2));
}); });
testWidgets('ListView should paint with offset', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView should paint with offset', (WidgetTester tester) async {
final ScrollController controller = ScrollController(initialScrollOffset: 120.0);
addTearDown(controller.dispose);
await tester.pumpWidget( await tester.pumpWidget(
MaterialApp( MaterialApp(
home: Scaffold( home: Scaffold(
body: SizedBox( body: SizedBox(
height: 500.0, height: 500.0,
child: CustomScrollView( child: CustomScrollView(
controller: ScrollController(initialScrollOffset: 120.0), controller: controller,
slivers: <Widget>[ slivers: <Widget>[
const SliverAppBar( const SliverAppBar(
expandedHeight: 250.0, expandedHeight: 250.0,
...@@ -493,9 +506,14 @@ void main() { ...@@ -493,9 +506,14 @@ void main() {
final RenderObject renderObject = tester.renderObject(find.byType(Scrollable)); final RenderObject renderObject = tester.renderObject(find.byType(Scrollable));
expect(renderObject, paintsExactlyCountTimes(#drawParagraph, 10)); expect(renderObject, paintsExactlyCountTimes(#drawParagraph, 10));
}); },
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134661
notDisposedAllowList: <String, int?> {'AnnotatedRegionLayer<SystemUiOverlayStyle>': 1},
));
testWidgets('ListView should paint with rtl', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView should paint with rtl', (WidgetTester tester) async {
await tester.pumpWidget( await tester.pumpWidget(
Directionality( Directionality(
textDirection: TextDirection.rtl, textDirection: TextDirection.rtl,
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
List<String> items = <String>[ List<String> items = <String>[
'one', 'one',
...@@ -40,7 +41,7 @@ Widget buildFrame() { ...@@ -40,7 +41,7 @@ Widget buildFrame() {
} }
void main() { void main() {
testWidgets('ListView is a build function (smoketest)', (WidgetTester tester) async { testWidgetsWithLeakTracking('ListView is a build function (smoketest)', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame()); await tester.pumpWidget(buildFrame());
expect(find.text('one'), findsOneWidget); expect(find.text('one'), findsOneWidget);
expect(find.text('two'), findsOneWidget); expect(find.text('two'), findsOneWidget);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment