627 lines
28 KiB
Dart
627 lines
28 KiB
Dart
// 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/rendering.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
List<TreeSliverNode<String>> _setUpNodes() {
|
|
return <TreeSliverNode<String>>[
|
|
TreeSliverNode<String>('First'),
|
|
TreeSliverNode<String>(
|
|
'Second',
|
|
children: <TreeSliverNode<String>>[
|
|
TreeSliverNode<String>(
|
|
'alpha',
|
|
children: <TreeSliverNode<String>>[
|
|
TreeSliverNode<String>('uno'),
|
|
TreeSliverNode<String>('dos'),
|
|
TreeSliverNode<String>('tres'),
|
|
],
|
|
),
|
|
TreeSliverNode<String>('beta'),
|
|
TreeSliverNode<String>('kappa'),
|
|
],
|
|
),
|
|
TreeSliverNode<String>(
|
|
'Third',
|
|
expanded: true,
|
|
children: <TreeSliverNode<String>>[
|
|
TreeSliverNode<String>('gamma'),
|
|
TreeSliverNode<String>('delta'),
|
|
TreeSliverNode<String>('epsilon'),
|
|
],
|
|
),
|
|
TreeSliverNode<String>('Fourth'),
|
|
];
|
|
}
|
|
|
|
List<TreeSliverNode<String>> treeNodes = _setUpNodes();
|
|
|
|
void main() {
|
|
testWidgets('asserts proper axis directions', (WidgetTester tester) async {
|
|
final exceptions = <Object?>[];
|
|
final FlutterExceptionHandler? oldHandler = FlutterError.onError;
|
|
FlutterError.onError = (FlutterErrorDetails details) {
|
|
exceptions.add(details.exception);
|
|
};
|
|
addTearDown(() {
|
|
FlutterError.onError = oldHandler;
|
|
});
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: CustomScrollView(
|
|
reverse: true,
|
|
slivers: <Widget>[TreeSliver<String>(tree: treeNodes)],
|
|
),
|
|
),
|
|
);
|
|
|
|
FlutterError.onError = oldHandler;
|
|
expect(exceptions.isNotEmpty, isTrue);
|
|
expect(
|
|
exceptions[0].toString(),
|
|
contains('TreeSliver is only supported in Viewports with an AxisDirection.down.'),
|
|
);
|
|
|
|
exceptions.clear();
|
|
await tester.pumpWidget(Container());
|
|
FlutterError.onError = (FlutterErrorDetails details) {
|
|
exceptions.add(details.exception);
|
|
};
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: CustomScrollView(
|
|
scrollDirection: Axis.horizontal,
|
|
reverse: true,
|
|
slivers: <Widget>[TreeSliver<String>(tree: treeNodes)],
|
|
),
|
|
),
|
|
);
|
|
|
|
FlutterError.onError = oldHandler;
|
|
expect(exceptions.isNotEmpty, isTrue);
|
|
expect(
|
|
exceptions[0].toString(),
|
|
contains('TreeSliver is only supported in Viewports with an AxisDirection.down.'),
|
|
);
|
|
|
|
exceptions.clear();
|
|
await tester.pumpWidget(Container());
|
|
FlutterError.onError = (FlutterErrorDetails details) {
|
|
exceptions.add(details.exception);
|
|
};
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: CustomScrollView(
|
|
scrollDirection: Axis.horizontal,
|
|
slivers: <Widget>[TreeSliver<String>(tree: treeNodes)],
|
|
),
|
|
),
|
|
);
|
|
|
|
FlutterError.onError = oldHandler;
|
|
expect(exceptions.isNotEmpty, isTrue);
|
|
expect(
|
|
exceptions[0].toString(),
|
|
contains('TreeSliver is only supported in Viewports with an AxisDirection.down.'),
|
|
);
|
|
});
|
|
|
|
testWidgets('Basic layout', (WidgetTester tester) async {
|
|
treeNodes = _setUpNodes();
|
|
// Default layout, custom indentation values, row extents.
|
|
var treeSliver = TreeSliver<String>(tree: treeNodes);
|
|
await tester.pumpWidget(MaterialApp(home: CustomScrollView(slivers: <Widget>[treeSliver])));
|
|
await tester.pump();
|
|
expect(
|
|
find.byType(TreeSliver<String>),
|
|
paints
|
|
..paragraph(offset: const Offset(46.0, 8.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 48.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 88.0))
|
|
..paragraph(offset: const Offset(56.0, 128.0))
|
|
..paragraph(offset: const Offset(56.0, 168.0))
|
|
..paragraph(offset: const Offset(56.0, 208.0))
|
|
..paragraph(offset: const Offset(46.0, 248.0)),
|
|
);
|
|
expect(find.text('First'), findsOneWidget);
|
|
expect(tester.getRect(find.text('First')), const Rect.fromLTRB(46.0, 8.0, 286.0, 32.0));
|
|
expect(find.text('Second'), findsOneWidget);
|
|
expect(tester.getRect(find.text('Second')), const Rect.fromLTRB(46.0, 48.0, 334.0, 72.0));
|
|
expect(find.text('Third'), findsOneWidget);
|
|
expect(tester.getRect(find.text('Third')), const Rect.fromLTRB(46.0, 88.0, 286.0, 112.0));
|
|
expect(find.text('gamma'), findsOneWidget);
|
|
expect(tester.getRect(find.text('gamma')), const Rect.fromLTRB(56.0, 128.0, 296.0, 152.0));
|
|
expect(find.text('delta'), findsOneWidget);
|
|
expect(tester.getRect(find.text('delta')), const Rect.fromLTRB(56.0, 168.0, 296.0, 192.0));
|
|
expect(find.text('epsilon'), findsOneWidget);
|
|
expect(tester.getRect(find.text('epsilon')), const Rect.fromLTRB(56.0, 208.0, 392.0, 232.0));
|
|
expect(find.text('Fourth'), findsOneWidget);
|
|
expect(tester.getRect(find.text('Fourth')), const Rect.fromLTRB(46.0, 248.0, 334.0, 272.0));
|
|
|
|
treeSliver = TreeSliver<String>(tree: treeNodes, indentation: TreeSliverIndentationType.none);
|
|
await tester.pumpWidget(MaterialApp(home: CustomScrollView(slivers: <Widget>[treeSliver])));
|
|
await tester.pump();
|
|
expect(
|
|
find.byType(TreeSliver<String>),
|
|
paints
|
|
..paragraph(offset: const Offset(46.0, 8.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 48.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 88.0))
|
|
..paragraph(offset: const Offset(46.0, 128.0))
|
|
..paragraph(offset: const Offset(46.0, 168.0))
|
|
..paragraph(offset: const Offset(46.0, 208.0))
|
|
..paragraph(offset: const Offset(46.0, 248.0)),
|
|
);
|
|
expect(find.text('First'), findsOneWidget);
|
|
expect(tester.getRect(find.text('First')), const Rect.fromLTRB(46.0, 8.0, 286.0, 32.0));
|
|
expect(find.text('Second'), findsOneWidget);
|
|
expect(tester.getRect(find.text('Second')), const Rect.fromLTRB(46.0, 48.0, 334.0, 72.0));
|
|
expect(find.text('Third'), findsOneWidget);
|
|
expect(tester.getRect(find.text('Third')), const Rect.fromLTRB(46.0, 88.0, 286.0, 112.0));
|
|
expect(find.text('gamma'), findsOneWidget);
|
|
expect(tester.getRect(find.text('gamma')), const Rect.fromLTRB(46.0, 128.0, 286.0, 152.0));
|
|
expect(find.text('delta'), findsOneWidget);
|
|
expect(tester.getRect(find.text('delta')), const Rect.fromLTRB(46.0, 168.0, 286.0, 192.0));
|
|
expect(find.text('epsilon'), findsOneWidget);
|
|
expect(tester.getRect(find.text('epsilon')), const Rect.fromLTRB(46.0, 208.0, 382.0, 232.0));
|
|
expect(find.text('Fourth'), findsOneWidget);
|
|
expect(tester.getRect(find.text('Fourth')), const Rect.fromLTRB(46.0, 248.0, 334.0, 272.0));
|
|
|
|
treeSliver = TreeSliver<String>(
|
|
tree: treeNodes,
|
|
indentation: TreeSliverIndentationType.custom(50.0),
|
|
);
|
|
await tester.pumpWidget(MaterialApp(home: CustomScrollView(slivers: <Widget>[treeSliver])));
|
|
await tester.pump();
|
|
expect(
|
|
find.byType(TreeSliver<String>),
|
|
paints
|
|
..paragraph(offset: const Offset(46.0, 8.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 48.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 88.0))
|
|
..paragraph(offset: const Offset(96.0, 128.0))
|
|
..paragraph(offset: const Offset(96.0, 168.0))
|
|
..paragraph(offset: const Offset(96.0, 208.0))
|
|
..paragraph(offset: const Offset(46.0, 248.0)),
|
|
);
|
|
expect(find.text('First'), findsOneWidget);
|
|
expect(tester.getRect(find.text('First')), const Rect.fromLTRB(46.0, 8.0, 286.0, 32.0));
|
|
expect(find.text('Second'), findsOneWidget);
|
|
expect(tester.getRect(find.text('Second')), const Rect.fromLTRB(46.0, 48.0, 334.0, 72.0));
|
|
expect(find.text('Third'), findsOneWidget);
|
|
expect(tester.getRect(find.text('Third')), const Rect.fromLTRB(46.0, 88.0, 286.0, 112.0));
|
|
expect(find.text('gamma'), findsOneWidget);
|
|
expect(tester.getRect(find.text('gamma')), const Rect.fromLTRB(96.0, 128.0, 336.0, 152.0));
|
|
expect(find.text('delta'), findsOneWidget);
|
|
expect(tester.getRect(find.text('delta')), const Rect.fromLTRB(96.0, 168.0, 336.0, 192.0));
|
|
expect(find.text('epsilon'), findsOneWidget);
|
|
expect(tester.getRect(find.text('epsilon')), const Rect.fromLTRB(96.0, 208.0, 432.0, 232.0));
|
|
expect(find.text('Fourth'), findsOneWidget);
|
|
expect(tester.getRect(find.text('Fourth')), const Rect.fromLTRB(46.0, 248.0, 334.0, 272.0));
|
|
|
|
treeSliver = TreeSliver<String>(tree: treeNodes, treeRowExtentBuilder: (_, _) => 100);
|
|
await tester.pumpWidget(MaterialApp(home: CustomScrollView(slivers: <Widget>[treeSliver])));
|
|
await tester.pump();
|
|
expect(
|
|
find.byType(TreeSliver<String>),
|
|
paints
|
|
..paragraph(offset: const Offset(46.0, 26.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 126.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 226.0))
|
|
..paragraph(offset: const Offset(56.0, 326.0))
|
|
..paragraph(offset: const Offset(56.0, 426.0))
|
|
..paragraph(offset: const Offset(56.0, 526.0)),
|
|
);
|
|
expect(find.text('First'), findsOneWidget);
|
|
expect(tester.getRect(find.text('First')), const Rect.fromLTRB(46.0, 26.0, 286.0, 74.0));
|
|
expect(find.text('Second'), findsOneWidget);
|
|
expect(tester.getRect(find.text('Second')), const Rect.fromLTRB(46.0, 126.0, 334.0, 174.0));
|
|
expect(find.text('Third'), findsOneWidget);
|
|
expect(tester.getRect(find.text('Third')), const Rect.fromLTRB(46.0, 226.0, 286.0, 274.0));
|
|
expect(find.text('gamma'), findsOneWidget);
|
|
expect(tester.getRect(find.text('gamma')), const Rect.fromLTRB(56.0, 326.0, 296.0, 374.0));
|
|
expect(find.text('delta'), findsOneWidget);
|
|
expect(tester.getRect(find.text('delta')), const Rect.fromLTRB(56.0, 426.0, 296.0, 474.0));
|
|
expect(find.text('epsilon'), findsOneWidget);
|
|
expect(tester.getRect(find.text('epsilon')), const Rect.fromLTRB(56.0, 526.0, 392.0, 574.0));
|
|
expect(find.text('Fourth'), findsNothing);
|
|
});
|
|
|
|
testWidgets('Animating node segment', (WidgetTester tester) async {
|
|
treeNodes = _setUpNodes();
|
|
var treeSliver = TreeSliver<String>(tree: treeNodes);
|
|
await tester.pumpWidget(MaterialApp(home: CustomScrollView(slivers: <Widget>[treeSliver])));
|
|
await tester.pump();
|
|
expect(
|
|
find.byType(TreeSliver<String>),
|
|
paints
|
|
..paragraph(offset: const Offset(46.0, 8.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 48.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 88.0))
|
|
..paragraph(offset: const Offset(56.0, 128.0))
|
|
..paragraph(offset: const Offset(56.0, 168.0))
|
|
..paragraph(offset: const Offset(56.0, 208.0))
|
|
..paragraph(offset: const Offset(46.0, 248.0)),
|
|
);
|
|
expect(find.text('alpha'), findsNothing);
|
|
await tester.tap(find.byType(Icon).first);
|
|
await tester.pump();
|
|
expect(
|
|
find.byType(TreeSliver<String>),
|
|
paints
|
|
..paragraph(offset: const Offset(46.0, 8.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 48.0))
|
|
..paragraph(offset: const Offset(56.0, 8.0)) // beta animating in
|
|
..paragraph(offset: const Offset(56.0, 48.0)) // kappa animating in
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 88.0))
|
|
..paragraph(offset: const Offset(56.0, 128.0))
|
|
..paragraph(offset: const Offset(56.0, 168.0))
|
|
..paragraph(offset: const Offset(56.0, 208.0))
|
|
..paragraph(offset: const Offset(46.0, 248.0)),
|
|
);
|
|
// New nodes have been inserted into the tree, alpha
|
|
// is not visible yet.
|
|
expect(find.text('alpha'), findsNothing);
|
|
expect(find.text('beta'), findsOneWidget);
|
|
expect(tester.getRect(find.text('beta')), const Rect.fromLTRB(56.0, 8.0, 248.0, 32.0));
|
|
expect(find.text('kappa'), findsOneWidget);
|
|
expect(tester.getRect(find.text('kappa')), const Rect.fromLTRB(56.0, 48.0, 296.0, 72.0));
|
|
// Progress the animation.
|
|
await tester.pump(const Duration(milliseconds: 50));
|
|
expect(
|
|
find.byType(TreeSliver<String>),
|
|
paints
|
|
..paragraph(offset: const Offset(46.0, 8.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 48.0))
|
|
..paragraph() // alpha icon
|
|
..paragraph(offset: const Offset(56.0, 8.0)) // alpha animating in
|
|
..paragraph(offset: const Offset(56.0, 48.0)) // beta animating in
|
|
..paragraph(offset: const Offset(56.0, 88.0)) // kappa animating in
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 128.0))
|
|
..paragraph(offset: const Offset(56.0, 168.0))
|
|
..paragraph(offset: const Offset(56.0, 208.0))
|
|
..paragraph(offset: const Offset(56.0, 248.0))
|
|
..paragraph(offset: const Offset(46.0, 288.0)),
|
|
);
|
|
expect(tester.getRect(find.text('alpha')).top.floor(), 8.0);
|
|
expect(find.text('beta'), findsOneWidget);
|
|
expect(tester.getRect(find.text('beta')).top.floor(), 48.0);
|
|
expect(find.text('kappa'), findsOneWidget);
|
|
expect(tester.getRect(find.text('kappa')).top.floor(), 88.0);
|
|
// Complete the animation
|
|
await tester.pumpAndSettle();
|
|
expect(
|
|
find.byType(TreeSliver<String>),
|
|
paints
|
|
..paragraph(offset: const Offset(46.0, 8.0)) // First
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 48.0)) // Second
|
|
..paragraph() // alpha icon
|
|
..paragraph(offset: const Offset(56.0, 88.0)) // alpha
|
|
..paragraph(offset: const Offset(56.0, 128.0)) // beta
|
|
..paragraph(offset: const Offset(56.0, 168.0)) // kappa
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 208.0)) // Third
|
|
..paragraph(offset: const Offset(56.0, 248.0)) // gamma
|
|
..paragraph(offset: const Offset(56.0, 288.0)) // delta
|
|
..paragraph(offset: const Offset(56.0, 328.0)) // epsilon
|
|
..paragraph(offset: const Offset(46.0, 368.0)), // Fourth
|
|
);
|
|
expect(find.text('alpha'), findsOneWidget);
|
|
expect(tester.getRect(find.text('alpha')), const Rect.fromLTRB(56.0, 88.0, 296.0, 112.0));
|
|
expect(find.text('beta'), findsOneWidget);
|
|
expect(tester.getRect(find.text('beta')), const Rect.fromLTRB(56.0, 128.0, 248.0, 152.0));
|
|
expect(find.text('kappa'), findsOneWidget);
|
|
expect(tester.getRect(find.text('kappa')), const Rect.fromLTRB(56.0, 168.0, 296.0, 192.0));
|
|
|
|
// Customize the animation
|
|
treeSliver = TreeSliver<String>(
|
|
tree: treeNodes,
|
|
toggleAnimationStyle: const AnimationStyle(
|
|
duration: Duration(milliseconds: 500),
|
|
curve: Curves.bounceIn,
|
|
),
|
|
);
|
|
await tester.pumpWidget(MaterialApp(home: CustomScrollView(slivers: <Widget>[treeSliver])));
|
|
await tester.pump();
|
|
expect(
|
|
find.byType(TreeSliver<String>),
|
|
paints
|
|
..paragraph(offset: const Offset(46.0, 8.0)) // First
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 48.0)) // Second
|
|
..paragraph() // alpha icon
|
|
..paragraph(offset: const Offset(56.0, 88.0)) // alpha
|
|
..paragraph(offset: const Offset(56.0, 128.0)) // beta
|
|
..paragraph(offset: const Offset(56.0, 168.0)) // kappa
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 208.0)) // Third
|
|
..paragraph(offset: const Offset(56.0, 248.0)) // gamma
|
|
..paragraph(offset: const Offset(56.0, 288.0)) // delta
|
|
..paragraph(offset: const Offset(56.0, 328.0)) // epsilon
|
|
..paragraph(offset: const Offset(46.0, 368.0)), // Fourth
|
|
);
|
|
// Still visible from earlier.
|
|
expect(find.text('alpha'), findsOneWidget);
|
|
expect(tester.getRect(find.text('alpha')), const Rect.fromLTRB(56.0, 88.0, 296.0, 112.0));
|
|
// Collapse the node now
|
|
await tester.tap(find.byType(Icon).first);
|
|
await tester.pump();
|
|
await tester.pump(const Duration(milliseconds: 200));
|
|
expect(find.text('alpha'), findsOneWidget);
|
|
expect(tester.getRect(find.text('alpha')).top.floor(), -22);
|
|
expect(find.text('beta'), findsOneWidget);
|
|
expect(tester.getRect(find.text('beta')).top.floor(), 18);
|
|
expect(find.text('kappa'), findsOneWidget);
|
|
expect(tester.getRect(find.text('kappa')).top.floor(), 58);
|
|
// Progress the animation.
|
|
await tester.pump(const Duration(milliseconds: 200));
|
|
expect(find.text('alpha'), findsOneWidget);
|
|
expect(tester.getRect(find.text('alpha')).top.floor(), -25);
|
|
expect(find.text('beta'), findsOneWidget);
|
|
expect(tester.getRect(find.text('beta')).top.floor(), 15);
|
|
expect(find.text('kappa'), findsOneWidget);
|
|
expect(tester.getRect(find.text('kappa')).top.floor(), 55.0);
|
|
// Complete the animation
|
|
await tester.pumpAndSettle();
|
|
expect(
|
|
find.byType(TreeSliver<String>),
|
|
paints
|
|
..paragraph(offset: const Offset(46.0, 8.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 48.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 88.0))
|
|
..paragraph(offset: const Offset(56.0, 128.0))
|
|
..paragraph(offset: const Offset(56.0, 168.0))
|
|
..paragraph(offset: const Offset(56.0, 208.0))
|
|
..paragraph(offset: const Offset(46.0, 248.0)),
|
|
);
|
|
expect(find.text('alpha'), findsNothing);
|
|
|
|
// Disable the animation
|
|
treeSliver = TreeSliver<String>(
|
|
tree: treeNodes,
|
|
toggleAnimationStyle: AnimationStyle.noAnimation,
|
|
);
|
|
await tester.pumpWidget(MaterialApp(home: CustomScrollView(slivers: <Widget>[treeSliver])));
|
|
await tester.pump();
|
|
expect(
|
|
find.byType(TreeSliver<String>),
|
|
paints
|
|
..paragraph(offset: const Offset(46.0, 8.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 48.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 88.0))
|
|
..paragraph(offset: const Offset(56.0, 128.0))
|
|
..paragraph(offset: const Offset(56.0, 168.0))
|
|
..paragraph(offset: const Offset(56.0, 208.0))
|
|
..paragraph(offset: const Offset(46.0, 248.0)),
|
|
);
|
|
// Not in the tree.
|
|
expect(find.text('alpha'), findsNothing);
|
|
// Collapse the node now
|
|
await tester.tap(find.byType(Icon).first);
|
|
await tester.pump();
|
|
// No animating, straight to positions.
|
|
expect(
|
|
find.byType(TreeSliver<String>),
|
|
paints
|
|
..paragraph(offset: const Offset(46.0, 8.0)) // First
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 48.0)) // Second
|
|
..paragraph() // alpha icon
|
|
..paragraph(offset: const Offset(56.0, 88.0)) // alpha
|
|
..paragraph(offset: const Offset(56.0, 128.0)) // beta
|
|
..paragraph(offset: const Offset(56.0, 168.0)) // kappa
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 208.0)) // Third
|
|
..paragraph(offset: const Offset(56.0, 248.0)) // gamma
|
|
..paragraph(offset: const Offset(56.0, 288.0)) // delta
|
|
..paragraph(offset: const Offset(56.0, 328.0)) // epsilon
|
|
..paragraph(offset: const Offset(46.0, 368.0)), // Fourth
|
|
);
|
|
expect(find.text('alpha'), findsOneWidget);
|
|
expect(tester.getRect(find.text('alpha')), const Rect.fromLTRB(56.0, 88.0, 296.0, 112.0));
|
|
expect(find.text('beta'), findsOneWidget);
|
|
expect(tester.getRect(find.text('beta')), const Rect.fromLTRB(56.0, 128.0, 248.0, 152.0));
|
|
expect(find.text('kappa'), findsOneWidget);
|
|
expect(tester.getRect(find.text('kappa')), const Rect.fromLTRB(56.0, 168.0, 296.0, 192.0));
|
|
});
|
|
|
|
testWidgets('Multiple animating node segments', (WidgetTester tester) async {
|
|
treeNodes = _setUpNodes();
|
|
final treeSliver = TreeSliver<String>(tree: treeNodes);
|
|
await tester.pumpWidget(MaterialApp(home: CustomScrollView(slivers: <Widget>[treeSliver])));
|
|
await tester.pump();
|
|
expect(
|
|
find.byType(TreeSliver<String>),
|
|
paints
|
|
..paragraph(offset: const Offset(46.0, 8.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 48.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 88.0))
|
|
..paragraph(offset: const Offset(56.0, 128.0))
|
|
..paragraph(offset: const Offset(56.0, 168.0))
|
|
..paragraph(offset: const Offset(56.0, 208.0))
|
|
..paragraph(offset: const Offset(46.0, 248.0)),
|
|
);
|
|
expect(find.text('Second'), findsOneWidget);
|
|
expect(find.text('alpha'), findsNothing); // Second is collapsed
|
|
expect(find.text('Third'), findsOneWidget);
|
|
expect(find.text('gamma'), findsOneWidget); // Third is expanded
|
|
|
|
expect(tester.getRect(find.text('Second')), const Rect.fromLTRB(46.0, 48.0, 334.0, 72.0));
|
|
expect(tester.getRect(find.text('Third')), const Rect.fromLTRB(46.0, 88.0, 286.0, 112.0));
|
|
expect(tester.getRect(find.text('gamma')), const Rect.fromLTRB(56.0, 128.0, 296.0, 152.0));
|
|
|
|
// Trigger two animations to run together.
|
|
// Collapse Third
|
|
await tester.tap(find.byType(Icon).last);
|
|
// Expand Second
|
|
await tester.tap(find.byType(Icon).first);
|
|
await tester.pump(const Duration(milliseconds: 15));
|
|
expect(
|
|
find.byType(TreeSliver<String>),
|
|
paints
|
|
..paragraph(offset: const Offset(46.0, 8.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 48.0))
|
|
..paragraph(offset: const Offset(56.0, 8.0)) // beta entering
|
|
..paragraph(offset: const Offset(56.0, 48.0)) // kappa entering
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 88.0))
|
|
..paragraph(offset: const Offset(56.0, 128.0))
|
|
..paragraph(offset: const Offset(56.0, 168.0))
|
|
..paragraph(offset: const Offset(56.0, 208.0))
|
|
..paragraph(offset: const Offset(46.0, 248.0)),
|
|
);
|
|
// Third is collapsing
|
|
expect(tester.getRect(find.text('Third')), const Rect.fromLTRB(46.0, 88.0, 286.0, 112.0));
|
|
expect(tester.getRect(find.text('gamma')), const Rect.fromLTRB(56.0, 128.0, 296.0, 152.0));
|
|
// Second is expanding
|
|
expect(tester.getRect(find.text('Second')), const Rect.fromLTRB(46.0, 48.0, 334.0, 72.0));
|
|
// beta has been added and is animating into view.
|
|
expect(tester.getRect(find.text('beta')).top.floor(), 8.0);
|
|
await tester.pump(const Duration(milliseconds: 15));
|
|
expect(
|
|
find.byType(TreeSliver<String>),
|
|
paints
|
|
..paragraph(offset: const Offset(46.0, 8.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 48.0))
|
|
..paragraph() // alpha icon animating
|
|
..paragraph(offset: const Offset(56.0, -20.0)) // alpha animating
|
|
..paragraph(offset: const Offset(56.0, 20.0)) // beta
|
|
..paragraph(offset: const Offset(56.0, 60.0)) // kappa
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 100.0)) // Third
|
|
// Children of Third are animating, but the expand and
|
|
// collapse counter each other, so their position is unchanged.
|
|
..paragraph(offset: const Offset(56.0, 128.0))
|
|
..paragraph(offset: const Offset(56.0, 168.0))
|
|
..paragraph(offset: const Offset(56.0, 208.0))
|
|
..paragraph(offset: const Offset(46.0, 248.0)),
|
|
);
|
|
// Third is still collapsing. Third is sliding down
|
|
// as Seconds's children slide in, gamma is still exiting.
|
|
expect(tester.getRect(find.text('Third')).top.floor(), 100.0);
|
|
// gamma appears to not have moved, this is because it is
|
|
// intersecting both animations, the positive offset of
|
|
// Second animation == the negative offset of Third
|
|
expect(tester.getRect(find.text('gamma')), const Rect.fromLTRB(56.0, 128.0, 296.0, 152.0));
|
|
// Second is still expanding
|
|
expect(tester.getRect(find.text('Second')), const Rect.fromLTRB(46.0, 48.0, 334.0, 72.0));
|
|
// alpha is still animating into view.
|
|
expect(tester.getRect(find.text('alpha')).top.floor(), -20.0);
|
|
// Progress the animation further
|
|
await tester.pump(const Duration(milliseconds: 15));
|
|
expect(
|
|
find.byType(TreeSliver<String>),
|
|
paints
|
|
..paragraph(offset: const Offset(46.0, 8.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 48.0))
|
|
..paragraph() // alpha icon animating
|
|
..paragraph(offset: const Offset(56.0, -8.0)) // alpha animating
|
|
..paragraph(offset: const Offset(56.0, 32.0)) // beta
|
|
..paragraph(offset: const Offset(56.0, 72.0)) // kappa
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 112.0)) // Third
|
|
// Children of Third are animating, but the expand and
|
|
// collapse counter each other, so their position is unchanged.
|
|
..paragraph(offset: const Offset(56.0, 128.0))
|
|
..paragraph(offset: const Offset(56.0, 168.0))
|
|
..paragraph(offset: const Offset(56.0, 208.0))
|
|
..paragraph(offset: const Offset(46.0, 248.0)),
|
|
);
|
|
// Third is still collapsing. Third is sliding down
|
|
// as Seconds's children slide in, gamma is still exiting.
|
|
expect(tester.getRect(find.text('Third')).top.floor(), 112.0);
|
|
// gamma appears to not have moved, this is because it is
|
|
// intersecting both animations, the positive offset of
|
|
// Second animation == the negative offset of Third
|
|
expect(tester.getRect(find.text('gamma')), const Rect.fromLTRB(56.0, 128.0, 296.0, 152.0));
|
|
// Second is still expanding
|
|
expect(tester.getRect(find.text('Second')), const Rect.fromLTRB(46.0, 48.0, 334.0, 72.0));
|
|
// alpha is still animating into view.
|
|
expect(tester.getRect(find.text('alpha')).top.floor(), -8.0);
|
|
// Complete the animations
|
|
await tester.pumpAndSettle();
|
|
expect(
|
|
find.byType(TreeSliver<String>),
|
|
paints
|
|
..paragraph(offset: const Offset(46.0, 8.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 48.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(56.0, 88.0))
|
|
..paragraph(offset: const Offset(56.0, 128.0))
|
|
..paragraph(offset: const Offset(56.0, 168.0))
|
|
..paragraph() // Icon
|
|
..paragraph(offset: const Offset(46.0, 208.0))
|
|
..paragraph(offset: const Offset(46.0, 248.0)),
|
|
);
|
|
expect(tester.getRect(find.text('Third')), const Rect.fromLTRB(46.0, 208.0, 286.0, 232.0));
|
|
// gamma has left the building
|
|
expect(find.text('gamma'), findsNothing);
|
|
expect(tester.getRect(find.text('Second')), const Rect.fromLTRB(46.0, 48.0, 334.0, 72.0));
|
|
// alpha is in place.
|
|
expect(tester.getRect(find.text('alpha')), const Rect.fromLTRB(56.0, 88.0, 296.0, 112.0));
|
|
});
|
|
|
|
testWidgets('only paints visible rows', (WidgetTester tester) async {
|
|
treeNodes = _setUpNodes();
|
|
final scrollController = ScrollController();
|
|
addTearDown(scrollController.dispose);
|
|
treeNodes = _setUpNodes();
|
|
final treeSliver = TreeSliver<String>(treeRowExtentBuilder: (_, _) => 200, tree: treeNodes);
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
home: CustomScrollView(controller: scrollController, slivers: <Widget>[treeSliver]),
|
|
),
|
|
);
|
|
await tester.pump();
|
|
expect(scrollController.position.pixels, 0.0);
|
|
expect(scrollController.position.maxScrollExtent, 800.0);
|
|
bool rowNeedsPaint(String row) {
|
|
return find.text(row).evaluate().first.renderObject!.debugNeedsPaint;
|
|
}
|
|
|
|
expect(rowNeedsPaint('First'), isFalse);
|
|
expect(rowNeedsPaint('Second'), isFalse);
|
|
expect(rowNeedsPaint('Third'), isFalse);
|
|
expect(find.text('gamma'), findsNothing); // Not visible
|
|
|
|
// Change the scroll offset
|
|
scrollController.jumpTo(200);
|
|
await tester.pump();
|
|
expect(find.text('First'), findsNothing);
|
|
expect(rowNeedsPaint('Second'), isFalse);
|
|
expect(rowNeedsPaint('Third'), isFalse);
|
|
expect(rowNeedsPaint('gamma'), isFalse); // Now visible
|
|
});
|
|
}
|