From a29be6bbd06e50c9f737a8ea8a6bdfa41466d108 Mon Sep 17 00:00:00 2001 From: Badreddine Kouki Date: Sat, 17 Jan 2026 16:29:58 +0100 Subject: [PATCH] test: add async searchable list widget test --- test/async_searchable_listview_test.dart | 206 +++++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 test/async_searchable_listview_test.dart diff --git a/test/async_searchable_listview_test.dart b/test/async_searchable_listview_test.dart new file mode 100644 index 0000000..99cfe04 --- /dev/null +++ b/test/async_searchable_listview_test.dart @@ -0,0 +1,206 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:searchable_listview/searchable_listview.dart'; + +import 'dummies/dummy_list_item.dart'; + +void main() { + group(''' + Checking default async searchable listview display + ''', () { + testWidgets(''' + Should display a searchable listview with dummy list items. + checking default appearance. + ''', (test) async { + final intList = List.generate(10, (index) => index); + var basicSearchableList = SearchableList.async( + asyncListCallback: () async => intList, + itemBuilder: (item) => DummyListItem(index: item), + asyncListFilter: (query, _) => + intList.where((item) => item.toString().contains(query)).toList(), + ); + + await test.pumpWidget( + MaterialApp( + home: Scaffold( + body: Center( + child: basicSearchableList, + ), + ), + ), + ); + await test.pumpAndSettle(); + + // Initial assertions + // Check that some items and the search field are present + expect(find.byType(DummyListItem), findsNWidgets(10)); + expect(find.byType(TextField), findsOneWidget); + expect(find.byIcon(Icons.search), findsOneWidget); + + final searchField = find.byType(TextField); + await test.enterText(searchField, '1'); + await test.pumpAndSettle(); + + expect(find.byIcon(Icons.clear), findsOneWidget); + }); + + testWidgets(''' + Checking search field customization. + ''', (test) async { + final intList = List.generate(10, (index) => index); + var basicSearchableList = SearchableList.async( + asyncListCallback: () async => intList, + itemBuilder: (item) => DummyListItem(index: item), + inputDecoration: InputDecoration( + labelText: 'Search Items', + border: OutlineInputBorder(), + ), + asyncListFilter: (query, _) => + intList.where((item) => item.toString().contains(query)).toList(), + ); + + await test.pumpWidget( + MaterialApp( + home: Scaffold( + body: Center( + child: basicSearchableList, + ), + ), + ), + ); + await test.pumpAndSettle(); + + // Initial assertions + // Check that some items and the search field are present + expect(find.text('Search Items'), findsOneWidget); + final searchField = find.byType(TextField); + expect( + test.widget(searchField).decoration!.border + is OutlineInputBorder, + isTrue, + ); + }); + }); + + group(''' + Async Searchable Listview Tests + ''', () { + testWidgets(''' + Should display a searchable listview with async data source. + ''', (test) async { + final intList = List.generate(10, (index) => index); + var basicSearchableList = SearchableList.async( + asyncListCallback: () async => intList, + itemBuilder: (item) => DummyListItem(index: item), + asyncListFilter: (query, _) => + intList.where((item) => item.toString().contains(query)).toList(), + ); + + await test.pumpWidget( + MaterialApp( + home: Scaffold( + body: Center( + child: basicSearchableList, + ), + ), + ), + ); + await test.pumpAndSettle(); + expect(find.text('Item 0'), findsOneWidget); + expect(find.text('Item 5'), findsOneWidget); + expect(find.byType(TextField), findsOneWidget); + + final searchField = find.byType(TextField); + await test.enterText(searchField, '1'); + await test.pumpAndSettle(); + + expect(find.text('Item 1'), findsOneWidget); + }); + + testWidgets(''' + Checking filter when search yields no results. + ''', (test) async { + final intList = List.generate(10, (index) => index); + var basicSearchableList = SearchableList.async( + asyncListCallback: () async => intList, + itemBuilder: (item) => DummyListItem(index: item), + asyncListFilter: (query, _) => + intList.where((item) => item.toString().contains(query)).toList(), + ); + + await test.pumpWidget( + MaterialApp( + home: Scaffold( + body: Center( + child: basicSearchableList, + ), + ), + ), + ); + await test.pumpAndSettle(); + + final searchField = find.byType(TextField); + await test.enterText(searchField, '12'); + await test.pumpAndSettle(); + expect(find.byType(DummyListItem), findsNothing); + }); + + testWidgets(''' + Checking filter with empty list. + ''', (test) async { + var basicSearchableList = SearchableList.async( + asyncListCallback: () async => [], + itemBuilder: (item) => DummyListItem(index: item), + asyncListFilter: (query, _) => [], + ); + + await test.pumpWidget( + MaterialApp( + home: Scaffold( + body: Center( + child: basicSearchableList, + ), + ), + ), + ); + await test.pumpAndSettle(); + expect(find.byType(DummyListItem), findsNothing); + + final searchField = find.byType(TextField); + await test.enterText(searchField, '1'); + await test.pumpAndSettle(); + expect(find.byType(DummyListItem), findsNothing); + }); + + testWidgets(''' + Checking custom empty widget when no results found. + ''', (test) async { + final intList = List.generate(10, (index) => index); + var basicSearchableList = SearchableList.async( + asyncListCallback: () async => intList, + itemBuilder: (item) => DummyListItem(index: item), + emptyWidget: const Text('No items found'), + asyncListFilter: (query, _) => + intList.where((item) => item.toString().contains(query)).toList(), + ); + + await test.pumpWidget( + MaterialApp( + home: Scaffold( + body: Center( + child: basicSearchableList, + ), + ), + ), + ); + await test.pumpAndSettle(); + expect(find.byType(DummyListItem), findsNWidgets(10)); + + final searchField = find.byType(TextField); + await test.enterText(searchField, '99'); + await test.pumpAndSettle(); + expect(find.byType(DummyListItem), findsNothing); + expect(find.text('No items found'), findsOneWidget); + }); + }); +}