@@ -6,6 +6,8 @@ import 'package:flutter/widgets.dart' hide SliverPaintOrder;
6
6
import 'package:flutter_test/flutter_test.dart' ;
7
7
import 'package:zulip/widgets/scrolling.dart' ;
8
8
9
+ import '../flutter_checks.dart' ;
10
+
9
11
void main () {
10
12
group ('CustomPaintOrderScrollView paint order' , () {
11
13
final paintLog = < int > [];
@@ -127,6 +129,78 @@ void main() {
127
129
.deepEquals (sliverIds (result.path));
128
130
});
129
131
});
132
+
133
+ group ('MessageListScrollView' , () {
134
+ Future <void > prepare (WidgetTester tester,
135
+ {required double topHeight, required double bottomHeight}) async {
136
+ await tester.pumpWidget (Directionality (textDirection: TextDirection .ltr,
137
+ child: MessageListScrollView (
138
+ controller: MessageListScrollController (),
139
+ center: const ValueKey ('center' ),
140
+ slivers: [
141
+ SliverToBoxAdapter (
142
+ child: SizedBox (height: topHeight, child: Text ('top' ))),
143
+ SliverToBoxAdapter (key: const ValueKey ('center' ),
144
+ child: SizedBox (height: bottomHeight, child: Text ('bottom' ))),
145
+ ])));
146
+ await tester.pump ();
147
+ }
148
+
149
+ // The `skipOffstage: false` produces more informative output
150
+ // when a test fails because one of the slivers is just offscreen.
151
+ final findTop = find.text ('top' , skipOffstage: false );
152
+ final findBottom = find.text ('bottom' , skipOffstage: false );
153
+
154
+ testWidgets ('short/short -> starts scrolled to bottom' , (tester) async {
155
+ // Starts out with items at bottom of viewport.
156
+ await prepare (tester, topHeight: 100 , bottomHeight: 100 );
157
+ check (tester.getRect (findBottom)).bottom.equals (600 );
158
+
159
+ // Try scrolling down (by dragging up); doesn't move.
160
+ await tester.drag (findTop, Offset (0 , - 100 ));
161
+ await tester.pump ();
162
+ check (tester.getRect (findBottom)).bottom.equals (600 );
163
+ });
164
+
165
+ testWidgets ('short/long -> starts scrolled to bottom' , (tester) async {
166
+ // Starts out scrolled to bottom.
167
+ await prepare (tester, topHeight: 100 , bottomHeight: 800 );
168
+ check (tester.getRect (findBottom)).bottom.equals (600 );
169
+
170
+ // Try scrolling down (by dragging up); doesn't move.
171
+ await tester.drag (findBottom, Offset (0 , - 100 ));
172
+ await tester.pump ();
173
+ check (tester.getRect (findBottom)).bottom.equals (600 );
174
+ });
175
+
176
+ testWidgets ('starts at bottom, even when bottom underestimated at first' , (tester) async {
177
+ const numItems = 10 ;
178
+ const itemHeight = 300.0 ;
179
+
180
+ // A list where the bottom sliver takes several rounds of layout
181
+ // to see how long it really is.
182
+ final controller = MessageListScrollController ();
183
+ await tester.pumpWidget (Directionality (textDirection: TextDirection .ltr,
184
+ child: MessageListScrollView (
185
+ controller: controller,
186
+ center: const ValueKey ('center' ),
187
+ slivers: [
188
+ SliverToBoxAdapter (
189
+ child: SizedBox (height: 100 , child: Text ('top' ))),
190
+ SliverList .list (key: const ValueKey ('center' ),
191
+ children: List .generate (numItems, (i) =>
192
+ SizedBox (height: (i+ 1 ) * itemHeight, child: Text ('item $i ' )))),
193
+ ])));
194
+ await tester.pump ();
195
+
196
+ // Starts out scrolled all the way to the bottom,
197
+ // even though it must have taken several rounds of layout to find that.
198
+ check (controller.position.pixels)
199
+ .equals (itemHeight * numItems * (numItems + 1 )/ 2 );
200
+ check (tester.getRect (find.text ('item ${numItems -1 }' , skipOffstage: false )))
201
+ .bottom.equals (600 );
202
+ });
203
+ });
130
204
}
131
205
132
206
class TestCustomPainter extends CustomPainter {
0 commit comments