blob: 126d3dee43c6f46ed2db5a3ca1a50ba313980e5e [file] [log] [blame]
// 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 'dart:ui';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart';
import 'semantics_tester.dart';
class TestScrollPosition extends ScrollPositionWithSingleContext {
TestScrollPosition({
ScrollPhysics physics,
ScrollContext state,
double initialPixels: 0.0,
ScrollPosition oldPosition,
}) : super(
physics: physics,
context: state,
initialPixels: initialPixels,
oldPosition: oldPosition,
);
}
class TestScrollController extends ScrollController {
@override
ScrollPosition createScrollPosition(ScrollPhysics physics, ScrollContext context, ScrollPosition oldPosition) {
return new TestScrollPosition(
physics: physics,
state: context,
initialPixels: initialScrollOffset,
oldPosition: oldPosition,
);
}
}
void main() {
testWidgets('SingleChildScrollView control test', (WidgetTester tester) async {
await tester.pumpWidget(new SingleChildScrollView(
child: new Container(
height: 2000.0,
color: const Color(0xFF00FF00),
),
));
final RenderBox box = tester.renderObject(find.byType(Container));
expect(box.localToGlobal(Offset.zero), equals(Offset.zero));
await tester.drag(find.byType(SingleChildScrollView), const Offset(-200.0, -200.0));
expect(box.localToGlobal(Offset.zero), equals(const Offset(0.0, -200.0)));
});
testWidgets('Changing controllers changes scroll position', (WidgetTester tester) async {
final TestScrollController controller = new TestScrollController();
await tester.pumpWidget(new SingleChildScrollView(
child: new Container(
height: 2000.0,
color: const Color(0xFF00FF00),
),
));
await tester.pumpWidget(new SingleChildScrollView(
controller: controller,
child: new Container(
height: 2000.0,
color: const Color(0xFF00FF00),
),
));
final ScrollableState scrollable = tester.state(find.byType(Scrollable));
expect(scrollable.position, const isInstanceOf<TestScrollPosition>());
});
testWidgets('Sets PrimaryScrollController when primary', (WidgetTester tester) async {
final ScrollController primaryScrollController = new ScrollController();
await tester.pumpWidget(new PrimaryScrollController(
controller: primaryScrollController,
child: new SingleChildScrollView(
primary: true,
child: new Container(
height: 2000.0,
color: const Color(0xFF00FF00),
),
),
));
final Scrollable scrollable = tester.widget(find.byType(Scrollable));
expect(scrollable.controller, primaryScrollController);
});
testWidgets('Changing scroll controller inside dirty layout builder does not assert', (WidgetTester tester) async {
final ScrollController controller = new ScrollController();
await tester.pumpWidget(new Center(
child: new SizedBox(
width: 750.0,
child: new LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return new SingleChildScrollView(
child: new Container(
height: 2000.0,
color: const Color(0xFF00FF00),
),
);
},
),
),
));
await tester.pumpWidget(new Center(
child: new SizedBox(
width: 700.0,
child: new LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return new SingleChildScrollView(
controller: controller,
child: new Container(
height: 2000.0,
color: const Color(0xFF00FF00),
),
);
},
),
),
));
});
testWidgets('Vertical SingleChildScrollViews are primary by default', (WidgetTester tester) async {
final SingleChildScrollView view = new SingleChildScrollView(scrollDirection: Axis.vertical);
expect(view.primary, isTrue);
});
testWidgets('Horizontal SingleChildScrollViews are non-primary by default', (WidgetTester tester) async {
final SingleChildScrollView view = new SingleChildScrollView(scrollDirection: Axis.horizontal);
expect(view.primary, isFalse);
});
testWidgets('SingleChildScrollViews with controllers are non-primary by default', (WidgetTester tester) async {
final SingleChildScrollView view = new SingleChildScrollView(
controller: new ScrollController(),
scrollDirection: Axis.vertical,
);
expect(view.primary, isFalse);
});
testWidgets('Nested scrollables have a null PrimaryScrollController', (WidgetTester tester) async {
const Key innerKey = const Key('inner');
final ScrollController primaryScrollController = new ScrollController();
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new PrimaryScrollController(
controller: primaryScrollController,
child: new SingleChildScrollView(
primary: true,
child: new Container(
constraints: const BoxConstraints(maxHeight: 200.0),
child: new ListView(key: innerKey, primary: true),
),
),
),
),
);
final Scrollable innerScrollable = tester.widget(
find.descendant(
of: find.byKey(innerKey),
matching: find.byType(Scrollable),
),
);
expect(innerScrollable.controller, isNull);
});
testWidgets('SingleChildScrollView semantics', (WidgetTester tester) async {
final SemanticsTester semantics = new SemanticsTester(tester);
final ScrollController controller = new ScrollController();
await tester.pumpWidget(
new Directionality(
textDirection: TextDirection.ltr,
child: new SingleChildScrollView(
controller: controller,
child: new Column(
children: new List<Widget>.generate(30, (int i) {
return new Container(
height: 200.0,
child: new Text('Tile $i'),
);
}),
),
),
),
);
expect(semantics, hasSemantics(
new TestSemantics(
children: <TestSemantics>[
new TestSemantics(
actions: <SemanticsAction>[
SemanticsAction.scrollUp,
],
children: <TestSemantics>[
new TestSemantics(
label: r'Tile 0',
textDirection: TextDirection.ltr,
),
new TestSemantics(
label: r'Tile 1',
textDirection: TextDirection.ltr,
),
new TestSemantics(
label: r'Tile 2',
textDirection: TextDirection.ltr,
),
new TestSemantics(
flags: <SemanticsFlag>[
SemanticsFlag.isHidden,
],
label: r'Tile 3',
textDirection: TextDirection.ltr,
),
new TestSemantics(
flags: <SemanticsFlag>[
SemanticsFlag.isHidden,],
label: r'Tile 4',
textDirection: TextDirection.ltr,
),
],
),
],
),
ignoreRect: true, ignoreTransform: true, ignoreId: true,
));
controller.jumpTo(3000.0);
await tester.pumpAndSettle();
expect(semantics, hasSemantics(
new TestSemantics(
children: <TestSemantics>[
new TestSemantics(
actions: <SemanticsAction>[
SemanticsAction.scrollUp,
SemanticsAction.scrollDown,
],
children: <TestSemantics>[
new TestSemantics(
flags: <SemanticsFlag>[
SemanticsFlag.isHidden,
],
label: r'Tile 13',
textDirection: TextDirection.ltr,
),
new TestSemantics(
flags: <SemanticsFlag>[
SemanticsFlag.isHidden,
],
label: r'Tile 14',
textDirection: TextDirection.ltr,
),
new TestSemantics(
label: r'Tile 15',
textDirection: TextDirection.ltr,
),
new TestSemantics(
label: r'Tile 16',
textDirection: TextDirection.ltr,
),
new TestSemantics(
label: r'Tile 17',
textDirection: TextDirection.ltr,
),
new TestSemantics(
flags: <SemanticsFlag>[
SemanticsFlag.isHidden,
],
label: r'Tile 18',
textDirection: TextDirection.ltr,
),
new TestSemantics(
flags: <SemanticsFlag>[
SemanticsFlag.isHidden,
],
label: r'Tile 19',
textDirection: TextDirection.ltr,
),
],
),
],
),
ignoreRect: true, ignoreTransform: true, ignoreId: true,
));
controller.jumpTo(6000.0);
await tester.pumpAndSettle();
expect(semantics, hasSemantics(
new TestSemantics(
children: <TestSemantics>[
new TestSemantics(
actions: <SemanticsAction>[
SemanticsAction.scrollDown,
],
children: <TestSemantics>[
new TestSemantics(
flags: <SemanticsFlag>[
SemanticsFlag.isHidden,
],
label: r'Tile 25',
textDirection: TextDirection.ltr,
),
new TestSemantics(
flags: <SemanticsFlag>[
SemanticsFlag.isHidden,
],
label: r'Tile 26',
textDirection: TextDirection.ltr,
),
new TestSemantics(
label: r'Tile 27',
textDirection: TextDirection.ltr,
),
new TestSemantics(
label: r'Tile 28',
textDirection: TextDirection.ltr,
),
new TestSemantics(
label: r'Tile 29',
textDirection: TextDirection.ltr,
),
],
),
],
),
ignoreRect: true, ignoreTransform: true, ignoreId: true,
));
semantics.dispose();
});
}