blob: 1a970f41d2bf3c5c95ee096546689febf854e6e5 [file] [log] [blame]
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart';
import 'test_widgets.dart';
void main() {
testWidgets('simultaneously dispose a widget and end the scroll animation', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: FlipWidget(
left: ListView(children: List<Widget>.generate(250, (int i) => Text('$i'))),
right: Container(),
),
),
);
await tester.fling(find.byType(ListView), const Offset(0.0, -200.0), 1000.0);
await tester.pump();
tester.state<FlipWidgetState>(find.byType(FlipWidget)).flip();
await tester.pump(const Duration(hours: 5));
});
testWidgets('Disposing a (nested) Scrollable while holding in overscroll does not crash', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/27707.
final ScrollController controller = ScrollController();
final Key outterContainer = GlobalKey();
await tester.pumpWidget(
MaterialApp(
home: Center(
child: Container(
key: outterContainer,
color: Colors.purple,
width: 400.0,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: Container(
width: 500.0,
child: ListView.builder(
controller: controller,
itemBuilder: (BuildContext context, int index) {
return Container(
color: index % 2 == 0 ? Colors.red : Colors.green,
height: 200.0,
child: Text('Hello $index'),
);
},
),
),
),
),
),
),
);
// Go into overscroll.
double lastScrollOffset;
await tester.fling(find.text('Hello 0'), const Offset(0.0, 1000.0), 1000.0);
await tester.pump(const Duration(milliseconds: 100));
expect(lastScrollOffset = controller.offset, lessThan(0.0));
// Reduce the overscroll a little, but don't let it go back to 0.0.
await tester.pump(const Duration(milliseconds: 100));
expect(controller.offset, greaterThan(lastScrollOffset));
expect(controller.offset, lessThan(0.0));
final double currentOffset = controller.offset;
// Start a hold activity by putting one pointer down.
await tester.startGesture(tester.getTopLeft(find.byKey(outterContainer)) + const Offset(50.0, 50.0));
await tester.pumpAndSettle(); // This shouldn't change the scroll offset because of the down event above.
expect(controller.offset, currentOffset);
// Dispose the scrollables while the finger is still down, this should not crash.
await tester.pumpWidget(
MaterialApp(
home: Container(),
),
);
await tester.pumpAndSettle();
expect(controller.hasClients, isFalse);
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
}