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

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

parent 083ac65c
......@@ -306,7 +306,7 @@ void main() {
expect(find.text('popped'), findsOneWidget);
},
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(someone): remove after fixing
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134205
notDisposedAllowList: <String, int?> {'_RestorableRouteInformation': 1},
));
......@@ -338,7 +338,7 @@ void main() {
expect(find.text('popped'), findsOneWidget);
},
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(someone): remove after fixing
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134205
notDisposedAllowList: <String, int?> {'_RestorableRouteInformation': 1},
));
......@@ -434,7 +434,7 @@ void main() {
expect(find.text('popped'), findsOneWidget);
},
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(someone): remove after fixing
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134205
notDisposedAllowList: <String, int?> {'_RestorableRouteInformation': 1},
));
......@@ -455,7 +455,7 @@ void main() {
expect(find.text('/'), findsOneWidget);
},
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(someone): remove after fixing
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134205
notDisposedAllowList: <String, int?> {'_RestorableRouteInformation': 1},
));
......
......@@ -14,11 +14,12 @@ 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 'semantics_tester.dart';
void main() {
testWidgets('Drag and drop - control test', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - control test', (WidgetTester tester) async {
final List<int> accepted = <int>[];
final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
int dragStartedCount = 0;
......@@ -93,7 +94,7 @@ void main() {
});
// Regression test for https://github.com/flutter/flutter/issues/76825
testWidgets('Drag and drop - onLeave callback fires correctly with generic parameter', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - onLeave callback fires correctly with generic parameter', (WidgetTester tester) async {
final Map<String,int> leftBehind = <String,int>{
'Target 1': 0,
'Target 2': 0,
......@@ -168,7 +169,7 @@ void main() {
expect(leftBehind['Target 2'], equals(1));
});
testWidgets('Drag and drop - onLeave callback fires correctly', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - onLeave callback fires correctly', (WidgetTester tester) async {
final Map<String,int> leftBehind = <String,int>{
'Target 1': 0,
'Target 2': 0,
......@@ -244,7 +245,7 @@ void main() {
});
// Regression test for https://github.com/flutter/flutter/issues/76825
testWidgets('Drag and drop - onMove callback fires correctly with generic parameter', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - onMove callback fires correctly with generic parameter', (WidgetTester tester) async {
final Map<String,int> targetMoveCount = <String,int>{
'Target 1': 0,
'Target 2': 0,
......@@ -317,7 +318,7 @@ void main() {
expect(targetMoveCount['Target 2'], equals(1));
});
testWidgets('Drag and drop - onMove callback fires correctly', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - onMove callback fires correctly', (WidgetTester tester) async {
final Map<String,int> targetMoveCount = <String,int>{
'Target 1': 0,
'Target 2': 0,
......@@ -394,7 +395,7 @@ void main() {
expect(targetMoveCount['Target 2'], equals(1));
});
testWidgets('Drag and drop - dragging over button', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - dragging over button', (WidgetTester tester) async {
final List<String> events = <String>[];
Offset firstLocation, secondLocation;
......@@ -487,7 +488,7 @@ void main() {
events.clear();
});
testWidgets('Drag and drop - tapping button', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - tapping button', (WidgetTester tester) async {
final List<String> events = <String>[];
Offset firstLocation, secondLocation;
......@@ -544,7 +545,7 @@ void main() {
events.clear();
});
testWidgets('Drag and drop - long press draggable, short press', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - long press draggable, short press', (WidgetTester tester) async {
final List<String> events = <String>[];
Offset firstLocation, secondLocation;
......@@ -593,7 +594,7 @@ void main() {
expect(events, isEmpty);
});
testWidgets('Drag and drop - long press draggable, long press', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - long press draggable, long press', (WidgetTester tester) async {
final List<String> events = <String>[];
Offset firstLocation, secondLocation;
......@@ -644,7 +645,7 @@ void main() {
expect(events, equals(<String>['drop', 'details']));
});
testWidgets('Drag and drop - horizontal and vertical draggables in vertical block', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - horizontal and vertical draggables in vertical block', (WidgetTester tester) async {
final List<String> events = <String>[];
Offset firstLocation, secondLocation, thirdLocation;
......@@ -754,7 +755,7 @@ void main() {
events.clear();
});
testWidgets('Drag and drop - horizontal and vertical draggables in horizontal block', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - horizontal and vertical draggables in horizontal block', (WidgetTester tester) async {
final List<String> events = <String>[];
Offset firstLocation, secondLocation, thirdLocation;
......@@ -913,7 +914,7 @@ void main() {
),
);
}
testWidgets('Null axis draggable moves along all axes', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Null axis draggable moves along all axes', (WidgetTester tester) async {
await tester.pumpWidget(build());
final Offset firstLocation = tester.getTopLeft(find.text('N'));
final Offset secondLocation = firstLocation + const Offset(300.0, 300.0);
......@@ -928,7 +929,7 @@ void main() {
expect(tester.getTopLeft(find.text('N')), thirdLocation);
});
testWidgets('Horizontal axis draggable moves horizontally', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Horizontal axis draggable moves horizontally', (WidgetTester tester) async {
await tester.pumpWidget(build());
final Offset firstLocation = tester.getTopLeft(find.text('H'));
final Offset secondLocation = firstLocation + const Offset(300.0, 0.0);
......@@ -943,7 +944,7 @@ void main() {
expect(tester.getTopLeft(find.text('H')), thirdLocation);
});
testWidgets('Horizontal axis draggable does not move vertically', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Horizontal axis draggable does not move vertically', (WidgetTester tester) async {
await tester.pumpWidget(build());
final Offset firstLocation = tester.getTopLeft(find.text('H'));
final Offset secondDragLocation = firstLocation + const Offset(300.0, 200.0);
......@@ -961,7 +962,7 @@ void main() {
expect(tester.getTopLeft(find.text('H')), thirdWidgetLocation);
});
testWidgets('Vertical axis draggable moves vertically', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Vertical axis draggable moves vertically', (WidgetTester tester) async {
await tester.pumpWidget(build());
final Offset firstLocation = tester.getTopLeft(find.text('V'));
final Offset secondLocation = firstLocation + const Offset(0.0, 300.0);
......@@ -976,7 +977,7 @@ void main() {
expect(tester.getTopLeft(find.text('V')), thirdLocation);
});
testWidgets('Vertical axis draggable does not move horizontally', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Vertical axis draggable does not move horizontally', (WidgetTester tester) async {
await tester.pumpWidget(build());
final Offset firstLocation = tester.getTopLeft(find.text('V'));
final Offset secondDragLocation = firstLocation + const Offset(200.0, 300.0);
......@@ -1042,7 +1043,7 @@ void main() {
);
}
testWidgets('Null axis onDragUpdate called only if draggable moves in any direction', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Null axis onDragUpdate called only if draggable moves in any direction', (WidgetTester tester) async {
await tester.pumpWidget(build());
expect(updated, 0);
......@@ -1077,7 +1078,7 @@ void main() {
expect(dragDelta.dy, 10);
});
testWidgets('Vertical axis onDragUpdate only called if draggable moves vertical', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Vertical axis onDragUpdate only called if draggable moves vertical', (WidgetTester tester) async {
await tester.pumpWidget(build());
expect(updated, 0);
......@@ -1112,7 +1113,7 @@ void main() {
expect(dragDelta.dy, 10);
});
testWidgets('Horizontal axis onDragUpdate only called if draggable moves horizontal', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Horizontal axis onDragUpdate only called if draggable moves horizontal', (WidgetTester tester) async {
await tester.pumpWidget(build());
expect(updated, 0);
......@@ -1148,7 +1149,7 @@ void main() {
});
});
testWidgets('Drag and drop - onDraggableCanceled not called if dropped on accepting target', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - onDraggableCanceled not called if dropped on accepting target', (WidgetTester tester) async {
final List<int> accepted = <int>[];
final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
bool onDraggableCanceledCalled = false;
......@@ -1216,7 +1217,7 @@ void main() {
expect(onDraggableCanceledCalled, isFalse);
});
testWidgets('Drag and drop - onDraggableCanceled called if dropped on non-accepting target', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - onDraggableCanceled called if dropped on non-accepting target', (WidgetTester tester) async {
final List<int> accepted = <int>[];
final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
bool onDraggableCanceledCalled = false;
......@@ -1293,7 +1294,7 @@ void main() {
expect(onDraggableCanceledOffset, equals(Offset(secondLocation.dx, secondLocation.dy)));
});
testWidgets('Drag and drop - onDraggableCanceled called if dropped on non-accepting target with details', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - onDraggableCanceled called if dropped on non-accepting target with details', (WidgetTester tester) async {
final List<int> accepted = <int>[];
final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
bool onDraggableCanceledCalled = false;
......@@ -1370,7 +1371,7 @@ void main() {
expect(onDraggableCanceledOffset, equals(Offset(secondLocation.dx, secondLocation.dy)));
});
testWidgets('Drag and drop - onDraggableCanceled called if dropped on non-accepting target with correct velocity', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - onDraggableCanceled called if dropped on non-accepting target with correct velocity', (WidgetTester tester) async {
final List<int> accepted = <int>[];
final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
bool onDraggableCanceledCalled = false;
......@@ -1422,7 +1423,7 @@ void main() {
expect(onDraggableCanceledOffset, equals(Offset(flingStart.dx, flingStart.dy) + const Offset(0.0, 100.0)));
});
testWidgets('Drag and drop - onDragEnd not called if dropped on non-accepting target', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - onDragEnd not called if dropped on non-accepting target', (WidgetTester tester) async {
final List<int> accepted = <int>[];
final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
bool onDragEndCalled = false;
......@@ -1498,7 +1499,7 @@ void main() {
);
});
testWidgets('Drag and drop - onDragEnd not called if dropped on non-accepting target with details', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - onDragEnd not called if dropped on non-accepting target with details', (WidgetTester tester) async {
final List<int> accepted = <int>[];
final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
bool onDragEndCalled = false;
......@@ -1574,7 +1575,7 @@ void main() {
);
});
testWidgets('Drag and drop - DragTarget rebuilds with and without rejected data when a rejected draggable enters and leaves', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - DragTarget rebuilds with and without rejected data when a rejected draggable enters and leaves', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: Column(
children: <Widget>[
......@@ -1628,7 +1629,7 @@ void main() {
});
testWidgets('Drag and drop - Can drag and drop over a non-accepting target multiple times', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - Can drag and drop over a non-accepting target multiple times', (WidgetTester tester) async {
int numberOfTimesOnDraggableCanceledCalled = 0;
await tester.pumpWidget(MaterialApp(
home: Column(
......@@ -1710,7 +1711,7 @@ void main() {
expect(find.text('Rejected'), findsNothing);
});
testWidgets('Drag and drop - onDragCompleted not called if dropped on non-accepting target', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - onDragCompleted not called if dropped on non-accepting target', (WidgetTester tester) async {
final List<int> accepted = <int>[];
final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
bool onDragCompletedCalled = false;
......@@ -1781,7 +1782,7 @@ void main() {
expect(onDragCompletedCalled, isFalse);
});
testWidgets('Drag and drop - onDragCompleted not called if dropped on non-accepting target with details', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - onDragCompleted not called if dropped on non-accepting target with details', (WidgetTester tester) async {
final List<int> accepted = <int>[];
final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
bool onDragCompletedCalled = false;
......@@ -1852,7 +1853,7 @@ void main() {
expect(onDragCompletedCalled, isFalse);
});
testWidgets('Drag and drop - onDragEnd called if dropped on accepting target', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - onDragEnd called if dropped on accepting target', (WidgetTester tester) async {
final List<int> accepted = <int>[];
final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
bool onDragEndCalled = false;
......@@ -1928,7 +1929,7 @@ void main() {
expect(onDragEndDraggableDetails.offset, equals(expectedDropOffset));
});
testWidgets('DragTarget does not call onDragEnd when remove from the tree', (WidgetTester tester) async {
testWidgetsWithLeakTracking('DragTarget does not call onDragEnd when remove from the tree', (WidgetTester tester) async {
final List<String> events = <String>[];
Offset firstLocation, secondLocation;
int timesOnDragEndCalled = 0;
......@@ -1994,7 +1995,7 @@ void main() {
await tester.pump();
});
testWidgets('Drag and drop - onDragCompleted called if dropped on accepting target', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - onDragCompleted called if dropped on accepting target', (WidgetTester tester) async {
final List<int> accepted = <int>[];
final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
bool onDragCompletedCalled = false;
......@@ -2062,7 +2063,7 @@ void main() {
expect(onDragCompletedCalled, isTrue);
});
testWidgets('Drag and drop - allow pass through of unaccepted data test', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - allow pass through of unaccepted data test', (WidgetTester tester) async {
final List<int> acceptedInts = <int>[];
final List<DragTargetDetails<int>> acceptedIntsDetails = <DragTargetDetails<int>>[];
final List<double> acceptedDoubles = <double>[];
......@@ -2196,7 +2197,7 @@ void main() {
expect(find.text('DoubleDragging'), findsNothing);
});
testWidgets('Drag and drop - allow pass through of unaccepted data twice test', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - allow pass through of unaccepted data twice test', (WidgetTester tester) async {
final List<DragTargetData> acceptedDragTargetDatas = <DragTargetData>[];
final List<DragTargetDetails<DragTargetData>> acceptedDragTargetDataDetails = <DragTargetDetails<DragTargetData>>[];
final List<ExtendedDragTargetData> acceptedExtendedDragTargetDatas = <ExtendedDragTargetData>[];
......@@ -2264,7 +2265,7 @@ void main() {
}
});
testWidgets('Drag and drop - maxSimultaneousDrags', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - maxSimultaneousDrags', (WidgetTester tester) async {
final List<int> accepted = <int>[];
final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
......@@ -2391,14 +2392,17 @@ void main() {
expect(find.text('Target'), findsOneWidget);
});
testWidgets('Draggable disposes recognizer', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Draggable disposes recognizer', (WidgetTester tester) async {
late final OverlayEntry entry;
addTearDown(() => entry..remove()..dispose());
bool didTap = false;
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Overlay(
initialEntries: <OverlayEntry>[
OverlayEntry(
entry = OverlayEntry(
builder: (BuildContext context) => GestureDetector(
onTap: () {
didTap = true;
......@@ -2430,7 +2434,7 @@ void main() {
});
// Regression test for https://github.com/flutter/flutter/issues/6128.
testWidgets('Draggable plays nice with onTap', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Draggable plays nice with onTap', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
......@@ -2463,7 +2467,7 @@ void main() {
await secondGesture.up();
});
testWidgets('DragTarget does not set state when remove from the tree', (WidgetTester tester) async {
testWidgetsWithLeakTracking('DragTarget does not set state when remove from the tree', (WidgetTester tester) async {
final List<String> events = <String>[];
Offset firstLocation, secondLocation;
......@@ -2525,7 +2529,7 @@ void main() {
await tester.pump();
});
testWidgets('Drag and drop - remove draggable', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - remove draggable', (WidgetTester tester) async {
final List<int> accepted = <int>[];
final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
......@@ -2605,7 +2609,7 @@ void main() {
expect(find.text('Target'), findsOneWidget);
});
testWidgets('Tap above long-press draggable works', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Tap above long-press draggable works', (WidgetTester tester) async {
final List<String> events = <String>[];
await tester.pumpWidget(MaterialApp(
......@@ -2629,7 +2633,7 @@ void main() {
expect(events, equals(<String>['tap']));
});
testWidgets('long-press draggable calls onDragEnd called if dropped on accepting target', (WidgetTester tester) async {
testWidgetsWithLeakTracking('long-press draggable calls onDragEnd called if dropped on accepting target', (WidgetTester tester) async {
final List<int> accepted = <int>[];
final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
bool onDragEndCalled = false;
......@@ -2716,7 +2720,7 @@ void main() {
expect(onDragEndDraggableDetails.offset, equals(expectedDropOffset));
});
testWidgets('long-press draggable calls onDragCompleted called if dropped on accepting target', (WidgetTester tester) async {
testWidgetsWithLeakTracking('long-press draggable calls onDragCompleted called if dropped on accepting target', (WidgetTester tester) async {
final List<int> accepted = <int>[];
final List<DragTargetDetails<int>> acceptedDetails = <DragTargetDetails<int>>[];
bool onDragCompletedCalled = false;
......@@ -2792,7 +2796,7 @@ void main() {
expect(onDragCompletedCalled, isTrue);
});
testWidgets('long-press draggable calls onDragStartedCalled after long press', (WidgetTester tester) async {
testWidgetsWithLeakTracking('long-press draggable calls onDragStartedCalled after long press', (WidgetTester tester) async {
bool onDragStartedCalled = false;
await tester.pumpWidget(MaterialApp(
......@@ -2825,7 +2829,7 @@ void main() {
expect(onDragStartedCalled, isTrue);
});
testWidgets('Custom long press delay for LongPressDraggable', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Custom long press delay for LongPressDraggable', (WidgetTester tester) async {
bool onDragStartedCalled = false;
await tester.pumpWidget(MaterialApp(
home: LongPressDraggable<int>(
......@@ -2859,7 +2863,7 @@ void main() {
expect(onDragStartedCalled, isTrue);
});
testWidgets('Default long press delay for LongPressDraggable', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Default long press delay for LongPressDraggable', (WidgetTester tester) async {
bool onDragStartedCalled = false;
await tester.pumpWidget(MaterialApp(
home: LongPressDraggable<int>(
......@@ -2892,23 +2896,23 @@ void main() {
expect(onDragStartedCalled, isTrue);
});
testWidgets('long-press draggable calls Haptic Feedback onStart', (WidgetTester tester) async {
testWidgetsWithLeakTracking('long-press draggable calls Haptic Feedback onStart', (WidgetTester tester) async {
await _testLongPressDraggableHapticFeedback(tester: tester, hapticFeedbackOnStart: true, expectedHapticFeedbackCount: 1);
});
testWidgets('long-press draggable can disable Haptic Feedback', (WidgetTester tester) async {
testWidgetsWithLeakTracking('long-press draggable can disable Haptic Feedback', (WidgetTester tester) async {
await _testLongPressDraggableHapticFeedback(tester: tester, hapticFeedbackOnStart: false, expectedHapticFeedbackCount: 0);
});
testWidgets('Drag feedback with child anchor positions correctly', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag feedback with child anchor positions correctly', (WidgetTester tester) async {
await _testChildAnchorFeedbackPosition(tester: tester);
});
testWidgets('Drag feedback with child anchor within a non-global Overlay positions correctly', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag feedback with child anchor within a non-global Overlay positions correctly', (WidgetTester tester) async {
await _testChildAnchorFeedbackPosition(tester: tester, left: 100.0, top: 100.0);
});
testWidgets('Drag feedback is put on root overlay with [rootOverlay] flag', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag feedback is put on root overlay with [rootOverlay] flag', (WidgetTester tester) async {
final GlobalKey<NavigatorState> rootNavigatorKey = GlobalKey<NavigatorState>();
final GlobalKey<NavigatorState> childNavigatorKey = GlobalKey<NavigatorState>();
// Create a [MaterialApp], with a nested [Navigator], which has the
......@@ -2976,7 +2980,7 @@ void main() {
});
// Regression test for https://github.com/flutter/flutter/issues/72483
testWidgets('Drag and drop - DragTarget<Object> can accept Draggable<int> data', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - DragTarget<Object> can accept Draggable<int> data', (WidgetTester tester) async {
final List<Object> accepted = <Object>[];
await tester.pumpWidget(MaterialApp(
home: Column(
......@@ -3012,7 +3016,7 @@ void main() {
expect(accepted, equals(<int>[1]));
});
testWidgets('Drag and drop - DragTarget<int> can accept Draggable<Object> data when runtime type is int', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - DragTarget<int> can accept Draggable<Object> data when runtime type is int', (WidgetTester tester) async {
final List<int> accepted = <int>[];
await tester.pumpWidget(MaterialApp(
home: Column(
......@@ -3048,7 +3052,7 @@ void main() {
expect(accepted, equals(<int>[1]));
});
testWidgets('Drag and drop - DragTarget<int> should not accept Draggable<Object> data when runtime type null', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - DragTarget<int> should not accept Draggable<Object> data when runtime type null', (WidgetTester tester) async {
final List<int> accepted = <int>[];
bool isReceiveNullDataForCheck = false;
await tester.pumpWidget(MaterialApp(
......@@ -3091,7 +3095,7 @@ void main() {
expect(isReceiveNullDataForCheck, true);
});
testWidgets('Drag and drop can contribute semantics', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop can contribute semantics', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
await tester.pumpWidget(MaterialApp(
home: ListView(
......@@ -3257,7 +3261,7 @@ void main() {
semantics.dispose();
});
testWidgets('Drag and drop - when a dragAnchorStrategy is provided it gets called', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drag and drop - when a dragAnchorStrategy is provided it gets called', (WidgetTester tester) async {
bool dragAnchorStrategyCalled = false;
await tester.pumpWidget(MaterialApp(
......@@ -3281,7 +3285,7 @@ void main() {
expect(dragAnchorStrategyCalled, true);
});
testWidgets('configurable Draggable hit test behavior', (WidgetTester tester) async {
testWidgetsWithLeakTracking('configurable Draggable hit test behavior', (WidgetTester tester) async {
const HitTestBehavior hitTestBehavior = HitTestBehavior.deferToChild;
await tester.pumpWidget(
......@@ -3301,7 +3305,7 @@ void main() {
});
// Regression test for https://github.com/flutter/flutter/issues/92083
testWidgets('feedback respect the MouseRegion cursor configure', (WidgetTester tester) async {
testWidgetsWithLeakTracking('feedback respect the MouseRegion cursor configure', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Column(
......@@ -3329,7 +3333,7 @@ void main() {
expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.grabbing);
});
testWidgets('configurable feedback ignore pointer behavior', (WidgetTester tester) async {
testWidgetsWithLeakTracking('configurable feedback ignore pointer behavior', (WidgetTester tester) async {
bool onTap = false;
await tester.pumpWidget(
MaterialApp(
......@@ -3358,7 +3362,7 @@ void main() {
expect(onTap, true);
});
testWidgets('configurable feedback ignore pointer behavior - LongPressDraggable', (WidgetTester tester) async {
testWidgetsWithLeakTracking('configurable feedback ignore pointer behavior - LongPressDraggable', (WidgetTester tester) async {
bool onTap = false;
await tester.pumpWidget(
MaterialApp(
......@@ -3389,7 +3393,7 @@ void main() {
expect(onTap, true);
});
testWidgets('configurable DragTarget hit test behavior', (WidgetTester tester) async {
testWidgetsWithLeakTracking('configurable DragTarget hit test behavior', (WidgetTester tester) async {
const HitTestBehavior hitTestBehavior = HitTestBehavior.deferToChild;
await tester.pumpWidget(
......@@ -3410,7 +3414,7 @@ void main() {
expect(tester.widget<MetaData>(find.byType(MetaData)).behavior, hitTestBehavior);
});
testWidgets('LongPressDraggable.dragAnchorStrategy', (WidgetTester tester) async {
testWidgetsWithLeakTracking('LongPressDraggable.dragAnchorStrategy', (WidgetTester tester) async {
const Widget widget1 = Placeholder(key: ValueKey<int>(1));
const Widget widget2 = Placeholder(key: ValueKey<int>(2));
Offset dummyStrategy(Draggable<Object> draggable, BuildContext context, Offset position) => Offset.zero;
......@@ -3420,7 +3424,7 @@ void main() {
expect(LongPressDraggable<int>(feedback: widget2, dragAnchorStrategy: dummyStrategy, child: widget1).dragAnchorStrategy, dummyStrategy);
});
testWidgets('Test allowedButtonsFilter', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Test allowedButtonsFilter', (WidgetTester tester) async {
Widget build(bool Function(int buttons)? allowedButtonsFilter) {
return MaterialApp(
home: Draggable<int>(
......@@ -3462,7 +3466,7 @@ void main() {
await gesture3.up();
});
testWidgets('throws error when both onWillAccept and onWillAcceptWithDetails are provided', (WidgetTester tester) async {
testWidgetsWithLeakTracking('throws error when both onWillAccept and onWillAcceptWithDetails are provided', (WidgetTester tester) async {
expect(() => DragTarget<int>(
builder: (BuildContext context, List<int?> data, List<dynamic> rejects) {
return const SizedBox(height: 100.0, child: Text('Target'));
......
......@@ -8,12 +8,13 @@ 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';
void main() {
testWidgets('Drawer control test', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drawer control test', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
late BuildContext savedContext;
await tester.pumpWidget(
......@@ -44,7 +45,7 @@ void main() {
expect(find.text('drawer'), findsNothing);
});
testWidgets('Drawer tap test', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drawer tap test', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
await tester.pumpWidget(
MaterialApp(
......@@ -76,7 +77,7 @@ void main() {
expect(find.text('drawer'), findsNothing);
});
testWidgets('Drawer hover test', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drawer hover test', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
final List<String> logs = <String>[];
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
......@@ -146,7 +147,7 @@ void main() {
logs.clear();
});
testWidgets('Drawer drag cancel resume (LTR)', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drawer drag cancel resume (LTR)', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
await tester.pumpWidget(
MaterialApp(
......@@ -197,7 +198,7 @@ void main() {
await gesture.up();
});
testWidgets('Drawer drag cancel resume (RTL)', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drawer drag cancel resume (RTL)', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
await tester.pumpWidget(
MaterialApp(
......@@ -251,7 +252,7 @@ void main() {
await gesture.up();
});
testWidgets('Drawer navigator back button', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drawer navigator back button', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
bool buttonPressed = false;
......@@ -299,7 +300,7 @@ void main() {
expect(buttonPressed, equals(true));
});
testWidgets('Dismissible ModalBarrier includes button in semantic tree', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Dismissible ModalBarrier includes button in semantic tree', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
......@@ -326,7 +327,7 @@ void main() {
semantics.dispose();
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('Dismissible ModalBarrier is hidden on Android (back button is used to dismiss)', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Dismissible ModalBarrier is hidden on Android (back button is used to dismiss)', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
......@@ -354,7 +355,7 @@ void main() {
semantics.dispose();
}, variant: TargetPlatformVariant.only(TargetPlatform.android));
testWidgets('Drawer contains route semantics flags', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Drawer contains route semantics flags', (WidgetTester tester) async {
final SemanticsTester semantics = SemanticsTester(tester);
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
......
......@@ -4,13 +4,15 @@
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('runs animations', (WidgetTester tester) async {
testWidgetsWithLeakTracking('runs animations', (WidgetTester tester) async {
final AnimationController controller = AnimationController(
vsync: const TestVSync(),
duration: const Duration(milliseconds: 300),
);
addTearDown(controller.dispose);
await tester.pumpWidget(Center(
child: DualTransitionBuilder(
......@@ -74,11 +76,12 @@ void main() {
expect(_getOpacity(tester), 1.0);
});
testWidgets('keeps state', (WidgetTester tester) async {
testWidgetsWithLeakTracking('keeps state', (WidgetTester tester) async {
final AnimationController controller = AnimationController(
vsync: const TestVSync(),
duration: const Duration(milliseconds: 300),
);
addTearDown(controller.dispose);
await tester.pumpWidget(Directionality(
textDirection: TextDirection.ltr,
......@@ -138,11 +141,13 @@ void main() {
expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
});
testWidgets('does not jump when interrupted - forward', (WidgetTester tester) async {
testWidgetsWithLeakTracking('does not jump when interrupted - forward', (WidgetTester tester) async {
final AnimationController controller = AnimationController(
vsync: const TestVSync(),
duration: const Duration(milliseconds: 300),
);
addTearDown(controller.dispose);
await tester.pumpWidget(Center(
child: DualTransitionBuilder(
animation: controller,
......@@ -202,12 +207,14 @@ void main() {
expect(_getOpacity(tester), 1.0);
});
testWidgets('does not jump when interrupted - reverse', (WidgetTester tester) async {
testWidgetsWithLeakTracking('does not jump when interrupted - reverse', (WidgetTester tester) async {
final AnimationController controller = AnimationController(
value: 1.0,
vsync: const TestVSync(),
duration: const Duration(milliseconds: 300),
);
addTearDown(controller.dispose);
await tester.pumpWidget(Center(
child: DualTransitionBuilder(
animation: controller,
......
......@@ -15,23 +15,34 @@ 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 'editable_text_utils.dart';
final TextEditingController controller = TextEditingController();
final FocusNode focusNode = FocusNode();
final FocusScopeNode focusScopeNode = FocusScopeNode();
const TextStyle textStyle = TextStyle();
const Color cursorColor = Color.fromARGB(0xFF, 0xFF, 0x00, 0x00);
void main() {
late TextEditingController controller;
late FocusNode focusNode;
late FocusScopeNode focusScopeNode;
setUp(() async {
// Fill the clipboard so that the Paste option is available in the text
// selection menu.
await Clipboard.setData(const ClipboardData(text: 'Clipboard data'));
controller = TextEditingController();
focusNode = FocusNode();
focusScopeNode = FocusScopeNode();
});
tearDown(() {
controller.dispose();
focusNode.dispose();
focusScopeNode.dispose();
});
testWidgets('cursor has expected width, height, and radius', (WidgetTester tester) async {
testWidgetsWithLeakTracking('cursor has expected width, height, and radius', (WidgetTester tester) async {
await tester.pumpWidget(
MediaQuery(
data: const MediaQueryData(),
......@@ -57,7 +68,7 @@ void main() {
expect(editableText.cursorRadius!.x, 2.0);
});
testWidgets('cursor layout has correct width', (WidgetTester tester) async {
testWidgetsWithLeakTracking('cursor layout has correct width', (WidgetTester tester) async {
EditableText.debugDeterministicCursor = true;
final GlobalKey<EditableTextState> editableTextKey = GlobalKey<EditableTextState>();
......@@ -68,8 +79,8 @@ void main() {
child: EditableText(
backgroundCursorColor: Colors.grey,
key: editableTextKey,
controller: TextEditingController(),
focusNode: FocusNode(),
controller: controller,
focusNode: focusNode,
style: Typography.material2018().black.titleMedium!,
cursorColor: Colors.blue,
selectionControls: materialTextSelectionControls,
......@@ -113,7 +124,7 @@ void main() {
EditableText.debugDeterministicCursor = false;
});
testWidgets('cursor layout has correct radius', (WidgetTester tester) async {
testWidgetsWithLeakTracking('cursor layout has correct radius', (WidgetTester tester) async {
final GlobalKey<EditableTextState> editableTextKey = GlobalKey<EditableTextState>();
late String changedValue;
......@@ -123,8 +134,8 @@ void main() {
child: EditableText(
backgroundCursorColor: Colors.grey,
key: editableTextKey,
controller: TextEditingController(),
focusNode: FocusNode(),
controller: controller,
focusNode: focusNode,
style: Typography.material2018().black.titleMedium!,
cursorColor: Colors.blue,
selectionControls: materialTextSelectionControls,
......@@ -168,7 +179,7 @@ void main() {
);
});
testWidgets('Cursor animates on iOS', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Cursor animates on iOS', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Material(
......@@ -219,7 +230,7 @@ void main() {
await verifyKeyFrame(opacity: 1.0, at: 1000000);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('Cursor does not animate on non-iOS platforms', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Cursor does not animate on non-iOS platforms', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: Material(child: TextField(maxLines: 3)),
......@@ -238,7 +249,7 @@ void main() {
}
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('Cursor does not animate on Android', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Cursor does not animate on Android', (WidgetTester tester) async {
final Color defaultCursorColor = Color(ThemeData.fallback().colorScheme.primary.value);
const Widget widget = MaterialApp(
home: Material(
......@@ -276,9 +287,14 @@ void main() {
await tester.pump(const Duration(milliseconds: 500));
expect(renderEditable.cursorColor!.alpha, 0);
expect(renderEditable, paintsExactlyCountTimes(#drawRect, 0));
});
},
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134386
notDisposedAllowList: <String, int?> {'LeaderLayer': 5},
));
testWidgets('Cursor does not animates when debugDeterministicCursor is set', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Cursor does not animates when debugDeterministicCursor is set', (WidgetTester tester) async {
EditableText.debugDeterministicCursor = true;
final Color defaultCursorColor = Color(ThemeData.fallback().colorScheme.primary.value);
const Widget widget = MaterialApp(
......@@ -314,9 +330,15 @@ void main() {
expect(renderEditable, paints..rrect(color: defaultCursorColor));
EditableText.debugDeterministicCursor = false;
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
},
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }),
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134386
notDisposedAllowList: <String, int?> {'LeaderLayer': 6},
));
testWidgets('Cursor does not animate on Android when debugDeterministicCursor is set', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Cursor does not animate on Android when debugDeterministicCursor is set', (WidgetTester tester) async {
final Color defaultCursorColor = Color(ThemeData.fallback().colorScheme.primary.value);
EditableText.debugDeterministicCursor = true;
const Widget widget = MaterialApp(
......@@ -353,17 +375,23 @@ void main() {
expect(renderEditable, paints..rect(color: defaultCursorColor));
EditableText.debugDeterministicCursor = false;
});
},
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134386
notDisposedAllowList: <String, int?> {'LeaderLayer': 4},
));
testWidgets('Cursor animation restarts when it is moved using keys on desktop', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Cursor animation restarts when it is moved using keys on desktop', (WidgetTester tester) async {
debugDefaultTargetPlatformOverride = TargetPlatform.macOS;
const String testText = 'Some text long enough to move the cursor around';
final TextEditingController controller = TextEditingController(text: testText);
controller.text = testText;
final Widget widget = MaterialApp(
home: EditableText(
controller: controller,
focusNode: FocusNode(),
focusNode: focusNode,
style: const TextStyle(fontSize: 20.0),
cursorColor: Colors.blue,
backgroundCursorColor: Colors.grey,
......@@ -430,9 +458,15 @@ void main() {
expect(renderEditable, paintsExactlyCountTimes(#drawRect, 0));
debugDefaultTargetPlatformOverride = null;
}, variant: KeySimulatorTransitModeVariant.all());
},
variant: KeySimulatorTransitModeVariant.all(),
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134386
notDisposedAllowList: <String, int?> {'LeaderLayer': 18},
));
testWidgets('Cursor does not show when showCursor set to false', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Cursor does not show when showCursor set to false', (WidgetTester tester) async {
const Widget widget = MaterialApp(
home: Material(
child: TextField(
......@@ -458,11 +492,15 @@ void main() {
await tester.pump(const Duration(milliseconds: 200));
expect(renderEditable, paintsExactlyCountTimes(#drawRect, 0));
});
},
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134386
notDisposedAllowList: <String, int?> {'LeaderLayer': 3},
));
testWidgets('Cursor does not show when not focused', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Cursor does not show when not focused', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/106512 .
final FocusNode focusNode = FocusNode();
await tester.pumpWidget(
MaterialApp(
home: Material(
......@@ -489,9 +527,14 @@ void main() {
await tester.pump();
await tester.pump(const Duration(milliseconds: 100));
expect(renderEditable, isNot(paintsExactlyCountTimes(#drawRect, 0)));
});
},
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134386
notDisposedAllowList: <String, int?> {'LeaderLayer': 2},
));
testWidgets('Cursor radius is 2.0', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Cursor radius is 2.0', (WidgetTester tester) async {
const Widget widget = MaterialApp(
home: Material(
child: TextField(
......@@ -507,10 +550,9 @@ void main() {
expect(renderEditable.cursorRadius, const Radius.circular(2.0));
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('Cursor gets placed correctly after going out of bounds', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Cursor gets placed correctly after going out of bounds', (WidgetTester tester) async {
const String text = 'hello world this is fun and cool and awesome!';
controller.text = text;
final FocusNode focusNode = FocusNode();
await tester.pumpWidget(
MediaQuery(
......@@ -602,10 +644,9 @@ void main() {
expect(controller.selection.baseOffset, 10);
});
testWidgets('Updating the floating cursor correctly moves the cursor', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Updating the floating cursor correctly moves the cursor', (WidgetTester tester) async {
const String text = 'hello world this is fun and cool and awesome!';
controller.text = text;
final FocusNode focusNode = FocusNode();
await tester.pumpWidget(
MediaQuery(
......@@ -659,10 +700,9 @@ void main() {
expect(controller.selection.baseOffset, 10);
});
testWidgets('Updating the floating cursor can end without update', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Updating the floating cursor can end without update', (WidgetTester tester) async {
const String text = 'hello world this is fun and cool and awesome!';
controller.text = text;
final FocusNode focusNode = FocusNode();
await tester.pumpWidget(
MediaQuery(
......@@ -703,10 +743,9 @@ void main() {
expect(tester.takeException(), null);
});
testWidgets("Drag the floating cursor, it won't blink.", (WidgetTester tester) async {
testWidgetsWithLeakTracking("Drag the floating cursor, it won't blink.", (WidgetTester tester) async {
const String text = 'hello world this is fun and cool and awesome!';
controller.text = text;
final FocusNode focusNode = FocusNode();
await tester.pumpWidget(
MediaQuery(
......@@ -770,7 +809,7 @@ void main() {
await checkCursorBlinking();
});
testWidgets('Turning showCursor off stops the cursor', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Turning showCursor off stops the cursor', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/108187.
final bool debugDeterministicCursor = EditableText.debugDeterministicCursor;
// This doesn't really matter.
......@@ -819,10 +858,9 @@ void main() {
});
// Regression test for https://github.com/flutter/flutter/pull/30475.
testWidgets('Trying to select with the floating cursor does not crash', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Trying to select with the floating cursor does not crash', (WidgetTester tester) async {
const String text = 'hello world this is fun and cool and awesome!';
controller.text = text;
final FocusNode focusNode = FocusNode();
await tester.pumpWidget(
MediaQuery(
......@@ -885,12 +923,10 @@ void main() {
await tester.pumpAndSettle();
});
testWidgets('autofocus sets cursor to the end of text', (WidgetTester tester) async {
testWidgetsWithLeakTracking('autofocus sets cursor to the end of text', (WidgetTester tester) async {
const String text = 'hello world';
final FocusScopeNode focusScopeNode = FocusScopeNode();
final FocusNode focusNode = FocusNode();
controller.text = text;
await tester.pumpWidget(
MediaQuery(
data: const MediaQueryData(),
......@@ -917,12 +953,10 @@ void main() {
expect(controller.selection.baseOffset, text.length);
});
testWidgets('Floating cursor is painted', (WidgetTester tester) async {
final TextEditingController controller = TextEditingController();
testWidgetsWithLeakTracking('Floating cursor is painted', (WidgetTester tester) async {
const TextStyle textStyle = TextStyle();
const String text = 'hello world this is fun and cool and awesome!';
controller.text = text;
final FocusNode focusNode = FocusNode();
await tester.pumpWidget(
MaterialApp(
......@@ -995,9 +1029,15 @@ void main() {
editableTextState.updateFloatingCursor(RawFloatingCursorPoint(state: FloatingCursorDragState.End));
await tester.pumpAndSettle();
debugDefaultTargetPlatformOverride = null;
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
},
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }),
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134386
notDisposedAllowList: <String, int?> {'LeaderLayer': 4},
));
testWidgets('cursor layout', (WidgetTester tester) async {
testWidgetsWithLeakTracking('cursor layout', (WidgetTester tester) async {
EditableText.debugDeterministicCursor = true;
final GlobalKey<EditableTextState> editableTextKey = GlobalKey<EditableTextState>();
......@@ -1011,8 +1051,8 @@ void main() {
EditableText(
backgroundCursorColor: Colors.grey,
key: editableTextKey,
controller: TextEditingController(),
focusNode: FocusNode(),
controller: controller,
focusNode: focusNode,
style: Typography.material2018(platform: TargetPlatform.iOS).black.titleMedium!,
cursorColor: Colors.blue,
selectionControls: materialTextSelectionControls,
......@@ -1058,7 +1098,7 @@ void main() {
EditableText.debugDeterministicCursor = false;
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('cursor layout has correct height', (WidgetTester tester) async {
testWidgetsWithLeakTracking('cursor layout has correct height', (WidgetTester tester) async {
EditableText.debugDeterministicCursor = true;
final GlobalKey<EditableTextState> editableTextKey = GlobalKey<EditableTextState>();
......@@ -1072,8 +1112,8 @@ void main() {
EditableText(
backgroundCursorColor: Colors.grey,
key: editableTextKey,
controller: TextEditingController(),
focusNode: FocusNode(),
controller: controller,
focusNode: focusNode,
style: Typography.material2018(platform: TargetPlatform.iOS).black.titleMedium!,
cursorColor: Colors.blue,
selectionControls: materialTextSelectionControls,
......@@ -1120,7 +1160,7 @@ void main() {
EditableText.debugDeterministicCursor = false;
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
testWidgets('password briefly does not show last character when disabled by system', (WidgetTester tester) async {
testWidgetsWithLeakTracking('password briefly does not show last character when disabled by system', (WidgetTester tester) async {
final bool debugDeterministicCursor = EditableText.debugDeterministicCursor;
EditableText.debugDeterministicCursor = false;
addTearDown(() {
......@@ -1156,23 +1196,23 @@ void main() {
expect((findRenderEditable(tester).text! as TextSpan).text, '•••');
});
testWidgets('getLocalRectForCaret with empty text', (WidgetTester tester) async {
testWidgetsWithLeakTracking('getLocalRectForCaret with empty text', (WidgetTester tester) async {
EditableText.debugDeterministicCursor = true;
addTearDown(() { EditableText.debugDeterministicCursor = false; });
const String text = '12';
final TextEditingController controller = TextEditingController.fromValue(
const TextEditingValue(
text: text,
selection: TextSelection.collapsed(offset: text.length),
),
);
addTearDown(controller.dispose);
final Widget widget = EditableText(
autofocus: true,
backgroundCursorColor: Colors.grey,
controller: controller,
focusNode: FocusNode(),
focusNode: focusNode,
style: const TextStyle(fontSize: 20),
textAlign: TextAlign.center,
keyboardType: TextInputType.text,
......@@ -1201,21 +1241,23 @@ void main() {
expect(controller.text, isEmpty);
});
testWidgets('Caret center space test', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Caret center space test', (WidgetTester tester) async {
EditableText.debugDeterministicCursor = true;
addTearDown(() { EditableText.debugDeterministicCursor = false; });
final String text = 'test${' ' * 1000}';
final Widget widget = EditableText(
autofocus: true,
backgroundCursorColor: Colors.grey,
controller: TextEditingController.fromValue(
final TextEditingController controller = TextEditingController.fromValue(
TextEditingValue(
text: text,
selection: TextSelection.collapsed(offset: text.length, affinity: TextAffinity.upstream),
),
),
focusNode: FocusNode(),
);
addTearDown(controller.dispose);
final Widget widget = EditableText(
autofocus: true,
backgroundCursorColor: Colors.grey,
controller: controller,
focusNode: focusNode,
style: const TextStyle(),
textAlign: TextAlign.center,
keyboardType: TextInputType.text,
......@@ -1243,25 +1285,31 @@ void main() {
renderEditable,
paints..rect(color: cursorColor, rect: caretRect),
);
}, skip: isBrowser && !isCanvasKit); // https://github.com/flutter/flutter/issues/56308
},
skip: isBrowser && !isCanvasKit, // https://github.com/flutter/flutter/issues/56308
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134386
notDisposedAllowList: <String, int?> {'LeaderLayer': 1},
));
testWidgets('getLocalRectForCaret reports the real caret Rect', (WidgetTester tester) async {
testWidgetsWithLeakTracking('getLocalRectForCaret reports the real caret Rect', (WidgetTester tester) async {
EditableText.debugDeterministicCursor = true;
addTearDown(() { EditableText.debugDeterministicCursor = false; });
final String text = 'test${' ' * 50}\n'
'2nd line\n'
'\n';
final TextEditingController controller = TextEditingController.fromValue(TextEditingValue(
text: text,
selection: const TextSelection.collapsed(offset: 0),
));
addTearDown(controller.dispose);
final Widget widget = EditableText(
autofocus: true,
backgroundCursorColor: Colors.grey,
controller: controller,
focusNode: FocusNode(),
focusNode: focusNode,
style: const TextStyle(fontSize: 20),
textAlign: TextAlign.center,
keyboardType: TextInputType.text,
......@@ -1287,5 +1335,11 @@ void main() {
paints..rect(color: cursorColor, rect: localRect.shift(editableTextRect.topLeft)),
);
}
}, variant: TargetPlatformVariant.all());
},
variant: TargetPlatformVariant.all(),
leakTrackingTestConfig: const LeakTrackingTestConfig(
// TODO(ksokolovskyi): remove after fixing
// https://github.com/flutter/flutter/issues/134386
notDisposedAllowList: <String, int?> {'LeaderLayer': 792},
));
}
......@@ -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';
import 'clipboard_utils.dart';
import 'keyboard_utils.dart';
......@@ -97,7 +98,7 @@ void main() {
group('backspace', () {
const LogicalKeyboardKey trigger = LogicalKeyboardKey.backspace;
testWidgets('backspace', (WidgetTester tester) async {
testWidgetsWithLeakTracking('backspace', (WidgetTester tester) async {
controller.text = testText;
// Move the selection to the beginning of the 2nd line (after the newline
// character).
......@@ -122,7 +123,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('backspace readonly', (WidgetTester tester) async {
testWidgetsWithLeakTracking('backspace readonly', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 20,
......@@ -140,7 +141,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('backspace at start', (WidgetTester tester) async {
testWidgetsWithLeakTracking('backspace at start', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 0,
......@@ -163,7 +164,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('backspace at end', (WidgetTester tester) async {
testWidgetsWithLeakTracking('backspace at end', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 72,
......@@ -187,7 +188,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('backspace inside of a cluster', (WidgetTester tester) async {
testWidgetsWithLeakTracking('backspace inside of a cluster', (WidgetTester tester) async {
controller.text = testCluster;
controller.selection = const TextSelection.collapsed(
offset: 1,
......@@ -208,7 +209,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('backspace at cluster boundary', (WidgetTester tester) async {
testWidgetsWithLeakTracking('backspace at cluster boundary', (WidgetTester tester) async {
controller.text = testCluster;
controller.selection = const TextSelection.collapsed(
offset: 8,
......@@ -233,7 +234,7 @@ void main() {
group('delete: ', () {
const LogicalKeyboardKey trigger = LogicalKeyboardKey.delete;
testWidgets('delete', (WidgetTester tester) async {
testWidgetsWithLeakTracking('delete', (WidgetTester tester) async {
controller.text = testText;
// Move the selection to the beginning of the 2nd line (after the newline
// character).
......@@ -259,7 +260,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('delete readonly', (WidgetTester tester) async {
testWidgetsWithLeakTracking('delete readonly', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 20,
......@@ -277,7 +278,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('delete at start', (WidgetTester tester) async {
testWidgetsWithLeakTracking('delete at start', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 0,
......@@ -300,7 +301,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('delete at end', (WidgetTester tester) async {
testWidgetsWithLeakTracking('delete at end', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 72,
......@@ -324,7 +325,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('delete inside of a cluster', (WidgetTester tester) async {
testWidgetsWithLeakTracking('delete inside of a cluster', (WidgetTester tester) async {
controller.text = testCluster;
controller.selection = const TextSelection.collapsed(
offset: 1,
......@@ -345,7 +346,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('delete at cluster boundary', (WidgetTester tester) async {
testWidgetsWithLeakTracking('delete at cluster boundary', (WidgetTester tester) async {
controller.text = testCluster;
controller.selection = const TextSelection.collapsed(
offset: 8,
......@@ -371,7 +372,7 @@ void main() {
// This shares the same logic as backspace.
const LogicalKeyboardKey trigger = LogicalKeyboardKey.delete;
testWidgets('inside of a cluster', (WidgetTester tester) async {
testWidgetsWithLeakTracking('inside of a cluster', (WidgetTester tester) async {
controller.text = testCluster;
controller.selection = const TextSelection(
baseOffset: 9,
......@@ -392,7 +393,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('at the boundaries of a cluster', (WidgetTester tester) async {
testWidgetsWithLeakTracking('at the boundaries of a cluster', (WidgetTester tester) async {
controller.text = testCluster;
controller.selection = const TextSelection(
baseOffset: 8,
......@@ -413,7 +414,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('cross-cluster', (WidgetTester tester) async {
testWidgetsWithLeakTracking('cross-cluster', (WidgetTester tester) async {
controller.text = testCluster;
controller.selection = const TextSelection(
baseOffset: 1,
......@@ -434,7 +435,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('cross-cluster obscured text', (WidgetTester tester) async {
testWidgetsWithLeakTracking('cross-cluster obscured text', (WidgetTester tester) async {
controller.text = testCluster;
controller.selection = const TextSelection(
baseOffset: 1,
......@@ -464,7 +465,7 @@ void main() {
return SingleActivator(trigger, control: !isApple, alt: isApple);
}
testWidgets('WordModifier-backspace', (WidgetTester tester) async {
testWidgetsWithLeakTracking('WordModifier-backspace', (WidgetTester tester) async {
controller.text = testText;
// Place the caret before "people".
controller.selection = const TextSelection.collapsed(
......@@ -489,7 +490,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('readonly', (WidgetTester tester) async {
testWidgetsWithLeakTracking('readonly', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 29,
......@@ -507,7 +508,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('at start', (WidgetTester tester) async {
testWidgetsWithLeakTracking('at start', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 0,
......@@ -530,7 +531,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('at end', (WidgetTester tester) async {
testWidgetsWithLeakTracking('at end', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 72,
......@@ -554,7 +555,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('inside of a cluster', (WidgetTester tester) async {
testWidgetsWithLeakTracking('inside of a cluster', (WidgetTester tester) async {
controller.text = testCluster;
controller.selection = const TextSelection.collapsed(
offset: 1,
......@@ -575,7 +576,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('at cluster boundary', (WidgetTester tester) async {
testWidgetsWithLeakTracking('at cluster boundary', (WidgetTester tester) async {
controller.text = testCluster;
controller.selection = const TextSelection.collapsed(
offset: 8,
......@@ -604,7 +605,7 @@ void main() {
return SingleActivator(trigger, control: !isApple, alt: isApple);
}
testWidgets('WordModifier-delete', (WidgetTester tester) async {
testWidgetsWithLeakTracking('WordModifier-delete', (WidgetTester tester) async {
controller.text = testText;
// Place the caret after "all".
controller.selection = const TextSelection.collapsed(
......@@ -629,7 +630,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('readonly', (WidgetTester tester) async {
testWidgetsWithLeakTracking('readonly', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 23,
......@@ -647,7 +648,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('at start', (WidgetTester tester) async {
testWidgetsWithLeakTracking('at start', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 0,
......@@ -670,7 +671,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('at end', (WidgetTester tester) async {
testWidgetsWithLeakTracking('at end', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 72,
......@@ -687,7 +688,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('inside of a cluster', (WidgetTester tester) async {
testWidgetsWithLeakTracking('inside of a cluster', (WidgetTester tester) async {
controller.text = testCluster;
controller.selection = const TextSelection.collapsed(
offset: 1,
......@@ -708,7 +709,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{ TargetPlatform.iOS }));
testWidgets('at cluster boundary', (WidgetTester tester) async {
testWidgetsWithLeakTracking('at cluster boundary', (WidgetTester tester) async {
controller.text = testCluster;
controller.selection = const TextSelection.collapsed(
offset: 8,
......@@ -737,7 +738,7 @@ void main() {
return SingleActivator(trigger, meta: isApple, alt: !isApple);
}
testWidgets('alt-backspace', (WidgetTester tester) async {
testWidgetsWithLeakTracking('alt-backspace', (WidgetTester tester) async {
controller.text = testText;
// Place the caret before "people".
controller.selection = const TextSelection.collapsed(
......@@ -762,7 +763,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('softwrap line boundary, upstream', (WidgetTester tester) async {
testWidgetsWithLeakTracking('softwrap line boundary, upstream', (WidgetTester tester) async {
controller.text = testSoftwrapText;
// Place the caret at the end of the 2nd line.
controller.selection = const TextSelection.collapsed(
......@@ -786,7 +787,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('softwrap line boundary, downstream', (WidgetTester tester) async {
testWidgetsWithLeakTracking('softwrap line boundary, downstream', (WidgetTester tester) async {
controller.text = testSoftwrapText;
// Place the caret at the beginning of the 3rd line.
controller.selection = const TextSelection.collapsed(
......@@ -803,7 +804,7 @@ void main() {
expect(controller.text, testSoftwrapText);
}, variant: TargetPlatformVariant.all());
testWidgets('readonly', (WidgetTester tester) async {
testWidgetsWithLeakTracking('readonly', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 29,
......@@ -821,7 +822,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('at start', (WidgetTester tester) async {
testWidgetsWithLeakTracking('at start', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 0,
......@@ -844,7 +845,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('at end', (WidgetTester tester) async {
testWidgetsWithLeakTracking('at end', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 72,
......@@ -867,7 +868,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('inside of a cluster', (WidgetTester tester) async {
testWidgetsWithLeakTracking('inside of a cluster', (WidgetTester tester) async {
controller.text = testCluster;
controller.selection = const TextSelection.collapsed(
offset: 1,
......@@ -888,7 +889,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('at cluster boundary', (WidgetTester tester) async {
testWidgetsWithLeakTracking('at cluster boundary', (WidgetTester tester) async {
controller.text = testCluster;
controller.selection = const TextSelection.collapsed(
offset: 8,
......@@ -917,7 +918,7 @@ void main() {
return SingleActivator(trigger, meta: isApple, alt: !isApple);
}
testWidgets('alt-delete', (WidgetTester tester) async {
testWidgetsWithLeakTracking('alt-delete', (WidgetTester tester) async {
controller.text = testText;
// Place the caret after "all".
controller.selection = const TextSelection.collapsed(
......@@ -942,7 +943,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('softwrap line boundary, upstream', (WidgetTester tester) async {
testWidgetsWithLeakTracking('softwrap line boundary, upstream', (WidgetTester tester) async {
controller.text = testSoftwrapText;
// Place the caret at the end of the 2nd line.
controller.selection = const TextSelection.collapsed(
......@@ -961,7 +962,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('softwrap line boundary, downstream', (WidgetTester tester) async {
testWidgetsWithLeakTracking('softwrap line boundary, downstream', (WidgetTester tester) async {
controller.text = testSoftwrapText;
// Place the caret at the beginning of the 3rd line.
controller.selection = const TextSelection.collapsed(
......@@ -984,7 +985,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('readonly', (WidgetTester tester) async {
testWidgetsWithLeakTracking('readonly', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 23,
......@@ -1002,7 +1003,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('at start', (WidgetTester tester) async {
testWidgetsWithLeakTracking('at start', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 0,
......@@ -1025,7 +1026,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('at end', (WidgetTester tester) async {
testWidgetsWithLeakTracking('at end', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 72,
......@@ -1042,7 +1043,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('inside of a cluster', (WidgetTester tester) async {
testWidgetsWithLeakTracking('inside of a cluster', (WidgetTester tester) async {
controller.text = testCluster;
controller.selection = const TextSelection.collapsed(
offset: 1,
......@@ -1063,7 +1064,7 @@ void main() {
);
}, variant: TargetPlatformVariant.all());
testWidgets('at cluster boundary', (WidgetTester tester) async {
testWidgetsWithLeakTracking('at cluster boundary', (WidgetTester tester) async {
controller.text = testCluster;
controller.selection = const TextSelection.collapsed(
offset: 8,
......@@ -1089,7 +1090,7 @@ void main() {
group('left', () {
const LogicalKeyboardKey trigger = LogicalKeyboardKey.arrowLeft;
testWidgets('at start', (WidgetTester tester) async {
testWidgetsWithLeakTracking('at start', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 0,
......@@ -1109,7 +1110,7 @@ void main() {
}
}, variant: TargetPlatformVariant.all());
testWidgets('base arrow key movement', (WidgetTester tester) async {
testWidgetsWithLeakTracking('base arrow key movement', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 20,
......@@ -1123,7 +1124,7 @@ void main() {
));
}, variant: TargetPlatformVariant.all());
testWidgets('word modifier + arrow key movement', (WidgetTester tester) async {
testWidgetsWithLeakTracking('word modifier + arrow key movement', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 7, // Before the first "the"
......@@ -1137,7 +1138,7 @@ void main() {
));
}, variant: allExceptApple);
testWidgets('line modifier + arrow key movement', (WidgetTester tester) async {
testWidgetsWithLeakTracking('line modifier + arrow key movement', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 24, // Before the "good".
......@@ -1155,7 +1156,7 @@ void main() {
group('right', () {
const LogicalKeyboardKey trigger = LogicalKeyboardKey.arrowRight;
testWidgets('at end', (WidgetTester tester) async {
testWidgetsWithLeakTracking('at end', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 72,
......@@ -1172,7 +1173,7 @@ void main() {
}
}, variant: TargetPlatformVariant.all());
testWidgets('base arrow key movement', (WidgetTester tester) async {
testWidgetsWithLeakTracking('base arrow key movement', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 20,
......@@ -1186,7 +1187,7 @@ void main() {
));
}, variant: TargetPlatformVariant.all());
testWidgets('word modifier + arrow key movement', (WidgetTester tester) async {
testWidgetsWithLeakTracking('word modifier + arrow key movement', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 7, // Before the first "the"
......@@ -1200,7 +1201,7 @@ void main() {
));
}, variant: allExceptApple);
testWidgets('line modifier + arrow key movement', (WidgetTester tester) async {
testWidgetsWithLeakTracking('line modifier + arrow key movement', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 24, // Before the "good".
......@@ -1217,7 +1218,7 @@ void main() {
});
group('With initial non-collapsed selection', () {
testWidgets('base arrow key movement', (WidgetTester tester) async {
testWidgetsWithLeakTracking('base arrow key movement', (WidgetTester tester) async {
controller.text = testText;
// The word "all" is selected.
controller.selection = const TextSelection(
......@@ -1269,7 +1270,7 @@ void main() {
));
}, variant: TargetPlatformVariant.all());
testWidgets('word modifier + arrow key movement', (WidgetTester tester) async {
testWidgetsWithLeakTracking('word modifier + arrow key movement', (WidgetTester tester) async {
controller.text = testText;
// "good" to "come" is selected.
controller.selection = const TextSelection(
......@@ -1322,7 +1323,7 @@ void main() {
));
}, variant: allExceptApple);
testWidgets('line modifier + arrow key movement', (WidgetTester tester) async {
testWidgetsWithLeakTracking('line modifier + arrow key movement', (WidgetTester tester) async {
controller.text = testText;
// "good" to "come" is selected.
controller.selection = const TextSelection(
......@@ -1378,7 +1379,7 @@ void main() {
});
group('vertical movement', () {
testWidgets('at start', (WidgetTester tester) async {
testWidgetsWithLeakTracking('at start', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 0,
......@@ -1411,7 +1412,7 @@ void main() {
}
}, variant: TargetPlatformVariant.all());
testWidgets('at end', (WidgetTester tester) async {
testWidgetsWithLeakTracking('at end', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 72,
......@@ -1438,7 +1439,7 @@ void main() {
}
}, variant: TargetPlatformVariant.all());
testWidgets('run', (WidgetTester tester) async {
testWidgetsWithLeakTracking('run', (WidgetTester tester) async {
controller.text =
'aa\n' // 3
'a\n' // 3 + 2 = 5
......@@ -1525,7 +1526,7 @@ void main() {
));
}, variant: TargetPlatformVariant.all());
testWidgets('run with page down/up', (WidgetTester tester) async {
testWidgetsWithLeakTracking('run with page down/up', (WidgetTester tester) async {
controller.text =
'aa\n' // 3
'a\n' // 3 + 2 = 5
......@@ -1560,7 +1561,7 @@ void main() {
));
}, variant: TargetPlatformVariant.all(excluding: <TargetPlatform>{TargetPlatform.iOS, TargetPlatform.macOS})); // intended: on macOS Page Up/Down only scrolls
testWidgets('run can be interrupted by layout changes', (WidgetTester tester) async {
testWidgetsWithLeakTracking('run can be interrupted by layout changes', (WidgetTester tester) async {
controller.text =
'aa\n' // 3
'a\n' // 3 + 2 = 5
......@@ -1589,7 +1590,7 @@ void main() {
));
}, variant: TargetPlatformVariant.all());
testWidgets('run can be interrupted by selection changes', (WidgetTester tester) async {
testWidgetsWithLeakTracking('run can be interrupted by selection changes', (WidgetTester tester) async {
controller.text =
'aa\n' // 3
'a\n' // 3 + 2 = 5
......@@ -1624,7 +1625,7 @@ void main() {
));
}, variant: TargetPlatformVariant.all());
testWidgets('long run with fractional text height', (WidgetTester tester) async {
testWidgetsWithLeakTracking('long run with fractional text height', (WidgetTester tester) async {
controller.text = "${'źdźbło\n' * 49}źdźbło";
controller.selection = const TextSelection.collapsed(offset: 2);
await tester.pumpWidget(buildEditableText(style: const TextStyle(fontSize: 13.0, height: 1.17)));
......@@ -1658,7 +1659,7 @@ void main() {
group('macOS shortcuts', () {
final TargetPlatformVariant macOSOnly = TargetPlatformVariant.only(TargetPlatform.macOS);
testWidgets('word modifier + arrowLeft', (WidgetTester tester) async {
testWidgetsWithLeakTracking('word modifier + arrowLeft', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 7, // Before the first "the"
......@@ -1672,7 +1673,7 @@ void main() {
));
}, variant: macOSOnly);
testWidgets('word modifier + arrowRight', (WidgetTester tester) async {
testWidgetsWithLeakTracking('word modifier + arrowRight', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 7, // Before the first "the"
......@@ -1686,7 +1687,7 @@ void main() {
));
}, variant: macOSOnly);
testWidgets('line modifier + arrowLeft', (WidgetTester tester) async {
testWidgetsWithLeakTracking('line modifier + arrowLeft', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 24, // Before the "good".
......@@ -1700,7 +1701,7 @@ void main() {
));
}, variant: macOSOnly);
testWidgets('line modifier + arrowRight', (WidgetTester tester) async {
testWidgetsWithLeakTracking('line modifier + arrowRight', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 24, // Before the "good".
......@@ -1715,7 +1716,7 @@ void main() {
));
}, variant: macOSOnly);
testWidgets('word modifier + arrow key movement', (WidgetTester tester) async {
testWidgetsWithLeakTracking('word modifier + arrow key movement', (WidgetTester tester) async {
controller.text = testText;
// "good" to "come" is selected.
controller.selection = const TextSelection(
......@@ -1768,7 +1769,7 @@ void main() {
));
}, variant: macOSOnly);
testWidgets('line modifier + arrow key movement', (WidgetTester tester) async {
testWidgetsWithLeakTracking('line modifier + arrow key movement', (WidgetTester tester) async {
controller.text = testText;
// "good" to "come" is selected.
controller.selection = const TextSelection(
......@@ -1828,7 +1829,7 @@ void main() {
const TargetPlatformVariant appleOnly = TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.macOS, TargetPlatform.iOS });
group('macOS shortcuts', () {
testWidgets('word modifier + arrowLeft', (WidgetTester tester) async {
testWidgetsWithLeakTracking('word modifier + arrowLeft', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 7, // Before the first "the"
......@@ -1840,7 +1841,7 @@ void main() {
expect(controller.selection, const TextSelection.collapsed(offset: 7));
}, variant: appleOnly);
testWidgets('word modifier + arrowRight', (WidgetTester tester) async {
testWidgetsWithLeakTracking('word modifier + arrowRight', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 7, // Before the first "the"
......@@ -1852,7 +1853,7 @@ void main() {
expect(controller.selection, const TextSelection.collapsed(offset: 7));
}, variant: appleOnly);
testWidgets('line modifier + arrowLeft', (WidgetTester tester) async {
testWidgetsWithLeakTracking('line modifier + arrowLeft', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 24, // Before the "good".
......@@ -1864,7 +1865,7 @@ void main() {
expect(controller.selection, const TextSelection.collapsed(offset: 24,));
}, variant: appleOnly);
testWidgets('line modifier + arrowRight', (WidgetTester tester) async {
testWidgetsWithLeakTracking('line modifier + arrowRight', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 24, // Before the "good".
......@@ -1878,7 +1879,7 @@ void main() {
));
}, variant: appleOnly);
testWidgets('word modifier + arrow key movement', (WidgetTester tester) async {
testWidgetsWithLeakTracking('word modifier + arrow key movement', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection(
baseOffset: 24,
......@@ -1931,7 +1932,7 @@ void main() {
));
}, variant: appleOnly);
testWidgets('line modifier + arrow key movement', (WidgetTester tester) async {
testWidgetsWithLeakTracking('line modifier + arrow key movement', (WidgetTester tester) async {
controller.text = testText;
// "good" to "come" is selected.
controller.selection = const TextSelection(
......@@ -1988,7 +1989,7 @@ void main() {
}, variant: appleOnly);
});
testWidgets('vertical movement outside of selection',
testWidgetsWithLeakTracking('vertical movement outside of selection',
(WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
......@@ -2014,7 +2015,7 @@ void main() {
}
}, variant: TargetPlatformVariant.all());
testWidgets('select all non apple', (WidgetTester tester) async {
testWidgetsWithLeakTracking('select all non apple', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 0,
......@@ -2027,7 +2028,7 @@ void main() {
expect(controller.selection, const TextSelection.collapsed(offset: 0));
}, variant: allExceptApple);
testWidgets('select all apple', (WidgetTester tester) async {
testWidgetsWithLeakTracking('select all apple', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(
offset: 0,
......@@ -2040,7 +2041,7 @@ void main() {
expect(controller.selection, const TextSelection.collapsed(offset: 0));
}, variant: appleOnly);
testWidgets('copy non apple', (WidgetTester tester) async {
testWidgetsWithLeakTracking('copy non apple', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection(
baseOffset: 0,
......@@ -2055,7 +2056,7 @@ void main() {
expect(clipboardData['text'], 'empty');
}, variant: allExceptApple);
testWidgets('copy apple', (WidgetTester tester) async {
testWidgetsWithLeakTracking('copy apple', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection(
baseOffset: 0,
......@@ -2070,7 +2071,7 @@ void main() {
expect(clipboardData['text'], 'empty');
}, variant: appleOnly);
testWidgets('cut non apple', (WidgetTester tester) async {
testWidgetsWithLeakTracking('cut non apple', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection(
baseOffset: 0,
......@@ -2089,7 +2090,7 @@ void main() {
));
}, variant: allExceptApple);
testWidgets('cut apple', (WidgetTester tester) async {
testWidgetsWithLeakTracking('cut apple', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection(
baseOffset: 0,
......@@ -2108,7 +2109,7 @@ void main() {
));
}, variant: appleOnly);
testWidgets('paste non apple', (WidgetTester tester) async {
testWidgetsWithLeakTracking('paste non apple', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(offset: 0);
mockClipboard.clipboardData = <String, dynamic>{
......@@ -2121,7 +2122,7 @@ void main() {
expect(controller.text, testText);
}, variant: allExceptApple);
testWidgets('paste apple', (WidgetTester tester) async {
testWidgetsWithLeakTracking('paste apple', (WidgetTester tester) async {
controller.text = testText;
controller.selection = const TextSelection.collapsed(offset: 0);
mockClipboard.clipboardData = <String, dynamic>{
......@@ -2137,7 +2138,7 @@ void main() {
}, skip: !kIsWeb);// [intended] specific tests target web.
group('Web does accept', () {
testWidgets('select up', (WidgetTester tester) async {
testWidgetsWithLeakTracking('select up', (WidgetTester tester) async {
const SingleActivator selectUp =
SingleActivator(LogicalKeyboardKey.arrowUp, shift: true);
controller.text = testVerticalText;
......@@ -2159,7 +2160,7 @@ void main() {
);
}, variant: TargetPlatformVariant.desktop());
testWidgets('select down', (WidgetTester tester) async {
testWidgetsWithLeakTracking('select down', (WidgetTester tester) async {
const SingleActivator selectDown =
SingleActivator(LogicalKeyboardKey.arrowDown, shift: true);
controller.text = testVerticalText;
......@@ -2181,7 +2182,7 @@ void main() {
);
}, variant: TargetPlatformVariant.desktop());
testWidgets('select all up', (WidgetTester tester) async {
testWidgetsWithLeakTracking('select all up', (WidgetTester tester) async {
final bool isMacOS = defaultTargetPlatform == TargetPlatform.macOS;
final SingleActivator selectAllUp = isMacOS
? const SingleActivator(LogicalKeyboardKey.arrowUp,
......@@ -2207,7 +2208,7 @@ void main() {
);
}, variant: TargetPlatformVariant.desktop());
testWidgets('select all down', (WidgetTester tester) async {
testWidgetsWithLeakTracking('select all down', (WidgetTester tester) async {
final bool isMacOS = defaultTargetPlatform == TargetPlatform.macOS;
final SingleActivator selectAllDown = isMacOS
? const SingleActivator(LogicalKeyboardKey.arrowDown,
......@@ -2233,7 +2234,7 @@ void main() {
);
}, variant: TargetPlatformVariant.desktop());
testWidgets('select left', (WidgetTester tester) async {
testWidgetsWithLeakTracking('select left', (WidgetTester tester) async {
const SingleActivator selectLeft =
SingleActivator(LogicalKeyboardKey.arrowLeft, shift: true);
controller.text = 'testing';
......@@ -2253,7 +2254,7 @@ void main() {
);
}, variant: TargetPlatformVariant.desktop());
testWidgets('select right', (WidgetTester tester) async {
testWidgetsWithLeakTracking('select right', (WidgetTester tester) async {
const SingleActivator selectRight =
SingleActivator(LogicalKeyboardKey.arrowRight, shift: true);
controller.text = 'testing';
......@@ -2273,7 +2274,7 @@ void main() {
);
}, variant: TargetPlatformVariant.desktop());
testWidgets(
testWidgetsWithLeakTracking(
'select left should not expand selection if selection is disabled',
(WidgetTester tester) async {
const SingleActivator selectLeft =
......@@ -2296,7 +2297,7 @@ void main() {
);
}, variant: TargetPlatformVariant.desktop());
testWidgets(
testWidgetsWithLeakTracking(
'select right should not expand selection if selection is disabled',
(WidgetTester tester) async {
const SingleActivator selectRight =
......@@ -2317,7 +2318,7 @@ void main() {
);
}, variant: TargetPlatformVariant.desktop());
testWidgets('select all left', (WidgetTester tester) async {
testWidgetsWithLeakTracking('select all left', (WidgetTester tester) async {
final bool isMacOS = defaultTargetPlatform == TargetPlatform.macOS;
final SingleActivator selectAllLeft = isMacOS
? const SingleActivator(LogicalKeyboardKey.arrowLeft,
......@@ -2341,7 +2342,7 @@ void main() {
);
}, variant: TargetPlatformVariant.desktop());
testWidgets('select all right', (WidgetTester tester) async {
testWidgetsWithLeakTracking('select all right', (WidgetTester tester) async {
final bool isMacOS = defaultTargetPlatform == TargetPlatform.macOS;
final SingleActivator selectAllRight = isMacOS
? const SingleActivator(LogicalKeyboardKey.arrowRight,
......
......@@ -7,6 +7,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter/src/foundation/constants.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
class _TestSliverPersistentHeaderDelegate extends SliverPersistentHeaderDelegate {
_TestSliverPersistentHeaderDelegate({
......@@ -40,11 +41,23 @@ class _TestSliverPersistentHeaderDelegate extends SliverPersistentHeaderDelegate
void main() {
const TextStyle textStyle = TextStyle();
const Color cursorColor = Color.fromARGB(0xFF, 0xFF, 0x00, 0x00);
final FocusNode focusNode = FocusNode();
testWidgets('tapping on a partly visible editable brings it fully on screen', (WidgetTester tester) async {
late TextEditingController controller;
late FocusNode focusNode;
setUp(() {
controller = TextEditingController();
focusNode = FocusNode();
});
tearDown(() {
controller.dispose();
focusNode.dispose();
});
testWidgetsWithLeakTracking('tapping on a partly visible editable brings it fully on screen', (WidgetTester tester) async {
final ScrollController scrollController = ScrollController();
final TextEditingController controller = TextEditingController();
addTearDown(scrollController.dispose);
await tester.pumpWidget(MaterialApp(
home: Center(
......@@ -80,10 +93,9 @@ void main() {
expect(scrollController.offset, 0.0);
});
testWidgets('tapping on a partly visible editable brings it fully on screen with scrollInsets', (WidgetTester tester) async {
testWidgetsWithLeakTracking('tapping on a partly visible editable brings it fully on screen with scrollInsets', (WidgetTester tester) async {
final ScrollController scrollController = ScrollController();
final TextEditingController controller = TextEditingController();
final FocusNode focusNode = FocusNode();
addTearDown(scrollController.dispose);
await tester.pumpWidget(MaterialApp(
home: Center(
......@@ -126,10 +138,9 @@ void main() {
expect(scrollController.offset, greaterThan(200.0 - 50.0 - 5.0));
});
testWidgets('editable comes back on screen when entering text while it is off-screen', (WidgetTester tester) async {
testWidgetsWithLeakTracking('editable comes back on screen when entering text while it is off-screen', (WidgetTester tester) async {
final ScrollController scrollController = ScrollController(initialScrollOffset: 100.0);
final TextEditingController controller = TextEditingController();
final FocusNode focusNode = FocusNode();
addTearDown(scrollController.dispose);
await tester.pumpWidget(MaterialApp(
home: Center(
......@@ -173,12 +184,10 @@ void main() {
expect(find.byType(EditableText), findsOneWidget);
});
testWidgets('entering text does not scroll when scrollPhysics.allowImplicitScrolling = false', (WidgetTester tester) async {
testWidgetsWithLeakTracking('entering text does not scroll when scrollPhysics.allowImplicitScrolling = false', (WidgetTester tester) async {
// regression test for https://github.com/flutter/flutter/issues/19523
final ScrollController scrollController = ScrollController(initialScrollOffset: 100.0);
final TextEditingController controller = TextEditingController();
final FocusNode focusNode = FocusNode();
addTearDown(scrollController.dispose);
await tester.pumpWidget(MaterialApp(
home: Center(
......@@ -223,11 +232,10 @@ void main() {
expect(find.byType(EditableText), findsNothing);
});
testWidgets('entering text does not scroll a surrounding PageView', (WidgetTester tester) async {
testWidgetsWithLeakTracking('entering text does not scroll a surrounding PageView', (WidgetTester tester) async {
// regression test for https://github.com/flutter/flutter/issues/19523
final TextEditingController textController = TextEditingController();
final PageController pageController = PageController(initialPage: 1);
addTearDown(pageController.dispose);
await tester.pumpWidget(
MaterialApp(
......@@ -245,7 +253,7 @@ void main() {
ColoredBox(
color: Colors.green,
child: TextField(
controller: textController,
controller: controller,
),
),
Container(
......@@ -261,7 +269,7 @@ void main() {
await tester.showKeyboard(find.byType(EditableText));
await tester.pumpAndSettle();
expect(textController.text, '');
expect(controller.text, '');
tester.testTextInput.enterText('H');
final int frames = await tester.pumpAndSettle();
......@@ -269,13 +277,12 @@ void main() {
// that the surrounding PageView is incorrectly scrolling back-and-forth.
expect(frames, 1);
expect(textController.text, 'H');
expect(controller.text, 'H');
});
testWidgets('focused multi-line editable scrolls caret back into view when typing', (WidgetTester tester) async {
testWidgetsWithLeakTracking('focused multi-line editable scrolls caret back into view when typing', (WidgetTester tester) async {
final ScrollController scrollController = ScrollController();
final TextEditingController controller = TextEditingController();
final FocusNode focusNode = FocusNode();
addTearDown(scrollController.dispose);
controller.text = "Start${'\n' * 39}End";
await tester.pumpWidget(MaterialApp(
......@@ -322,10 +329,9 @@ void main() {
expect(scrollController.offset, greaterThan(0.0));
});
testWidgets('focused multi-line editable does not scroll to old position when non-collapsed selection set', (WidgetTester tester) async {
testWidgetsWithLeakTracking('focused multi-line editable does not scroll to old position when non-collapsed selection set', (WidgetTester tester) async {
final ScrollController scrollController = ScrollController();
final TextEditingController controller = TextEditingController();
final FocusNode focusNode = FocusNode();
addTearDown(scrollController.dispose);
final String text = "Start${'\n' * 39}End";
controller.value = TextEditingValue(text: text, selection: TextSelection.collapsed(offset: text.length - 3));
......@@ -374,11 +380,9 @@ void main() {
expect(scrollController.offset, 28.0);
});
testWidgets('scrolls into view with scrollInserts after the keyboard pops up', (WidgetTester tester) async {
testWidgetsWithLeakTracking('scrolls into view with scrollInserts after the keyboard pops up', (WidgetTester tester) async {
final ScrollController scrollController = ScrollController();
final TextEditingController controller = TextEditingController();
final FocusNode focusNode = FocusNode();
addTearDown(scrollController.dispose);
const Key container = Key('container');
await tester.pumpWidget(MaterialApp(
......@@ -418,15 +422,14 @@ void main() {
expect(find.byKey(container), findsNothing);
});
testWidgets(
testWidgetsWithLeakTracking(
'A pinned persistent header should not scroll when its descendant EditableText gains focus',
(WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/25507.
ScrollController controller;
final TextEditingController textEditingController = TextEditingController();
final FocusNode focusNode = FocusNode();
final ScrollController scrollController = ScrollController();
addTearDown(scrollController.dispose);
const Key headerKey = Key('header');
await tester.pumpWidget(
MaterialApp(
home: Center(
......@@ -434,7 +437,7 @@ void main() {
height: 600.0,
width: 600.0,
child: CustomScrollView(
controller: controller = ScrollController(),
controller: scrollController,
slivers: List<Widget>.generate(50, (int i) {
return i == 10
? SliverPersistentHeader(
......@@ -447,7 +450,7 @@ void main() {
child: EditableText(
key: headerKey,
backgroundCursorColor: Colors.grey,
controller: textEditingController,
controller: controller,
focusNode: focusNode,
style: textStyle,
cursorColor: cursorColor,
......@@ -469,24 +472,23 @@ void main() {
);
// The persistent header should now be pinned at the top.
controller.jumpTo(100.0 * 15);
scrollController.jumpTo(100.0 * 15);
await tester.pumpAndSettle();
expect(controller.offset, 100.0 * 15);
expect(scrollController.offset, 100.0 * 15);
focusNode.requestFocus();
await tester.pumpAndSettle();
// The scroll offset should remain the same.
expect(controller.offset, 100.0 * 15);
expect(scrollController.offset, 100.0 * 15);
},
);
testWidgets(
testWidgetsWithLeakTracking(
'A pinned persistent header should not scroll when its descendant EditableText gains focus (no animation)',
(WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/25507.
ScrollController controller;
final TextEditingController textEditingController = TextEditingController();
final FocusNode focusNode = FocusNode();
final ScrollController scrollController = ScrollController();
addTearDown(scrollController.dispose);
const Key headerKey = Key('header');
await tester.pumpWidget(
......@@ -496,7 +498,7 @@ void main() {
height: 600.0,
width: 600.0,
child: CustomScrollView(
controller: controller = ScrollController(),
controller: scrollController,
slivers: List<Widget>.generate(50, (int i) {
return i == 10
? SliverPersistentHeader(
......@@ -510,7 +512,7 @@ void main() {
child: EditableText(
key: headerKey,
backgroundCursorColor: Colors.grey,
controller: textEditingController,
controller: controller,
focusNode: focusNode,
style: textStyle,
cursorColor: cursorColor,
......@@ -532,20 +534,19 @@ void main() {
);
// The persistent header should now be pinned at the top.
controller.jumpTo(100.0 * 15);
scrollController.jumpTo(100.0 * 15);
await tester.pumpAndSettle();
expect(controller.offset, 100.0 * 15);
expect(scrollController.offset, 100.0 * 15);
focusNode.requestFocus();
await tester.pumpAndSettle();
// The scroll offset should remain the same.
expect(controller.offset, 100.0 * 15);
expect(scrollController.offset, 100.0 * 15);
},
);
void testShowCaretOnScreen({ required bool readOnly }) {
group('EditableText._showCaretOnScreen, readOnly=$readOnly', () {
final TextEditingController textEditingController = TextEditingController();
final TextInputFormatter rejectEverythingFormatter = TextInputFormatter.withFunction((TextEditingValue old, TextEditingValue value) => old);
bool isCaretOnScreen(WidgetTester tester) {
......@@ -574,7 +575,7 @@ void main() {
const SizedBox(height: 599),
EditableText(
backgroundCursorColor: Colors.grey,
controller: textEditingController,
controller: controller,
scrollController: editableScrollController,
inputFormatters: <TextInputFormatter>[if (rejectUserInputs) rejectEverythingFormatter],
focusNode: focusNode,
......@@ -588,11 +589,13 @@ void main() {
);
}
testWidgets('focus-triggered showCaretOnScreen', (WidgetTester tester) async {
textEditingController.text = 'a' * 100;
textEditingController.selection = const TextSelection.collapsed(offset: 100);
testWidgetsWithLeakTracking('focus-triggered showCaretOnScreen', (WidgetTester tester) async {
controller.text = 'a' * 100;
controller.selection = const TextSelection.collapsed(offset: 100);
final ScrollController scrollController = ScrollController();
addTearDown(scrollController.dispose);
final ScrollController editableScrollController = ScrollController();
addTearDown(editableScrollController.dispose);
await tester.pumpWidget(
buildEditableText(
......@@ -617,11 +620,13 @@ void main() {
expect(editableScrollController.offset, readOnly ? 0.0 : greaterThan(0.0));
});
testWidgets('selection-triggered showCaretOnScreen: virtual keyboard', (WidgetTester tester) async {
textEditingController.text = 'a' * 100;
textEditingController.selection = const TextSelection.collapsed(offset: 80);
testWidgetsWithLeakTracking('selection-triggered showCaretOnScreen: virtual keyboard', (WidgetTester tester) async {
controller.text = 'a' * 100;
controller.selection = const TextSelection.collapsed(offset: 80);
final ScrollController scrollController = ScrollController();
addTearDown(scrollController.dispose);
final ScrollController editableScrollController = ScrollController();
addTearDown(editableScrollController.dispose);
await tester.pumpWidget(
buildEditableText(
......@@ -675,11 +680,13 @@ void main() {
expect(editableScrollController.offset, readOnly && !kIsWeb ? 0.0 : greaterThan(0.0));
});
testWidgets('selection-triggered showCaretOnScreen: text selection delegate', (WidgetTester tester) async {
textEditingController.text = 'a' * 100;
textEditingController.selection = const TextSelection.collapsed(offset: 80);
testWidgetsWithLeakTracking('selection-triggered showCaretOnScreen: text selection delegate', (WidgetTester tester) async {
controller.text = 'a' * 100;
controller.selection = const TextSelection.collapsed(offset: 80);
final ScrollController scrollController = ScrollController();
addTearDown(scrollController.dispose);
final ScrollController editableScrollController = ScrollController();
addTearDown(editableScrollController.dispose);
await tester.pumpWidget(
buildEditableText(
......@@ -739,10 +746,11 @@ void main() {
});
// Regression text for https://github.com/flutter/flutter/pull/74722.
testWidgets('does NOT randomly trigger when cursor blinks', (WidgetTester tester) async {
textEditingController.text = 'a' * 100;
textEditingController.selection = const TextSelection.collapsed(offset: 0);
testWidgetsWithLeakTracking('does NOT randomly trigger when cursor blinks', (WidgetTester tester) async {
controller.text = 'a' * 100;
controller.selection = const TextSelection.collapsed(offset: 0);
final ScrollController editableScrollController = ScrollController();
addTearDown(editableScrollController.dispose);
final bool deterministicCursor = EditableText.debugDeterministicCursor;
EditableText.debugDeterministicCursor = false;
......@@ -751,7 +759,7 @@ void main() {
home: Scaffold(
body: EditableText(
backgroundCursorColor: Colors.grey,
controller: textEditingController,
controller: controller,
scrollController: editableScrollController,
focusNode: focusNode,
style: textStyle,
......@@ -770,7 +778,7 @@ void main() {
expect(editableScrollController.offset, 0.0);
// Change the text but keep the cursor location.
state.updateEditingValue(textEditingController.value.copyWith(
state.updateEditingValue(controller.value.copyWith(
text: 'a' * 101,
));
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -7,6 +7,7 @@ import 'dart:math' as math;
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';
Finder findKey(int i) => find.byKey(ValueKey<int>(i), skipOffstage: false);
......@@ -68,7 +69,7 @@ Widget buildListView(Axis scrollDirection, { bool reverse = false, bool shrinkWr
void main() {
group('SingleChildScrollView', () {
testWidgets('SingleChildScrollView ensureVisible Axis.vertical', (WidgetTester tester) async {
testWidgetsWithLeakTracking('SingleChildScrollView ensureVisible Axis.vertical', (WidgetTester tester) async {
BuildContext findContext(int i) => tester.element(findKey(i));
await tester.pumpWidget(buildSingleChildScrollView(Axis.vertical));
......@@ -95,7 +96,7 @@ void main() {
expect(tester.getTopLeft(findKey(3)).dy, equals(100.0));
});
testWidgets('SingleChildScrollView ensureVisible Axis.horizontal', (WidgetTester tester) async {
testWidgetsWithLeakTracking('SingleChildScrollView ensureVisible Axis.horizontal', (WidgetTester tester) async {
BuildContext findContext(int i) => tester.element(findKey(i));
await tester.pumpWidget(buildSingleChildScrollView(Axis.horizontal));
......@@ -122,7 +123,7 @@ void main() {
expect(tester.getTopLeft(findKey(3)).dx, equals(100.0));
});
testWidgets('SingleChildScrollView ensureVisible Axis.vertical reverse', (WidgetTester tester) async {
testWidgetsWithLeakTracking('SingleChildScrollView ensureVisible Axis.vertical reverse', (WidgetTester tester) async {
BuildContext findContext(int i) => tester.element(findKey(i));
await tester.pumpWidget(buildSingleChildScrollView(Axis.vertical, reverse: true));
......@@ -190,7 +191,7 @@ void main() {
expect(tester.getBottomLeft(findKey(6)).dy, equals(500.0));
});
testWidgets('SingleChildScrollView ensureVisible Axis.horizontal reverse', (WidgetTester tester) async {
testWidgetsWithLeakTracking('SingleChildScrollView ensureVisible Axis.horizontal reverse', (WidgetTester tester) async {
BuildContext findContext(int i) => tester.element(findKey(i));
await tester.pumpWidget(buildSingleChildScrollView(Axis.horizontal, reverse: true));
......@@ -263,7 +264,7 @@ void main() {
expect(tester.getBottomLeft(findKey(6)).dx, equals(500.0));
});
testWidgets('SingleChildScrollView ensureVisible rotated child', (WidgetTester tester) async {
testWidgetsWithLeakTracking('SingleChildScrollView ensureVisible rotated child', (WidgetTester tester) async {
BuildContext findContext(int i) => tester.element(findKey(i));
await tester.pumpWidget(
......@@ -310,7 +311,7 @@ void main() {
expect(tester.getTopLeft(findKey(0)).dy, moreOrLessEquals(500.0, epsilon: 0.1));
});
testWidgets('Nested SingleChildScrollView ensureVisible behavior test', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Nested SingleChildScrollView ensureVisible behavior test', (WidgetTester tester) async {
// Regressing test for https://github.com/flutter/flutter/issues/65100
Finder findKey(String coordinate) => find.byKey(ValueKey<String>(coordinate));
BuildContext findContext(String coordinate) => tester.element(findKey(coordinate));
......@@ -388,7 +389,7 @@ void main() {
});
group('ListView', () {
testWidgets('ListView ensureVisible Axis.vertical', (WidgetTester tester) async {
testWidgetsWithLeakTracking('ListView ensureVisible Axis.vertical', (WidgetTester tester) async {
BuildContext findContext(int i) => tester.element(findKey(i));
Future<void> prepare(double offset) async {
tester.state<ScrollableState>(find.byType(Scrollable)).position.jumpTo(offset);
......@@ -424,7 +425,7 @@ void main() {
expect(tester.getTopLeft(findKey(3)).dy, equals(100.0));
});
testWidgets('ListView ensureVisible Axis.horizontal', (WidgetTester tester) async {
testWidgetsWithLeakTracking('ListView ensureVisible Axis.horizontal', (WidgetTester tester) async {
BuildContext findContext(int i) => tester.element(findKey(i));
Future<void> prepare(double offset) async {
tester.state<ScrollableState>(find.byType(Scrollable)).position.jumpTo(offset);
......@@ -460,7 +461,7 @@ void main() {
expect(tester.getTopLeft(findKey(3)).dx, equals(100.0));
});
testWidgets('ListView ensureVisible Axis.vertical reverse', (WidgetTester tester) async {
testWidgetsWithLeakTracking('ListView ensureVisible Axis.vertical reverse', (WidgetTester tester) async {
BuildContext findContext(int i) => tester.element(findKey(i));
Future<void> prepare(double offset) async {
tester.state<ScrollableState>(find.byType(Scrollable)).position.jumpTo(offset);
......@@ -536,7 +537,7 @@ void main() {
expect(tester.getBottomLeft(findKey(0)).dy, equals(500.0));
});
testWidgets('ListView ensureVisible Axis.horizontal reverse', (WidgetTester tester) async {
testWidgetsWithLeakTracking('ListView ensureVisible Axis.horizontal reverse', (WidgetTester tester) async {
BuildContext findContext(int i) => tester.element(findKey(i));
Future<void> prepare(double offset) async {
tester.state<ScrollableState>(find.byType(Scrollable)).position.jumpTo(offset);
......@@ -617,7 +618,7 @@ void main() {
expect(tester.getBottomLeft(findKey(0)).dx, equals(500.0));
});
testWidgets('ListView ensureVisible negative child', (WidgetTester tester) async {
testWidgetsWithLeakTracking('ListView ensureVisible negative child', (WidgetTester tester) async {
BuildContext findContext(int i) => tester.element(findKey(i));
Future<void> prepare(double offset) async {
tester.state<ScrollableState>(find.byType(Scrollable)).position.jumpTo(offset);
......@@ -675,7 +676,7 @@ void main() {
expect(getOffset(), equals(-400.0));
});
testWidgets('ListView ensureVisible rotated child', (WidgetTester tester) async {
testWidgetsWithLeakTracking('ListView ensureVisible rotated child', (WidgetTester tester) async {
BuildContext findContext(int i) => tester.element(findKey(i));
Future<void> prepare(double offset) async {
tester.state<ScrollableState>(find.byType(Scrollable)).position.jumpTo(offset);
......@@ -728,7 +729,7 @@ void main() {
});
group('ListView shrinkWrap', () {
testWidgets('ListView ensureVisible Axis.vertical', (WidgetTester tester) async {
testWidgetsWithLeakTracking('ListView ensureVisible Axis.vertical', (WidgetTester tester) async {
BuildContext findContext(int i) => tester.element(findKey(i));
Future<void> prepare(double offset) async {
tester.state<ScrollableState>(find.byType(Scrollable)).position.jumpTo(offset);
......@@ -764,7 +765,7 @@ void main() {
expect(tester.getTopLeft(findKey(3)).dy, equals(100.0));
});
testWidgets('ListView ensureVisible Axis.horizontal', (WidgetTester tester) async {
testWidgetsWithLeakTracking('ListView ensureVisible Axis.horizontal', (WidgetTester tester) async {
BuildContext findContext(int i) => tester.element(findKey(i));
Future<void> prepare(double offset) async {
tester.state<ScrollableState>(find.byType(Scrollable)).position.jumpTo(offset);
......@@ -800,7 +801,7 @@ void main() {
expect(tester.getTopLeft(findKey(3)).dx, equals(100.0));
});
testWidgets('ListView ensureVisible Axis.vertical reverse', (WidgetTester tester) async {
testWidgetsWithLeakTracking('ListView ensureVisible Axis.vertical reverse', (WidgetTester tester) async {
BuildContext findContext(int i) => tester.element(findKey(i));
Future<void> prepare(double offset) async {
tester.state<ScrollableState>(find.byType(Scrollable)).position.jumpTo(offset);
......@@ -876,7 +877,7 @@ void main() {
expect(tester.getBottomLeft(findKey(0)).dy, equals(500.0));
});
testWidgets('ListView ensureVisible Axis.horizontal reverse', (WidgetTester tester) async {
testWidgetsWithLeakTracking('ListView ensureVisible Axis.horizontal reverse', (WidgetTester tester) async {
BuildContext findContext(int i) => tester.element(findKey(i));
Future<void> prepare(double offset) async {
tester.state<ScrollableState>(find.byType(Scrollable)).position.jumpTo(offset);
......@@ -959,7 +960,7 @@ void main() {
});
group('Scrollable with center', () {
testWidgets('ensureVisible', (WidgetTester tester) async {
testWidgetsWithLeakTracking('ensureVisible', (WidgetTester tester) async {
BuildContext findContext(int i) => tester.element(findKey(i));
Future<void> prepare(double offset) async {
tester.state<ScrollableState>(find.byType(Scrollable)).position.jumpTo(offset);
......
......@@ -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('ErrorWidget.builder', (WidgetTester tester) async {
testWidgetsWithLeakTracking('ErrorWidget.builder', (WidgetTester tester) async {
final ErrorWidgetBuilder oldBuilder = ErrorWidget.builder;
ErrorWidget.builder = (FlutterErrorDetails details) {
return const Text('oopsie!', textDirection: TextDirection.ltr);
......@@ -25,7 +26,7 @@ void main() {
ErrorWidget.builder = oldBuilder;
});
testWidgets('ErrorWidget.builder', (WidgetTester tester) async {
testWidgetsWithLeakTracking('ErrorWidget.builder', (WidgetTester tester) async {
final ErrorWidgetBuilder oldBuilder = ErrorWidget.builder;
ErrorWidget.builder = (FlutterErrorDetails details) {
return ErrorWidget('');
......
......@@ -8,6 +8,7 @@ import 'dart:ui' as ui;
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
import '../image_data.dart';
import '../painting/image_test_utils.dart';
......@@ -90,14 +91,26 @@ FadeInImageParts findFadeInImage(WidgetTester tester) {
}
}
Future<void> main() async {
void main() {
// These must run outside test zone to complete
final ui.Image targetImage = await createTestImage();
final ui.Image placeholderImage = await createTestImage();
final ui.Image replacementImage = await createTestImage();
late final ui.Image targetImage;
late final ui.Image placeholderImage;
late final ui.Image replacementImage;
setUpAll(() async {
targetImage = await createTestImage();
placeholderImage = await createTestImage();
replacementImage = await createTestImage();
});
tearDownAll(() {
targetImage.dispose();
placeholderImage.dispose();
replacementImage.dispose();
});
group('FadeInImage', () {
testWidgets('animates an uncached image', (WidgetTester tester) async {
testWidgetsWithLeakTracking('animates an uncached image', (WidgetTester tester) async {
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
final TestImageProvider imageProvider = TestImageProvider(targetImage);
......@@ -147,7 +160,7 @@ Future<void> main() async {
expect(findFadeInImage(tester).target.opacity, 1);
});
testWidgets("FadeInImage's image obeys gapless playback", (WidgetTester tester) async {
testWidgetsWithLeakTracking("FadeInImage's image obeys gapless playback", (WidgetTester tester) async {
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
final TestImageProvider imageProvider = TestImageProvider(targetImage);
final TestImageProvider secondImageProvider = TestImageProvider(replacementImage);
......@@ -188,7 +201,7 @@ Future<void> main() async {
});
// Regression test for https://github.com/flutter/flutter/issues/111011
testWidgets("FadeInImage's image obeys gapless playback when first image is cached but second isn't",
testWidgetsWithLeakTracking("FadeInImage's image obeys gapless playback when first image is cached but second isn't",
(WidgetTester tester) async {
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
final TestImageProvider imageProvider = TestImageProvider(targetImage);
......@@ -225,7 +238,7 @@ Future<void> main() async {
expect(parts.target.opacity, 1);
});
testWidgets("FadeInImage's placeholder obeys gapless playback", (WidgetTester tester) async {
testWidgetsWithLeakTracking("FadeInImage's placeholder obeys gapless playback", (WidgetTester tester) async {
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
final TestImageProvider secondPlaceholderProvider = TestImageProvider(replacementImage);
final TestImageProvider imageProvider = TestImageProvider(targetImage);
......@@ -261,7 +274,7 @@ Future<void> main() async {
expect(parts.placeholder!.opacity, 1);
});
testWidgets('shows a cached image immediately when skipFadeOnSynchronousLoad=true', (WidgetTester tester) async {
testWidgetsWithLeakTracking('shows a cached image immediately when skipFadeOnSynchronousLoad=true', (WidgetTester tester) async {
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
final TestImageProvider imageProvider = TestImageProvider(targetImage);
imageProvider.resolve(ImageConfiguration.empty);
......@@ -277,7 +290,7 @@ Future<void> main() async {
expect(findFadeInImage(tester).target.opacity, 1);
});
testWidgets('handles updating the placeholder image', (WidgetTester tester) async {
testWidgetsWithLeakTracking('handles updating the placeholder image', (WidgetTester tester) async {
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
final TestImageProvider secondPlaceholderProvider = TestImageProvider(replacementImage);
final TestImageProvider imageProvider = TestImageProvider(targetImage);
......@@ -309,7 +322,7 @@ Future<void> main() async {
expect(findFadeInImage(tester).state, same(state));
});
testWidgets('does not keep the placeholder in the tree if it is invisible', (WidgetTester tester) async {
testWidgetsWithLeakTracking('does not keep the placeholder in the tree if it is invisible', (WidgetTester tester) async {
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
final TestImageProvider imageProvider = TestImageProvider(targetImage);
......@@ -331,7 +344,7 @@ Future<void> main() async {
expect(find.byType(Image), findsOneWidget);
});
testWidgets("doesn't interrupt in-progress animation when animation values are updated", (WidgetTester tester) async {
testWidgetsWithLeakTracking("doesn't interrupt in-progress animation when animation values are updated", (WidgetTester tester) async {
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
final TestImageProvider imageProvider = TestImageProvider(targetImage);
......@@ -434,7 +447,7 @@ Future<void> main() async {
});
group('semantics', () {
testWidgets('only one Semantics node appears within FadeInImage', (WidgetTester tester) async {
testWidgetsWithLeakTracking('only one Semantics node appears within FadeInImage', (WidgetTester tester) async {
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
final TestImageProvider imageProvider = TestImageProvider(targetImage);
......@@ -446,7 +459,7 @@ Future<void> main() async {
expect(find.byType(Semantics), findsOneWidget);
});
testWidgets('is excluded if excludeFromSemantics is true', (WidgetTester tester) async {
testWidgetsWithLeakTracking('is excluded if excludeFromSemantics is true', (WidgetTester tester) async {
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
final TestImageProvider imageProvider = TestImageProvider(targetImage);
......@@ -462,7 +475,7 @@ Future<void> main() async {
group('label', () {
const String imageSemanticText = 'Test image semantic label';
testWidgets('defaults to image label if placeholder label is unspecified', (WidgetTester tester) async {
testWidgetsWithLeakTracking('defaults to image label if placeholder label is unspecified', (WidgetTester tester) async {
Semantics semanticsWidget() => tester.widget(find.byType(Semantics));
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
......@@ -489,7 +502,7 @@ Future<void> main() async {
expect(semanticsWidget().properties.label, imageSemanticText);
});
testWidgets('is empty without any specified semantics labels', (WidgetTester tester) async {
testWidgetsWithLeakTracking('is empty without any specified semantics labels', (WidgetTester tester) async {
Semantics semanticsWidget() => tester.widget(find.byType(Semantics));
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
......@@ -515,7 +528,7 @@ Future<void> main() async {
});
group("placeholder's BoxFit", () {
testWidgets("should be the image's BoxFit when not set", (WidgetTester tester) async {
testWidgetsWithLeakTracking("should be the image's BoxFit when not set", (WidgetTester tester) async {
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
final TestImageProvider imageProvider = TestImageProvider(targetImage);
......@@ -529,7 +542,7 @@ Future<void> main() async {
expect(findFadeInImage(tester).placeholder!.fit, equals(BoxFit.cover));
});
testWidgets('should be the given value when set', (WidgetTester tester) async {
testWidgetsWithLeakTracking('should be the given value when set', (WidgetTester tester) async {
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
final TestImageProvider imageProvider = TestImageProvider(targetImage);
......@@ -546,7 +559,7 @@ Future<void> main() async {
});
group("placeholder's FilterQuality", () {
testWidgets("should be the image's FilterQuality when not set", (WidgetTester tester) async {
testWidgetsWithLeakTracking("should be the image's FilterQuality when not set", (WidgetTester tester) async {
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
final TestImageProvider imageProvider = TestImageProvider(targetImage);
......@@ -560,7 +573,7 @@ Future<void> main() async {
expect(findFadeInImage(tester).placeholder!.filterQuality, equals(FilterQuality.medium));
});
testWidgets('should be the given value when set', (WidgetTester tester) async {
testWidgetsWithLeakTracking('should be the given value when set', (WidgetTester tester) async {
final TestImageProvider placeholderProvider = TestImageProvider(placeholderImage);
final TestImageProvider imageProvider = TestImageProvider(targetImage);
......
......@@ -5,9 +5,10 @@
import 'package:flutter/foundation.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('FadeTransition', (WidgetTester tester) async {
testWidgetsWithLeakTracking('FadeTransition', (WidgetTester tester) async {
final DebugPrintCallback oldPrint = debugPrint;
final List<String> log = <String>[];
debugPrint = (String? message, { int? wrapWidth }) {
......
......@@ -5,9 +5,10 @@
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() {
testWidgets('Can size according to aspect ratio', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Can size according to aspect ratio', (WidgetTester tester) async {
final Key outside = UniqueKey();
final Key inside = UniqueKey();
......@@ -42,7 +43,7 @@ void main() {
expect(insidePoint, equals(outsidePoint));
});
testWidgets('Can contain child', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Can contain child', (WidgetTester tester) async {
final Key outside = UniqueKey();
final Key inside = UniqueKey();
......@@ -77,7 +78,7 @@ void main() {
expect(insidePoint, equals(outsidePoint));
});
testWidgets('Child can cover', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Child can cover', (WidgetTester tester) async {
final Key outside = UniqueKey();
final Key inside = UniqueKey();
......@@ -113,7 +114,7 @@ void main() {
expect(insidePoint, equals(outsidePoint));
});
testWidgets('FittedBox with no child', (WidgetTester tester) async {
testWidgetsWithLeakTracking('FittedBox with no child', (WidgetTester tester) async {
final Key key = UniqueKey();
await tester.pumpWidget(
Center(
......@@ -129,7 +130,7 @@ void main() {
expect(box.size.height, 0.0);
});
testWidgets('Child can be aligned multiple ways in a row', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Child can be aligned multiple ways in a row', (WidgetTester tester) async {
final Key outside = UniqueKey();
final Key inside = UniqueKey();
......@@ -339,7 +340,7 @@ void main() {
}
});
testWidgets('FittedBox layers - contain', (WidgetTester tester) async {
testWidgetsWithLeakTracking('FittedBox layers - contain', (WidgetTester tester) async {
await tester.pumpWidget(
const Center(
child: SizedBox(
......@@ -360,7 +361,7 @@ void main() {
expect(getLayers(), <Type>[TransformLayer, TransformLayer, OffsetLayer]);
});
testWidgets('FittedBox layers - cover - horizontal', (WidgetTester tester) async {
testWidgetsWithLeakTracking('FittedBox layers - cover - horizontal', (WidgetTester tester) async {
await tester.pumpWidget(
const Center(
child: SizedBox(
......@@ -383,7 +384,7 @@ void main() {
expect(getLayers(), <Type>[TransformLayer, ClipRectLayer, TransformLayer, OffsetLayer]);
});
testWidgets('FittedBox layers - cover - vertical', (WidgetTester tester) async {
testWidgetsWithLeakTracking('FittedBox layers - cover - vertical', (WidgetTester tester) async {
await tester.pumpWidget(
const Center(
child: SizedBox(
......@@ -406,7 +407,7 @@ void main() {
expect(getLayers(), <Type>[TransformLayer, ClipRectLayer, TransformLayer, OffsetLayer]);
});
testWidgets('FittedBox layers - none - clip', (WidgetTester tester) async {
testWidgetsWithLeakTracking('FittedBox layers - none - clip', (WidgetTester tester) async {
final List<double> values = <double>[10.0, 50.0, 100.0];
for (final double a in values) {
for (final double b in values) {
......@@ -442,7 +443,7 @@ void main() {
}
});
testWidgets('Big child into small fitted box - hit testing', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Big child into small fitted box - hit testing', (WidgetTester tester) async {
final GlobalKey key1 = GlobalKey();
bool pointerDown = false;
await tester.pumpWidget(
......@@ -474,7 +475,7 @@ void main() {
expect(pointerDown, isTrue);
});
testWidgets('Can set and update clipBehavior', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Can set and update clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget(FittedBox(fit: BoxFit.none, child: Container()));
final RenderFittedBox renderObject = tester.allRenderObjects.whereType<RenderFittedBox>().first;
expect(renderObject.clipBehavior, equals(Clip.none));
......@@ -483,7 +484,7 @@ void main() {
expect(renderObject.clipBehavior, equals(Clip.antiAlias));
});
testWidgets('BoxFit.scaleDown matches size of child', (WidgetTester tester) async {
testWidgetsWithLeakTracking('BoxFit.scaleDown matches size of child', (WidgetTester tester) async {
final Key outside = UniqueKey();
final Key inside = UniqueKey();
......@@ -544,7 +545,7 @@ void main() {
expect(insidePoint - outsidePoint, equals(Offset.zero));
});
testWidgets('Switching to and from BoxFit.scaleDown causes relayout', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Switching to and from BoxFit.scaleDown causes relayout', (WidgetTester tester) async {
final Key outside = UniqueKey();
final Widget scaleDownWidget = Center(
......@@ -588,7 +589,7 @@ void main() {
expect(outsideBox.size.height, 50.0);
});
testWidgets('FittedBox without child does not throw', (WidgetTester tester) async {
testWidgetsWithLeakTracking('FittedBox without child does not throw', (WidgetTester tester) async {
await tester.pumpWidget(
const Center(
child: SizedBox(
......
......@@ -5,9 +5,10 @@
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
void main() {
testWidgets('Can hit test flex children of stacks', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Can hit test flex children of stacks', (WidgetTester tester) async {
bool didReceiveTap = false;
await tester.pumpWidget(
Directionality(
......@@ -47,7 +48,7 @@ void main() {
expect(didReceiveTap, isTrue);
});
testWidgets('Flexible defaults to loose', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Flexible defaults to loose', (WidgetTester tester) async {
await tester.pumpWidget(
const Row(
textDirection: TextDirection.ltr,
......@@ -61,7 +62,7 @@ void main() {
expect(box.size.width, 100.0);
});
testWidgets("Doesn't overflow because of floating point accumulated error", (WidgetTester tester) async {
testWidgetsWithLeakTracking("Doesn't overflow because of floating point accumulated error", (WidgetTester tester) async {
// both of these cases have failed in the past due to floating point issues
await tester.pumpWidget(
const Center(
......@@ -99,7 +100,7 @@ void main() {
);
});
testWidgets('Error information is printed correctly', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Error information is printed correctly', (WidgetTester tester) async {
// We run this twice, the first time without an error, so that the second time
// we only get a single exception. Otherwise we'd get two, the one we want and
// an extra one when we discover we never computed a size.
......@@ -133,7 +134,7 @@ void main() {
expect(message, contains('\nSee also:'));
});
testWidgets('Can set and update clipBehavior', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Can set and update clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget(const Flex(direction: Axis.vertical));
final RenderFlex renderObject = tester.allRenderObjects.whereType<RenderFlex>().first;
expect(renderObject.clipBehavior, equals(Clip.none));
......
......@@ -5,6 +5,7 @@
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';
class TestFlowDelegate extends FlowDelegate {
TestFlowDelegate({required this.startOffset}) : super(repaint: startOffset);
......@@ -61,7 +62,7 @@ class DuplicatePainterOpacityFlowDelegate extends OpacityFlowDelegate {
}
void main() {
testWidgets('Flow control test', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Flow control test', (WidgetTester tester) async {
final AnimationController startOffset = AnimationController.unbounded(
vsync: tester,
);
......@@ -115,7 +116,7 @@ void main() {
expect(log, equals(<int>[0]));
});
testWidgets('paintChild gets called twice', (WidgetTester tester) async {
testWidgetsWithLeakTracking('paintChild gets called twice', (WidgetTester tester) async {
await tester.pumpWidget(
Flow(
delegate: DuplicatePainterOpacityFlowDelegate(1.0),
......@@ -137,7 +138,7 @@ void main() {
));
});
testWidgets('Flow opacity layer', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Flow opacity layer', (WidgetTester tester) async {
const double opacity = 0.2;
await tester.pumpWidget(
Flow(
......@@ -157,7 +158,7 @@ void main() {
expect(layer!.firstChild, isA<TransformLayer>());
});
testWidgets('Flow can set and update clipBehavior', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Flow can set and update clipBehavior', (WidgetTester tester) async {
const double opacity = 0.2;
await tester.pumpWidget(
Flow(
......@@ -186,7 +187,7 @@ void main() {
}
});
testWidgets('Flow.unwrapped can set and update clipBehavior', (WidgetTester tester) async {
testWidgetsWithLeakTracking('Flow.unwrapped can set and update clipBehavior', (WidgetTester tester) async {
const double opacity = 0.2;
await tester.pumpWidget(
Flow.unwrapped(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment