@@ -171,20 +171,58 @@ void main() {
171171 });
172172
173173 testWidgets ('short/long -> scrolls to ends and no farther' , (tester) async {
174- // Starts out scrolled to bottom.
174+ // Starts out scrolled to top (to show top of the bottom sliver) .
175175 await prepare (tester, topHeight: 100 , bottomHeight: 800 );
176- check (tester.getRect (findBottom)).bottom.equals (600 );
176+ check (tester.getRect (findTop)).top.equals (0 );
177+ check (tester.getRect (findBottom)).bottom.equals (900 );
177178
178- // Try scrolling down (by dragging up ); doesn't move.
179- await tester.drag (findBottom, Offset (0 , - 100 ));
179+ // Try scrolling up (by dragging down ); doesn't move.
180+ await tester.drag (findBottom, Offset (0 , 100 ));
180181 await tester.pump ();
181- check (tester.getRect (findBottom)).bottom.equals (600 );
182+ check (tester.getRect (findBottom)).bottom.equals (900 );
182183
183- // Try scrolling up (by dragging down ); moves only as far as top of list.
184- await tester.drag (findBottom, Offset (0 , 400 ));
184+ // Try scrolling down (by dragging up ); moves only as far as bottom of list.
185+ await tester.drag (findBottom, Offset (0 , - 400 ));
185186 await tester.pump ();
186- check (tester.getRect (findBottom)).bottom.equals (900 );
187+ check (tester.getRect (findBottom)).bottom.equals (600 );
188+ });
189+
190+ testWidgets ('starts by showing top of bottom sliver, long/long' , (tester) async {
191+ // Both slivers are long; the bottom sliver gets 75% of the viewport.
192+ await prepare (tester, topHeight: 1000 , bottomHeight: 3000 );
193+ check (tester.getRect (findBottom)).top.equals (150 );
194+ });
195+
196+ testWidgets ('starts by showing top of bottom sliver, short/long' , (tester) async {
197+ // The top sliver is shorter than 25% of the viewport.
198+ // It's shown in full, and the bottom sliver gets the rest (so >75%).
199+ await prepare (tester, topHeight: 50 , bottomHeight: 3000 );
187200 check (tester.getRect (findTop)).top.equals (0 );
201+ check (tester.getRect (findBottom)).top.equals (50 );
202+ });
203+
204+ testWidgets ('starts by showing top of bottom sliver, short/medium' , (tester) async {
205+ // The whole list fits in the viewport. It's pinned to the bottom,
206+ // even when that gives the bottom sliver more than 75%.
207+ await prepare (tester, topHeight: 50 , bottomHeight: 500 );
208+ check (tester.getRect (findTop))..top.equals (50 )..bottom.equals (100 );
209+ check (tester.getRect (findBottom)).bottom.equals (600 );
210+ });
211+
212+ testWidgets ('starts by showing top of bottom sliver, medium/short' , (tester) async {
213+ // The whole list fits in the viewport. It's pinned to the bottom,
214+ // even when that gives the top sliver more than 25%.
215+ await prepare (tester, topHeight: 300 , bottomHeight: 100 );
216+ check (tester.getRect (findTop))..top.equals (200 )..bottom.equals (500 );
217+ check (tester.getRect (findBottom)).bottom.equals (600 );
218+ });
219+
220+ testWidgets ('starts by showing top of bottom sliver, long/short' , (tester) async {
221+ // The bottom sliver is shorter than 75% of the viewport.
222+ // It's shown in full, and the top sliver gets the rest (so >25%).
223+ await prepare (tester, topHeight: 1000 , bottomHeight: 300 );
224+ check (tester.getRect (findTop)).bottom.equals (300 );
225+ check (tester.getRect (findBottom)).bottom.equals (600 );
188226 });
189227
190228 testWidgets ('short/short -> starts at bottom, immediately without animation' , (tester) async {
@@ -198,43 +236,46 @@ void main() {
198236 check (ys).deepEquals (List .generate (10 , (_) => 0.0 ));
199237 });
200238
201- testWidgets ('short/long -> starts at bottom , immediately without animation' , (tester) async {
239+ testWidgets ('short/long -> starts at desired start , immediately without animation' , (tester) async {
202240 await prepare (tester, topHeight: 100 , bottomHeight: 800 );
203241
204242 final ys = < double > [];
205243 for (int i = 0 ; i < 10 ; i++ ) {
206- ys.add (tester.getRect (findBottom).bottom - 600 );
244+ ys.add (tester.getRect (findTop).top );
207245 await tester.pump (Duration (milliseconds: 15 ));
208246 }
209247 check (ys).deepEquals (List .generate (10 , (_) => 0.0 ));
210248 });
211249
212- testWidgets ('starts at bottom , even when bottom underestimated at first' , (tester) async {
250+ testWidgets ('starts at desired start , even when bottom underestimated at first' , (tester) async {
213251 const numItems = 10 ;
214- const itemHeight = 300 .0 ;
252+ const itemHeight = 20 .0 ;
215253
216254 // A list where the bottom sliver takes several rounds of layout
217255 // to see how long it really is.
218256 final controller = MessageListScrollController ();
219257 await tester.pumpWidget (Directionality (textDirection: TextDirection .ltr,
220258 child: MessageListScrollView (
221259 controller: controller,
260+ // The tiny cacheExtent causes each layout round to only reach
261+ // the first item it expects will go beyond the viewport.
262+ cacheExtent: 1.0 , // in (logical) pixels!
222263 center: const ValueKey ('center' ),
223264 slivers: [
224265 SliverToBoxAdapter (
225- child: SizedBox (height: 100 , child: Text ('top' ))),
266+ child: SizedBox (height: 300 , child: Text ('top' ))),
226267 SliverList .list (key: const ValueKey ('center' ),
227268 children: List .generate (numItems, (i) =>
228269 SizedBox (height: (i+ 1 ) * itemHeight, child: Text ('item $i ' )))),
229270 ])));
230271 await tester.pump ();
231272
232- // Starts out scrolled all the way to the bottom,
233- // even though it must have taken several rounds of layout to find that.
234- check (controller.position.pixels)
235- . equals (itemHeight * numItems * (numItems + 1 ) / 2 );
236- check (tester. getRect (find. text ( 'item ${ numItems - 1 }' , skipOffstage : false )))
237- .bottom. equals ( 600 );
273+ // Starts out with the bottom sliver occupying 75% of the viewport…
274+ check (controller.position.pixels). equals ( 450 );
275+ // … even though it has more height than that.
276+ check (tester. getRect (find. text ( 'item 6' ))).bottom. isGreaterThan ( 600 );
277+ // (And even though on the first round of layout, it would have looked
278+ // much shorter so that the view would have tried to scroll to its end.)
238279 });
239280
240281 testWidgets ('stick to end of list when it grows' , (tester) async {
0 commit comments