Commit c9e4541c authored by Adam Barth's avatar Adam Barth Committed by GitHub

Port LazyBlock tests to ListView (#8026)

parent 1a61a76e
// Copyright 2016 The Chromium 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_test/flutter_test.dart';
import 'package:flutter/material.dart';
void main() {
testWidgets('Block inside LazyBlock', (WidgetTester tester) async {
await tester.pumpWidget(new LazyBlock(
delegate: new LazyBlockChildren(
children: <Widget>[
new Block(
children: <Widget>[
new Text('1'),
new Text('2'),
new Text('3'),
]
),
new Block(
children: <Widget>[
new Text('4'),
new Text('5'),
new Text('6'),
]
),
]
)
));
});
testWidgets('Underflowing LazyBlock should relayout for additional children', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/5950
await tester.pumpWidget(new LazyBlock(
delegate: new LazyBlockChildren(
children: <Widget>[
new SizedBox(height: 100.0, child: new Text('100')),
]
)
));
await tester.pumpWidget(new LazyBlock(
delegate: new LazyBlockChildren(
children: <Widget>[
new SizedBox(height: 100.0, child: new Text('100')),
new SizedBox(height: 200.0, child: new Text('200')),
]
)
));
expect(find.text('200'), findsOneWidget);
});
testWidgets('Underflowing LazyBlock contentExtent should track additional children', (WidgetTester tester) async {
await tester.pumpWidget(new LazyBlock(
delegate: new LazyBlockChildren(
children: <Widget>[
new SizedBox(height: 100.0, child: new Text('100')),
]
)
));
StatefulElement statefulElement = tester.element(find.byType(Scrollable));
ScrollableState scrollable = statefulElement.state;
OverscrollWhenScrollableBehavior scrollBehavior = scrollable.scrollBehavior;
expect(scrollBehavior.contentExtent, equals(100.0));
await tester.pumpWidget(new LazyBlock(
delegate: new LazyBlockChildren(
children: <Widget>[
new SizedBox(height: 100.0, child: new Text('100')),
new SizedBox(height: 200.0, child: new Text('200')),
]
)
));
expect(scrollBehavior.contentExtent, equals(300.0));
await tester.pumpWidget(new LazyBlock(
delegate: new LazyBlockChildren(
children: <Widget>[
]
)
));
expect(scrollBehavior.contentExtent, equals(0.0));
});
testWidgets('Overflowing LazyBlock should relayout for missing children', (WidgetTester tester) async {
await tester.pumpWidget(new LazyBlock(
delegate: new LazyBlockChildren(
children: <Widget>[
new SizedBox(height: 300.0, child: new Text('300')),
new SizedBox(height: 400.0, child: new Text('400')),
]
)
));
expect(find.text('300'), findsOneWidget);
expect(find.text('400'), findsOneWidget);
await tester.pumpWidget(new LazyBlock(
delegate: new LazyBlockChildren(
children: <Widget>[
new SizedBox(height: 300.0, child: new Text('300')),
]
)
));
expect(find.text('300'), findsOneWidget);
expect(find.text('400'), findsNothing);
await tester.pumpWidget(new LazyBlock(
delegate: new LazyBlockChildren(
children: <Widget>[
]
)
));
expect(find.text('300'), findsNothing);
expect(find.text('400'), findsNothing);
});
testWidgets('Overflowing LazyBlock should not relayout for additional children', (WidgetTester tester) async {
await tester.pumpWidget(new LazyBlock(
delegate: new LazyBlockChildren(
children: <Widget>[
new SizedBox(height: 300.0, child: new Text('300')),
new SizedBox(height: 400.0, child: new Text('400')),
]
)
));
expect(find.text('300'), findsOneWidget);
expect(find.text('400'), findsOneWidget);
await tester.pumpWidget(new LazyBlock(
delegate: new LazyBlockChildren(
children: <Widget>[
new SizedBox(height: 300.0, child: new Text('300')),
new SizedBox(height: 400.0, child: new Text('400')),
new SizedBox(height: 100.0, child: new Text('100')),
]
)
));
expect(find.text('300'), findsOneWidget);
expect(find.text('400'), findsOneWidget);
expect(find.text('100'), findsNothing);
StatefulElement statefulElement = tester.element(find.byType(Scrollable));
ScrollableState scrollable = statefulElement.state;
OverscrollWhenScrollableBehavior scrollBehavior = scrollable.scrollBehavior;
expect(scrollBehavior.contentExtent, equals(700.0));
});
testWidgets('Overflowing LazyBlock should become scrollable', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/5920
// When a LazyBlock's viewport hasn't overflowed, scrolling is disabled.
// When children are added that cause it to overflow, scrolling should
// be enabled.
await tester.pumpWidget(new LazyBlock(
delegate: new LazyBlockChildren(
children: <Widget>[
new SizedBox(height: 100.0, child: new Text('100')),
]
)
));
StatefulElement statefulElement = tester.element(find.byType(Scrollable));
ScrollableState scrollable = statefulElement.state;
OverscrollWhenScrollableBehavior scrollBehavior = scrollable.scrollBehavior;
expect(scrollBehavior.isScrollable, isFalse);
await tester.pumpWidget(new LazyBlock(
delegate: new LazyBlockChildren(
children: <Widget>[
new SizedBox(height: 100.0, child: new Text('100')),
new SizedBox(height: 200.0, child: new Text('200')),
new SizedBox(height: 400.0, child: new Text('400')),
]
)
));
expect(scrollBehavior.isScrollable, isTrue);
});
}
......@@ -8,35 +8,24 @@ import 'package:flutter/material.dart';
const double kHeight = 10.0;
const double kFlingOffset = kHeight * 20.0;
class TestDelegate extends LazyBlockDelegate {
@override
Widget buildItem(BuildContext context, int index) {
void main() {
testWidgets('Flings don\'t stutter', (WidgetTester tester) async {
await tester.pumpWidget(new ListView.builder(
itemBuilder: (BuildContext context, int index) {
return new Container(height: kHeight);
}
},
));
@override
double estimateTotalExtent(int firstIndex, int lastIndex, double minOffset, double firstStartOffset, double lastEndOffset) {
return double.INFINITY;
double getCurrentOffset() {
return tester.state<Scrollable2State>(find.byType(Scrollable2)).position.pixels;
}
@override
bool shouldRebuild(LazyBlockDelegate oldDelegate) => false;
}
double currentOffset;
void main() {
testWidgets('Flings don\'t stutter', (WidgetTester tester) async {
await tester.pumpWidget(new LazyBlock(
delegate: new TestDelegate(),
onScroll: (double scrollOffset) { currentOffset = scrollOffset; },
));
await tester.fling(find.byType(LazyBlock), const Offset(0.0, -kFlingOffset), 1000.0);
expect(currentOffset, kFlingOffset);
await tester.fling(find.byType(ListView), const Offset(0.0, -kFlingOffset), 1000.0);
expect(getCurrentOffset(), kFlingOffset);
while (tester.binding.transientCallbackCount > 0) {
double lastOffset = currentOffset;
double lastOffset = getCurrentOffset();
await tester.pump(const Duration(milliseconds: 20));
expect(currentOffset, greaterThan(lastOffset));
expect(getCurrentOffset(), greaterThan(lastOffset));
}
}, skip: true); // see https://github.com/flutter/flutter/issues/5339
}
// Copyright 2016 The Chromium 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_test/flutter_test.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
void main() {
testWidgets('Nested ListView with shrinkWrap', (WidgetTester tester) async {
await tester.pumpWidget(new ListView(
shrinkWrap: true,
children: <Widget>[
new ListView(
shrinkWrap: true,
children: <Widget>[
new Text('1'),
new Text('2'),
new Text('3'),
],
),
new ListView(
shrinkWrap: true,
children: <Widget>[
new Text('4'),
new Text('5'),
new Text('6'),
],
),
],
));
});
testWidgets('Underflowing ListView should relayout for additional children', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/5950
await tester.pumpWidget(new ListView(
children: <Widget>[
new SizedBox(height: 100.0, child: new Text('100')),
],
));
await tester.pumpWidget(new ListView(
children: <Widget>[
new SizedBox(height: 100.0, child: new Text('100')),
new SizedBox(height: 200.0, child: new Text('200')),
],
));
expect(find.text('200'), findsOneWidget);
});
testWidgets('Underflowing ListView contentExtent should track additional children', (WidgetTester tester) async {
await tester.pumpWidget(new ListView(
children: <Widget>[
new SizedBox(height: 100.0, child: new Text('100')),
],
));
RenderSliverList list = tester.renderObject(find.byType(SliverList));
expect(list.geometry.scrollExtent, equals(100.0));
await tester.pumpWidget(new ListView(
children: <Widget>[
new SizedBox(height: 100.0, child: new Text('100')),
new SizedBox(height: 200.0, child: new Text('200')),
],
));
expect(list.geometry.scrollExtent, equals(300.0));
await tester.pumpWidget(new ListView(
children: <Widget>[]
));
expect(list.geometry.scrollExtent, equals(0.0));
});
testWidgets('Overflowing ListView should relayout for missing children', (WidgetTester tester) async {
await tester.pumpWidget(new ListView(
children: <Widget>[
new SizedBox(height: 300.0, child: new Text('300')),
new SizedBox(height: 400.0, child: new Text('400')),
],
));
expect(find.text('300'), findsOneWidget);
expect(find.text('400'), findsOneWidget);
await tester.pumpWidget(new ListView(
children: <Widget>[
new SizedBox(height: 300.0, child: new Text('300')),
],
));
expect(find.text('300'), findsOneWidget);
expect(find.text('400'), findsNothing);
await tester.pumpWidget(new ListView(
children: <Widget>[]
));
expect(find.text('300'), findsNothing);
expect(find.text('400'), findsNothing);
});
testWidgets('Overflowing ListView should not relayout for additional children', (WidgetTester tester) async {
await tester.pumpWidget(new ListView(
children: <Widget>[
new SizedBox(height: 300.0, child: new Text('300')),
new SizedBox(height: 400.0, child: new Text('400')),
],
));
expect(find.text('300'), findsOneWidget);
expect(find.text('400'), findsOneWidget);
await tester.pumpWidget(new ListView(
children: <Widget>[
new SizedBox(height: 300.0, child: new Text('300')),
new SizedBox(height: 400.0, child: new Text('400')),
new SizedBox(height: 100.0, child: new Text('100')),
],
));
expect(find.text('300'), findsOneWidget);
expect(find.text('400'), findsOneWidget);
expect(find.text('100'), findsNothing);
RenderSliverList list = tester.renderObject(find.byType(SliverList));
expect(list.geometry.scrollExtent, equals(700.0));
});
testWidgets('Overflowing ListView should become scrollable', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/5920
// When a ListView's viewport hasn't overflowed, scrolling is disabled.
// When children are added that cause it to overflow, scrolling should
// be enabled.
await tester.pumpWidget(new ListView(
children: <Widget>[
new SizedBox(height: 100.0, child: new Text('100')),
],
));
Scrollable2State scrollable = tester.state(find.byType(Scrollable2));
expect(scrollable.position.maxScrollExtent, 0.0);
await tester.pumpWidget(new ListView(
children: <Widget>[
new SizedBox(height: 100.0, child: new Text('100')),
new SizedBox(height: 200.0, child: new Text('200')),
new SizedBox(height: 400.0, child: new Text('400')),
],
));
expect(scrollable.position.maxScrollExtent, 100.0);
});
}
......@@ -27,7 +27,7 @@ Widget buildFrame() {
}
void main() {
testWidgets('LazyBlock is a build function (smoketest)', (WidgetTester tester) async {
testWidgets('ListView is a build function (smoketest)', (WidgetTester tester) async {
await tester.pumpWidget(buildFrame());
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsOneWidget);
......
......@@ -7,32 +7,16 @@ import 'dart:io';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';
class TestDelegate extends LazyBlockDelegate {
@override
Widget buildItem(BuildContext context, int index) {
return new Text('$index');
}
@override
double estimateTotalExtent(int firstIndex, int lastIndex, double minOffset, double firstStartOffset, double lastEndOffset) {
return double.INFINITY;
}
@override
bool shouldRebuild(LazyBlockDelegate oldDelegate) => false;
}
double currentOffset;
Future<Null> pumpTest(WidgetTester tester, TargetPlatform platform) async {
await tester.pumpWidget(new Container());
await tester.pumpWidget(new MaterialApp(
theme: new ThemeData(
platform: platform
),
home: new LazyBlock(
delegate: new TestDelegate(),
onScroll: (double scrollOffset) { currentOffset = scrollOffset; },
home: new ListView.builder(
itemBuilder: (BuildContext context, int index) {
return new Text('$index');
},
),
));
return null;
......@@ -42,21 +26,25 @@ const double dragOffset = 213.82;
void main() {
testWidgets('Flings on different platforms', (WidgetTester tester) async {
double getCurrentOffset() {
return tester.state<Scrollable2State>(find.byType(Scrollable2)).position.pixels;
}
await pumpTest(tester, TargetPlatform.android);
await tester.fling(find.byType(LazyBlock), const Offset(0.0, -dragOffset), 1000.0);
expect(currentOffset, dragOffset);
await tester.fling(find.byType(ListView), const Offset(0.0, -dragOffset), 1000.0);
expect(getCurrentOffset(), dragOffset);
await tester.pump(); // trigger fling
expect(currentOffset, dragOffset);
expect(getCurrentOffset(), dragOffset);
await tester.pump(const Duration(seconds: 5));
final double result1 = currentOffset;
final double result1 = getCurrentOffset();
await pumpTest(tester, TargetPlatform.iOS);
await tester.fling(find.byType(LazyBlock), const Offset(0.0, -dragOffset), 1000.0);
expect(currentOffset, dragOffset);
await tester.fling(find.byType(ListView), const Offset(0.0, -dragOffset), 1000.0);
expect(getCurrentOffset(), dragOffset);
await tester.pump(); // trigger fling
expect(currentOffset, dragOffset);
expect(getCurrentOffset(), dragOffset);
await tester.pump(const Duration(seconds: 5));
final double result2 = currentOffset;
final double result2 = getCurrentOffset();
expect(result1, lessThan(result2)); // iOS (result2) is slipperier than Android (result1)
});
......@@ -67,19 +55,19 @@ void main() {
List<Widget> textWidgets = <Widget>[];
for (int i = 0; i < 250; i++)
textWidgets.add(new GestureDetector(onTap: () { log.add('tap $i'); }, child: new Text('$i')));
await tester.pumpWidget(new Block(children: textWidgets));
await tester.pumpWidget(new ListView(children: textWidgets));
expect(log, equals(<String>[]));
await tester.tap(find.byType(Scrollable));
await tester.tap(find.byType(Scrollable2));
await tester.pump(const Duration(milliseconds: 50));
expect(log, equals(<String>['tap 18']));
await tester.fling(find.byType(Scrollable), const Offset(0.0, -200.0), 1000.0);
await tester.fling(find.byType(Scrollable2), const Offset(0.0, -200.0), 1000.0);
await tester.pump(const Duration(milliseconds: 50));
expect(log, equals(<String>['tap 18']));
await tester.tap(find.byType(Scrollable));
await tester.tap(find.byType(Scrollable2));
await tester.pump(const Duration(milliseconds: 50));
expect(log, equals(<String>['tap 18']));
await tester.tap(find.byType(Scrollable));
await tester.tap(find.byType(Scrollable2));
await tester.pump(const Duration(milliseconds: 50));
expect(log, equals(<String>['tap 18', 'tap 31']));
}, skip: Platform.isMacOS); // Skip due to https://github.com/flutter/flutter/issues/6961
......@@ -90,18 +78,18 @@ void main() {
List<Widget> textWidgets = <Widget>[];
for (int i = 0; i < 250; i++)
textWidgets.add(new GestureDetector(onTap: () { log.add('tap $i'); }, child: new Text('$i')));
await tester.pumpWidget(new Block(children: textWidgets));
await tester.pumpWidget(new ListView(children: textWidgets));
expect(log, equals(<String>[]));
await tester.tap(find.byType(Scrollable));
await tester.tap(find.byType(Scrollable2));
await tester.pump(const Duration(milliseconds: 50));
expect(log, equals(<String>['tap 18']));
await tester.fling(find.byType(Scrollable), const Offset(0.0, -200.0), 1000.0);
await tester.fling(find.byType(Scrollable2), const Offset(0.0, -200.0), 1000.0);
await tester.pump(const Duration(milliseconds: 50));
expect(log, equals(<String>['tap 18']));
await tester.pump(const Duration(seconds: 50));
expect(log, equals(<String>['tap 18']));
await tester.tap(find.byType(Scrollable));
await tester.tap(find.byType(Scrollable2));
await tester.pump(const Duration(milliseconds: 50));
expect(log, equals(<String>['tap 18', 'tap 43']));
}, skip: Platform.isMacOS); // Skip due to https://github.com/flutter/flutter/issues/6961
......
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