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
...@@ -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']));
}); });
......
...@@ -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(
......
...@@ -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(
testWidgets('ListView should paint with rtl', (WidgetTester tester) async { // TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134661
notDisposedAllowList: <String, int?> {'AnnotatedRegionLayer<SystemUiOverlayStyle>': 1},
));
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