Skip to content

Commit eb424a5

Browse files
Merge pull request #154 from QueryaHub/issue/123-performance-50-themes-picker
TP-28: Performance test for 50+ themes in picker
2 parents 7c2b5ef + 5e16657 commit eb424a5

1 file changed

Lines changed: 118 additions & 0 deletions

File tree

test/features/settings/theme_picker_button_test.dart

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)