@@ -1726,6 +1726,85 @@ void main() {
17261726 // so there are some extra padding before "Item 1".
17271727 expect (tester.getTopLeft (find.text ('Item 1' ).last).dx, 48.0 );
17281728 });
1729+
1730+ testWidgetsWithLeakTracking ('DropdownMenu can have customized search algorithm' , (WidgetTester tester) async {
1731+ final ThemeData theme = ThemeData ();
1732+ Widget dropdownMenu ({ SearchCallback <int >? searchCallback }) {
1733+ return MaterialApp (
1734+ theme: theme,
1735+ home: Scaffold (
1736+ body: DropdownMenu <int >(
1737+ requestFocusOnTap: true ,
1738+ searchCallback: searchCallback,
1739+ dropdownMenuEntries: const < DropdownMenuEntry <int >> [
1740+ DropdownMenuEntry <int >(value: 0 , label: 'All' ),
1741+ DropdownMenuEntry <int >(value: 1 , label: 'Unread' ),
1742+ DropdownMenuEntry <int >(value: 2 , label: 'Read' ),
1743+ ],
1744+ ),
1745+ )
1746+ );
1747+ }
1748+
1749+ void checkExpectedHighlight ({String ? searchResult, required List <String > otherItems}) {
1750+ if (searchResult != null ) {
1751+ final Finder material = find.descendant (
1752+ of: find.widgetWithText (MenuItemButton , searchResult).last,
1753+ matching: find.byType (Material ),
1754+ );
1755+ final Material itemMaterial = tester.widget <Material >(material);
1756+ expect (itemMaterial.color, theme.colorScheme.onSurface.withOpacity (0.12 ));
1757+ }
1758+
1759+ for (final String nonHighlight in otherItems) {
1760+ final Finder material = find.descendant (
1761+ of: find.widgetWithText (MenuItemButton , nonHighlight).last,
1762+ matching: find.byType (Material ),
1763+ );
1764+ final Material itemMaterial = tester.widget <Material >(material);
1765+ expect (itemMaterial.color, Colors .transparent);
1766+ }
1767+ }
1768+
1769+ // Test default.
1770+ await tester.pumpWidget (dropdownMenu ());
1771+ await tester.pump ();
1772+ await tester.tap (find.byType (DropdownMenu <int >));
1773+ await tester.pumpAndSettle ();
1774+
1775+ await tester.enterText (find.byType (TextField ), 'read' );
1776+ await tester.pump ();
1777+ checkExpectedHighlight (searchResult: 'Unread' , otherItems: < String > ['All' , 'Read' ]); // Because "Unread" contains "read".
1778+
1779+ // Test custom search algorithm.
1780+ await tester.pumpWidget (dropdownMenu (
1781+ searchCallback: (_, __) => 0
1782+ ));
1783+ await tester.pump ();
1784+ await tester.enterText (find.byType (TextField ), 'read' );
1785+ await tester.pump ();
1786+ checkExpectedHighlight (searchResult: 'All' , otherItems: < String > ['Unread' , 'Read' ]); // Because the search result should always be index 0.
1787+
1788+ // Test custom search algorithm - exact match.
1789+ await tester.pumpWidget (dropdownMenu (
1790+ searchCallback: (List <DropdownMenuEntry <int >> entries, String query) {
1791+ if (query.isEmpty) {
1792+ return null ;
1793+ }
1794+ final int index = entries.indexWhere ((DropdownMenuEntry <int > entry) => entry.label == query);
1795+
1796+ return index != - 1 ? index : null ;
1797+ },
1798+ ));
1799+ await tester.pump ();
1800+
1801+ await tester.enterText (find.byType (TextField ), 'read' );
1802+ await tester.pump ();
1803+ checkExpectedHighlight (otherItems: < String > ['All' , 'Unread' , 'Read' ]); // Because it's case sensitive.
1804+ await tester.enterText (find.byType (TextField ), 'Read' );
1805+ await tester.pump ();
1806+ checkExpectedHighlight (searchResult: 'Read' , otherItems: < String > ['All' , 'Unread' ]);
1807+ });
17291808}
17301809
17311810enum TestMenu {
0 commit comments