@@ -187,6 +187,124 @@ void main() {
187187 });
188188 });
189189
190+ group ('ThemePickerButton large list' , () {
191+ Future <void > openMenu (WidgetTester tester) async {
192+ await tester.tap (find.text ('Theme 00' ));
193+ await tester.pumpAndSettle ();
194+ }
195+
196+ testWidgets ('uses ListView.builder for 60 themes without overflow' ,
197+ (tester) async {
198+ final themes = _fakeThemes (60 );
199+
200+ await tester.pumpWidget (
201+ queryaThemeTestShell (
202+ child: material.Scaffold (
203+ body: ThemePickerButton (
204+ themes: themes,
205+ selectedThemeId: 'theme-0' ,
206+ onSelected: (_) {},
207+ ),
208+ ),
209+ ),
210+ );
211+ await tester.pump ();
212+ await openMenu (tester);
213+
214+ expect (tester.takeException (), isNull);
215+ final listView = tester.widget< material.ListView > (
216+ find.byType (material.ListView ),
217+ );
218+ final delegate = listView.childrenDelegate;
219+ expect (delegate, isA< material.SliverChildBuilderDelegate > ());
220+ expect (
221+ (delegate as material.SliverChildBuilderDelegate ).childCount,
222+ 60 ,
223+ );
224+ });
225+
226+ testWidgets ('builds only a visible subset of 60 theme rows' , (tester) async {
227+ final themes = _fakeThemes (60 );
228+
229+ await tester.pumpWidget (
230+ queryaThemeTestShell (
231+ child: material.Scaffold (
232+ body: ThemePickerButton (
233+ themes: themes,
234+ selectedThemeId: 'theme-0' ,
235+ onSelected: (_) {},
236+ ),
237+ ),
238+ ),
239+ );
240+ await tester.pump ();
241+ await openMenu (tester);
242+
243+ var visibleCount = 0 ;
244+ for (var index = 0 ; index < 60 ; index++ ) {
245+ final label = 'Theme ${index .toString ().padLeft (2 , '0' )}' ;
246+ final row = find.descendant (
247+ of: find.byType (material.ListView ),
248+ matching: find.text (label),
249+ );
250+ if (row.evaluate ().isNotEmpty) visibleCount++ ;
251+ }
252+
253+ expect (visibleCount, greaterThan (3 ));
254+ expect (visibleCount, lessThan (60 ));
255+ expect (
256+ find.descendant (
257+ of: find.byType (material.ListView ),
258+ matching: find.text ('Theme 59' ),
259+ ),
260+ findsNothing,
261+ );
262+ expect (tester.takeException (), isNull);
263+ });
264+
265+ testWidgets ('selects last theme from large list' , (tester) async {
266+ final themes = _fakeThemes (60 );
267+ String ? picked;
268+ var selectedId = 'theme-0' ;
269+
270+ await tester.pumpWidget (
271+ queryaThemeTestShell (
272+ child: material.Scaffold (
273+ body: material.StatefulBuilder (
274+ builder: (context, setState) {
275+ return ThemePickerButton (
276+ themes: themes,
277+ selectedThemeId: selectedId,
278+ onSelected: (id) {
279+ picked = id;
280+ setState (() => selectedId = id);
281+ },
282+ );
283+ },
284+ ),
285+ ),
286+ ),
287+ );
288+ await tester.pump ();
289+ await openMenu (tester);
290+
291+ await tester.enterText (find.byType (material.TextField ), 'Theme 59' );
292+ await tester.pump ();
293+
294+ await tester.tap (
295+ find.descendant (
296+ of: find.byType (material.ListView ),
297+ matching: find.text ('Theme 59' ),
298+ ),
299+ );
300+ await tester.pumpAndSettle ();
301+
302+ expect (picked, 'theme-59' );
303+ expect (find.text ('Theme 59' ), findsOneWidget);
304+ expect (tester.takeException (), isNull);
305+ });
306+ });
307+
190308 group ('ThemePickerButton search' , () {
191309 Future <void > openMenu (WidgetTester tester) async {
192310 await tester.tap (find.text ('Theme 00' ));
0 commit comments