Unverified Commit efe8a397 authored by Darren Austin's avatar Darren Austin Committed by GitHub

Added some tests and comments from Shi-Hao for the ReorderableLists. (#74689)

parent 1e7f3955
...@@ -136,6 +136,9 @@ class ReorderableList extends StatefulWidget { ...@@ -136,6 +136,9 @@ class ReorderableList extends StatefulWidget {
final IndexedWidgetBuilder itemBuilder; final IndexedWidgetBuilder itemBuilder;
/// The number of items in the list. /// The number of items in the list.
///
/// It must be a non-negative integer. When zero, nothing is displayed and
/// the widget occupies no space.
final int itemCount; final int itemCount;
/// A callback used by the list to report that a list item has been dragged /// A callback used by the list to report that a list item has been dragged
......
...@@ -8,6 +8,85 @@ import 'package:flutter/material.dart'; ...@@ -8,6 +8,85 @@ import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
void main() { void main() {
testWidgets('negative itemCount should assert', (WidgetTester tester) async {
final List<int> items = <int>[1, 2, 3];
await tester.pumpWidget(MaterialApp(
home: StatefulBuilder(
builder: (BuildContext outerContext, StateSetter setState) {
return CustomScrollView(
slivers: <Widget>[
SliverReorderableList(
itemCount: -1,
onReorder: (int fromIndex, int toIndex) {
setState(() {
if (toIndex > fromIndex) {
toIndex -= 1;
}
items.insert(toIndex, items.removeAt(fromIndex));
});
},
itemBuilder: (BuildContext context, int index) {
return Container(
height: 100,
child: Text('item ${items[index]}'),
);
},
),
],
);
}
),
));
expect(tester.takeException(), isA<AssertionError>());
});
testWidgets('zero itemCount should not build widget', (WidgetTester tester) async {
final List<int> items = <int>[1, 2, 3];
await tester.pumpWidget(MaterialApp(
home: StatefulBuilder(
builder: (BuildContext outerContext, StateSetter setState) {
return CustomScrollView(
slivers: <Widget>[
SliverFixedExtentList(
itemExtent: 50.0,
delegate: SliverChildListDelegate(<Widget>[
const Text('before'),
]),
),
SliverReorderableList(
itemCount: 0,
onReorder: (int fromIndex, int toIndex) {
setState(() {
if (toIndex > fromIndex) {
toIndex -= 1;
}
items.insert(toIndex, items.removeAt(fromIndex));
});
},
itemBuilder: (BuildContext context, int index) {
return Container(
height: 100,
child: Text('item ${items[index]}'),
);
},
),
SliverFixedExtentList(
itemExtent: 50.0,
delegate: SliverChildListDelegate(<Widget>[
const Text('after'),
]),
),
],
);
}
),
));
expect(find.text('before'), findsOneWidget);
expect(find.byType(SliverReorderableList), findsNothing);
expect(find.text('after'), findsOneWidget);
});
testWidgets('SliverReorderableList, drag and drop, fixed height items', (WidgetTester tester) async { testWidgets('SliverReorderableList, drag and drop, fixed height items', (WidgetTester tester) async {
final List<int> items = List<int>.generate(8, (int index) => index); final List<int> items = List<int>.generate(8, (int index) => index);
...@@ -126,6 +205,69 @@ void main() { ...@@ -126,6 +205,69 @@ void main() {
expect(getIconStyle().color, iconColor); expect(getIconStyle().color, iconColor);
expect(getTextStyle().color, textColor); expect(getTextStyle().color, textColor);
}); });
testWidgets('SliverReorderableList - custom proxyDecorator', (WidgetTester tester) async {
const ValueKey<String> fadeTransitionKey = ValueKey<String>('reordered-fade');
await tester.pumpWidget(
TestList(
items: List<int>.from(<int>[0, 1, 2, 3]),
proxyDecorator: (
Widget child,
int index,
Animation<double> animation,
) {
return AnimatedBuilder(
animation: animation,
builder: (BuildContext context, Widget? child) {
final Tween<double> fadeValues = Tween<double>(begin: 1.0, end: 0.5);
final Animation<double> fadeAnimation = animation.drive(fadeValues);
return FadeTransition(
key: fadeTransitionKey,
opacity: fadeAnimation,
child: child,
);
},
child: child,
);
},
),
);
Finder getItemFadeTransition() => find.byKey(fadeTransitionKey);
expect(getItemFadeTransition(), findsNothing);
// Start gesture on first item
final TestGesture drag = await tester.startGesture(tester.getCenter(find.text('item 0')));
await tester.pump(kPressTimeout);
// Drag enough for transition animation defined in proxyDecorator to start.
await drag.moveBy(const Offset(0, 50));
await tester.pump();
// At the start, opacity should be at 1.0.
expect(getItemFadeTransition(), findsOneWidget);
FadeTransition fadeTransition = tester.widget(getItemFadeTransition());
expect(fadeTransition.opacity.value, 1.0);
// Let animation run halfway.
await tester.pump(const Duration(milliseconds: 125));
fadeTransition = tester.widget(getItemFadeTransition());
expect(fadeTransition.opacity.value, greaterThan(0.5));
expect(fadeTransition.opacity.value, lessThan(1.0));
// Allow animation to run to the end.
await tester.pumpAndSettle();
expect(find.byKey(fadeTransitionKey), findsOneWidget);
fadeTransition = tester.widget(getItemFadeTransition());
expect(fadeTransition.opacity.value, 0.5);
// Finish reordering.
await drag.up();
await tester.pumpAndSettle();
expect(getItemFadeTransition(), findsNothing);
});
} }
class TestList extends StatefulWidget { class TestList extends StatefulWidget {
...@@ -133,12 +275,14 @@ class TestList extends StatefulWidget { ...@@ -133,12 +275,14 @@ class TestList extends StatefulWidget {
Key? key, Key? key,
this.textColor, this.textColor,
this.iconColor, this.iconColor,
this.proxyDecorator,
required this.items, required this.items,
}) : super(key: key); }) : super(key: key);
final List<int> items; final List<int> items;
final Color? textColor; final Color? textColor;
final Color? iconColor; final Color? iconColor;
final ReorderItemProxyDecorator? proxyDecorator;
@override @override
_TestListState createState() => _TestListState(); _TestListState createState() => _TestListState();
...@@ -185,6 +329,7 @@ class _TestListState extends State<TestList> { ...@@ -185,6 +329,7 @@ class _TestListState extends State<TestList> {
items.insert(toIndex, items.removeAt(fromIndex)); items.insert(toIndex, items.removeAt(fromIndex));
}); });
}, },
proxyDecorator: widget.proxyDecorator,
), ),
], ],
); );
......
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