Skip to content

Commit 3cf206b

Browse files
authored
Update CheckboxListTile and CalendarDatePicker tests for M2/M3 (flutter#131363)
1 parent b928b3c commit 3cf206b

File tree

2 files changed

+254
-7
lines changed

2 files changed

+254
-7
lines changed

packages/flutter/test/material/calendar_date_picker_test.dart

Lines changed: 95 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ void main() {
2626
DatePickerMode initialCalendarMode = DatePickerMode.day,
2727
SelectableDayPredicate? selectableDayPredicate,
2828
TextDirection textDirection = TextDirection.ltr,
29+
bool? useMaterial3,
2930
}) {
3031
return MaterialApp(
31-
theme: ThemeData(useMaterial3: false),
32+
theme: ThemeData(useMaterial3: useMaterial3),
3233
home: Material(
3334
child: Directionality(
3435
textDirection: textDirection,
@@ -347,8 +348,9 @@ void main() {
347348
expect(find.text('January 2018'), findsOneWidget);
348349
});
349350

350-
testWidgets('currentDate is highlighted', (WidgetTester tester) async {
351+
testWidgets('Material2 - currentDate is highlighted', (WidgetTester tester) async {
351352
await tester.pumpWidget(calendarDatePicker(
353+
useMaterial3: false,
352354
currentDate: DateTime(2016, 1, 2),
353355
));
354356
const Color todayColor = Color(0xff2196f3); // default primary color
@@ -363,8 +365,26 @@ void main() {
363365
);
364366
});
365367

366-
testWidgets('currentDate is highlighted even if it is disabled', (WidgetTester tester) async {
368+
testWidgets('Material3 - currentDate is highlighted', (WidgetTester tester) async {
367369
await tester.pumpWidget(calendarDatePicker(
370+
useMaterial3: true,
371+
currentDate: DateTime(2016, 1, 2),
372+
));
373+
const Color todayColor = Color(0xff6750a4); // default primary color
374+
expect(
375+
Material.of(tester.element(find.text('2'))),
376+
// The current day should be painted with a circle outline.
377+
paints..circle(
378+
color: todayColor,
379+
style: PaintingStyle.stroke,
380+
strokeWidth: 1.0,
381+
),
382+
);
383+
});
384+
385+
testWidgets('Material2 - currentDate is highlighted even if it is disabled', (WidgetTester tester) async {
386+
await tester.pumpWidget(calendarDatePicker(
387+
useMaterial3: false,
368388
firstDate: DateTime(2016, 1, 3),
369389
lastDate: DateTime(2016, 1, 31),
370390
currentDate: DateTime(2016, 1, 2), // not between first and last
@@ -383,6 +403,27 @@ void main() {
383403
);
384404
});
385405

406+
testWidgets('Material3 - currentDate is highlighted even if it is disabled', (WidgetTester tester) async {
407+
await tester.pumpWidget(calendarDatePicker(
408+
useMaterial3: true,
409+
firstDate: DateTime(2016, 1, 3),
410+
lastDate: DateTime(2016, 1, 31),
411+
currentDate: DateTime(2016, 1, 2), // not between first and last
412+
initialDate: DateTime(2016, 1, 5),
413+
));
414+
const Color disabledColor = Color(0x616750a4); // default disabled color
415+
expect(
416+
Material.of(tester.element(find.text('2'))),
417+
// The current day should be painted with a circle outline.
418+
paints
419+
..circle(
420+
color: disabledColor,
421+
style: PaintingStyle.stroke,
422+
strokeWidth: 1.0,
423+
),
424+
);
425+
});
426+
386427
testWidgets('Selecting date does not switch picker to year selection', (WidgetTester tester) async {
387428
await tester.pumpWidget(calendarDatePicker(
388429
initialDate: DateTime(2020, DateTime.may, 10),
@@ -397,7 +438,7 @@ void main() {
397438
expect(find.text('2017'), findsNothing);
398439
});
399440

400-
testWidgets('Updates to initialDate parameter is reflected in the state', (WidgetTester tester) async {
441+
testWidgets('Material2 - Updates to initialDate parameter is reflected in the state', (WidgetTester tester) async {
401442
final Key pickerKey = UniqueKey();
402443
final DateTime initialDate = DateTime(2020, 1, 21);
403444
final DateTime updatedDate = DateTime(1976, 2, 23);
@@ -407,6 +448,55 @@ void main() {
407448

408449
await tester.pumpWidget(calendarDatePicker(
409450
key: pickerKey,
451+
useMaterial3: false,
452+
initialDate: initialDate,
453+
firstDate: firstDate,
454+
lastDate: lastDate,
455+
onDateChanged: (DateTime value) {},
456+
));
457+
await tester.pumpAndSettle();
458+
459+
// Month should show as January 2020
460+
expect(find.text('January 2020'), findsOneWidget);
461+
// Selected date should be painted with a colored circle.
462+
expect(
463+
Material.of(tester.element(find.text('21'))),
464+
paints..circle(color: selectedColor, style: PaintingStyle.fill),
465+
);
466+
467+
// Change to the updated initialDate
468+
await tester.pumpWidget(calendarDatePicker(
469+
key: pickerKey,
470+
useMaterial3: false,
471+
initialDate: updatedDate,
472+
firstDate: firstDate,
473+
lastDate: lastDate,
474+
onDateChanged: (DateTime value) {},
475+
));
476+
// Wait for the page scroll animation to finish.
477+
await tester.pumpAndSettle(const Duration(milliseconds: 200));
478+
479+
// Month should show as February 1976
480+
expect(find.text('January 2020'), findsNothing);
481+
expect(find.text('February 1976'), findsOneWidget);
482+
// Selected date should be painted with a colored circle.
483+
expect(
484+
Material.of(tester.element(find.text('23'))),
485+
paints..circle(color: selectedColor, style: PaintingStyle.fill),
486+
);
487+
});
488+
489+
testWidgets('Material3 - Updates to initialDate parameter is reflected in the state', (WidgetTester tester) async {
490+
final Key pickerKey = UniqueKey();
491+
final DateTime initialDate = DateTime(2020, 1, 21);
492+
final DateTime updatedDate = DateTime(1976, 2, 23);
493+
final DateTime firstDate = DateTime(1970);
494+
final DateTime lastDate = DateTime(2099, 31, 12);
495+
const Color selectedColor = Color(0xff6750a4); // default primary color
496+
497+
await tester.pumpWidget(calendarDatePicker(
498+
key: pickerKey,
499+
useMaterial3: true,
410500
initialDate: initialDate,
411501
firstDate: firstDate,
412502
lastDate: lastDate,
@@ -425,6 +515,7 @@ void main() {
425515
// Change to the updated initialDate
426516
await tester.pumpWidget(calendarDatePicker(
427517
key: pickerKey,
518+
useMaterial3: true,
428519
initialDate: updatedDate,
429520
firstDate: firstDate,
430521
lastDate: lastDate,

packages/flutter/test/material/checkbox_list_tile_test.dart

Lines changed: 159 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// found in the LICENSE file.
44

55
import 'package:flutter/cupertino.dart';
6+
import 'package:flutter/foundation.dart';
67
import 'package:flutter/gestures.dart';
78
import 'package:flutter/material.dart';
89
import 'package:flutter/rendering.dart';
@@ -38,7 +39,7 @@ void main() {
3839
expect(log, equals(<dynamic>[false, '-', false]));
3940
});
4041

41-
testWidgetsWithLeakTracking('CheckboxListTile checkColor test', (WidgetTester tester) async {
42+
testWidgetsWithLeakTracking('Material2 - CheckboxListTile checkColor test', (WidgetTester tester) async {
4243
const Color checkBoxBorderColor = Color(0xff2196f3);
4344
Color checkBoxCheckColor = const Color(0xffFFFFFF);
4445

@@ -70,6 +71,38 @@ void main() {
7071
expect(getCheckboxListTileRenderer(), paints..path(color: checkBoxBorderColor)..path(color: checkBoxCheckColor));
7172
});
7273

74+
testWidgetsWithLeakTracking('Material3 - CheckboxListTile checkColor test', (WidgetTester tester) async {
75+
const Color checkBoxBorderColor = Color(0xff6750a4);
76+
Color checkBoxCheckColor = const Color(0xffFFFFFF);
77+
78+
Widget buildFrame(Color? color) {
79+
return MaterialApp(
80+
theme: ThemeData(useMaterial3: true),
81+
home: Material(
82+
child: CheckboxListTile(
83+
value: true,
84+
checkColor: color,
85+
onChanged: (bool? value) {},
86+
),
87+
),
88+
);
89+
}
90+
91+
RenderBox getCheckboxListTileRenderer() {
92+
return tester.renderObject<RenderBox>(find.byType(CheckboxListTile));
93+
}
94+
95+
await tester.pumpWidget(buildFrame(null));
96+
await tester.pumpAndSettle();
97+
expect(getCheckboxListTileRenderer(), paints..path(color: checkBoxBorderColor)..path(color: checkBoxCheckColor));
98+
99+
checkBoxCheckColor = const Color(0xFF000000);
100+
101+
await tester.pumpWidget(buildFrame(checkBoxCheckColor));
102+
await tester.pumpAndSettle();
103+
expect(getCheckboxListTileRenderer(), paints..path(color: checkBoxBorderColor)..path(color: checkBoxCheckColor));
104+
});
105+
73106
testWidgetsWithLeakTracking('CheckboxListTile activeColor test', (WidgetTester tester) async {
74107
Widget buildFrame(Color? themeColor, Color? activeColor) {
75108
return wrap(
@@ -710,7 +743,7 @@ void main() {
710743
);
711744
});
712745

713-
testWidgets('CheckboxListTile respects overlayColor in active/pressed/hovered states', (WidgetTester tester) async {
746+
testWidgets('Material2 - CheckboxListTile respects overlayColor in active/pressed/hovered states', (WidgetTester tester) async {
714747
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
715748

716749
const Color fillColor = Color(0xFF000000);
@@ -826,6 +859,129 @@ void main() {
826859
);
827860
});
828861

862+
testWidgets('Material3 - CheckboxListTile respects overlayColor in active/pressed/hovered states', (WidgetTester tester) async {
863+
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
864+
865+
const Color fillColor = Color(0xFF000000);
866+
const Color activePressedOverlayColor = Color(0xFF000001);
867+
const Color inactivePressedOverlayColor = Color(0xFF000002);
868+
const Color hoverOverlayColor = Color(0xFF000003);
869+
const Color hoverColor = Color(0xFF000005);
870+
871+
Color? getOverlayColor(Set<MaterialState> states) {
872+
if (states.contains(MaterialState.pressed)) {
873+
if (states.contains(MaterialState.selected)) {
874+
return activePressedOverlayColor;
875+
}
876+
return inactivePressedOverlayColor;
877+
}
878+
if (states.contains(MaterialState.hovered)) {
879+
return hoverOverlayColor;
880+
}
881+
return null;
882+
}
883+
const double splashRadius = 24.0;
884+
885+
Widget buildCheckbox({bool active = false, bool useOverlay = true}) {
886+
return MaterialApp(
887+
theme: ThemeData(useMaterial3: true),
888+
home: Material(
889+
child: CheckboxListTile(
890+
value: active,
891+
onChanged: (_) { },
892+
fillColor: const MaterialStatePropertyAll<Color>(fillColor),
893+
overlayColor: useOverlay ? MaterialStateProperty.resolveWith(getOverlayColor) : null,
894+
hoverColor: hoverColor,
895+
splashRadius: splashRadius,
896+
),
897+
),
898+
);
899+
}
900+
901+
await tester.pumpWidget(buildCheckbox(useOverlay: false));
902+
await tester.startGesture(tester.getCenter(find.byType(Checkbox)));
903+
await tester.pumpAndSettle();
904+
905+
expect(
906+
Material.of(tester.element(find.byType(Checkbox))),
907+
kIsWeb ? (paints..circle()..circle(
908+
color: fillColor.withAlpha(kRadialReactionAlpha),
909+
radius: splashRadius,
910+
)) : (paints..circle(
911+
color: fillColor.withAlpha(kRadialReactionAlpha),
912+
radius: splashRadius,
913+
)),
914+
reason: 'Default inactive pressed Checkbox should have overlay color from fillColor',
915+
);
916+
917+
await tester.pumpWidget(buildCheckbox(active: true, useOverlay: false));
918+
await tester.startGesture(tester.getCenter(find.byType(Checkbox)));
919+
await tester.pumpAndSettle();
920+
921+
expect(
922+
Material.of(tester.element(find.byType(Checkbox))),
923+
kIsWeb ? (paints..circle()..circle(
924+
color: fillColor.withAlpha(kRadialReactionAlpha),
925+
radius: splashRadius,
926+
)) : (paints..circle(
927+
color: fillColor.withAlpha(kRadialReactionAlpha),
928+
radius: splashRadius,
929+
)),
930+
reason: 'Default active pressed Checkbox should have overlay color from fillColor',
931+
);
932+
933+
await tester.pumpWidget(buildCheckbox());
934+
await tester.startGesture(tester.getCenter(find.byType(Checkbox)));
935+
await tester.pumpAndSettle();
936+
937+
expect(
938+
Material.of(tester.element(find.byType(Checkbox))),
939+
kIsWeb ? (paints..circle()..circle(
940+
color: inactivePressedOverlayColor,
941+
radius: splashRadius,
942+
)) : (paints..circle(
943+
color: inactivePressedOverlayColor,
944+
radius: splashRadius,
945+
)),
946+
reason: 'Inactive pressed Checkbox should have overlay color: $inactivePressedOverlayColor',
947+
);
948+
949+
await tester.pumpWidget(buildCheckbox(active: true));
950+
await tester.startGesture(tester.getCenter(find.byType(Checkbox)));
951+
await tester.pumpAndSettle();
952+
953+
expect(
954+
Material.of(tester.element(find.byType(Checkbox))),
955+
kIsWeb ? (paints..circle()..circle(
956+
color: activePressedOverlayColor,
957+
radius: splashRadius,
958+
)) : (paints..circle(
959+
color: activePressedOverlayColor,
960+
radius: splashRadius,
961+
)),
962+
reason: 'Active pressed Checkbox should have overlay color: $activePressedOverlayColor',
963+
);
964+
965+
// Start hovering
966+
await tester.pumpWidget(Container());
967+
await tester.pumpWidget(buildCheckbox());
968+
await tester.pumpAndSettle();
969+
970+
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
971+
await gesture.addPointer();
972+
await gesture.moveTo(tester.getCenter(find.byType(Checkbox)));
973+
await tester.pumpAndSettle();
974+
975+
expect(
976+
Material.of(tester.element(find.byType(Checkbox))),
977+
paints..circle(
978+
color: hoverOverlayColor,
979+
radius: splashRadius,
980+
),
981+
reason: 'Hovered Checkbox should use overlay color $hoverOverlayColor over $hoverColor',
982+
);
983+
});
984+
829985
testWidgetsWithLeakTracking('CheckboxListTile respects splashRadius', (WidgetTester tester) async {
830986
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
831987
const double splashRadius = 30;
@@ -881,7 +1037,7 @@ void main() {
8811037
expect(tester.getSize(find.byType(Checkbox)), const Size(48.0, 48.0));
8821038
});
8831039

884-
testWidgetsWithLeakTracking('CheckboxListTile respects isError - M3', (WidgetTester tester) async {
1040+
testWidgetsWithLeakTracking('Material3 - CheckboxListTile respects isError', (WidgetTester tester) async {
8851041
final ThemeData themeData = ThemeData(useMaterial3: true);
8861042
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
8871043
bool? value = true;

0 commit comments

Comments
 (0)