import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:ikar/frontend/screens/chats/chat/view/anchored_message_list.dart'; void main() { testWidgets( 'a distant message can become the center without walking the list', (tester) async { final controller = ScrollController(); final anchor = ValueNotifier(null); final keys = {}; addTearDown(controller.dispose); addTearDown(anchor.dispose); await tester.pumpWidget( MaterialApp( home: Scaffold( body: SizedBox( height: 300, child: ValueListenableBuilder( valueListenable: anchor, builder: (context, index, _) => AnchoredMessageList( controller: controller, cacheExtent: 300, padding: EdgeInsets.zero, epoch: 0, itemCount: 500, anchorIndex: index, itemBuilder: (context, i) => KeyedSubtree( key: keys.putIfAbsent(i, GlobalKey.new), child: SizedBox( key: ValueKey('message-$i'), height: 60, child: Text('message $i'), ), ), bottomSpacer: const SizedBox.shrink(), loadingOlder: false, loadingIndicator: const SizedBox(height: 30), ), ), ), ), ), ); expect(find.byKey(const ValueKey('message-499')), findsOneWidget); expect(find.byKey(const ValueKey('message-20')), findsNothing); anchor.value = 20; controller.jumpTo( AnchoredMessageList.anchoredPixels( alignment: 0.3, viewport: controller.position.viewportDimension, anchorHeight: 0, ), ); await tester.pump(); expect(find.byKey(const ValueKey('message-20')), findsOneWidget); expect( find.byKey(const ValueKey('message-20')).hitTestable(), findsOneWidget, ); expect(controller.position.pixels.isFinite, isTrue); expect(controller.position.minScrollExtent, lessThan(0)); expect( AnchoredMessageList.distanceFromBottom(controller.position), greaterThan(120), ); controller.jumpTo(controller.position.minScrollExtent); await tester.pump(); expect( AnchoredMessageList.distanceFromBottom(controller.position), lessThanOrEqualTo(120), ); anchor.value = null; await tester.pump(); controller.jumpTo(controller.position.minScrollExtent); await tester.pump(); expect( find.byKey(const ValueKey('message-499')).hitTestable(), findsOneWidget, ); expect(tester.takeException(), isNull); }, ); testWidgets('older loading indicator remains on the history edge', ( tester, ) async { final controller = ScrollController(); addTearDown(controller.dispose); await tester.pumpWidget( MaterialApp( home: Scaffold( body: SizedBox( height: 300, child: AnchoredMessageList( controller: controller, cacheExtent: 300, padding: EdgeInsets.zero, epoch: 0, itemCount: 3, anchorIndex: 1, itemBuilder: (context, i) => SizedBox(height: 60, child: Text('message $i')), bottomSpacer: const SizedBox.shrink(), loadingOlder: true, loadingIndicator: const Text('loading older'), ), ), ), ), ); expect(find.text('loading older'), findsOneWidget); expect(tester.takeException(), isNull); }); }