mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
parent
c3db020993
commit
98ebab58ee
@ -4,9 +4,10 @@
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Scroll flings twice in a row does not crash', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scroll flings twice in a row does not crash', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
|
||||
@ -5,9 +5,10 @@
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('ScrollMetricsNotification test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ScrollMetricsNotification test', (WidgetTester tester) async {
|
||||
final List<Notification> events = <Notification>[];
|
||||
Widget buildFrame(double height) {
|
||||
return NotificationListener<Notification>(
|
||||
@ -62,7 +63,7 @@ void main() {
|
||||
expect(events.length, 0);
|
||||
});
|
||||
|
||||
testWidgets('Scroll notification basics', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scroll notification basics', (WidgetTester tester) async {
|
||||
late ScrollNotification notification;
|
||||
|
||||
await tester.pumpWidget(NotificationListener<ScrollNotification>(
|
||||
@ -103,7 +104,7 @@ void main() {
|
||||
expect(end.dragDetails!.velocity, equals(Velocity.zero));
|
||||
});
|
||||
|
||||
testWidgets('Scroll notification depth', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scroll notification depth', (WidgetTester tester) async {
|
||||
final List<Type> depth0Types = <Type>[];
|
||||
final List<Type> depth1Types = <Type>[];
|
||||
final List<int> depth0Values = <int>[];
|
||||
@ -158,7 +159,7 @@ void main() {
|
||||
expect(depth1Values, equals(<int>[1, 1, 1, 1, 1]));
|
||||
});
|
||||
|
||||
testWidgets('ScrollNotifications bubble past Scaffold Material', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ScrollNotifications bubble past Scaffold Material', (WidgetTester tester) async {
|
||||
final List<Type> notificationTypes = <Type>[];
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -206,7 +207,7 @@ void main() {
|
||||
expect(notificationTypes, equals(types));
|
||||
});
|
||||
|
||||
testWidgets('ScrollNotificationObserver', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ScrollNotificationObserver', (WidgetTester tester) async {
|
||||
late ScrollNotificationObserverState observer;
|
||||
ScrollNotification? notification;
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
class TestScrollPhysics extends ScrollPhysics {
|
||||
const TestScrollPhysics({
|
||||
@ -339,7 +340,7 @@ FlutterError
|
||||
}
|
||||
});
|
||||
|
||||
testWidgets('PageScrollPhysics work with NestedScrollView', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('PageScrollPhysics work with NestedScrollView', (WidgetTester tester) async {
|
||||
// Regression test for: https://github.com/flutter/flutter/issues/47850
|
||||
await tester.pumpWidget(Material(
|
||||
child: Directionality(
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
ScrollController _controller = ScrollController(
|
||||
initialScrollOffset: 110.0,
|
||||
@ -140,7 +141,7 @@ Future<void> performTest(WidgetTester tester, bool maintainState) async {
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets("ScrollPosition jumpTo() doesn't call notifyListeners twice", (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking("ScrollPosition jumpTo() doesn't call notifyListeners twice", (WidgetTester tester) async {
|
||||
int count = 0;
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: ListView.builder(
|
||||
@ -159,15 +160,22 @@ void main() {
|
||||
expect(count, 1);
|
||||
});
|
||||
|
||||
testWidgets('whether we remember our scroll position', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('whether we remember our scroll position', (WidgetTester tester) async {
|
||||
await performTest(tester, true);
|
||||
await performTest(tester, false);
|
||||
});
|
||||
|
||||
testWidgets('scroll alignment is honored by ensureVisible', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('scroll alignment is honored by ensureVisible', (WidgetTester tester) async {
|
||||
final List<int> items = List<int>.generate(11, (int index) => index).toList();
|
||||
final List<FocusNode> nodes = List<FocusNode>.generate(11, (int index) => FocusNode(debugLabel: 'Item ${index + 1}')).toList();
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in nodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: ListView(
|
||||
@ -226,7 +234,7 @@ void main() {
|
||||
expect(controller.position.pixels, equals(0.0));
|
||||
});
|
||||
|
||||
testWidgets('jumpTo recommends deferred loading', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('jumpTo recommends deferred loading', (WidgetTester tester) async {
|
||||
int loadedWithDeferral = 0;
|
||||
int buildCount = 0;
|
||||
const double height = 500;
|
||||
|
||||
@ -6,6 +6,7 @@ import 'package:flutter/gestures.dart' show DragStartBehavior;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart' show LogicalKeyboardKey;
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
import 'states.dart';
|
||||
|
||||
@ -68,7 +69,7 @@ Widget primaryScrollControllerBoilerplate({ required Widget child, required Scro
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('ListView control test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView control test', (WidgetTester tester) async {
|
||||
final List<String> log = <String>[];
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -110,8 +111,13 @@ void main() {
|
||||
log.clear();
|
||||
});
|
||||
|
||||
testWidgets('ListView dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: ListView(
|
||||
@ -143,7 +149,7 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('GridView.builder supports null items', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView.builder supports null items', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: GridView.builder(
|
||||
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
|
||||
@ -163,7 +169,7 @@ void main() {
|
||||
expect(find.text('item'), findsNWidgets(5));
|
||||
});
|
||||
|
||||
testWidgets('ListView.builder supports null items', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView.builder supports null items', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: ListView.builder(
|
||||
itemCount: 42,
|
||||
@ -180,11 +186,14 @@ void main() {
|
||||
expect(find.text('item'), findsNWidgets(5));
|
||||
});
|
||||
|
||||
testWidgets('PageView supports null items in itemBuilder', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('PageView supports null items in itemBuilder', (WidgetTester tester) async {
|
||||
final PageController controller = PageController(viewportFraction: 1 / 5);
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: PageView.builder(
|
||||
itemCount: 5,
|
||||
controller: PageController(viewportFraction: 1/5),
|
||||
controller: controller,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
if (index == 2) {
|
||||
return null;
|
||||
@ -198,7 +207,7 @@ void main() {
|
||||
expect(find.text('item'), findsNWidgets(2));
|
||||
});
|
||||
|
||||
testWidgets('ListView.separated supports null items in itemBuilder', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView.separated supports null items in itemBuilder', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: ListView.separated(
|
||||
itemCount: 42,
|
||||
@ -219,8 +228,13 @@ void main() {
|
||||
expect(find.text('separator'), findsNWidgets(5));
|
||||
});
|
||||
|
||||
testWidgets('ListView.builder dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView.builder dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: ListView.builder(
|
||||
@ -253,8 +267,13 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('ListView.custom dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView.custom dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: ListView.custom(
|
||||
@ -289,8 +308,13 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('ListView.separated dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView.separated dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: ListView.separated(
|
||||
@ -324,8 +348,13 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('GridView dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: GridView(
|
||||
@ -358,8 +387,13 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('GridView.builder dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView.builder dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: GridView.builder(
|
||||
@ -393,8 +427,13 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('GridView.count dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView.count dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: GridView.count(
|
||||
@ -427,8 +466,13 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('GridView.extent dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView.extent dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: GridView.extent(
|
||||
@ -461,8 +505,13 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('GridView.custom dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView.custom dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: GridView.custom(
|
||||
@ -498,8 +547,13 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('ListView dismiss keyboard manual test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView dismiss keyboard manual test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: ListView(
|
||||
@ -530,8 +584,13 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('ListView.builder dismiss keyboard manual test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView.builder dismiss keyboard manual test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: ListView.builder(
|
||||
@ -563,8 +622,13 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('ListView.custom dismiss keyboard manual test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView.custom dismiss keyboard manual test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: ListView.custom(
|
||||
@ -598,8 +662,13 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('ListView.separated dismiss keyboard manual test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView.separated dismiss keyboard manual test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: ListView.separated(
|
||||
@ -632,8 +701,13 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('GridView dismiss keyboard manual test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView dismiss keyboard manual test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: GridView(
|
||||
@ -665,8 +739,13 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('GridView.builder dismiss keyboard manual test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView.builder dismiss keyboard manual test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: GridView.builder(
|
||||
@ -699,8 +778,13 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('GridView.count dismiss keyboard manual test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView.count dismiss keyboard manual test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: GridView.count(
|
||||
@ -732,8 +816,13 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('GridView.extent dismiss keyboard manual test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView.extent dismiss keyboard manual test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: GridView.extent(
|
||||
@ -765,8 +854,13 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('GridView.custom dismiss keyboard manual test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView.custom dismiss keyboard manual test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: GridView.custom(
|
||||
@ -801,7 +895,7 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('ListView restart ballistic activity out of range', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView restart ballistic activity out of range', (WidgetTester tester) async {
|
||||
Widget buildListView(int n) {
|
||||
return Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -831,7 +925,7 @@ void main() {
|
||||
expect(viewport.offset.pixels, equals(2400.0));
|
||||
});
|
||||
|
||||
testWidgets('CustomScrollView control test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('CustomScrollView control test', (WidgetTester tester) async {
|
||||
final List<String> log = <String>[];
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -879,8 +973,13 @@ void main() {
|
||||
log.clear();
|
||||
});
|
||||
|
||||
testWidgets('CustomScrollView dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('CustomScrollView dismiss keyboard onDrag test', (WidgetTester tester) async {
|
||||
final List<FocusNode> focusNodes = List<FocusNode>.generate(50, (int i) => FocusNode());
|
||||
addTearDown(() {
|
||||
for (final FocusNode node in focusNodes) {
|
||||
node.dispose();
|
||||
}
|
||||
});
|
||||
|
||||
await tester.pumpWidget(textFieldBoilerplate(
|
||||
child: CustomScrollView(
|
||||
@ -918,9 +1017,10 @@ void main() {
|
||||
expect(textField.focusNode!.hasFocus, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('Can jumpTo during drag', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Can jumpTo during drag', (WidgetTester tester) async {
|
||||
final List<Type> log = <Type>[];
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
@ -977,23 +1077,26 @@ void main() {
|
||||
});
|
||||
|
||||
test('PrimaryScrollController.automaticallyInheritOnPlatforms defaults to all mobile platforms', (){
|
||||
final PrimaryScrollController primaryScrollController = PrimaryScrollController(
|
||||
controller: ScrollController(),
|
||||
child: const SizedBox(),
|
||||
);
|
||||
expect(
|
||||
primaryScrollController.automaticallyInheritForPlatforms,
|
||||
TargetPlatformVariant.mobile().values,
|
||||
);
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
final PrimaryScrollController primaryScrollController = PrimaryScrollController(
|
||||
controller: controller,
|
||||
child: const SizedBox(),
|
||||
);
|
||||
expect(
|
||||
primaryScrollController.automaticallyInheritForPlatforms,
|
||||
TargetPlatformVariant.mobile().values,
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Vertical CustomScrollViews are not primary by default', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Vertical CustomScrollViews are not primary by default', (WidgetTester tester) async {
|
||||
const CustomScrollView view = CustomScrollView();
|
||||
expect(view.primary, isNull);
|
||||
});
|
||||
|
||||
testWidgets('Vertical CustomScrollViews use PrimaryScrollController by default on mobile', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Vertical CustomScrollViews use PrimaryScrollController by default on mobile', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(primaryScrollControllerBoilerplate(
|
||||
child: const CustomScrollView(),
|
||||
controller: controller,
|
||||
@ -1001,8 +1104,9 @@ void main() {
|
||||
expect(controller.hasClients, isTrue);
|
||||
}, variant: TargetPlatformVariant.mobile());
|
||||
|
||||
testWidgets("Vertical CustomScrollViews don't use PrimaryScrollController by default on desktop", (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking("Vertical CustomScrollViews don't use PrimaryScrollController by default on desktop", (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(primaryScrollControllerBoilerplate(
|
||||
child: const CustomScrollView(),
|
||||
controller: controller,
|
||||
@ -1010,13 +1114,14 @@ void main() {
|
||||
expect(controller.hasClients, isFalse);
|
||||
}, variant: TargetPlatformVariant.desktop());
|
||||
|
||||
testWidgets('Vertical ListViews are not primary by default', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Vertical ListViews are not primary by default', (WidgetTester tester) async {
|
||||
final ListView view = ListView();
|
||||
expect(view.primary, isNull);
|
||||
});
|
||||
|
||||
testWidgets('Vertical ListViews use PrimaryScrollController by default on mobile', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Vertical ListViews use PrimaryScrollController by default on mobile', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(primaryScrollControllerBoilerplate(
|
||||
child: ListView(),
|
||||
controller: controller,
|
||||
@ -1024,8 +1129,9 @@ void main() {
|
||||
expect(controller.hasClients, isTrue);
|
||||
}, variant: TargetPlatformVariant.mobile());
|
||||
|
||||
testWidgets("Vertical ListViews don't use PrimaryScrollController by default on desktop", (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking("Vertical ListViews don't use PrimaryScrollController by default on desktop", (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(primaryScrollControllerBoilerplate(
|
||||
child: ListView(),
|
||||
controller: controller,
|
||||
@ -1033,13 +1139,14 @@ void main() {
|
||||
expect(controller.hasClients, isFalse);
|
||||
}, variant: TargetPlatformVariant.desktop());
|
||||
|
||||
testWidgets('Vertical GridViews are not primary by default', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Vertical GridViews are not primary by default', (WidgetTester tester) async {
|
||||
final GridView view = GridView.count(crossAxisCount: 1);
|
||||
expect(view.primary, isNull);
|
||||
});
|
||||
|
||||
testWidgets('Vertical GridViews use PrimaryScrollController by default on mobile', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Vertical GridViews use PrimaryScrollController by default on mobile', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(primaryScrollControllerBoilerplate(
|
||||
child: GridView.count(crossAxisCount: 1),
|
||||
controller: controller,
|
||||
@ -1047,8 +1154,9 @@ void main() {
|
||||
expect(controller.hasClients, isTrue);
|
||||
}, variant: TargetPlatformVariant.mobile());
|
||||
|
||||
testWidgets("Vertical GridViews don't use PrimaryScrollController by default on desktop", (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking("Vertical GridViews don't use PrimaryScrollController by default on desktop", (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(primaryScrollControllerBoilerplate(
|
||||
child: GridView.count(crossAxisCount: 1),
|
||||
controller: controller,
|
||||
@ -1056,79 +1164,98 @@ void main() {
|
||||
expect(controller.hasClients, isFalse);
|
||||
}, variant: TargetPlatformVariant.desktop());
|
||||
|
||||
testWidgets('Horizontal CustomScrollViews are non-primary by default', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
testWidgetsWithLeakTracking('Horizontal CustomScrollViews are non-primary by default', (WidgetTester tester) async {
|
||||
final ScrollController controller1 = ScrollController();
|
||||
addTearDown(controller1.dispose);
|
||||
final ScrollController controller2 = ScrollController();
|
||||
addTearDown(controller2.dispose);
|
||||
await tester.pumpWidget(primaryScrollControllerBoilerplate(
|
||||
child: CustomScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
controller: ScrollController(),
|
||||
controller: controller2,
|
||||
),
|
||||
controller: controller,
|
||||
controller: controller1,
|
||||
));
|
||||
expect(controller.hasClients, isFalse);
|
||||
expect(controller1.hasClients, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('Horizontal ListViews are non-primary by default', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
testWidgetsWithLeakTracking('Horizontal ListViews are non-primary by default', (WidgetTester tester) async {
|
||||
final ScrollController controller1 = ScrollController();
|
||||
addTearDown(controller1.dispose);
|
||||
final ScrollController controller2 = ScrollController();
|
||||
addTearDown(controller2.dispose);
|
||||
await tester.pumpWidget(primaryScrollControllerBoilerplate(
|
||||
child: ListView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
controller: ScrollController(),
|
||||
controller: controller2,
|
||||
),
|
||||
controller: controller,
|
||||
controller: controller1,
|
||||
));
|
||||
expect(controller.hasClients, isFalse);
|
||||
expect(controller1.hasClients, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('Horizontal GridViews are non-primary by default', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
testWidgetsWithLeakTracking('Horizontal GridViews are non-primary by default', (WidgetTester tester) async {
|
||||
final ScrollController controller1 = ScrollController();
|
||||
addTearDown(controller1.dispose);
|
||||
final ScrollController controller2 = ScrollController();
|
||||
addTearDown(controller2.dispose);
|
||||
await tester.pumpWidget(primaryScrollControllerBoilerplate(
|
||||
child: GridView.count(
|
||||
scrollDirection: Axis.horizontal,
|
||||
controller: ScrollController(),
|
||||
controller: controller2,
|
||||
crossAxisCount: 1,
|
||||
),
|
||||
controller: controller,
|
||||
controller: controller1,
|
||||
));
|
||||
expect(controller.hasClients, isFalse);
|
||||
expect(controller1.hasClients, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('CustomScrollViews with controllers are non-primary by default', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
testWidgetsWithLeakTracking('CustomScrollViews with controllers are non-primary by default', (WidgetTester tester) async {
|
||||
final ScrollController controller1 = ScrollController();
|
||||
addTearDown(controller1.dispose);
|
||||
final ScrollController controller2 = ScrollController();
|
||||
addTearDown(controller2.dispose);
|
||||
await tester.pumpWidget(primaryScrollControllerBoilerplate(
|
||||
child: CustomScrollView(
|
||||
controller: ScrollController(),
|
||||
controller: controller2,
|
||||
),
|
||||
controller: controller,
|
||||
controller: controller1,
|
||||
));
|
||||
expect(controller.hasClients, isFalse);
|
||||
expect(controller1.hasClients, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('ListViews with controllers are non-primary by default', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
testWidgetsWithLeakTracking('ListViews with controllers are non-primary by default', (WidgetTester tester) async {
|
||||
final ScrollController controller1 = ScrollController();
|
||||
addTearDown(controller1.dispose);
|
||||
final ScrollController controller2 = ScrollController();
|
||||
addTearDown(controller2.dispose);
|
||||
await tester.pumpWidget(primaryScrollControllerBoilerplate(
|
||||
child: ListView(
|
||||
controller: ScrollController(),
|
||||
controller: controller2,
|
||||
),
|
||||
controller: controller,
|
||||
controller: controller1,
|
||||
));
|
||||
expect(controller.hasClients, isFalse);
|
||||
expect(controller1.hasClients, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('GridViews with controllers are non-primary by default', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
testWidgetsWithLeakTracking('GridViews with controllers are non-primary by default', (WidgetTester tester) async {
|
||||
final ScrollController controller1 = ScrollController();
|
||||
addTearDown(controller1.dispose);
|
||||
final ScrollController controller2 = ScrollController();
|
||||
addTearDown(controller2.dispose);
|
||||
await tester.pumpWidget(primaryScrollControllerBoilerplate(
|
||||
child: GridView.count(
|
||||
controller: ScrollController(),
|
||||
controller: controller2,
|
||||
crossAxisCount: 1,
|
||||
),
|
||||
controller: controller,
|
||||
controller: controller1,
|
||||
));
|
||||
expect(controller.hasClients, isFalse);
|
||||
expect(controller1.hasClients, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('CustomScrollView sets PrimaryScrollController when primary', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('CustomScrollView sets PrimaryScrollController when primary', (WidgetTester tester) async {
|
||||
final ScrollController primaryScrollController = ScrollController();
|
||||
addTearDown(primaryScrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1142,8 +1269,9 @@ void main() {
|
||||
expect(scrollable.controller, primaryScrollController);
|
||||
});
|
||||
|
||||
testWidgets('ListView sets PrimaryScrollController when primary', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView sets PrimaryScrollController when primary', (WidgetTester tester) async {
|
||||
final ScrollController primaryScrollController = ScrollController();
|
||||
addTearDown(primaryScrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1157,8 +1285,9 @@ void main() {
|
||||
expect(scrollable.controller, primaryScrollController);
|
||||
});
|
||||
|
||||
testWidgets('GridView sets PrimaryScrollController when primary', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView sets PrimaryScrollController when primary', (WidgetTester tester) async {
|
||||
final ScrollController primaryScrollController = ScrollController();
|
||||
addTearDown(primaryScrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1172,9 +1301,10 @@ void main() {
|
||||
expect(scrollable.controller, primaryScrollController);
|
||||
});
|
||||
|
||||
testWidgets('Nested scrollables have a null PrimaryScrollController', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Nested scrollables have a null PrimaryScrollController', (WidgetTester tester) async {
|
||||
const Key innerKey = Key('inner');
|
||||
final ScrollController primaryScrollController = ScrollController();
|
||||
addTearDown(primaryScrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1202,27 +1332,27 @@ void main() {
|
||||
expect(innerScrollable.controller, isNull);
|
||||
});
|
||||
|
||||
testWidgets('Primary ListViews are always scrollable', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Primary ListViews are always scrollable', (WidgetTester tester) async {
|
||||
final ListView view = ListView(primary: true);
|
||||
expect(view.physics, isA<AlwaysScrollableScrollPhysics>());
|
||||
});
|
||||
|
||||
testWidgets('Non-primary ListViews are not always scrollable', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Non-primary ListViews are not always scrollable', (WidgetTester tester) async {
|
||||
final ListView view = ListView(primary: false);
|
||||
expect(view.physics, isNot(isA<AlwaysScrollableScrollPhysics>()));
|
||||
});
|
||||
|
||||
testWidgets('Defaulting-to-primary ListViews are always scrollable', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Defaulting-to-primary ListViews are always scrollable', (WidgetTester tester) async {
|
||||
final ListView view = ListView();
|
||||
expect(view.physics, isA<AlwaysScrollableScrollPhysics>());
|
||||
});
|
||||
|
||||
testWidgets('Defaulting-to-not-primary ListViews are not always scrollable', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Defaulting-to-not-primary ListViews are not always scrollable', (WidgetTester tester) async {
|
||||
final ListView view = ListView(scrollDirection: Axis.horizontal);
|
||||
expect(view.physics, isNot(isA<AlwaysScrollableScrollPhysics>()));
|
||||
});
|
||||
|
||||
testWidgets('primary:true leads to scrolling', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('primary:true leads to scrolling', (WidgetTester tester) async {
|
||||
bool scrolled = false;
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
@ -1242,7 +1372,7 @@ void main() {
|
||||
expect(scrolled, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('primary:false leads to no scrolling', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('primary:false leads to no scrolling', (WidgetTester tester) async {
|
||||
bool scrolled = false;
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
@ -1262,7 +1392,7 @@ void main() {
|
||||
expect(scrolled, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('physics:AlwaysScrollableScrollPhysics actually overrides primary:false default behavior', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('physics:AlwaysScrollableScrollPhysics actually overrides primary:false default behavior', (WidgetTester tester) async {
|
||||
bool scrolled = false;
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
@ -1283,7 +1413,7 @@ void main() {
|
||||
expect(scrolled, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('physics:ScrollPhysics actually overrides primary:true default behavior', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('physics:ScrollPhysics actually overrides primary:true default behavior', (WidgetTester tester) async {
|
||||
bool scrolled = false;
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
@ -1304,7 +1434,7 @@ void main() {
|
||||
expect(scrolled, isFalse);
|
||||
});
|
||||
|
||||
testWidgets('separatorBuilder must return something', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('separatorBuilder must return something', (WidgetTester tester) async {
|
||||
const List<String> listOfValues = <String>['ALPHA', 'BETA', 'GAMMA', 'DELTA'];
|
||||
|
||||
Widget buildFrame(Widget firstSeparator) {
|
||||
@ -1332,7 +1462,7 @@ void main() {
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('when itemBuilder throws, creates Error Widget', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('when itemBuilder throws, creates Error Widget', (WidgetTester tester) async {
|
||||
const List<String> listOfValues = <String>['ALPHA', 'BETA', 'GAMMA', 'DELTA'];
|
||||
|
||||
Widget buildFrame(bool throwOnFirstItem) {
|
||||
@ -1363,7 +1493,7 @@ void main() {
|
||||
expect(finder, findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('when separatorBuilder throws, creates ErrorWidget', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('when separatorBuilder throws, creates ErrorWidget', (WidgetTester tester) async {
|
||||
const List<String> listOfValues = <String>['ALPHA', 'BETA', 'GAMMA', 'DELTA'];
|
||||
const Key key = Key('list');
|
||||
|
||||
@ -1399,14 +1529,14 @@ void main() {
|
||||
expect(finder, findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('ListView asserts on both non-null itemExtent and prototypeItem', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView asserts on both non-null itemExtent and prototypeItem', (WidgetTester tester) async {
|
||||
expect(() => ListView(
|
||||
itemExtent: 100,
|
||||
prototypeItem: const SizedBox(),
|
||||
), throwsAssertionError);
|
||||
});
|
||||
|
||||
testWidgets('ListView.builder asserts on negative childCount', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView.builder asserts on negative childCount', (WidgetTester tester) async {
|
||||
expect(() => ListView.builder(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return const SizedBox();
|
||||
@ -1415,7 +1545,7 @@ void main() {
|
||||
), throwsAssertionError);
|
||||
});
|
||||
|
||||
testWidgets('ListView.builder asserts on negative semanticChildCount', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView.builder asserts on negative semanticChildCount', (WidgetTester tester) async {
|
||||
expect(() => ListView.builder(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return const SizedBox();
|
||||
@ -1425,7 +1555,7 @@ void main() {
|
||||
), throwsAssertionError);
|
||||
});
|
||||
|
||||
testWidgets('ListView.builder asserts on nonsensical childCount/semanticChildCount', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView.builder asserts on nonsensical childCount/semanticChildCount', (WidgetTester tester) async {
|
||||
expect(() => ListView.builder(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return const SizedBox();
|
||||
@ -1435,7 +1565,7 @@ void main() {
|
||||
), throwsAssertionError);
|
||||
});
|
||||
|
||||
testWidgets('ListView.builder asserts on both non-null itemExtent and prototypeItem', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView.builder asserts on both non-null itemExtent and prototypeItem', (WidgetTester tester) async {
|
||||
expect(() => ListView.builder(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return const SizedBox();
|
||||
@ -1445,7 +1575,7 @@ void main() {
|
||||
), throwsAssertionError);
|
||||
});
|
||||
|
||||
testWidgets('ListView.custom asserts on both non-null itemExtent and prototypeItem', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView.custom asserts on both non-null itemExtent and prototypeItem', (WidgetTester tester) async {
|
||||
expect(() => ListView.custom(
|
||||
childrenDelegate: SliverChildBuilderDelegate(
|
||||
(BuildContext context, int index) {
|
||||
@ -1457,7 +1587,7 @@ void main() {
|
||||
), throwsAssertionError);
|
||||
});
|
||||
|
||||
testWidgets('PrimaryScrollController provides fallback ScrollActions', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('PrimaryScrollController provides fallback ScrollActions', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: CustomScrollView(
|
||||
@ -1501,7 +1631,7 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Fallback ScrollActions handle too many positions with error message', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Fallback ScrollActions handle too many positions with error message', (WidgetTester tester) async {
|
||||
Widget getScrollView() {
|
||||
return SizedBox(
|
||||
width: 400.0,
|
||||
@ -1550,7 +1680,7 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('if itemExtent is non-null, children have same extent in the scroll direction', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('if itemExtent is non-null, children have same extent in the scroll direction', (WidgetTester tester) async {
|
||||
final List<int> numbers = <int>[0,1,2];
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -1588,7 +1718,7 @@ void main() {
|
||||
expect(item2Height, 30.0);
|
||||
});
|
||||
|
||||
testWidgets('if prototypeItem is non-null, children have same extent in the scroll direction', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('if prototypeItem is non-null, children have same extent in the scroll direction', (WidgetTester tester) async {
|
||||
final List<int> numbers = <int>[0,1,2];
|
||||
|
||||
await tester.pumpWidget(
|
||||
|
||||
@ -5,10 +5,12 @@
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Does not animate if already at target position', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Does not animate if already at target position', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -27,8 +29,9 @@ void main() {
|
||||
expect(controller.position.pixels, currentPosition);
|
||||
});
|
||||
|
||||
testWidgets('Does not animate if already at target position within tolerance', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Does not animate if already at target position within tolerance', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -50,8 +53,9 @@ void main() {
|
||||
expect(controller.position.pixels, targetPosition);
|
||||
});
|
||||
|
||||
testWidgets('Animates if going to a position outside of tolerance', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Animates if going to a position outside of tolerance', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
|
||||
@ -4,11 +4,12 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
import 'test_widgets.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('simultaneously dispose a widget and end the scroll animation', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('simultaneously dispose a widget and end the scroll animation', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -26,10 +27,11 @@ void main() {
|
||||
await tester.pump(const Duration(hours: 5));
|
||||
});
|
||||
|
||||
testWidgets('Disposing a (nested) Scrollable while holding in overscroll does not crash', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Disposing a (nested) Scrollable while holding in overscroll does not crash', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/27707.
|
||||
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
final Key outerContainer = GlobalKey();
|
||||
|
||||
await tester.pumpWidget(
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
import 'package:flutter/gestures.dart' show DragStartBehavior;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
const TextStyle testFont = TextStyle(
|
||||
color: Color(0xFF00FF00),
|
||||
@ -31,7 +32,7 @@ Future<void> pumpTest(WidgetTester tester, TargetPlatform platform) async {
|
||||
const double dragOffset = 213.82;
|
||||
|
||||
void main() {
|
||||
testWidgets('Flings on different platforms', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Flings on different platforms', (WidgetTester tester) async {
|
||||
double getCurrentOffset() {
|
||||
return tester.state<ScrollableState>(find.byType(Scrollable)).position.pixels;
|
||||
}
|
||||
@ -96,7 +97,7 @@ void main() {
|
||||
expect(linuxResult, equals(androidResult));
|
||||
});
|
||||
|
||||
testWidgets('fling and tap to stop', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('fling and tap to stop', (WidgetTester tester) async {
|
||||
final List<String> log = <String>[];
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
@ -126,7 +127,7 @@ void main() {
|
||||
expect(log, equals(<String>['tap 21', 'tap 35']));
|
||||
});
|
||||
|
||||
testWidgets('fling and wait and tap', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('fling and wait and tap', (WidgetTester tester) async {
|
||||
final List<String> log = <String>[];
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
|
||||
@ -4,9 +4,10 @@
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('GridView default control', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView default control', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -20,7 +21,7 @@ void main() {
|
||||
});
|
||||
|
||||
// Tests https://github.com/flutter/flutter/issues/5522
|
||||
testWidgets('GridView displays correct children with nonzero padding', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView displays correct children with nonzero padding', (WidgetTester tester) async {
|
||||
const EdgeInsets padding = EdgeInsets.fromLTRB(0.0, 100.0, 0.0, 0.0);
|
||||
|
||||
final Widget testWidget = Directionality(
|
||||
@ -76,7 +77,7 @@ void main() {
|
||||
expect(find.text('4'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('GridView.count() fixed itemExtent, scroll to end, append, scroll', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView.count() fixed itemExtent, scroll to end, append, scroll', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/9506
|
||||
Widget buildFrame(int itemCount) {
|
||||
return Directionality(
|
||||
|
||||
@ -6,6 +6,7 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
final LogicalKeyboardKey modifierKey = defaultTargetPlatform == TargetPlatform.macOS
|
||||
? LogicalKeyboardKey.metaLeft
|
||||
@ -13,8 +14,9 @@ final LogicalKeyboardKey modifierKey = defaultTargetPlatform == TargetPlatform.m
|
||||
|
||||
void main() {
|
||||
group('ScrollableDetails', (){
|
||||
final ScrollController controller = ScrollController();
|
||||
test('copyWith / == / hashCode', () {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
final ScrollableDetails details = ScrollableDetails(
|
||||
direction: AxisDirection.down,
|
||||
controller: controller,
|
||||
@ -42,6 +44,8 @@ void main() {
|
||||
});
|
||||
|
||||
test('toString', (){
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
const ScrollableDetails bareDetails = ScrollableDetails(
|
||||
direction: AxisDirection.right,
|
||||
);
|
||||
@ -86,8 +90,9 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets("Keyboard scrolling doesn't happen if scroll physics are set to NeverScrollableScrollPhysics", (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking("Keyboard scrolling doesn't happen if scroll physics are set to NeverScrollableScrollPhysics", (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeData(platform: TargetPlatform.fuchsia),
|
||||
@ -152,8 +157,9 @@ void main() {
|
||||
);
|
||||
}, variant: KeySimulatorTransitModeVariant.all());
|
||||
|
||||
testWidgets('Vertical scrollables are scrolled when activated via keyboard.', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Vertical scrollables are scrolled when activated via keyboard.', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeData(platform: TargetPlatform.fuchsia),
|
||||
@ -223,8 +229,9 @@ void main() {
|
||||
);
|
||||
}, variant: KeySimulatorTransitModeVariant.all());
|
||||
|
||||
testWidgets('Horizontal scrollables are scrolled when activated via keyboard.', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Horizontal scrollables are scrolled when activated via keyboard.', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeData(platform: TargetPlatform.fuchsia),
|
||||
@ -283,8 +290,9 @@ void main() {
|
||||
);
|
||||
}, variant: KeySimulatorTransitModeVariant.all());
|
||||
|
||||
testWidgets('Horizontal scrollables are scrolled the correct direction in RTL locales.', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Horizontal scrollables are scrolled the correct direction in RTL locales.', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeData(platform: TargetPlatform.fuchsia),
|
||||
@ -346,9 +354,11 @@ void main() {
|
||||
);
|
||||
}, variant: KeySimulatorTransitModeVariant.all());
|
||||
|
||||
testWidgets('Reversed vertical scrollables are scrolled when activated via keyboard.', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Reversed vertical scrollables are scrolled when activated via keyboard.', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
final FocusNode focusNode = FocusNode(debugLabel: 'SizedBox');
|
||||
addTearDown(focusNode.dispose);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeData(platform: TargetPlatform.fuchsia),
|
||||
@ -420,9 +430,11 @@ void main() {
|
||||
);
|
||||
}, variant: KeySimulatorTransitModeVariant.all());
|
||||
|
||||
testWidgets('Reversed horizontal scrollables are scrolled when activated via keyboard.', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Reversed horizontal scrollables are scrolled when activated via keyboard.', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
final FocusNode focusNode = FocusNode(debugLabel: 'SizedBox');
|
||||
addTearDown(focusNode.dispose);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeData(platform: TargetPlatform.fuchsia),
|
||||
@ -479,8 +491,9 @@ void main() {
|
||||
await tester.pumpAndSettle();
|
||||
}, variant: KeySimulatorTransitModeVariant.all());
|
||||
|
||||
testWidgets('Custom scrollables with a center sliver are scrolled when activated via keyboard.', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Custom scrollables with a center sliver are scrolled when activated via keyboard.', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
final List<String> items = List<String>.generate(20, (int index) => 'Item $index');
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
@ -550,7 +563,7 @@ void main() {
|
||||
);
|
||||
}, variant: KeySimulatorTransitModeVariant.all());
|
||||
|
||||
testWidgets('Can scroll using intents only', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Can scroll using intents only', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: ListView(
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
test('Can dispose ScrollPosition when hasPixels is false', () {
|
||||
@ -18,9 +19,10 @@ void main() {
|
||||
position.dispose(); // Should not throw/assert.
|
||||
});
|
||||
|
||||
testWidgets('scrollable in hidden overlay does not crash when unhidden', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('scrollable in hidden overlay does not crash when unhidden', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/44269.
|
||||
final TabController controller = TabController(vsync: const TestVSync(), length: 1);
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
final OverlayEntry entry1 = OverlayEntry(
|
||||
maintainState: true,
|
||||
|
||||
@ -5,11 +5,12 @@
|
||||
import 'package:flutter/gestures.dart' show DragStartBehavior;
|
||||
import 'package:flutter/widgets.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];
|
||||
|
||||
void main() {
|
||||
testWidgets('Tap item after scroll - horizontal', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Tap item after scroll - horizontal', (WidgetTester tester) async {
|
||||
final List<int> tapped = <int>[];
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
@ -51,7 +52,7 @@ void main() {
|
||||
expect(tapped, equals(<int>[2]));
|
||||
});
|
||||
|
||||
testWidgets('Tap item after scroll - vertical', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Tap item after scroll - vertical', (WidgetTester tester) async {
|
||||
final List<int> tapped = <int>[];
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
@ -94,7 +95,7 @@ void main() {
|
||||
expect(tapped, equals(<int>[1])); // the center of the third item is off-screen so it shouldn't get hit
|
||||
});
|
||||
|
||||
testWidgets('Padding scroll anchor start', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Padding scroll anchor start', (WidgetTester tester) async {
|
||||
final List<int> tapped = <int>[];
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -126,7 +127,7 @@ void main() {
|
||||
expect(tapped, equals(<int>[0, 1, 1]));
|
||||
});
|
||||
|
||||
testWidgets('Padding scroll anchor end', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Padding scroll anchor end', (WidgetTester tester) async {
|
||||
final List<int> tapped = <int>[];
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -159,7 +160,7 @@ void main() {
|
||||
expect(tapped, equals(<int>[0, 1, 1]));
|
||||
});
|
||||
|
||||
testWidgets('Tap immediately following clamped overscroll', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Tap immediately following clamped overscroll', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/5709
|
||||
final List<int> tapped = <int>[];
|
||||
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
class ScrollPositionListener extends StatefulWidget {
|
||||
const ScrollPositionListener({ super.key, required this.child, required this.log});
|
||||
@ -123,9 +124,10 @@ class TestChildState extends State<TestChild> {
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('Scrollable.of() dependent rebuilds when Scrollable position changes', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrollable.of() dependent rebuilds when Scrollable position changes', (WidgetTester tester) async {
|
||||
late String logValue;
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
// Changing the SingleChildScrollView's physics causes the
|
||||
// ScrollController's ScrollPosition to be rebuilt.
|
||||
@ -163,7 +165,7 @@ void main() {
|
||||
expect(logValue, 'listener 400.0');
|
||||
});
|
||||
|
||||
testWidgets('Scrollable.of() is possible using ScrollNotification context', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrollable.of() is possible using ScrollNotification context', (WidgetTester tester) async {
|
||||
late ScrollNotification notification;
|
||||
|
||||
await tester.pumpWidget(NotificationListener<ScrollNotification>(
|
||||
@ -183,9 +185,11 @@ void main() {
|
||||
expect(Scrollable.of(notification.context!), equals(scrollableElement.state));
|
||||
});
|
||||
|
||||
testWidgets('Static Scrollable methods can target a specific axis', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Static Scrollable methods can target a specific axis', (WidgetTester tester) async {
|
||||
final TestScrollController horizontalController = TestScrollController(deferLoading: true);
|
||||
addTearDown(horizontalController.dispose);
|
||||
final TestScrollController verticalController = TestScrollController(deferLoading: false);
|
||||
addTearDown(verticalController.dispose);
|
||||
late final AxisDirection foundAxisDirection;
|
||||
late final bool foundRecommendation;
|
||||
|
||||
@ -218,7 +222,7 @@ void main() {
|
||||
expect(foundRecommendation, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('Axis targeting scrollables establishes the correct dependencies', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Axis targeting scrollables establishes the correct dependencies', (WidgetTester tester) async {
|
||||
final GlobalKey<TestScrollableState> verticalKey = GlobalKey<TestScrollableState>();
|
||||
final GlobalKey<TestChildState> childKey = GlobalKey<TestChildState>();
|
||||
|
||||
@ -237,12 +241,15 @@ void main() {
|
||||
expect(verticalKey.currentState!.dependenciesChanged, 1);
|
||||
expect(childKey.currentState!.dependenciesChanged, 1);
|
||||
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
// Change the horizontal ScrollView, adding a controller
|
||||
await tester.pumpWidget(Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
controller: ScrollController(),
|
||||
controller: controller,
|
||||
child: TestScrollable(
|
||||
key: verticalKey,
|
||||
child: TestChild(key: childKey),
|
||||
|
||||
@ -5,9 +5,10 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('CustomScrollView restoration', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('CustomScrollView restoration', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
TestHarness(
|
||||
child: CustomScrollView(
|
||||
@ -33,7 +34,7 @@ void main() {
|
||||
await restoreScrollAndVerify(tester);
|
||||
});
|
||||
|
||||
testWidgets('ListView restoration', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView restoration', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
TestHarness(
|
||||
child: ListView(
|
||||
@ -53,7 +54,7 @@ void main() {
|
||||
await restoreScrollAndVerify(tester);
|
||||
});
|
||||
|
||||
testWidgets('ListView.builder restoration', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView.builder restoration', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
TestHarness(
|
||||
child: ListView.builder(
|
||||
@ -70,7 +71,7 @@ void main() {
|
||||
await restoreScrollAndVerify(tester);
|
||||
});
|
||||
|
||||
testWidgets('ListView.separated restoration', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView.separated restoration', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
TestHarness(
|
||||
child: ListView.separated(
|
||||
@ -89,7 +90,7 @@ void main() {
|
||||
await restoreScrollAndVerify(tester);
|
||||
});
|
||||
|
||||
testWidgets('ListView.custom restoration', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListView.custom restoration', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
TestHarness(
|
||||
child: ListView.custom(
|
||||
@ -111,7 +112,7 @@ void main() {
|
||||
await restoreScrollAndVerify(tester);
|
||||
});
|
||||
|
||||
testWidgets('GridView restoration', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView restoration', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
TestHarness(
|
||||
child: GridView(
|
||||
@ -132,7 +133,7 @@ void main() {
|
||||
await restoreScrollAndVerify(tester);
|
||||
});
|
||||
|
||||
testWidgets('GridView.builder restoration', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView.builder restoration', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
TestHarness(
|
||||
child: GridView.builder(
|
||||
@ -150,7 +151,7 @@ void main() {
|
||||
await restoreScrollAndVerify(tester);
|
||||
});
|
||||
|
||||
testWidgets('GridView.custom restoration', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView.custom restoration', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
TestHarness(
|
||||
child: GridView.custom(
|
||||
@ -173,7 +174,7 @@ void main() {
|
||||
await restoreScrollAndVerify(tester);
|
||||
});
|
||||
|
||||
testWidgets('GridView.count restoration', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView.count restoration', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
TestHarness(
|
||||
child: GridView.count(
|
||||
@ -194,7 +195,7 @@ void main() {
|
||||
await restoreScrollAndVerify(tester);
|
||||
});
|
||||
|
||||
testWidgets('GridView.extent restoration', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('GridView.extent restoration', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
TestHarness(
|
||||
child: GridView.extent(
|
||||
@ -215,7 +216,7 @@ void main() {
|
||||
await restoreScrollAndVerify(tester);
|
||||
});
|
||||
|
||||
testWidgets('SingleChildScrollView restoration', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('SingleChildScrollView restoration', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
TestHarness(
|
||||
child: SingleChildScrollView(
|
||||
@ -262,7 +263,7 @@ void main() {
|
||||
expect(tester.getTopLeft(find.text('Tile 1')), const Offset(0, -475));
|
||||
});
|
||||
|
||||
testWidgets('PageView restoration', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('PageView restoration', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
TestHarness(
|
||||
child: PageView(
|
||||
@ -278,7 +279,7 @@ void main() {
|
||||
await pageViewScrollAndRestore(tester);
|
||||
});
|
||||
|
||||
testWidgets('PageView.builder restoration', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('PageView.builder restoration', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
TestHarness(
|
||||
child: PageView.builder(
|
||||
@ -294,7 +295,7 @@ void main() {
|
||||
await pageViewScrollAndRestore(tester);
|
||||
});
|
||||
|
||||
testWidgets('PageView.custom restoration', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('PageView.custom restoration', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
TestHarness(
|
||||
child: PageView.custom(
|
||||
@ -315,7 +316,7 @@ void main() {
|
||||
await pageViewScrollAndRestore(tester);
|
||||
});
|
||||
|
||||
testWidgets('ListWheelScrollView restoration', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListWheelScrollView restoration', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
TestHarness(
|
||||
child: ListWheelScrollView(
|
||||
@ -332,7 +333,7 @@ void main() {
|
||||
await restoreScrollAndVerify(tester, secondOffset: 542);
|
||||
});
|
||||
|
||||
testWidgets('ListWheelScrollView.useDelegate restoration', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ListWheelScrollView.useDelegate restoration', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
TestHarness(
|
||||
child: ListWheelScrollView.useDelegate(
|
||||
@ -354,7 +355,7 @@ void main() {
|
||||
await restoreScrollAndVerify(tester, secondOffset: 542);
|
||||
});
|
||||
|
||||
testWidgets('NestedScrollView restoration', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('NestedScrollView restoration', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: TestHarness(
|
||||
@ -422,7 +423,7 @@ void main() {
|
||||
expect(find.text('Tile 10'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('RestorationData is flushed even if no frame is scheduled', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('RestorationData is flushed even if no frame is scheduled', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
TestHarness(
|
||||
child: ListView(
|
||||
|
||||
@ -9,6 +9,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
import 'clipboard_utils.dart';
|
||||
import 'keyboard_utils.dart';
|
||||
@ -36,7 +37,7 @@ void main() {
|
||||
TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler(SystemChannels.platform, null);
|
||||
});
|
||||
|
||||
testWidgets('mouse can select multiple widgets', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('mouse can select multiple widgets', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
selectionControls: materialTextSelectionControls,
|
||||
@ -74,7 +75,7 @@ void main() {
|
||||
await gesture.up();
|
||||
});
|
||||
|
||||
testWidgets('mouse can select multiple widgets - horizontal', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('mouse can select multiple widgets - horizontal', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
selectionControls: materialTextSelectionControls,
|
||||
@ -107,7 +108,7 @@ void main() {
|
||||
await gesture.up();
|
||||
});
|
||||
|
||||
testWidgets('mouse can select multiple widgets on double-click drag', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('mouse can select multiple widgets on double-click drag', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
selectionControls: materialTextSelectionControls,
|
||||
@ -151,7 +152,7 @@ void main() {
|
||||
await gesture.up();
|
||||
}, skip: kIsWeb); // https://github.com/flutter/flutter/issues/125582.
|
||||
|
||||
testWidgets('mouse can select multiple widgets on double-click drag - horizontal', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('mouse can select multiple widgets on double-click drag - horizontal', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
selectionControls: materialTextSelectionControls,
|
||||
@ -190,8 +191,9 @@ void main() {
|
||||
await gesture.up();
|
||||
}, skip: kIsWeb); // https://github.com/flutter/flutter/issues/125582.
|
||||
|
||||
testWidgets('select to scroll forward', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('select to scroll forward', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
selectionControls: materialTextSelectionControls,
|
||||
@ -239,8 +241,9 @@ void main() {
|
||||
await gesture.up();
|
||||
});
|
||||
|
||||
testWidgets('select to scroll works for small scrollable', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('select to scroll works for small scrollable', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
home: SelectionArea(
|
||||
@ -285,8 +288,9 @@ void main() {
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('select to scroll backward', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('select to scroll backward', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
selectionControls: materialTextSelectionControls,
|
||||
@ -333,8 +337,9 @@ void main() {
|
||||
expect(paragraph3.selections[0], const TextSelection(baseOffset: 6, extentOffset: 0));
|
||||
});
|
||||
|
||||
testWidgets('select to scroll forward - horizontal', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('select to scroll forward - horizontal', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
selectionControls: materialTextSelectionControls,
|
||||
@ -381,8 +386,9 @@ void main() {
|
||||
await gesture.up();
|
||||
});
|
||||
|
||||
testWidgets('select to scroll backward - horizontal', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('select to scroll backward - horizontal', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
selectionControls: materialTextSelectionControls,
|
||||
@ -430,8 +436,9 @@ void main() {
|
||||
await gesture.up();
|
||||
});
|
||||
|
||||
testWidgets('preserve selection when out of view.', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('preserve selection when out of view.', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
selectionControls: materialTextSelectionControls,
|
||||
@ -477,8 +484,9 @@ void main() {
|
||||
expect(paragraph50.selections[0], const TextSelection(baseOffset: 2, extentOffset: 4));
|
||||
});
|
||||
|
||||
testWidgets('can select all non-Apple', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('can select all non-Apple', (WidgetTester tester) async {
|
||||
final FocusNode node = FocusNode();
|
||||
addTearDown(node.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
focusNode: node,
|
||||
@ -503,8 +511,9 @@ void main() {
|
||||
expect(find.text('Item 13'), findsNothing);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android, TargetPlatform.windows, TargetPlatform.linux, TargetPlatform.fuchsia }));
|
||||
|
||||
testWidgets('can select all - Apple', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('can select all - Apple', (WidgetTester tester) async {
|
||||
final FocusNode node = FocusNode();
|
||||
addTearDown(node.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
focusNode: node,
|
||||
@ -529,8 +538,9 @@ void main() {
|
||||
expect(find.text('Item 13'), findsNothing);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('select to scroll by dragging selection handles forward', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('select to scroll by dragging selection handles forward', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
selectionControls: materialTextSelectionControls,
|
||||
@ -586,8 +596,9 @@ void main() {
|
||||
await gesture.up();
|
||||
});
|
||||
|
||||
testWidgets('select to scroll by dragging start selection handle stops scroll when released', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('select to scroll by dragging start selection handle stops scroll when released', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
selectionControls: materialTextSelectionControls,
|
||||
@ -640,8 +651,9 @@ void main() {
|
||||
expect(controller.offset, previousOffset);
|
||||
});
|
||||
|
||||
testWidgets('select to scroll by dragging end selection handle stops scroll when released', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('select to scroll by dragging end selection handle stops scroll when released', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
selectionControls: materialTextSelectionControls,
|
||||
@ -693,9 +705,11 @@ void main() {
|
||||
expect(controller.offset, previousOffset);
|
||||
});
|
||||
|
||||
testWidgets('keyboard selection should auto scroll - vertical', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('keyboard selection should auto scroll - vertical', (WidgetTester tester) async {
|
||||
final FocusNode node = FocusNode();
|
||||
addTearDown(node.dispose);
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
focusNode: node,
|
||||
@ -756,9 +770,11 @@ void main() {
|
||||
expect(controller.offset, 72.0);
|
||||
}, variant: TargetPlatformVariant.all());
|
||||
|
||||
testWidgets('keyboard selection should auto scroll - vertical reversed', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('keyboard selection should auto scroll - vertical reversed', (WidgetTester tester) async {
|
||||
final FocusNode node = FocusNode();
|
||||
addTearDown(node.dispose);
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
focusNode: node,
|
||||
@ -820,9 +836,11 @@ void main() {
|
||||
expect(controller.offset, 72.0);
|
||||
}, variant: TargetPlatformVariant.all());
|
||||
|
||||
testWidgets('keyboard selection should auto scroll - horizontal', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('keyboard selection should auto scroll - horizontal', (WidgetTester tester) async {
|
||||
final FocusNode node = FocusNode();
|
||||
addTearDown(node.dispose);
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
focusNode: node,
|
||||
@ -866,9 +884,11 @@ void main() {
|
||||
expect(controller.offset, 352.0);
|
||||
}, variant: TargetPlatformVariant.all());
|
||||
|
||||
testWidgets('keyboard selection should auto scroll - horizontal reversed', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('keyboard selection should auto scroll - horizontal reversed', (WidgetTester tester) async {
|
||||
final FocusNode node = FocusNode();
|
||||
addTearDown(node.dispose);
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
focusNode: node,
|
||||
@ -922,8 +942,9 @@ void main() {
|
||||
}, variant: TargetPlatformVariant.all());
|
||||
|
||||
group('Complex cases', () {
|
||||
testWidgets('selection starts outside of the scrollable', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('selection starts outside of the scrollable', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
selectionControls: materialTextSelectionControls,
|
||||
@ -966,9 +987,11 @@ void main() {
|
||||
expect(controller.offset, 1000.0);
|
||||
});
|
||||
|
||||
testWidgets('nested scrollables keep selection alive', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('nested scrollables keep selection alive', (WidgetTester tester) async {
|
||||
final ScrollController outerController = ScrollController();
|
||||
addTearDown(outerController.dispose);
|
||||
final ScrollController innerController = ScrollController();
|
||||
addTearDown(innerController.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
selectionControls: materialTextSelectionControls,
|
||||
@ -1030,9 +1053,11 @@ void main() {
|
||||
expect(innerParagraph24.selections[0], const TextSelection(baseOffset: 0, extentOffset: 2));
|
||||
});
|
||||
|
||||
testWidgets('can copy off screen selection - Apple', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('can copy off screen selection - Apple', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
final FocusNode focusNode = FocusNode();
|
||||
addTearDown(focusNode.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
focusNode: focusNode,
|
||||
@ -1071,9 +1096,11 @@ void main() {
|
||||
expect(clipboardData['text'], 'em 0It');
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('can copy off screen selection - non-Apple', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('can copy off screen selection - non-Apple', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
final FocusNode focusNode = FocusNode();
|
||||
addTearDown(focusNode.dispose);
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: SelectionArea(
|
||||
focusNode: focusNode,
|
||||
|
||||
@ -6,6 +6,7 @@ import 'package:flutter/gestures.dart' show DragStartBehavior;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
import 'semantics_tester.dart';
|
||||
|
||||
@ -16,7 +17,7 @@ void main() {
|
||||
debugResetSemanticsIdCounter();
|
||||
});
|
||||
|
||||
testWidgets('scrollable exposes the correct semantic actions', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('scrollable exposes the correct semantic actions', (WidgetTester tester) async {
|
||||
semantics = SemanticsTester(tester);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
@ -42,7 +43,7 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('showOnScreen works in scrollable', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('showOnScreen works in scrollable', (WidgetTester tester) async {
|
||||
semantics = SemanticsTester(tester); // enables semantics tree generation
|
||||
|
||||
const double kItemHeight = 40.0;
|
||||
@ -57,6 +58,7 @@ void main() {
|
||||
final ScrollController scrollController = ScrollController(
|
||||
initialScrollOffset: kItemHeight / 2,
|
||||
);
|
||||
addTearDown(scrollController.dispose);
|
||||
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
@ -80,7 +82,7 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('showOnScreen works with pinned app bar and sliver list', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('showOnScreen works with pinned app bar and sliver list', (WidgetTester tester) async {
|
||||
semantics = SemanticsTester(tester); // enables semantics tree generation
|
||||
|
||||
const double kItemHeight = 100.0;
|
||||
@ -96,6 +98,7 @@ void main() {
|
||||
final ScrollController scrollController = ScrollController(
|
||||
initialScrollOffset: kItemHeight / 2,
|
||||
);
|
||||
addTearDown(scrollController.dispose);
|
||||
|
||||
await tester.pumpWidget(Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -142,7 +145,7 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('showOnScreen works with pinned app bar and individual slivers', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('showOnScreen works with pinned app bar and individual slivers', (WidgetTester tester) async {
|
||||
semantics = SemanticsTester(tester); // enables semantics tree generation
|
||||
|
||||
const double kItemHeight = 100.0;
|
||||
@ -166,6 +169,7 @@ void main() {
|
||||
final ScrollController scrollController = ScrollController(
|
||||
initialScrollOffset: 2.5 * kItemHeight,
|
||||
);
|
||||
addTearDown(scrollController.dispose);
|
||||
|
||||
await tester.pumpWidget(Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -210,7 +214,7 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('correct scrollProgress', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('correct scrollProgress', (WidgetTester tester) async {
|
||||
semantics = SemanticsTester(tester);
|
||||
|
||||
await tester.pumpWidget(Directionality(
|
||||
@ -253,7 +257,7 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('correct scrollProgress for unbound', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('correct scrollProgress for unbound', (WidgetTester tester) async {
|
||||
semantics = SemanticsTester(tester);
|
||||
|
||||
await tester.pumpWidget(Directionality(
|
||||
@ -303,7 +307,7 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('Semantics tree is populated mid-scroll', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Semantics tree is populated mid-scroll', (WidgetTester tester) async {
|
||||
semantics = SemanticsTester(tester);
|
||||
|
||||
final List<Widget> children = List<Widget>.generate(80, (int i) => SizedBox(
|
||||
@ -328,7 +332,7 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('Can toggle semantics on, off, on without crash', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Can toggle semantics on, off, on without crash', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -434,7 +438,7 @@ void main() {
|
||||
|
||||
});
|
||||
|
||||
testWidgets('brings item above leading edge to leading edge', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('brings item above leading edge to leading edge', (WidgetTester tester) async {
|
||||
semantics = SemanticsTester(tester); // enables semantics tree generation
|
||||
|
||||
await tester.pumpWidget(widgetUnderTest);
|
||||
@ -450,7 +454,7 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('brings item below trailing edge to trailing edge', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('brings item below trailing edge to trailing edge', (WidgetTester tester) async {
|
||||
semantics = SemanticsTester(tester); // enables semantics tree generation
|
||||
|
||||
await tester.pumpWidget(widgetUnderTest);
|
||||
@ -466,7 +470,7 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('does not change position of items already fully on-screen', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('does not change position of items already fully on-screen', (WidgetTester tester) async {
|
||||
semantics = SemanticsTester(tester); // enables semantics tree generation
|
||||
|
||||
await tester.pumpWidget(widgetUnderTest);
|
||||
@ -536,10 +540,13 @@ void main() {
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
});
|
||||
|
||||
testWidgets('brings item above leading edge to leading edge', (WidgetTester tester) async {
|
||||
tearDown(() {
|
||||
scrollController.dispose();
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('brings item above leading edge to leading edge', (WidgetTester tester) async {
|
||||
semantics = SemanticsTester(tester); // enables semantics tree generation
|
||||
|
||||
await tester.pumpWidget(widgetUnderTest);
|
||||
@ -555,7 +562,7 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('brings item below trailing edge to trailing edge', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('brings item below trailing edge to trailing edge', (WidgetTester tester) async {
|
||||
semantics = SemanticsTester(tester); // enables semantics tree generation
|
||||
|
||||
await tester.pumpWidget(widgetUnderTest);
|
||||
@ -571,7 +578,7 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('does not change position of items already fully on-screen', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('does not change position of items already fully on-screen', (WidgetTester tester) async {
|
||||
semantics = SemanticsTester(tester); // enables semantics tree generation
|
||||
|
||||
await tester.pumpWidget(widgetUnderTest);
|
||||
@ -589,7 +596,7 @@ void main() {
|
||||
|
||||
});
|
||||
|
||||
testWidgets('transform of inner node from useTwoPaneSemantics scrolls correctly with nested scrollables', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('transform of inner node from useTwoPaneSemantics scrolls correctly with nested scrollables', (WidgetTester tester) async {
|
||||
semantics = SemanticsTester(tester); // enables semantics tree generation
|
||||
|
||||
// Context: https://github.com/flutter/flutter/issues/61631
|
||||
|
||||
@ -5,13 +5,17 @@
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
import 'semantics_tester.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Traversal Order of SliverList', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Traversal Order of SliverList', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
|
||||
final ScrollController controller = ScrollController(initialScrollOffset: 3000.0);
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
final List<Widget> listChildren = List<Widget>.generate(30, (int i) {
|
||||
return SizedBox(
|
||||
height: 200.0,
|
||||
@ -38,7 +42,7 @@ void main() {
|
||||
child: MediaQuery(
|
||||
data: const MediaQueryData(),
|
||||
child: CustomScrollView(
|
||||
controller: ScrollController(initialScrollOffset: 3000.0),
|
||||
controller: controller,
|
||||
semanticChildCount: 30,
|
||||
slivers: <Widget>[
|
||||
SliverList(
|
||||
@ -182,9 +186,12 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('Traversal Order of SliverFixedExtentList', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Traversal Order of SliverFixedExtentList', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
|
||||
final ScrollController controller = ScrollController(initialScrollOffset: 3000.0);
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
final List<Widget> listChildren = List<Widget>.generate(30, (int i) {
|
||||
return SizedBox(
|
||||
height: 200.0,
|
||||
@ -211,7 +218,7 @@ void main() {
|
||||
child: MediaQuery(
|
||||
data: const MediaQueryData(),
|
||||
child: CustomScrollView(
|
||||
controller: ScrollController(initialScrollOffset: 3000.0),
|
||||
controller: controller,
|
||||
slivers: <Widget>[
|
||||
SliverFixedExtentList(
|
||||
itemExtent: 200.0,
|
||||
@ -321,9 +328,12 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('Traversal Order of SliverGrid', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Traversal Order of SliverGrid', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
|
||||
final ScrollController controller = ScrollController(initialScrollOffset: 1600.0);
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
final List<Widget> listChildren = List<Widget>.generate(30, (int i) {
|
||||
return SizedBox(
|
||||
height: 200.0,
|
||||
@ -338,7 +348,7 @@ void main() {
|
||||
child: MediaQuery(
|
||||
data: const MediaQueryData(),
|
||||
child: CustomScrollView(
|
||||
controller: ScrollController(initialScrollOffset: 1600.0),
|
||||
controller: controller,
|
||||
slivers: <Widget>[
|
||||
SliverGrid.count(
|
||||
crossAxisCount: 2,
|
||||
@ -449,9 +459,12 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('Traversal Order of List of individual slivers', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Traversal Order of List of individual slivers', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
|
||||
final ScrollController controller = ScrollController(initialScrollOffset: 3000.0);
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
final List<Widget> listChildren = List<Widget>.generate(30, (int i) {
|
||||
return SliverToBoxAdapter(
|
||||
child: SizedBox(
|
||||
@ -480,7 +493,7 @@ void main() {
|
||||
child: MediaQuery(
|
||||
data: const MediaQueryData(),
|
||||
child: CustomScrollView(
|
||||
controller: ScrollController(initialScrollOffset: 3000.0),
|
||||
controller: controller,
|
||||
slivers: listChildren,
|
||||
),
|
||||
),
|
||||
@ -585,9 +598,12 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('Traversal Order of in a SingleChildScrollView', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Traversal Order of in a SingleChildScrollView', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
|
||||
final ScrollController controller = ScrollController(initialScrollOffset: 3000.0);
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
final List<Widget> listChildren = List<Widget>.generate(30, (int i) {
|
||||
return SizedBox(
|
||||
height: 200.0,
|
||||
@ -614,7 +630,7 @@ void main() {
|
||||
child: MediaQuery(
|
||||
data: const MediaQueryData(),
|
||||
child: SingleChildScrollView(
|
||||
controller: ScrollController(initialScrollOffset: 3000.0),
|
||||
controller: controller,
|
||||
child: Column(
|
||||
children: listChildren,
|
||||
),
|
||||
@ -671,7 +687,7 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('Traversal Order with center child', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Traversal Order with center child', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
|
||||
await tester.pumpWidget(Semantics(
|
||||
|
||||
@ -10,6 +10,7 @@ import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter/scheduler.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
import 'semantics_tester.dart';
|
||||
|
||||
@ -109,7 +110,7 @@ void resetScrollOffset(WidgetTester tester) {
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('Flings on different platforms', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Flings on different platforms', (WidgetTester tester) async {
|
||||
await pumpTest(tester, TargetPlatform.android);
|
||||
await tester.fling(find.byType(Scrollable), const Offset(0.0, -dragOffset), 1000.0);
|
||||
expect(getScrollOffset(tester), dragOffset);
|
||||
@ -145,7 +146,7 @@ void main() {
|
||||
expect(macOSResult, lessThan(iOSResult)); // iOS is slipperier than macOS
|
||||
});
|
||||
|
||||
testWidgets('Holding scroll', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Holding scroll', (WidgetTester tester) async {
|
||||
await pumpTest(tester, debugDefaultTargetPlatformOverride);
|
||||
await tester.drag(find.byType(Scrollable), const Offset(0.0, 200.0), touchSlopY: 0.0);
|
||||
expect(getScrollOffset(tester), -200.0);
|
||||
@ -164,7 +165,7 @@ void main() {
|
||||
expect(getScrollOffset(tester), 0.0);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('Repeated flings builds momentum', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Repeated flings builds momentum', (WidgetTester tester) async {
|
||||
await pumpTest(tester, debugDefaultTargetPlatformOverride);
|
||||
await tester.fling(find.byType(Scrollable), const Offset(0.0, -dragOffset), 1000.0);
|
||||
await tester.pump(); // trigger fling
|
||||
@ -177,7 +178,7 @@ void main() {
|
||||
expect(getScrollVelocity(tester), greaterThan(1100.0));
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('Repeated flings do not build momentum on Android', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Repeated flings do not build momentum on Android', (WidgetTester tester) async {
|
||||
await pumpTest(tester, TargetPlatform.android);
|
||||
await tester.fling(find.byType(Scrollable), const Offset(0.0, -dragOffset), 1000.0);
|
||||
await tester.pump(); // trigger fling
|
||||
@ -190,7 +191,7 @@ void main() {
|
||||
expect(getScrollVelocity(tester), moreOrLessEquals(1000.0));
|
||||
});
|
||||
|
||||
testWidgets('A slower final fling does not apply carried momentum', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('A slower final fling does not apply carried momentum', (WidgetTester tester) async {
|
||||
await pumpTest(tester, debugDefaultTargetPlatformOverride);
|
||||
await tester.fling(find.byType(Scrollable), const Offset(0.0, -dragOffset), 1000.0);
|
||||
await tester.pump(); // trigger fling
|
||||
@ -207,7 +208,7 @@ void main() {
|
||||
expect(getScrollVelocity(tester), lessThan(200.0));
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('No iOS/macOS momentum build with flings in opposite directions', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('No iOS/macOS momentum build with flings in opposite directions', (WidgetTester tester) async {
|
||||
await pumpTest(tester, debugDefaultTargetPlatformOverride);
|
||||
await tester.fling(find.byType(Scrollable), const Offset(0.0, -dragOffset), 1000.0);
|
||||
await tester.pump(); // trigger fling
|
||||
@ -220,7 +221,7 @@ void main() {
|
||||
expect(getScrollVelocity(tester), -1000.0);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('No iOS/macOS momentum kept on hold gestures', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('No iOS/macOS momentum kept on hold gestures', (WidgetTester tester) async {
|
||||
await pumpTest(tester, debugDefaultTargetPlatformOverride);
|
||||
await tester.fling(find.byType(Scrollable), const Offset(0.0, -dragOffset), 1000.0);
|
||||
await tester.pump(); // trigger fling
|
||||
@ -233,7 +234,7 @@ void main() {
|
||||
expect(getScrollVelocity(tester), 0.0);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('Drags creeping unaffected on Android', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Drags creeping unaffected on Android', (WidgetTester tester) async {
|
||||
await pumpTest(tester, TargetPlatform.android);
|
||||
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(Scrollable), warnIfMissed: true));
|
||||
await gesture.moveBy(const Offset(0.0, -0.5));
|
||||
@ -244,7 +245,7 @@ void main() {
|
||||
expect(getScrollOffset(tester), 1.5);
|
||||
});
|
||||
|
||||
testWidgets('Drags creeping must break threshold on iOS/macOS', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Drags creeping must break threshold on iOS/macOS', (WidgetTester tester) async {
|
||||
await pumpTest(tester, debugDefaultTargetPlatformOverride);
|
||||
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(Scrollable), warnIfMissed: true));
|
||||
await gesture.moveBy(const Offset(0.0, -0.5));
|
||||
@ -264,7 +265,7 @@ void main() {
|
||||
expect(getScrollOffset(tester), 0.5);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('Big drag over threshold magnitude preserved on iOS/macOS', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Big drag over threshold magnitude preserved on iOS/macOS', (WidgetTester tester) async {
|
||||
await pumpTest(tester, debugDefaultTargetPlatformOverride);
|
||||
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(Scrollable), warnIfMissed: true));
|
||||
await gesture.moveBy(const Offset(0.0, -30.0));
|
||||
@ -272,7 +273,7 @@ void main() {
|
||||
expect(getScrollOffset(tester), 30.0);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('Slow threshold breaks are attenuated on iOS/macOS', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Slow threshold breaks are attenuated on iOS/macOS', (WidgetTester tester) async {
|
||||
await pumpTest(tester, debugDefaultTargetPlatformOverride);
|
||||
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(Scrollable), warnIfMissed: true));
|
||||
// This is a typical 'hesitant' iOS scroll start.
|
||||
@ -283,7 +284,7 @@ void main() {
|
||||
expect(getScrollOffset(tester), moreOrLessEquals(11.16666666666666673));
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('Small continuing motion preserved on iOS/macOS', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Small continuing motion preserved on iOS/macOS', (WidgetTester tester) async {
|
||||
await pumpTest(tester, debugDefaultTargetPlatformOverride);
|
||||
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(Scrollable), warnIfMissed: true));
|
||||
await gesture.moveBy(const Offset(0.0, -30.0)); // Break threshold.
|
||||
@ -296,7 +297,7 @@ void main() {
|
||||
expect(getScrollOffset(tester), 31.5);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('Motion stop resets threshold on iOS/macOS', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Motion stop resets threshold on iOS/macOS', (WidgetTester tester) async {
|
||||
await pumpTest(tester, debugDefaultTargetPlatformOverride);
|
||||
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(Scrollable), warnIfMissed: true));
|
||||
await gesture.moveBy(const Offset(0.0, -30.0)); // Break threshold.
|
||||
@ -319,7 +320,7 @@ void main() {
|
||||
expect(getScrollOffset(tester), 32.5);
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||
|
||||
testWidgets('Scroll pointer signals are handled on Fuchsia', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scroll pointer signals are handled on Fuchsia', (WidgetTester tester) async {
|
||||
await pumpTest(tester, TargetPlatform.fuchsia);
|
||||
final Offset scrollEventLocation = tester.getCenter(find.byType(Viewport));
|
||||
final TestPointer testPointer = TestPointer(1, ui.PointerDeviceKind.mouse);
|
||||
@ -332,7 +333,7 @@ void main() {
|
||||
expect(getScrollOffset(tester), 0.0);
|
||||
});
|
||||
|
||||
testWidgets('Scroll pointer signals are handled when there is competition', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scroll pointer signals are handled when there is competition', (WidgetTester tester) async {
|
||||
// This is a regression test. When there are multiple scrollables listening
|
||||
// to the same event, for example when scrollables are nested, there used
|
||||
// to be exceptions at scrolling events.
|
||||
@ -349,7 +350,7 @@ void main() {
|
||||
expect(getScrollOffset(tester), 0.0);
|
||||
});
|
||||
|
||||
testWidgets('Scroll pointer signals are ignored when scrolling is disabled', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scroll pointer signals are ignored when scrolling is disabled', (WidgetTester tester) async {
|
||||
await pumpTest(tester, TargetPlatform.fuchsia, scrollable: false);
|
||||
final Offset scrollEventLocation = tester.getCenter(find.byType(Viewport));
|
||||
final TestPointer testPointer = TestPointer(1, ui.PointerDeviceKind.mouse);
|
||||
@ -359,10 +360,12 @@ void main() {
|
||||
expect(getScrollOffset(tester), 0.0);
|
||||
});
|
||||
|
||||
testWidgets('Holding scroll and Scroll pointer signal will update ScrollDirection.forward / ScrollDirection.reverse', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Holding scroll and Scroll pointer signal will update ScrollDirection.forward / ScrollDirection.reverse', (WidgetTester tester) async {
|
||||
ScrollDirection? lastUserScrollingDirection;
|
||||
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
await pumpTest(tester, TargetPlatform.fuchsia, controller: controller);
|
||||
|
||||
controller.addListener(() {
|
||||
@ -393,7 +396,7 @@ void main() {
|
||||
});
|
||||
|
||||
|
||||
testWidgets('Scrolls in correct direction when scroll axis is reversed', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrolls in correct direction when scroll axis is reversed', (WidgetTester tester) async {
|
||||
await pumpTest(tester, TargetPlatform.fuchsia, reverse: true);
|
||||
|
||||
final Offset scrollEventLocation = tester.getCenter(find.byType(Viewport));
|
||||
@ -405,7 +408,7 @@ void main() {
|
||||
expect(getScrollOffset(tester), 20.0);
|
||||
});
|
||||
|
||||
testWidgets('Scrolls horizontally when shift is pressed by default', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrolls horizontally when shift is pressed by default', (WidgetTester tester) async {
|
||||
await pumpTest(
|
||||
tester,
|
||||
debugDefaultTargetPlatformOverride,
|
||||
@ -432,7 +435,7 @@ void main() {
|
||||
expect(getScrollOffset(tester), 20.0);
|
||||
}, variant: TargetPlatformVariant.all());
|
||||
|
||||
testWidgets('Scroll axis is not flipped for trackpad', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scroll axis is not flipped for trackpad', (WidgetTester tester) async {
|
||||
await pumpTest(
|
||||
tester,
|
||||
debugDefaultTargetPlatformOverride,
|
||||
@ -459,7 +462,7 @@ void main() {
|
||||
expect(getScrollOffset(tester), 0.0);
|
||||
}, variant: TargetPlatformVariant.all());
|
||||
|
||||
testWidgets('Scrolls horizontally when custom key is pressed', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrolls horizontally when custom key is pressed', (WidgetTester tester) async {
|
||||
await pumpTest(
|
||||
tester,
|
||||
debugDefaultTargetPlatformOverride,
|
||||
@ -487,7 +490,7 @@ void main() {
|
||||
expect(getScrollOffset(tester), 20.0);
|
||||
}, variant: TargetPlatformVariant.all());
|
||||
|
||||
testWidgets('Still scrolls horizontally when other keys are pressed at the same time', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Still scrolls horizontally when other keys are pressed at the same time', (WidgetTester tester) async {
|
||||
await pumpTest(
|
||||
tester,
|
||||
debugDefaultTargetPlatformOverride,
|
||||
@ -536,7 +539,7 @@ void main() {
|
||||
);
|
||||
}
|
||||
|
||||
testWidgets('Hold does not disable user interaction', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Hold does not disable user interaction', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/66816.
|
||||
await pumpTestWidget(tester, canDrag: true);
|
||||
final RenderIgnorePointer renderIgnorePointer = tester.renderObject<RenderIgnorePointer>(
|
||||
@ -555,7 +558,7 @@ void main() {
|
||||
expect(renderIgnorePointer.ignoring, false);
|
||||
});
|
||||
|
||||
testWidgets('Drag disables user interaction when recognized', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Drag disables user interaction when recognized', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/66816.
|
||||
await pumpTestWidget(tester, canDrag: true);
|
||||
final RenderIgnorePointer renderIgnorePointer = tester.renderObject<RenderIgnorePointer>(
|
||||
@ -577,7 +580,7 @@ void main() {
|
||||
expect(renderIgnorePointer.ignoring, false);
|
||||
});
|
||||
|
||||
testWidgets('Ballistic disables user interaction until it stops', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Ballistic disables user interaction until it stops', (WidgetTester tester) async {
|
||||
await pumpTestWidget(tester, canDrag: true);
|
||||
final RenderIgnorePointer renderIgnorePointer = tester.renderObject<RenderIgnorePointer>(
|
||||
find.descendant(of: find.byType(CustomScrollView), matching: find.byType(IgnorePointer)),
|
||||
@ -595,11 +598,13 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('Can recommendDeferredLoadingForContext - animation', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Can recommendDeferredLoadingForContext - animation', (WidgetTester tester) async {
|
||||
final List<String> widgetTracker = <String>[];
|
||||
int cheapWidgets = 0;
|
||||
int expensiveWidgets = 0;
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
await tester.pumpWidget(Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: ListView.builder(
|
||||
@ -650,7 +655,7 @@ void main() {
|
||||
expect(widgetTracker.skip(17).skip(25).skip(70).every((String type) => type == 'expensive'), true);
|
||||
});
|
||||
|
||||
testWidgets('Can recommendDeferredLoadingForContext - ballistics', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Can recommendDeferredLoadingForContext - ballistics', (WidgetTester tester) async {
|
||||
int cheapWidgets = 0;
|
||||
int expensiveWidgets = 0;
|
||||
await tester.pumpWidget(Directionality(
|
||||
@ -687,7 +692,7 @@ void main() {
|
||||
expect(cheapWidgets, 21);
|
||||
});
|
||||
|
||||
testWidgets('Can recommendDeferredLoadingForContext - override heuristic', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Can recommendDeferredLoadingForContext - override heuristic', (WidgetTester tester) async {
|
||||
int cheapWidgets = 0;
|
||||
int expensiveWidgets = 0;
|
||||
await tester.pumpWidget(Directionality(
|
||||
@ -731,7 +736,7 @@ void main() {
|
||||
expect(physics.count, 44 + 17);
|
||||
});
|
||||
|
||||
testWidgets('Can recommendDeferredLoadingForContext - override heuristic and always return true', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Can recommendDeferredLoadingForContext - override heuristic and always return true', (WidgetTester tester) async {
|
||||
int cheapWidgets = 0;
|
||||
int expensiveWidgets = 0;
|
||||
await tester.pumpWidget(Directionality(
|
||||
@ -772,8 +777,9 @@ void main() {
|
||||
expect(cheapWidgets, 61);
|
||||
});
|
||||
|
||||
testWidgets('ensureVisible does not move PageViews', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ensureVisible does not move PageViews', (WidgetTester tester) async {
|
||||
final PageController controller = PageController();
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
@ -855,7 +861,7 @@ void main() {
|
||||
expect(targetMidLeftPage1, findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('ensureVisible does not move TabViews', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ensureVisible does not move TabViews', (WidgetTester tester) async {
|
||||
final TickerProvider vsync = TestTickerProvider();
|
||||
final TabController controller = TabController(
|
||||
length: 3,
|
||||
@ -942,10 +948,13 @@ void main() {
|
||||
expect(targetMidLeftPage1, findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('PointerScroll on nested NeverScrollable ListView goes to outer Scrollable.', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('PointerScroll on nested NeverScrollable ListView goes to outer Scrollable.', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/70948
|
||||
final ScrollController outerController = ScrollController();
|
||||
addTearDown(outerController.dispose);
|
||||
final ScrollController innerController = ScrollController();
|
||||
addTearDown(innerController.dispose);
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
home: Scaffold(
|
||||
@ -999,8 +1008,10 @@ void main() {
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/71949
|
||||
testWidgets('Zero offset pointer scroll should not trigger an assertion.', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Zero offset pointer scroll should not trigger an assertion.', (WidgetTester tester) async {
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
Widget build(double height) {
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
@ -1039,7 +1050,7 @@ void main() {
|
||||
expect(tester.takeException(), null);
|
||||
});
|
||||
|
||||
testWidgets('Accepts drag with unknown device kind by default', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Accepts drag with unknown device kind by default', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/90912.
|
||||
await tester.pumpWidget(
|
||||
const MaterialApp(
|
||||
@ -1068,7 +1079,7 @@ void main() {
|
||||
await tester.pump();
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS, TargetPlatform.android }));
|
||||
|
||||
testWidgets('Does not scroll with mouse pointer drag when behavior is configured to ignore them', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Does not scroll with mouse pointer drag when behavior is configured to ignore them', (WidgetTester tester) async {
|
||||
await pumpTest(tester, debugDefaultTargetPlatformOverride, enableMouseDrag: false);
|
||||
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(Scrollable), warnIfMissed: true), kind: ui.PointerDeviceKind.mouse);
|
||||
|
||||
@ -1088,7 +1099,7 @@ void main() {
|
||||
await tester.pump();
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS, TargetPlatform.android }));
|
||||
|
||||
testWidgets("Support updating 'ScrollBehavior.dragDevices' at runtime", (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking("Support updating 'ScrollBehavior.dragDevices' at runtime", (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/111716
|
||||
Widget buildFrame(Set<ui.PointerDeviceKind>? dragDevices) {
|
||||
return MaterialApp(
|
||||
@ -1122,7 +1133,7 @@ void main() {
|
||||
expect(getScrollOffset(tester), 200.0);
|
||||
});
|
||||
|
||||
testWidgets('Does scroll with mouse pointer drag when behavior is not configured to ignore them', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Does scroll with mouse pointer drag when behavior is not configured to ignore them', (WidgetTester tester) async {
|
||||
await pumpTest(tester, debugDefaultTargetPlatformOverride);
|
||||
final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byType(Scrollable), warnIfMissed: true), kind: ui.PointerDeviceKind.mouse);
|
||||
|
||||
@ -1142,7 +1153,7 @@ void main() {
|
||||
await tester.pump();
|
||||
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS, TargetPlatform.android }));
|
||||
|
||||
testWidgets('Updated content dimensions correctly reflect in semantics', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Updated content dimensions correctly reflect in semantics', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/40419.
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
final UniqueKey listView = UniqueKey();
|
||||
@ -1200,7 +1211,7 @@ void main() {
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('Two panel semantics is added to the sibling nodes of direct children', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Two panel semantics is added to the sibling nodes of direct children', (WidgetTester tester) async {
|
||||
final SemanticsHandle handle = tester.ensureSemantics();
|
||||
final UniqueKey key = UniqueKey();
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
@ -1245,7 +1256,7 @@ void main() {
|
||||
handle.dispose();
|
||||
});
|
||||
|
||||
testWidgets('Scroll inertia cancel event', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scroll inertia cancel event', (WidgetTester tester) async {
|
||||
await pumpTest(tester, null);
|
||||
await tester.fling(find.byType(Scrollable), const Offset(0.0, -dragOffset), 1000.0);
|
||||
expect(getScrollOffset(tester), dragOffset);
|
||||
@ -1261,7 +1272,7 @@ void main() {
|
||||
expect(getScrollOffset(tester), closeTo(344.0642, 0.0001));
|
||||
});
|
||||
|
||||
testWidgets('Swapping viewports in a scrollable does not crash', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Swapping viewports in a scrollable does not crash', (WidgetTester tester) async {
|
||||
final SemanticsTester semantics = SemanticsTester(tester);
|
||||
final GlobalKey key = GlobalKey();
|
||||
final GlobalKey key1 = GlobalKey();
|
||||
@ -1270,11 +1281,13 @@ void main() {
|
||||
key: key,
|
||||
viewportBuilder: (BuildContext context, ViewportOffset position) {
|
||||
if (withViewPort) {
|
||||
final ViewportOffset offset = ViewportOffset.zero();
|
||||
addTearDown(() => offset.dispose());
|
||||
return Viewport(
|
||||
slivers: <Widget>[
|
||||
SliverToBoxAdapter(child: Semantics(key: key1, container: true, child: const Text('text1')))
|
||||
],
|
||||
offset: ViewportOffset.zero(),
|
||||
offset: offset,
|
||||
);
|
||||
}
|
||||
return Semantics(key: key1, container: true, child: const Text('text1'));
|
||||
@ -1306,7 +1319,7 @@ void main() {
|
||||
semantics.dispose();
|
||||
});
|
||||
|
||||
testWidgets('deltaToScrollOrigin getter', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('deltaToScrollOrigin getter', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const MaterialApp(
|
||||
home: CustomScrollView(
|
||||
@ -1327,7 +1340,7 @@ void main() {
|
||||
expect(scrollable.deltaToScrollOrigin, const Offset(0.0, 200));
|
||||
});
|
||||
|
||||
testWidgets('resolvedPhysics getter', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('resolvedPhysics getter', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
theme: ThemeData.light().copyWith(
|
||||
@ -1357,7 +1370,7 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('dragDevices change updates widget', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('dragDevices change updates widget', (WidgetTester tester) async {
|
||||
bool enable = false;
|
||||
|
||||
await tester.pumpWidget(
|
||||
@ -1410,7 +1423,7 @@ void main() {
|
||||
expect(getScrollOffset(tester), 200);
|
||||
});
|
||||
|
||||
testWidgets('dragDevices change updates widget when oldWidget scrollBehavior is null', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('dragDevices change updates widget when oldWidget scrollBehavior is null', (WidgetTester tester) async {
|
||||
ScrollBehavior? scrollBehavior;
|
||||
|
||||
await tester.pumpWidget(
|
||||
|
||||
@ -8,6 +8,7 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/src/physics/utils.dart' show nearEqual;
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
|
||||
const Color _kScrollbarColor = Color(0xFF123456);
|
||||
const double _kThickness = 2.5;
|
||||
@ -384,7 +385,7 @@ void main() {
|
||||
scrollMetrics: metrics,
|
||||
);
|
||||
|
||||
testWidgets('down', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('down', (WidgetTester tester) async {
|
||||
painter.update(
|
||||
metrics.copyWith(
|
||||
viewportDimension: size.height,
|
||||
@ -414,7 +415,7 @@ void main() {
|
||||
expect(size.width - rect1.right, padding.right);
|
||||
});
|
||||
|
||||
testWidgets('up', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('up', (WidgetTester tester) async {
|
||||
painter.update(
|
||||
metrics.copyWith(
|
||||
viewportDimension: size.height,
|
||||
@ -446,7 +447,7 @@ void main() {
|
||||
expect(size.width - rect1.right, padding.right);
|
||||
});
|
||||
|
||||
testWidgets('left', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('left', (WidgetTester tester) async {
|
||||
painter.update(
|
||||
metrics.copyWith(
|
||||
viewportDimension: size.width,
|
||||
@ -478,7 +479,7 @@ void main() {
|
||||
expect(rect1.left, padding.left);
|
||||
});
|
||||
|
||||
testWidgets('right', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('right', (WidgetTester tester) async {
|
||||
painter.update(
|
||||
metrics.copyWith(
|
||||
viewportDimension: size.width,
|
||||
@ -511,7 +512,7 @@ void main() {
|
||||
});
|
||||
});
|
||||
|
||||
testWidgets('thumb resizes gradually on overscroll', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('thumb resizes gradually on overscroll', (WidgetTester tester) async {
|
||||
const EdgeInsets padding = EdgeInsets.fromLTRB(1, 2, 3, 4);
|
||||
const Size size = Size(60, 300);
|
||||
final double scrollExtent = size.height * 10;
|
||||
@ -664,7 +665,7 @@ void main() {
|
||||
expect(trackRRect.trRadius, const Radius.circular(2.0));
|
||||
});
|
||||
|
||||
testWidgets('ScrollbarPainter asserts if no TextDirection has been provided', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ScrollbarPainter asserts if no TextDirection has been provided', (WidgetTester tester) async {
|
||||
final ScrollbarPainter painter = ScrollbarPainter(
|
||||
color: _kScrollbarColor,
|
||||
fadeoutOpacityAnimation: kAlwaysCompleteAnimation,
|
||||
@ -683,8 +684,9 @@ void main() {
|
||||
}
|
||||
});
|
||||
|
||||
testWidgets('Tapping the track area pages the Scroll View', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Tapping the track area pages the Scroll View', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -745,7 +747,7 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Scrollbar never goes away until finger lift', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrollbar never goes away until finger lift', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -803,7 +805,7 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Scrollbar does not fade away while hovering', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrollbar does not fade away while hovering', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -850,7 +852,7 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Scrollbar will fade back in when hovering over known track area', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrollbar will fade back in when hovering over known track area', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -911,7 +913,7 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Scrollbar will show on hover without needing to scroll first for metrics', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrollbar will show on hover without needing to scroll first for metrics', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
const Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -946,8 +948,9 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Scrollbar thumb can be dragged', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrollbar thumb can be dragged', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1001,8 +1004,9 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Scrollbar thumb cannot be dragged into overscroll if the physics do not allow', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrollbar thumb cannot be dragged into overscroll if the physics do not allow', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1053,8 +1057,9 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Scrollbar thumb cannot be dragged into overscroll if the platform does not allow it', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrollbar thumb cannot be dragged into overscroll if the platform does not allow it', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1121,8 +1126,9 @@ void main() {
|
||||
TargetPlatform.fuchsia,
|
||||
}));
|
||||
|
||||
testWidgets('Scrollbar thumb can be dragged into overscroll if the platform allows it', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrollbar thumb can be dragged into overscroll if the platform allows it', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1188,7 +1194,7 @@ void main() {
|
||||
}));
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/66444
|
||||
testWidgets("RawScrollbar doesn't show when scroll the inner scrollable widget", (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking("RawScrollbar doesn't show when scroll the inner scrollable widget", (WidgetTester tester) async {
|
||||
final GlobalKey key1 = GlobalKey();
|
||||
final GlobalKey key2 = GlobalKey();
|
||||
final GlobalKey outerKey = GlobalKey();
|
||||
@ -1250,8 +1256,9 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Scrollbar hit test area adjusts for PointerDeviceKind', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrollbar hit test area adjusts for PointerDeviceKind', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1339,9 +1346,10 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('hit test', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('hit test', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/99324
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
bool onTap = false;
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
@ -1388,12 +1396,14 @@ void main() {
|
||||
expect(onTap, true);
|
||||
});
|
||||
|
||||
testWidgets('RawScrollbar.thumbVisibility asserts that a ScrollPosition is attached', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('RawScrollbar.thumbVisibility asserts that a ScrollPosition is attached', (WidgetTester tester) async {
|
||||
final FlutterExceptionHandler? handler = FlutterError.onError;
|
||||
FlutterErrorDetails? error;
|
||||
FlutterError.onError = (FlutterErrorDetails details) {
|
||||
error = details;
|
||||
};
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
@ -1402,7 +1412,7 @@ void main() {
|
||||
data: const MediaQueryData(),
|
||||
child: RawScrollbar(
|
||||
thumbVisibility: true,
|
||||
controller: ScrollController(),
|
||||
controller: controller,
|
||||
thumbColor: const Color(0x11111111),
|
||||
child: const SingleChildScrollView(
|
||||
child: SizedBox(
|
||||
@ -1426,12 +1436,14 @@ void main() {
|
||||
FlutterError.onError = handler;
|
||||
});
|
||||
|
||||
testWidgets('RawScrollbar.thumbVisibility asserts that a ScrollPosition is attached', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('RawScrollbar.thumbVisibility asserts that a ScrollPosition is attached', (WidgetTester tester) async {
|
||||
final FlutterExceptionHandler? handler = FlutterError.onError;
|
||||
FlutterErrorDetails? error;
|
||||
FlutterError.onError = (FlutterErrorDetails details) {
|
||||
error = details;
|
||||
};
|
||||
final ScrollController controller = ScrollController();
|
||||
addTearDown(controller.dispose);
|
||||
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
@ -1440,7 +1452,7 @@ void main() {
|
||||
data: const MediaQueryData(),
|
||||
child: RawScrollbar(
|
||||
thumbVisibility: true,
|
||||
controller: ScrollController(),
|
||||
controller: controller,
|
||||
thumbColor: const Color(0x11111111),
|
||||
child: const SingleChildScrollView(
|
||||
child: SizedBox(
|
||||
@ -1464,9 +1476,11 @@ void main() {
|
||||
FlutterError.onError = handler;
|
||||
});
|
||||
|
||||
testWidgets('Interactive scrollbars should have a valid scroll controller', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Interactive scrollbars should have a valid scroll controller', (WidgetTester tester) async {
|
||||
final ScrollController primaryScrollController = ScrollController();
|
||||
addTearDown(primaryScrollController.dispose);
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
@ -1505,9 +1519,10 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Simultaneous dragging and pointer scrolling does not cause a crash', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Simultaneous dragging and pointer scrolling does not cause a crash', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/70105
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1679,8 +1694,9 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Scrollbar thumb can be dragged in reverse', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrollbar thumb can be dragged in reverse', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1735,7 +1751,7 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('ScrollbarPainter asserts if scrollbarOrientation is used with wrong axisDirection', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('ScrollbarPainter asserts if scrollbarOrientation is used with wrong axisDirection', (WidgetTester tester) async {
|
||||
final ScrollbarPainter painter = ScrollbarPainter(
|
||||
color: _kScrollbarColor,
|
||||
fadeoutOpacityAnimation: kAlwaysCompleteAnimation,
|
||||
@ -1753,8 +1769,9 @@ void main() {
|
||||
expect(() => painter.paint(testCanvas, size), throwsA(isA<AssertionError>()));
|
||||
});
|
||||
|
||||
testWidgets('RawScrollbar mainAxisMargin property works properly', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('RawScrollbar mainAxisMargin property works properly', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1783,8 +1800,9 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('shape property of RawScrollbar can draw a BeveledRectangleBorder', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('shape property of RawScrollbar can draw a BeveledRectangleBorder', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1820,8 +1838,9 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('minThumbLength property of RawScrollbar is respected', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('minThumbLength property of RawScrollbar is respected', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1846,8 +1865,9 @@ void main() {
|
||||
..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 21.0))); // thumb
|
||||
});
|
||||
|
||||
testWidgets('shape property of RawScrollbar can draw a CircleBorder', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('shape property of RawScrollbar can draw a CircleBorder', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1882,8 +1902,9 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('crossAxisMargin property of RawScrollbar is respected', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('crossAxisMargin property of RawScrollbar is respected', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1907,8 +1928,9 @@ void main() {
|
||||
..rect(rect: const Rect.fromLTRB(764.0, 0.0, 770.0, 360.0)));
|
||||
});
|
||||
|
||||
testWidgets('shape property of RawScrollbar can draw a RoundedRectangleBorder', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('shape property of RawScrollbar can draw a RoundedRectangleBorder', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1941,8 +1963,9 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('minOverscrollLength property of RawScrollbar is respected', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('minOverscrollLength property of RawScrollbar is respected', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1973,8 +1996,9 @@ void main() {
|
||||
..rect(rect: const Rect.fromLTRB(794.0, 0.0, 800.0, 8.0)));
|
||||
});
|
||||
|
||||
testWidgets('not passing any shape or radius to RawScrollbar will draw the usual rectangular thumb', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('not passing any shape or radius to RawScrollbar will draw the usual rectangular thumb', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -1999,8 +2023,9 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('The bar can show or hide when the viewport size change', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('The bar can show or hide when the viewport size change', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
Widget buildFrame(double height) {
|
||||
return Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -2030,10 +2055,11 @@ void main() {
|
||||
expect(find.byType(RawScrollbar), isNot(paints..rect())); // Hide the bar.
|
||||
});
|
||||
|
||||
testWidgets('The bar can show or hide when the view size change', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('The bar can show or hide when the view size change', (WidgetTester tester) async {
|
||||
addTearDown(tester.view.reset);
|
||||
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
Widget buildFrame() {
|
||||
return Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -2072,10 +2098,12 @@ void main() {
|
||||
expect(find.byType(RawScrollbar), isNot(paints..rect())); // Not shown.
|
||||
});
|
||||
|
||||
testWidgets('Scrollbar will not flip axes based on notification is there is a scroll controller', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrollbar will not flip axes based on notification is there is a scroll controller', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/87697
|
||||
final ScrollController verticalScrollController = ScrollController();
|
||||
addTearDown(verticalScrollController.dispose);
|
||||
final ScrollController horizontalScrollController = ScrollController();
|
||||
addTearDown(horizontalScrollController.dispose);
|
||||
Widget buildFrame() {
|
||||
return Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -2133,8 +2161,9 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('notificationPredicate depth test.', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('notificationPredicate depth test.', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
final List<int> depths = <int>[];
|
||||
Widget buildFrame() {
|
||||
return Directionality(
|
||||
@ -2167,8 +2196,9 @@ void main() {
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/92262
|
||||
testWidgets('Do not crash when resize from scrollable to non-scrollable.', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Do not crash when resize from scrollable to non-scrollable.', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
Widget buildFrame(double height) {
|
||||
return Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -2203,10 +2233,11 @@ void main() {
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets('Scrollbar thumb can be dragged when the scrollable widget has a negative minScrollExtent - desktop', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrollbar thumb can be dragged when the scrollable widget has a negative minScrollExtent - desktop', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/95840
|
||||
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
final UniqueKey uniqueKey = UniqueKey();
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
@ -2285,10 +2316,11 @@ void main() {
|
||||
);
|
||||
}, variant: TargetPlatformVariant.desktop());
|
||||
|
||||
testWidgets('Scrollbar thumb can be dragged when the scrollable widget has a negative minScrollExtent - mobile', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrollbar thumb can be dragged when the scrollable widget has a negative minScrollExtent - mobile', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/95840
|
||||
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
final UniqueKey uniqueKey = UniqueKey();
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
@ -2421,8 +2453,9 @@ void main() {
|
||||
expect(painter.shouldRepaint(createPainter(scrollbarOrientation: ScrollbarOrientation.bottom)), true);
|
||||
});
|
||||
|
||||
testWidgets('Scrollbar track can be drawn', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrollbar track can be drawn', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -2464,8 +2497,9 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('RawScrollbar correctly assigns colors', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('RawScrollbar correctly assigns colors', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -2510,8 +2544,9 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('trackRadius and radius properties of RawScrollbar can draw RoundedRectangularRect', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('trackRadius and radius properties of RawScrollbar can draw RoundedRectangularRect', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -2549,8 +2584,9 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('Scrollbar asserts that a visible track has a visible thumb', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrollbar asserts that a visible track has a visible thumb', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
Widget buildApp() {
|
||||
return Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -2573,9 +2609,10 @@ void main() {
|
||||
expect(() => tester.pumpWidget(buildApp()), throwsAssertionError);
|
||||
});
|
||||
|
||||
testWidgets('Skip the ScrollPosition check if the bar was unmounted', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Skip the ScrollPosition check if the bar was unmounted', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/103939
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
Widget buildApp(bool buildBar) {
|
||||
return Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -2611,9 +2648,10 @@ void main() {
|
||||
// Go without throw.
|
||||
});
|
||||
|
||||
testWidgets('Track offset respects MediaQuery padding', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Track offset respects MediaQuery padding', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/106834
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -2643,8 +2681,9 @@ void main() {
|
||||
); // thumb
|
||||
});
|
||||
|
||||
testWidgets('RawScrollbar.padding replaces MediaQueryData.padding', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('RawScrollbar.padding replaces MediaQueryData.padding', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -2675,8 +2714,9 @@ void main() {
|
||||
); // thumb
|
||||
});
|
||||
|
||||
testWidgets('Scrollbar respect the NeverScrollableScrollPhysics physics', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('Scrollbar respect the NeverScrollableScrollPhysics physics', (WidgetTester tester) async {
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -2717,9 +2757,10 @@ void main() {
|
||||
expect(scrollController.offset, 0.0);
|
||||
});
|
||||
|
||||
testWidgets('The thumb should follow the pointer when the scroll metrics changed during dragging', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('The thumb should follow the pointer when the scroll metrics changed during dragging', (WidgetTester tester) async {
|
||||
// Regressing test for https://github.com/flutter/flutter/issues/112072
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -2787,9 +2828,10 @@ void main() {
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets('The scrollable should not stutter when the scroll metrics shrink during dragging', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('The scrollable should not stutter when the scroll metrics shrink during dragging', (WidgetTester tester) async {
|
||||
// Regressing test for https://github.com/flutter/flutter/issues/121574
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
@ -2851,9 +2893,10 @@ void main() {
|
||||
expect(scrollController.offset, greaterThan(lastPosition));
|
||||
});
|
||||
|
||||
testWidgets('The bar support mouse wheel event', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('The bar support mouse wheel event', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/pull/109659
|
||||
final ScrollController scrollController = ScrollController();
|
||||
addTearDown(scrollController.dispose);
|
||||
Widget buildFrame() {
|
||||
return Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
|
||||
@ -9,6 +9,7 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
||||
import 'package:web/web.dart' as web;
|
||||
|
||||
extension on web.HTMLCollection {
|
||||
@ -59,8 +60,9 @@ void main() {
|
||||
expect(foundStyle, isTrue);
|
||||
});
|
||||
|
||||
testWidgets('right click can trigger select word', (WidgetTester tester) async {
|
||||
testWidgetsWithLeakTracking('right click can trigger select word', (WidgetTester tester) async {
|
||||
final FocusNode focusNode = FocusNode();
|
||||
addTearDown(focusNode.dispose);
|
||||
final UniqueKey spy = UniqueKey();
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user