|
2 | 2 | // Use of this source code is governed by a BSD-style license that can be
|
3 | 3 | // found in the LICENSE file.
|
4 | 4 |
|
| 5 | +import 'package:flutter/foundation.dart'; |
5 | 6 | import 'package:flutter/material.dart';
|
6 | 7 | import 'package:flutter_test/flutter_test.dart';
|
7 | 8 | import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';
|
8 | 9 |
|
| 10 | +import 'feedback_tester.dart'; |
| 11 | + |
9 | 12 | /// Adds the basic requirements for a Chip.
|
10 | 13 | Widget wrapForChip({
|
11 | 14 | required Widget child,
|
@@ -722,4 +725,198 @@ void main() {
|
722 | 725 |
|
723 | 726 | expect(getIconData(tester).color, const Color(0xff00ff00));
|
724 | 727 | });
|
| 728 | + |
| 729 | + testWidgetsWithLeakTracking('Material3 - FilterChip supports delete button', (WidgetTester tester) async { |
| 730 | + final ThemeData theme = ThemeData(); |
| 731 | + await tester.pumpWidget( |
| 732 | + MaterialApp( |
| 733 | + theme: theme, |
| 734 | + home: Material( |
| 735 | + child: Center( |
| 736 | + child: FilterChip( |
| 737 | + onDeleted: () { }, |
| 738 | + onSelected: (bool valueChanged) { }, |
| 739 | + label: const Text('FilterChip'), |
| 740 | + ), |
| 741 | + ), |
| 742 | + ), |
| 743 | + ), |
| 744 | + ); |
| 745 | + |
| 746 | + // Test the chip size with delete button. |
| 747 | + expect(find.text('FilterChip'), findsOneWidget); |
| 748 | + expect(tester.getSize(find.byType(FilterChip)), const Size(195.0, 48.0)); |
| 749 | + |
| 750 | + // Test the delete button icon. |
| 751 | + expect(tester.getSize(find.byIcon(Icons.clear)), const Size(18.0, 18.0)); |
| 752 | + expect(getIconData(tester).color, theme.colorScheme.onSecondaryContainer); |
| 753 | + |
| 754 | + await tester.pumpWidget( |
| 755 | + MaterialApp( |
| 756 | + theme: theme, |
| 757 | + home: Material( |
| 758 | + child: Center( |
| 759 | + child: FilterChip.elevated( |
| 760 | + onDeleted: () { }, |
| 761 | + onSelected: (bool valueChanged) { }, |
| 762 | + label: const Text('Elevated FilterChip'), |
| 763 | + ), |
| 764 | + ), |
| 765 | + ), |
| 766 | + ), |
| 767 | + ); |
| 768 | + |
| 769 | + // Test the elevated chip size with delete button. |
| 770 | + expect(find.text('Elevated FilterChip'), findsOneWidget); |
| 771 | + expect( |
| 772 | + tester.getSize(find.byType(FilterChip)), |
| 773 | + within(distance: 0.001, from: const Size(321.9, 48.0)), |
| 774 | + ); |
| 775 | + |
| 776 | + // Test the delete button icon. |
| 777 | + expect(tester.getSize(find.byIcon(Icons.clear)), const Size(18.0, 18.0)); |
| 778 | + expect(getIconData(tester).color, theme.colorScheme.onSecondaryContainer); |
| 779 | + }, skip: kIsWeb && !isCanvasKit); // https://github.com/flutter/flutter/issues/99933 |
| 780 | + |
| 781 | + testWidgetsWithLeakTracking('Material2 - FilterChip supports delete button', (WidgetTester tester) async { |
| 782 | + final ThemeData theme = ThemeData(useMaterial3: false); |
| 783 | + await tester.pumpWidget( |
| 784 | + MaterialApp( |
| 785 | + theme: theme, |
| 786 | + home: Material( |
| 787 | + child: Center( |
| 788 | + child: FilterChip( |
| 789 | + onDeleted: () { }, |
| 790 | + onSelected: (bool valueChanged) { }, |
| 791 | + label: const Text('FilterChip'), |
| 792 | + ), |
| 793 | + ), |
| 794 | + ), |
| 795 | + ), |
| 796 | + ); |
| 797 | + |
| 798 | + // Test the chip size with delete button. |
| 799 | + expect(find.text('FilterChip'), findsOneWidget); |
| 800 | + expect(tester.getSize(find.byType(FilterChip)), const Size(188.0, 48.0)); |
| 801 | + |
| 802 | + // Test the delete button icon. |
| 803 | + expect(tester.getSize(find.byIcon(Icons.cancel)), const Size(18.0, 18.0)); |
| 804 | + expect(getIconData(tester).color, theme.iconTheme.color?.withAlpha(0xde)); |
| 805 | + |
| 806 | + await tester.pumpWidget( |
| 807 | + MaterialApp( |
| 808 | + theme: theme, |
| 809 | + home: Material( |
| 810 | + child: Center( |
| 811 | + child: FilterChip.elevated( |
| 812 | + onDeleted: () { }, |
| 813 | + onSelected: (bool valueChanged) { }, |
| 814 | + label: const Text('Elevated FilterChip'), |
| 815 | + ), |
| 816 | + ), |
| 817 | + ), |
| 818 | + ), |
| 819 | + ); |
| 820 | + |
| 821 | + // Test the elevated chip size with delete button. |
| 822 | + expect(find.text('Elevated FilterChip'), findsOneWidget); |
| 823 | + expect(tester.getSize(find.byType(FilterChip)), const Size(314.0, 48.0)); |
| 824 | + |
| 825 | + // Test the delete button icon. |
| 826 | + expect(tester.getSize(find.byIcon(Icons.cancel)), const Size(18.0, 18.0)); |
| 827 | + expect(getIconData(tester).color, theme.iconTheme.color?.withAlpha(0xde)); |
| 828 | + }); |
| 829 | + |
| 830 | + testWidgetsWithLeakTracking('Customize FilterChip delete button', (WidgetTester tester) async { |
| 831 | + final ThemeData theme = ThemeData(); |
| 832 | + Widget buildChip({ |
| 833 | + Widget? deleteIcon, |
| 834 | + Color? deleteIconColor, |
| 835 | + String? deleteButtonTooltipMessage, |
| 836 | + }) { |
| 837 | + return MaterialApp( |
| 838 | + theme: theme, |
| 839 | + home: Material( |
| 840 | + child: Center( |
| 841 | + child: FilterChip( |
| 842 | + deleteIcon: deleteIcon, |
| 843 | + deleteIconColor: deleteIconColor, |
| 844 | + deleteButtonTooltipMessage: deleteButtonTooltipMessage, |
| 845 | + onDeleted: () { }, |
| 846 | + onSelected: (bool valueChanged) { }, |
| 847 | + label: const Text('FilterChip'), |
| 848 | + ), |
| 849 | + ), |
| 850 | + ), |
| 851 | + ); |
| 852 | + } |
| 853 | + |
| 854 | + // Test the custom delete icon. |
| 855 | + await tester.pumpWidget(buildChip(deleteIcon: const Icon(Icons.delete))); |
| 856 | + |
| 857 | + expect(find.byIcon(Icons.clear), findsNothing); |
| 858 | + expect(find.byIcon(Icons.delete), findsOneWidget); |
| 859 | + |
| 860 | + // Test the custom delete icon color. |
| 861 | + await tester.pumpWidget(buildChip( |
| 862 | + deleteIcon: const Icon(Icons.delete), |
| 863 | + deleteIconColor: const Color(0xff00ff00)), |
| 864 | + ); |
| 865 | + await tester.pumpAndSettle(); |
| 866 | + |
| 867 | + expect(find.byIcon(Icons.clear), findsNothing); |
| 868 | + expect(find.byIcon(Icons.delete), findsOneWidget); |
| 869 | + expect(getIconData(tester).color, const Color(0xff00ff00)); |
| 870 | + |
| 871 | + // Test the custom delete button tooltip message. |
| 872 | + await tester.pumpWidget(buildChip(deleteButtonTooltipMessage: 'Delete FilterChip')); |
| 873 | + await tester.pumpAndSettle(); |
| 874 | + |
| 875 | + // Hover over the delete icon of the chip |
| 876 | + final TestGesture gesture = await tester.startGesture(tester.getCenter(find.byIcon(Icons.clear))); |
| 877 | + |
| 878 | + await tester.pumpAndSettle(); |
| 879 | + |
| 880 | + // Verify the tooltip message is set. |
| 881 | + expect(find.widgetWithText(Tooltip, 'Delete FilterChip'), findsOneWidget); |
| 882 | + |
| 883 | + await gesture.up(); |
| 884 | + }); |
| 885 | + |
| 886 | + testWidgetsWithLeakTracking('FilterChip delete button control test', (WidgetTester tester) async { |
| 887 | + final FeedbackTester feedback = FeedbackTester(); |
| 888 | + final List<String> deletedButtonStrings = <String>[]; |
| 889 | + await tester.pumpWidget( |
| 890 | + MaterialApp( |
| 891 | + home: Material( |
| 892 | + child: Center( |
| 893 | + child: FilterChip( |
| 894 | + onDeleted: () { |
| 895 | + deletedButtonStrings.add('A'); |
| 896 | + }, |
| 897 | + onSelected: (bool valueChanged) { }, |
| 898 | + label: const Text('FilterChip'), |
| 899 | + ), |
| 900 | + ), |
| 901 | + ), |
| 902 | + ), |
| 903 | + ); |
| 904 | + |
| 905 | + expect(feedback.clickSoundCount, 0); |
| 906 | + |
| 907 | + expect(deletedButtonStrings, isEmpty); |
| 908 | + await tester.tap(find.byIcon(Icons.clear)); |
| 909 | + expect(deletedButtonStrings, equals(<String>['A'])); |
| 910 | + |
| 911 | + await tester.pumpAndSettle(const Duration(seconds: 1)); |
| 912 | + expect(feedback.clickSoundCount, 1); |
| 913 | + |
| 914 | + await tester.tap(find.byIcon(Icons.clear)); |
| 915 | + expect(deletedButtonStrings, equals(<String>['A', 'A'])); |
| 916 | + |
| 917 | + await tester.pumpAndSettle(const Duration(seconds: 1)); |
| 918 | + expect(feedback.clickSoundCount, 2); |
| 919 | + |
| 920 | + feedback.dispose(); |
| 921 | + }); |
725 | 922 | }
|
0 commit comments