Unverified Commit dd0b6e35 authored by Qun Cheng's avatar Qun Cheng Committed by GitHub

Update `Checkbox` tests for M2/M3 (#130351)

Updated unit tests for `Checkbox` to have M2 and M3 versions.

More info in #127064
parent ab39bff2
...@@ -414,7 +414,8 @@ void main() { ...@@ -414,7 +414,8 @@ void main() {
semanticsTester.dispose(); semanticsTester.dispose();
}); });
testWidgets('Checkbox tristate rendering, programmatic transitions', (WidgetTester tester) async { testWidgets('Material2 - Checkbox tristate rendering, programmatic transitions', (WidgetTester tester) async {
final ThemeData theme = ThemeData(useMaterial3: false);
Widget buildFrame(bool? checkboxValue) { Widget buildFrame(bool? checkboxValue) {
return Theme( return Theme(
data: theme, data: theme,
...@@ -446,8 +447,8 @@ void main() { ...@@ -446,8 +447,8 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getCheckboxRenderer(), expect(getCheckboxRenderer(),
paints paints
..path(color: theme.useMaterial3 ? theme.colorScheme.primary : theme.colorScheme.secondary) ..path(color: theme.colorScheme.secondary)
..path(color: theme.useMaterial3 ? theme.colorScheme.onPrimary : const Color(0xFFFFFFFF)) ..path(color: const Color(0xFFFFFFFF))
); // checkmark is rendered as a path ); // checkmark is rendered as a path
await tester.pumpWidget(buildFrame(false)); await tester.pumpWidget(buildFrame(false));
...@@ -464,8 +465,8 @@ void main() { ...@@ -464,8 +465,8 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getCheckboxRenderer(), expect(getCheckboxRenderer(),
paints paints
..path(color: theme.useMaterial3 ? theme.colorScheme.primary : theme.colorScheme.secondary) ..path(color: theme.colorScheme.secondary)
..path(color: theme.useMaterial3 ? theme.colorScheme.onPrimary : const Color(0xFFFFFFFF)) ..path(color: const Color(0xFFFFFFFF))
); // checkmark is rendered as a path ); // checkmark is rendered as a path
await tester.pumpWidget(buildFrame(null)); await tester.pumpWidget(buildFrame(null));
...@@ -473,10 +474,69 @@ void main() { ...@@ -473,10 +474,69 @@ void main() {
expect(getCheckboxRenderer(), paints..line()); // null is rendered as a line (a "dash") expect(getCheckboxRenderer(), paints..line()); // null is rendered as a line (a "dash")
}); });
testWidgets('Checkbox color rendering', (WidgetTester tester) async { testWidgets('Material3 - Checkbox tristate rendering, programmatic transitions', (WidgetTester tester) async {
final ThemeData theme = ThemeData(); final ThemeData theme = ThemeData(useMaterial3: true);
Widget buildFrame(bool? checkboxValue) {
return Theme(
data: theme,
child: Material(
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Checkbox(
tristate: true,
value: checkboxValue,
onChanged: (bool? value) { },
);
},
),
),
);
}
RenderBox getCheckboxRenderer() {
return tester.renderObject<RenderBox>(find.byType(Checkbox));
}
await tester.pumpWidget(buildFrame(false));
await tester.pumpAndSettle();
expect(getCheckboxRenderer(), paints..path(color: Colors.transparent)); // paint transparent border
expect(getCheckboxRenderer(), isNot(paints..line())); // null is rendered as a line (a "dash")
expect(getCheckboxRenderer(), paints..drrect()); // empty checkbox
await tester.pumpWidget(buildFrame(true));
await tester.pumpAndSettle();
expect(getCheckboxRenderer(),
paints
..path(color: theme.colorScheme.primary)
..path(color: theme.colorScheme.onPrimary)
); // checkmark is rendered as a path
await tester.pumpWidget(buildFrame(false));
await tester.pumpAndSettle();
expect(getCheckboxRenderer(), paints..path(color: Colors.transparent)); // paint transparent border
expect(getCheckboxRenderer(), isNot(paints..line())); // null is rendered as a line (a "dash")
expect(getCheckboxRenderer(), paints..drrect()); // empty checkbox
await tester.pumpWidget(buildFrame(null));
await tester.pumpAndSettle();
expect(getCheckboxRenderer(), paints..line()); // null is rendered as a line (a "dash")
await tester.pumpWidget(buildFrame(true));
await tester.pumpAndSettle();
expect(getCheckboxRenderer(),
paints
..path(color: theme.colorScheme.primary)
..path(color: theme.colorScheme.onPrimary)
); // checkmark is rendered as a path
await tester.pumpWidget(buildFrame(null));
await tester.pumpAndSettle();
expect(getCheckboxRenderer(), paints..line()); // null is rendered as a line (a "dash")
});
testWidgets('Material2 - Checkbox color rendering', (WidgetTester tester) async {
ThemeData theme = ThemeData(useMaterial3: false);
const Color borderColor = Color(0xff2196f3); const Color borderColor = Color(0xff2196f3);
const Color m3BorderColor = Color(0xFF6750A4);
Color checkColor = const Color(0xffFFFFFF); Color checkColor = const Color(0xffFFFFFF);
Color activeColor; Color activeColor;
...@@ -504,24 +564,20 @@ void main() { ...@@ -504,24 +564,20 @@ void main() {
await tester.pumpWidget(buildFrame(checkColor: checkColor)); await tester.pumpWidget(buildFrame(checkColor: checkColor));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getCheckboxRenderer(), paints..path(color: theme.useMaterial3 ? m3BorderColor : borderColor)..path(color: checkColor)); // paints's color is 0xFFFFFFFF (default color) expect(getCheckboxRenderer(), paints..path(color: borderColor)..path(color: checkColor)); // paints's color is 0xFFFFFFFF (default color)
checkColor = const Color(0xFF000000); checkColor = const Color(0xFF000000);
await tester.pumpWidget(buildFrame(checkColor: checkColor)); await tester.pumpWidget(buildFrame(checkColor: checkColor));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getCheckboxRenderer(), paints..path(color: theme.useMaterial3 ? m3BorderColor : borderColor)..path(color: checkColor)); // paints's color is 0xFF000000 (params) expect(getCheckboxRenderer(), paints..path(color: borderColor)..path(color: checkColor)); // paints's color is 0xFF000000 (params)
activeColor = const Color(0xFF00FF00); activeColor = const Color(0xFF00FF00);
ThemeData themeData = ThemeData(); final ColorScheme colorScheme = const ColorScheme.light().copyWith(secondary: activeColor);
final bool material3 = themeData.useMaterial3; theme = theme.copyWith(colorScheme: colorScheme);
final ColorScheme colorScheme = material3
? const ColorScheme.light().copyWith(primary: activeColor)
: const ColorScheme.light().copyWith(secondary: activeColor);
themeData = themeData.copyWith(colorScheme: colorScheme);
await tester.pumpWidget(buildFrame( await tester.pumpWidget(buildFrame(
themeData: themeData), themeData: theme),
); );
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getCheckboxRenderer(), paints..path(color: activeColor)); // paints's color is 0xFF00FF00 (theme) expect(getCheckboxRenderer(), paints..path(color: activeColor)); // paints's color is 0xFF00FF00 (theme)
...@@ -530,13 +586,137 @@ void main() { ...@@ -530,13 +586,137 @@ void main() {
await tester.pumpWidget(buildFrame(activeColor: activeColor)); await tester.pumpWidget(buildFrame(activeColor: activeColor));
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(getCheckboxRenderer(), paints..path(color: activeColor)); // paints's color is 0xFF000000 (params) expect(getCheckboxRenderer(), paints..path(color: activeColor));
}); });
testWidgets('Checkbox is focusable and has correct focus color', (WidgetTester tester) async { testWidgets('Material3 - Checkbox color rendering', (WidgetTester tester) async {
ThemeData theme = ThemeData(useMaterial3: true);
const Color borderColor = Color(0xFF6750A4);
Color checkColor = const Color(0xffFFFFFF);
Color activeColor;
Widget buildFrame({Color? activeColor, Color? checkColor, ThemeData? themeData}) {
return Material(
child: Theme(
data: themeData ?? theme,
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Checkbox(
value: true,
activeColor: activeColor,
checkColor: checkColor,
onChanged: (bool? value) { },
);
},
),
),
);
}
RenderBox getCheckboxRenderer() {
return tester.renderObject<RenderBox>(find.byType(Checkbox));
}
await tester.pumpWidget(buildFrame(checkColor: checkColor));
await tester.pumpAndSettle();
expect(getCheckboxRenderer(), paints..path(color: borderColor)..path(color: checkColor)); // paints's color is 0xFFFFFFFF (default color)
checkColor = const Color(0xFF000000);
await tester.pumpWidget(buildFrame(checkColor: checkColor));
await tester.pumpAndSettle();
expect(getCheckboxRenderer(), paints..path(color: borderColor)..path(color: checkColor)); // paints's color is 0xFF000000 (params)
activeColor = const Color(0xFF00FF00);
final ColorScheme colorScheme = const ColorScheme.light().copyWith(primary: activeColor);
theme = theme.copyWith(colorScheme: colorScheme);
await tester.pumpWidget(buildFrame(themeData: theme));
await tester.pumpAndSettle();
expect(getCheckboxRenderer(), paints..path(color: activeColor)); // paints's color is 0xFF00FF00 (theme)
activeColor = const Color(0xFF000000);
await tester.pumpWidget(buildFrame(activeColor: activeColor));
await tester.pumpAndSettle();
expect(getCheckboxRenderer(), paints..path(color: activeColor));
});
testWidgets('Material2 - Checkbox is focusable and has correct focus color', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Checkbox'); final FocusNode focusNode = FocusNode(debugLabel: 'Checkbox');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
bool? value = true; bool? value = true;
Widget buildApp({bool enabled = true}) {
return MaterialApp(
theme: ThemeData(useMaterial3: false),
home: Material(
child: Center(
child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
return Checkbox(
value: value,
onChanged: enabled ? (bool? newValue) {
setState(() {
value = newValue;
});
} : null,
focusColor: Colors.orange[500],
autofocus: true,
focusNode: focusNode,
);
}),
),
),
);
}
await tester.pumpWidget(buildApp());
await tester.pumpAndSettle();
expect(focusNode.hasPrimaryFocus, isTrue);
expect(
Material.of(tester.element(find.byType(Checkbox))),
paints
..circle(color: Colors.orange[500])
..path(color: const Color(0xff2196f3))
..path(color: Colors.white)
);
// Check the false value.
value = false;
await tester.pumpWidget(buildApp());
await tester.pumpAndSettle();
expect(focusNode.hasPrimaryFocus, isTrue);
expect(
Material.of(tester.element(find.byType(Checkbox))),
paints
..circle(color: Colors.orange[500])
..drrect(
color: const Color(0x8a000000),
outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(1.0)),
inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero),
),
);
// Check what happens when disabled.
value = false;
await tester.pumpWidget(buildApp(enabled: false));
await tester.pumpAndSettle();
expect(focusNode.hasPrimaryFocus, isFalse);
expect(
Material.of(tester.element(find.byType(Checkbox))),
paints
..drrect(
color: const Color(0x61000000),
outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(1.0)),
inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero),
),
);
});
testWidgets('Material3 - Checkbox is focusable and has correct focus color', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Checkbox');
final ThemeData theme = ThemeData(useMaterial3: true);
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
bool? value = true;
Widget buildApp({bool enabled = true}) { Widget buildApp({bool enabled = true}) {
return MaterialApp( return MaterialApp(
theme: theme, theme: theme,
...@@ -562,19 +742,13 @@ void main() { ...@@ -562,19 +742,13 @@ void main() {
await tester.pumpWidget(buildApp()); await tester.pumpWidget(buildApp());
await tester.pumpAndSettle(); await tester.pumpAndSettle();
final bool material3 = theme.useMaterial3;
expect(focusNode.hasPrimaryFocus, isTrue); expect(focusNode.hasPrimaryFocus, isTrue);
expect( expect(
Material.of(tester.element(find.byType(Checkbox))), Material.of(tester.element(find.byType(Checkbox))),
material3 paints
? (paints
..circle(color: Colors.orange[500]) ..circle(color: Colors.orange[500])
..path(color: theme.colorScheme.primary) ..path(color: theme.colorScheme.primary)
..path(color: theme.colorScheme.onPrimary)) ..path(color: theme.colorScheme.onPrimary)
: (paints
..circle(color: Colors.orange[500])
..path(color: const Color(0xff2196f3))
..path(color: Colors.white))
); );
// Check the false value. // Check the false value.
...@@ -587,8 +761,8 @@ void main() { ...@@ -587,8 +761,8 @@ void main() {
paints paints
..circle(color: Colors.orange[500]) ..circle(color: Colors.orange[500])
..drrect( ..drrect(
color: material3 ? theme.colorScheme.onSurface : const Color(0x8a000000), color: theme.colorScheme.onSurface,
outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, material3 ? const Radius.circular(2.0) : const Radius.circular(1.0)), outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(2.0)),
inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero), inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero),
), ),
); );
...@@ -602,8 +776,8 @@ void main() { ...@@ -602,8 +776,8 @@ void main() {
Material.of(tester.element(find.byType(Checkbox))), Material.of(tester.element(find.byType(Checkbox))),
paints paints
..drrect( ..drrect(
color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000), color: theme.colorScheme.onSurface.withOpacity(0.38),
outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, material3 ? const Radius.circular(2.0) : const Radius.circular(1.0)), outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(2.0)),
inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero), inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero),
), ),
); );
...@@ -670,10 +844,10 @@ void main() { ...@@ -670,10 +844,10 @@ void main() {
); );
}); });
testWidgets('Checkbox can be hovered and has correct hover color', (WidgetTester tester) async { testWidgets('Material2 - Checkbox can be hovered and has correct hover color', (WidgetTester tester) async {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
bool? value = true; bool? value = true;
final bool material3 = theme.useMaterial3; final ThemeData theme = ThemeData(useMaterial3: false);
Widget buildApp({bool enabled = true}) { Widget buildApp({bool enabled = true}) {
return MaterialApp( return MaterialApp(
theme: theme, theme: theme,
...@@ -699,8 +873,8 @@ void main() { ...@@ -699,8 +873,8 @@ void main() {
expect( expect(
Material.of(tester.element(find.byType(Checkbox))), Material.of(tester.element(find.byType(Checkbox))),
paints paints
..path(color: material3 ? const Color(0xff6750a4) : const Color(0xff2196f3)) ..path(color: const Color(0xff2196f3))
..path(color: material3 ? theme.colorScheme.onPrimary : const Color(0xffffffff), style: PaintingStyle.stroke, strokeWidth: 2.0), ..path(color: const Color(0xffffffff), style: PaintingStyle.stroke, strokeWidth: 2.0),
); );
// Start hovering // Start hovering
...@@ -712,8 +886,8 @@ void main() { ...@@ -712,8 +886,8 @@ void main() {
expect( expect(
Material.of(tester.element(find.byType(Checkbox))), Material.of(tester.element(find.byType(Checkbox))),
paints paints
..path(color: material3 ? const Color(0xff6750a4) : const Color(0xff2196f3)) ..path(color: const Color(0xff2196f3))
..path(color: material3 ? theme.colorScheme.onPrimary : const Color(0xffffffff), style: PaintingStyle.stroke, strokeWidth: 2.0), ..path(color: const Color(0xffffffff), style: PaintingStyle.stroke, strokeWidth: 2.0),
); );
// Check what happens when disabled. // Check what happens when disabled.
...@@ -722,8 +896,65 @@ void main() { ...@@ -722,8 +896,65 @@ void main() {
expect( expect(
Material.of(tester.element(find.byType(Checkbox))), Material.of(tester.element(find.byType(Checkbox))),
paints paints
..path(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000)) ..path(color: const Color(0x61000000))
..path(color: material3 ? theme.colorScheme.surface : const Color(0xffffffff), style: PaintingStyle.stroke, strokeWidth: 2.0), ..path(color: const Color(0xffffffff), style: PaintingStyle.stroke, strokeWidth: 2.0),
);
});
testWidgets('Material3 - Checkbox can be hovered and has correct hover color', (WidgetTester tester) async {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
bool? value = true;
final ThemeData theme = ThemeData(useMaterial3: true);
Widget buildApp({bool enabled = true}) {
return MaterialApp(
theme: theme,
home: Material(
child: Center(
child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
return Checkbox(
value: value,
onChanged: enabled ? (bool? newValue) {
setState(() {
value = newValue;
});
} : null,
hoverColor: Colors.orange[500],
);
}),
),
),
);
}
await tester.pumpWidget(buildApp());
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Checkbox))),
paints
..path(color: const Color(0xff6750a4))
..path(color: theme.colorScheme.onPrimary, style: PaintingStyle.stroke, strokeWidth: 2.0),
);
// Start hovering
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
await gesture.moveTo(tester.getCenter(find.byType(Checkbox)));
await tester.pumpWidget(buildApp());
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Checkbox))),
paints
..path(color: const Color(0xff6750a4))
..path(color: theme.colorScheme.onPrimary, style: PaintingStyle.stroke, strokeWidth: 2.0),
);
// Check what happens when disabled.
await tester.pumpWidget(buildApp(enabled: false));
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Checkbox))),
paints
..path(color: theme.colorScheme.onSurface.withOpacity(0.38))
..path(color: theme.colorScheme.surface, style: PaintingStyle.stroke, strokeWidth: 2.0),
); );
}); });
...@@ -1108,12 +1339,12 @@ void main() { ...@@ -1108,12 +1339,12 @@ void main() {
); );
}); });
testWidgets('Checkbox default overlay color in active/pressed/focused/hovered states', (WidgetTester tester) async { testWidgets('Material2 - Checkbox default overlay color in active/pressed/focused/hovered states', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Checkbox'); final FocusNode focusNode = FocusNode(debugLabel: 'Checkbox');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
final ThemeData theme = ThemeData(useMaterial3: false);
final ColorScheme colors = theme.colorScheme; final ColorScheme colors = theme.colorScheme;
final bool material3 = theme.useMaterial3;
Widget buildCheckbox({bool active = false, bool focused = false}) { Widget buildCheckbox({bool active = false, bool focused = false}) {
return MaterialApp( return MaterialApp(
theme: theme, theme: theme,
...@@ -1134,11 +1365,8 @@ void main() { ...@@ -1134,11 +1365,8 @@ void main() {
expect( expect(
Material.of(tester.element(find.byType(Checkbox))), Material.of(tester.element(find.byType(Checkbox))),
material3 paints
? (paints..circle(color: colors.primary.withOpacity(0.12))) ..circle(color: theme.unselectedWidgetColor.withAlpha(kRadialReactionAlpha)),
: (paints
..circle(color: theme.unselectedWidgetColor.withAlpha(kRadialReactionAlpha),)
),
reason: 'Default inactive pressed Checkbox should have overlay color from default fillColor', reason: 'Default inactive pressed Checkbox should have overlay color from default fillColor',
); );
...@@ -1148,11 +1376,73 @@ void main() { ...@@ -1148,11 +1376,73 @@ void main() {
expect( expect(
Material.of(tester.element(find.byType(Checkbox))), Material.of(tester.element(find.byType(Checkbox))),
material3 paints
? (paints..circle(color: colors.onSurface.withOpacity(0.12))) ..circle(color: colors.secondary.withAlpha(kRadialReactionAlpha)),
: (paints reason: 'Default active pressed Checkbox should have overlay color from default fillColor',
..circle(color: colors.secondary.withAlpha(kRadialReactionAlpha),) );
await tester.pumpWidget(Container()); // reset test
await tester.pumpWidget(buildCheckbox(focused: true));
await tester.pumpAndSettle();
expect(focusNode.hasPrimaryFocus, isTrue);
expect(
Material.of(tester.element(find.byType(Checkbox))),
paints..circle(color: theme.focusColor),
reason: 'Focused Checkbox should use default focused overlay color',
);
await tester.pumpWidget(Container()); // reset test
await tester.pumpWidget(buildCheckbox());
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
await gesture.addPointer();
await gesture.moveTo(tester.getCenter(find.byType(Checkbox)));
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Checkbox))),
paints..circle(color: theme.hoverColor),
reason: 'Hovered Checkbox should use default hovered overlay color',
);
});
testWidgets('Material3 - Checkbox default overlay color in active/pressed/focused/hovered states', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Checkbox');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
final ThemeData theme = ThemeData(useMaterial3: true);
final ColorScheme colors = theme.colorScheme;
Widget buildCheckbox({bool active = false, bool focused = false}) {
return MaterialApp(
theme: theme,
home: Scaffold(
body: Checkbox(
focusNode: focusNode,
autofocus: focused,
value: active,
onChanged: (_) { },
),
), ),
);
}
await tester.pumpWidget(buildCheckbox());
await tester.startGesture(tester.getCenter(find.byType(Checkbox)));
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Checkbox))),
paints..circle(color: colors.primary.withOpacity(0.12)),
reason: 'Default inactive pressed Checkbox should have overlay color from default fillColor',
);
await tester.pumpWidget(buildCheckbox(active: true));
await tester.startGesture(tester.getCenter(find.byType(Checkbox)));
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Checkbox))),
paints..circle(color: colors.onSurface.withOpacity(0.12)),
reason: 'Default active pressed Checkbox should have overlay color from default fillColor', reason: 'Default active pressed Checkbox should have overlay color from default fillColor',
); );
...@@ -1163,9 +1453,7 @@ void main() { ...@@ -1163,9 +1453,7 @@ void main() {
expect(focusNode.hasPrimaryFocus, isTrue); expect(focusNode.hasPrimaryFocus, isTrue);
expect( expect(
Material.of(tester.element(find.byType(Checkbox))), Material.of(tester.element(find.byType(Checkbox))),
material3 paints..circle(color: colors.onSurface.withOpacity(0.12)),
? (paints..circle(color: colors.onSurface.withOpacity(0.12)))
: (paints..circle(color: theme.focusColor)),
reason: 'Focused Checkbox should use default focused overlay color', reason: 'Focused Checkbox should use default focused overlay color',
); );
...@@ -1178,9 +1466,7 @@ void main() { ...@@ -1178,9 +1466,7 @@ void main() {
expect( expect(
Material.of(tester.element(find.byType(Checkbox))), Material.of(tester.element(find.byType(Checkbox))),
material3 paints..circle(color: colors.onSurface.withOpacity(0.08)),
? (paints..circle(color: colors.onSurface.withOpacity(0.08)))
: (paints..circle(color: theme.hoverColor)),
reason: 'Hovered Checkbox should use default hovered overlay color', reason: 'Hovered Checkbox should use default hovered overlay color',
); );
}); });
...@@ -1516,13 +1802,67 @@ void main() { ...@@ -1516,13 +1802,67 @@ void main() {
expect(getCheckboxRenderer(), paints..path(color: activeColor)); // checkbox fill expect(getCheckboxRenderer(), paints..path(color: activeColor)); // checkbox fill
}); });
testWidgets('Checkbox MaterialStateBorderSide applies unconditionally', (WidgetTester tester) async { testWidgets('Material2 - Checkbox MaterialStateBorderSide applies unconditionally', (WidgetTester tester) async {
const Color borderColor = Color(0xfff44336);
const BorderSide side = BorderSide(
width: 4,
color: borderColor,
);
final ThemeData theme = ThemeData(useMaterial3: false);
Widget buildApp({ bool? value, bool enabled = true }) {
return MaterialApp(
theme: theme,
home: Material(
child: Center(
child: Checkbox(
value: value,
tristate: value == null,
onChanged: enabled ? (bool? newValue) { } : null,
side: MaterialStateBorderSide.resolveWith((Set<MaterialState> states) => side),
),
),
),
);
}
void expectBorder() {
expect(
tester.renderObject<RenderBox>(find.byType(Checkbox)),
paints
..drrect(
color: borderColor,
outer: RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(1)),
inner: RRect.fromLTRBR(19, 19, 29, 29, Radius.zero),
),
);
}
await tester.pumpWidget(buildApp(value: false));
await tester.pumpAndSettle();
expectBorder();
await tester.pumpWidget(buildApp(value: false, enabled: false));
await tester.pumpAndSettle();
expectBorder();
await tester.pumpWidget(buildApp(value: true));
await tester.pumpAndSettle();
expectBorder();
await tester.pumpWidget(buildApp());
await tester.pumpAndSettle();
expectBorder();
});
testWidgets('Material3 - Checkbox MaterialStateBorderSide applies unconditionally', (WidgetTester tester) async {
const Color borderColor = Color(0xfff44336); const Color borderColor = Color(0xfff44336);
const BorderSide side = BorderSide( const BorderSide side = BorderSide(
width: 4, width: 4,
color: borderColor, color: borderColor,
); );
final bool material3 = theme.useMaterial3; final ThemeData theme = ThemeData(useMaterial3: true);
Widget buildApp({ bool? value, bool enabled = true }) { Widget buildApp({ bool? value, bool enabled = true }) {
return MaterialApp( return MaterialApp(
...@@ -1546,7 +1886,7 @@ void main() { ...@@ -1546,7 +1886,7 @@ void main() {
paints paints
..drrect( ..drrect(
color: borderColor, color: borderColor,
outer: material3 ? RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(2)) : RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(1)), outer: RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(2)),
inner: RRect.fromLTRBR(19, 19, 29, 29, Radius.zero), inner: RRect.fromLTRBR(19, 19, 29, 29, Radius.zero),
), ),
); );
...@@ -1624,7 +1964,7 @@ void main() { ...@@ -1624,7 +1964,7 @@ void main() {
expect(find.text(tapTooltip), findsOneWidget); expect(find.text(tapTooltip), findsOneWidget);
}); });
testWidgets('Checkbox has default error color when isError is set to true - M3', (WidgetTester tester) async { testWidgets('Material3 - Checkbox has default error color when isError is set to true', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Checkbox'); final FocusNode focusNode = FocusNode(debugLabel: 'Checkbox');
final ThemeData themeData = ThemeData(useMaterial3: true); final ThemeData themeData = ThemeData(useMaterial3: true);
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
...@@ -1696,7 +2036,7 @@ void main() { ...@@ -1696,7 +2036,7 @@ void main() {
await tester.pump(); await tester.pump();
}); });
testWidgets('Checkbox MaterialStateBorderSide applies in error states - M3', (WidgetTester tester) async { testWidgets('Material3 - Checkbox MaterialStateBorderSide applies in error states', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Checkbox'); final FocusNode focusNode = FocusNode(debugLabel: 'Checkbox');
final ThemeData themeData = ThemeData(useMaterial3: true); final ThemeData themeData = ThemeData(useMaterial3: true);
const Color borderColor = Color(0xffffeb3b); const Color borderColor = Color(0xffffeb3b);
...@@ -1775,7 +2115,7 @@ void main() { ...@@ -1775,7 +2115,7 @@ void main() {
await tester.pump(); await tester.pump();
}); });
testWidgets('Checkbox has correct default shape - M3', (WidgetTester tester) async { testWidgets('Material3 - Checkbox has correct default shape', (WidgetTester tester) async {
final ThemeData themeData = ThemeData(useMaterial3: true); final ThemeData themeData = ThemeData(useMaterial3: true);
Widget buildApp() { Widget buildApp() {
...@@ -1841,7 +2181,8 @@ void main() { ...@@ -1841,7 +2181,8 @@ void main() {
} }
}); });
testWidgets('Checkbox respects fillColor when it is unchecked', (WidgetTester tester) async { testWidgets('Material2 - Checkbox respects fillColor when it is unchecked', (WidgetTester tester) async {
final ThemeData theme = ThemeData(useMaterial3: false);
const Color activeBackgroundColor = Color(0xff123456); const Color activeBackgroundColor = Color(0xff123456);
const Color inactiveBackgroundColor = Color(0xff654321); const Color inactiveBackgroundColor = Color(0xff654321);
...@@ -1870,14 +2211,66 @@ void main() { ...@@ -1870,14 +2211,66 @@ void main() {
} }
// Checkbox is unselected, so the default BorderSide appears and fillColor is checkbox's background color. // Checkbox is unselected, so the default BorderSide appears and fillColor is checkbox's background color.
await tester.pumpWidget(buildApp());
await tester.pumpAndSettle();
expect(
getCheckboxRenderer(),
paints
..drrect(
color: theme.unselectedWidgetColor,
),
);
expect(getCheckboxRenderer(), paints..path(color: inactiveBackgroundColor));
await tester.pumpWidget(buildApp(enabled: false));
await tester.pumpAndSettle();
expect(
getCheckboxRenderer(),
paints
..drrect(
color: theme.disabledColor,
),
);
expect(getCheckboxRenderer(), paints..path(color: inactiveBackgroundColor));
});
testWidgets('Material3 - Checkbox respects fillColor when it is unchecked', (WidgetTester tester) async {
final ThemeData theme = ThemeData(useMaterial3: true);
const Color activeBackgroundColor = Color(0xff123456);
const Color inactiveBackgroundColor = Color(0xff654321);
Widget buildApp({ bool enabled = true }) {
return MaterialApp(
theme: theme,
home: Material(
child: Center(
child: Checkbox(
fillColor: MaterialStateProperty.resolveWith((Set<MaterialState> states) {
if (states.contains(MaterialState.selected)) {
return activeBackgroundColor;
}
return inactiveBackgroundColor;
}),
value: false,
onChanged: enabled ? (bool? newValue) { } : null,
),
),
),
);
}
RenderBox getCheckboxRenderer() {
return tester.renderObject<RenderBox>(find.byType(Checkbox));
}
// Checkbox is unselected, so the default BorderSide appears and fillColor is checkbox's background color.
await tester.pumpWidget(buildApp()); await tester.pumpWidget(buildApp());
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect( expect(
getCheckboxRenderer(), getCheckboxRenderer(),
paints paints
..drrect( ..drrect(
color: theme.useMaterial3 ? theme.colorScheme.onSurfaceVariant : theme.unselectedWidgetColor, color: theme.colorScheme.onSurfaceVariant,
), ),
); );
expect(getCheckboxRenderer(), paints..path(color: inactiveBackgroundColor)); expect(getCheckboxRenderer(), paints..path(color: inactiveBackgroundColor));
...@@ -1888,7 +2281,7 @@ void main() { ...@@ -1888,7 +2281,7 @@ void main() {
getCheckboxRenderer(), getCheckboxRenderer(),
paints paints
..drrect( ..drrect(
color: theme.useMaterial3 ? theme.colorScheme.onSurface.withOpacity(0.38) : theme.disabledColor, color: theme.colorScheme.onSurface.withOpacity(0.38),
), ),
); );
expect(getCheckboxRenderer(), paints..path(color: inactiveBackgroundColor)); expect(getCheckboxRenderer(), paints..path(color: inactiveBackgroundColor));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment