Unverified Commit 1ed54f8e authored by Qun Cheng's avatar Qun Cheng Committed by GitHub

Update `Radio` tests for M2/M3 (#129814)

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

More info in https://github.com/flutter/flutter/issues/127064
parent 0bb9409f
...@@ -398,7 +398,7 @@ void main() { ...@@ -398,7 +398,7 @@ void main() {
tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null); tester.binding.defaultBinaryMessenger.setMockDecodedMessageHandler<dynamic>(SystemChannels.accessibility, null);
}); });
testWidgets('Radio ink ripple is displayed correctly - M2', (WidgetTester tester) async { testWidgets('Material2 - Radio ink ripple is displayed correctly', (WidgetTester tester) async {
final Key painterKey = UniqueKey(); final Key painterKey = UniqueKey();
const Key radioKey = Key('radio'); const Key radioKey = Key('radio');
...@@ -428,7 +428,41 @@ void main() { ...@@ -428,7 +428,41 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
await expectLater( await expectLater(
find.byKey(painterKey), find.byKey(painterKey),
matchesGoldenFile('radio.ink_ripple.png'), matchesGoldenFile('m2_radio.ink_ripple.png'),
);
});
testWidgets('Material3 - Radio ink ripple is displayed correctly', (WidgetTester tester) async {
final Key painterKey = UniqueKey();
const Key radioKey = Key('radio');
await tester.pumpWidget(MaterialApp(
theme: ThemeData(useMaterial3: true),
home: Scaffold(
body: RepaintBoundary(
key: painterKey,
child: Center(
child: Container(
width: 100,
height: 100,
color: Colors.white,
child: Radio<int>(
key: radioKey,
value: 1,
groupValue: 1,
onChanged: (int? value) { },
),
),
),
),
),
));
await tester.press(find.byKey(radioKey));
await tester.pumpAndSettle();
await expectLater(
find.byKey(painterKey),
matchesGoldenFile('m3_radio.ink_ripple.png'),
); );
}); });
...@@ -469,15 +503,14 @@ void main() { ...@@ -469,15 +503,14 @@ void main() {
); );
}); });
testWidgets('Radio is focusable and has correct focus color', (WidgetTester tester) async { testWidgets('Material2 - Radio is focusable and has correct focus color', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Radio'); final FocusNode focusNode = FocusNode(debugLabel: 'Radio');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
int? groupValue = 0; int? groupValue = 0;
const Key radioKey = Key('radio'); const Key radioKey = Key('radio');
final bool material3 = theme.useMaterial3;
Widget buildApp({bool enabled = true}) { Widget buildApp({bool enabled = true}) {
return MaterialApp( return MaterialApp(
theme: theme, theme: ThemeData(useMaterial3: false),
home: Material( home: Material(
child: Center( child: Center(
child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) { child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
...@@ -516,8 +549,8 @@ void main() { ...@@ -516,8 +549,8 @@ void main() {
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0), rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
) )
..circle(color: Colors.orange[500]) ..circle(color: Colors.orange[500])
..circle(color: material3 ? theme.colorScheme.primary : const Color(0xff2196f3)) ..circle(color: const Color(0xff2196f3))
..circle(color: material3 ? theme.colorScheme.primary : const Color(0xff2196f3)), ..circle(color: const Color(0xff2196f3)),
); );
// Check when the radio isn't selected. // Check when the radio isn't selected.
...@@ -527,15 +560,13 @@ void main() { ...@@ -527,15 +560,13 @@ void main() {
expect(focusNode.hasPrimaryFocus, isTrue); expect(focusNode.hasPrimaryFocus, isTrue);
expect( expect(
Material.of(tester.element(find.byKey(radioKey))), Material.of(tester.element(find.byKey(radioKey))),
theme.useMaterial3 paints
? (paints..rect()..circle(color: Colors.orange[500])..circle(color: theme.colorScheme.onSurface))
: (paints
..rect( ..rect(
color: const Color(0xffffffff), color: const Color(0xffffffff),
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0), rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
) )
..circle(color: Colors.orange[500]) ..circle(color: Colors.orange[500])
..circle(color: const Color(0x8a000000), style: PaintingStyle.stroke, strokeWidth: 2.0)), ..circle(color: const Color(0x8a000000), style: PaintingStyle.stroke, strokeWidth: 2.0),
); );
// Check when the radio is selected, but disabled. // Check when the radio is selected, but disabled.
...@@ -550,16 +581,177 @@ void main() { ...@@ -550,16 +581,177 @@ void main() {
color: const Color(0xffffffff), color: const Color(0xffffffff),
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0), rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
) )
..circle(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000)) ..circle(color: const Color(0x61000000))
..circle(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000)), ..circle(color: const Color(0x61000000)),
);
});
testWidgets('Material3 - Radio is focusable and has correct focus color', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Radio');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
int? groupValue = 0;
const Key radioKey = Key('radio');
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 Container(
width: 100,
height: 100,
color: Colors.white,
child: Radio<int>(
key: radioKey,
value: 0,
onChanged: enabled ? (int? newValue) {
setState(() {
groupValue = newValue;
});
} : null,
focusColor: Colors.orange[500],
autofocus: true,
focusNode: focusNode,
groupValue: groupValue,
),
);
}),
),
),
);
}
await tester.pumpWidget(buildApp());
await tester.pumpAndSettle();
expect(focusNode.hasPrimaryFocus, isTrue);
expect(
Material.of(tester.element(find.byKey(radioKey))),
paints
..rect(
color: const Color(0xffffffff),
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
)
..circle(color: Colors.orange[500])
..circle(color: theme.colorScheme.primary)
..circle(color: theme.colorScheme.primary),
);
// Check when the radio isn't selected.
groupValue = 1;
await tester.pumpWidget(buildApp());
await tester.pumpAndSettle();
expect(focusNode.hasPrimaryFocus, isTrue);
expect(
Material.of(tester.element(find.byKey(radioKey))),
paints..rect()..circle(color: Colors.orange[500])..circle(color: theme.colorScheme.onSurface),
);
// Check when the radio is selected, but disabled.
groupValue = 0;
await tester.pumpWidget(buildApp(enabled: false));
await tester.pumpAndSettle();
expect(focusNode.hasPrimaryFocus, isFalse);
expect(
Material.of(tester.element(find.byKey(radioKey))),
paints
..rect(
color: const Color(0xffffffff),
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
)
..circle(color: theme.colorScheme.onSurface.withOpacity(0.38))
..circle(color: theme.colorScheme.onSurface.withOpacity(0.38)),
);
});
testWidgets('Material2 - Radio can be hovered and has correct hover color', (WidgetTester tester) async {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
int? groupValue = 0;
const Key radioKey = Key('radio');
Widget buildApp({bool enabled = true}) {
return MaterialApp(
theme: ThemeData(useMaterial3: false),
home: Material(
child: Center(
child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
return Container(
width: 100,
height: 100,
color: Colors.white,
child: Radio<int>(
key: radioKey,
value: 0,
onChanged: enabled ? (int? newValue) {
setState(() {
groupValue = newValue;
});
} : null,
hoverColor: Colors.orange[500],
groupValue: groupValue,
),
);
}),
),
),
);
}
await tester.pumpWidget(buildApp());
await tester.pump();
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byKey(radioKey))),
paints
..rect(
color: const Color(0xffffffff),
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
)
..circle(color: const Color(0xff2196f3))
..circle(color: const Color(0xff2196f3)),
);
// Start hovering
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
await gesture.moveTo(tester.getCenter(find.byKey(radioKey)));
// Check when the radio isn't selected.
groupValue = 1;
await tester.pumpWidget(buildApp());
await tester.pump();
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byKey(radioKey))),
paints
..rect(
color: const Color(0xffffffff),
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
)
..circle(color: Colors.orange[500])
..circle(color: const Color(0x8a000000), style: PaintingStyle.stroke, strokeWidth: 2.0),
);
// Check when the radio is selected, but disabled.
groupValue = 0;
await tester.pumpWidget(buildApp(enabled: false));
await tester.pump();
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byKey(radioKey))),
paints
..rect(
color: const Color(0xffffffff),
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
)
..circle(color: const Color(0x61000000))
..circle(color: const Color(0x61000000)),
); );
}); });
testWidgets('Radio can be hovered and has correct hover color', (WidgetTester tester) async { testWidgets('Material3 - Radio can be hovered and has correct hover color', (WidgetTester tester) async {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
int? groupValue = 0; int? groupValue = 0;
const Key radioKey = Key('radio'); const Key radioKey = Key('radio');
final bool material3 = theme.useMaterial3; final ThemeData theme = ThemeData(useMaterial3: true);
Widget buildApp({bool enabled = true}) { Widget buildApp({bool enabled = true}) {
return MaterialApp( return MaterialApp(
theme: theme, theme: theme,
...@@ -598,8 +790,8 @@ void main() { ...@@ -598,8 +790,8 @@ void main() {
color: const Color(0xffffffff), color: const Color(0xffffffff),
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0), rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
) )
..circle(color: material3 ? theme.colorScheme.primary : const Color(0xff2196f3)) ..circle(color: theme.colorScheme.primary)
..circle(color: material3 ? theme.colorScheme.primary : const Color(0xff2196f3)), ..circle(color: theme.colorScheme.primary),
); );
// Start hovering // Start hovering
...@@ -619,7 +811,7 @@ void main() { ...@@ -619,7 +811,7 @@ void main() {
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0), rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
) )
..circle(color: Colors.orange[500]) ..circle(color: Colors.orange[500])
..circle(color: theme.useMaterial3 ? theme.colorScheme.onSurface : const Color(0x8a000000), style: PaintingStyle.stroke, strokeWidth: 2.0), ..circle(color: theme.colorScheme.onSurface, style: PaintingStyle.stroke, strokeWidth: 2.0),
); );
// Check when the radio is selected, but disabled. // Check when the radio is selected, but disabled.
...@@ -634,8 +826,8 @@ void main() { ...@@ -634,8 +826,8 @@ void main() {
color: const Color(0xffffffff), color: const Color(0xffffffff),
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0), rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
) )
..circle(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000)) ..circle(color: theme.colorScheme.onSurface.withOpacity(0.38))
..circle(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000)), ..circle(color: theme.colorScheme.onSurface.withOpacity(0.38)),
); );
}); });
...@@ -951,7 +1143,7 @@ void main() { ...@@ -951,7 +1143,7 @@ void main() {
); );
}); });
testWidgets('Radio fill color resolves in hovered/focused states', (WidgetTester tester) async { testWidgets('Material2 - Radio fill color resolves in hovered/focused states', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'radio'); final FocusNode focusNode = FocusNode(debugLabel: 'radio');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
const Color hoveredFillColor = Color(0xFF000001); const Color hoveredFillColor = Color(0xFF000001);
...@@ -967,11 +1159,11 @@ void main() { ...@@ -967,11 +1159,11 @@ void main() {
return Colors.transparent; return Colors.transparent;
} }
final MaterialStateProperty<Color> fillColor = final MaterialStateProperty<Color> fillColor = MaterialStateColor.resolveWith(getFillColor);
MaterialStateColor.resolveWith(getFillColor);
int? groupValue = 0; int? groupValue = 0;
const Key radioKey = Key('radio'); const Key radioKey = Key('radio');
final ThemeData theme = ThemeData(useMaterial3: false);
Widget buildApp() { Widget buildApp() {
return MaterialApp( return MaterialApp(
theme: theme, theme: theme,
...@@ -1007,15 +1199,13 @@ void main() { ...@@ -1007,15 +1199,13 @@ void main() {
expect(focusNode.hasPrimaryFocus, isTrue); expect(focusNode.hasPrimaryFocus, isTrue);
expect( expect(
Material.of(tester.element(find.byKey(radioKey))), Material.of(tester.element(find.byKey(radioKey))),
theme.useMaterial3 paints
? (paints..rect()..circle(color: theme.colorScheme.primary.withOpacity(0.12))..circle(color: focusedFillColor))
: (paints
..rect( ..rect(
color: const Color(0xffffffff), color: const Color(0xffffffff),
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0), rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
) )
..circle(color: Colors.black12) ..circle(color: Colors.black12)
..circle(color: focusedFillColor)), ..circle(color: focusedFillColor),
); );
// Start hovering // Start hovering
...@@ -1031,7 +1221,85 @@ void main() { ...@@ -1031,7 +1221,85 @@ void main() {
color: const Color(0xffffffff), color: const Color(0xffffffff),
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0), rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
) )
..circle(color: theme.useMaterial3 ? theme.colorScheme.primary.withOpacity(0.08) : theme.hoverColor) ..circle(color: theme.hoverColor)
..circle(color: hoveredFillColor),
);
});
testWidgets('Material3 - Radio fill color resolves in hovered/focused states', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'radio');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
const Color hoveredFillColor = Color(0xFF000001);
const Color focusedFillColor = Color(0xFF000002);
Color getFillColor(Set<MaterialState> states) {
if (states.contains(MaterialState.hovered)) {
return hoveredFillColor;
}
if (states.contains(MaterialState.focused)) {
return focusedFillColor;
}
return Colors.transparent;
}
final MaterialStateProperty<Color> fillColor =
MaterialStateColor.resolveWith(getFillColor);
int? groupValue = 0;
const Key radioKey = Key('radio');
final ThemeData theme = ThemeData(useMaterial3: true);
Widget buildApp() {
return MaterialApp(
theme: theme,
home: Material(
child: Center(
child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
return Container(
width: 100,
height: 100,
color: Colors.white,
child: Radio<int>(
autofocus: true,
focusNode: focusNode,
key: radioKey,
value: 0,
fillColor: fillColor,
onChanged: (int? newValue) {
setState(() {
groupValue = newValue;
});
},
groupValue: groupValue,
),
);
}),
),
),
);
}
await tester.pumpWidget(buildApp());
await tester.pumpAndSettle();
expect(focusNode.hasPrimaryFocus, isTrue);
expect(
Material.of(tester.element(find.byKey(radioKey))),
paints..rect()..circle(color: theme.colorScheme.primary.withOpacity(0.12))..circle(color: focusedFillColor),
);
// Start hovering
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
await gesture.addPointer();
await gesture.moveTo(tester.getCenter(find.byKey(radioKey)));
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byKey(radioKey))),
paints
..rect(
color: const Color(0xffffffff),
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
)
..circle(color: theme.colorScheme.primary.withOpacity(0.08))
..circle(color: hoveredFillColor), ..circle(color: hoveredFillColor),
); );
}); });
...@@ -1263,8 +1531,54 @@ void main() { ...@@ -1263,8 +1531,54 @@ void main() {
expect(find.text(tapTooltip), findsOneWidget); expect(find.text(tapTooltip), findsOneWidget);
}); });
testWidgets('Radio button default colors', (WidgetTester tester) async { testWidgets('Material2 - Radio button default colors', (WidgetTester tester) async {
final bool material3 = theme.useMaterial3; Widget buildRadio({bool enabled = true, bool selected = true}) {
return MaterialApp(
theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: Radio<bool>(
value: true,
groupValue: true,
onChanged: enabled ? (_) {} : null,
),
)
);
}
await tester.pumpWidget(buildRadio());
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
paints
..circle(color: const Color(0xFF2196F3)) // Outer circle - primary value
..circle(color: const Color(0xFF2196F3))..restore(), // Inner circle - primary value
);
await tester.pumpWidget(Container());
await tester.pumpWidget(buildRadio(selected: false));
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
paints
..save()
..circle(color: const Color(0xFF2196F3))
..restore(),
);
await tester.pumpWidget(Container());
await tester.pumpWidget(buildRadio(enabled: false));
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
paints..circle(color: Colors.black38)
);
});
testWidgets('Material3 - Radio button default colors', (WidgetTester tester) async {
final ThemeData theme = ThemeData(useMaterial3: true);
Widget buildRadio({bool enabled = true, bool selected = true}) { Widget buildRadio({bool enabled = true, bool selected = true}) {
return MaterialApp( return MaterialApp(
theme: theme, theme: theme,
...@@ -1284,8 +1598,8 @@ void main() { ...@@ -1284,8 +1598,8 @@ void main() {
expect( expect(
Material.of(tester.element(find.byType(Radio<bool>))), Material.of(tester.element(find.byType(Radio<bool>))),
paints paints
..circle(color: material3 ? theme.colorScheme.primary : const Color(0xFF2196F3)) // Outer circle - primary value ..circle(color: theme.colorScheme.primary) // Outer circle - primary value
..circle(color: material3 ? theme.colorScheme.primary : const Color(0xFF2196F3))..restore(), // Inner circle - primary value ..circle(color: theme.colorScheme.primary)..restore(), // Inner circle - primary value
); );
await tester.pumpWidget(Container()); await tester.pumpWidget(Container());
...@@ -1296,7 +1610,7 @@ void main() { ...@@ -1296,7 +1610,7 @@ void main() {
Material.of(tester.element(find.byType(Radio<bool>))), Material.of(tester.element(find.byType(Radio<bool>))),
paints paints
..save() ..save()
..circle(color: material3 ? theme.colorScheme.primary : const Color(0xFF2196F3)) ..circle(color: theme.colorScheme.primary)
..restore(), ..restore(),
); );
...@@ -1306,19 +1620,17 @@ void main() { ...@@ -1306,19 +1620,17 @@ void main() {
expect( expect(
Material.of(tester.element(find.byType(Radio<bool>))), Material.of(tester.element(find.byType(Radio<bool>))),
theme.useMaterial3 paints
? (paints ..circle(color: theme.colorScheme.onSurface.withOpacity(0.38))
..circle(color: theme.colorScheme.onSurface.withOpacity(0.38)))
: (paints..circle(color: Colors.black38))
); );
}); });
testWidgets('Radio button default overlay colors in hover/focus/press states', (WidgetTester tester) async { testWidgets('Material2 - Radio button default overlay colors in hover/focus/press states', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Radio'); final FocusNode focusNode = FocusNode(debugLabel: 'Radio');
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 buildRadio({bool enabled = true, bool focused = false, bool selected = true}) { Widget buildRadio({bool enabled = true, bool focused = false, bool selected = true}) {
return MaterialApp( return MaterialApp(
theme: theme, theme: theme,
...@@ -1339,9 +1651,7 @@ void main() { ...@@ -1339,9 +1651,7 @@ void main() {
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect( expect(
Material.of(tester.element(find.byType(Radio<bool>))), Material.of(tester.element(find.byType(Radio<bool>))),
material3 paints..circle(color: colors.secondary)
? (paints..circle(color: colors.primary.withOpacity(1)))
: (paints..circle(color: colors.secondary))
); );
// selected radio in pressed state // selected radio in pressed state
...@@ -1351,12 +1661,8 @@ void main() { ...@@ -1351,12 +1661,8 @@ void main() {
expect( expect(
Material.of(tester.element(find.byType(Radio<bool>))), Material.of(tester.element(find.byType(Radio<bool>))),
paints..circle(color: material3 paints..circle(color: colors.secondary.withAlpha(0x1F))
? colors.onSurface.withOpacity(0.12) ..circle(color: colors.secondary
: colors.secondary.withAlpha(0x1F))
..circle(color: material3
? colors.primary.withOpacity(1)
: colors.secondary
) )
); );
...@@ -1367,9 +1673,7 @@ void main() { ...@@ -1367,9 +1673,7 @@ void main() {
expect( expect(
Material.of(tester.element(find.byType(Radio<bool>))), Material.of(tester.element(find.byType(Radio<bool>))),
material3 paints..circle(color: theme.unselectedWidgetColor.withAlpha(0x1F))..circle(color: theme.unselectedWidgetColor)
? (paints..circle(color: colors.primary.withOpacity(0.12))..circle(color: colors.onSurfaceVariant.withOpacity(1)))
: (paints..circle(color: theme.unselectedWidgetColor.withAlpha(0x1F))..circle(color: theme.unselectedWidgetColor))
); );
// selected radio in focused state // selected radio in focused state
...@@ -1380,9 +1684,7 @@ void main() { ...@@ -1380,9 +1684,7 @@ void main() {
expect( expect(
Material.of(tester.element(find.byType(Radio<bool>))), Material.of(tester.element(find.byType(Radio<bool>))),
material3 paints..circle(color: theme.focusColor)..circle(color: colors.secondary)
? (paints..circle(color: colors.primary.withOpacity(0.12))..circle(color: colors.primary.withOpacity(1)))
: (paints..circle(color: theme.focusColor)..circle(color: colors.secondary))
); );
// unselected radio in focused state // unselected radio in focused state
...@@ -1393,9 +1695,7 @@ void main() { ...@@ -1393,9 +1695,7 @@ void main() {
expect( expect(
Material.of(tester.element(find.byType(Radio<bool>))), Material.of(tester.element(find.byType(Radio<bool>))),
material3 paints..circle(color: theme.focusColor)..circle(color: theme.unselectedWidgetColor)
? (paints..circle(color: colors.onSurface.withOpacity(0.12))..circle(color: colors.onSurface.withOpacity(1)))
: (paints..circle(color: theme.focusColor)..circle(color: theme.unselectedWidgetColor))
); );
// selected radio in hovered state // selected radio in hovered state
...@@ -1408,9 +1708,93 @@ void main() { ...@@ -1408,9 +1708,93 @@ void main() {
expect( expect(
Material.of(tester.element(find.byType(Radio<bool>))), Material.of(tester.element(find.byType(Radio<bool>))),
material3 paints..circle(color: theme.hoverColor)..circle(color: colors.secondary)
? (paints..circle(color: colors.primary.withOpacity(0.08))..circle(color: colors.primary.withOpacity(1))) );
: (paints..circle(color: theme.hoverColor)..circle(color: colors.secondary)) });
testWidgets('Material3 - Radio button default overlay colors in hover/focus/press states', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Radio');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
final ThemeData theme = ThemeData(useMaterial3: true);
final ColorScheme colors = theme.colorScheme;
Widget buildRadio({bool enabled = true, bool focused = false, bool selected = true}) {
return MaterialApp(
theme: theme,
home: Scaffold(
body: Radio<bool>(
focusNode: focusNode,
autofocus: focused,
value: true,
groupValue: selected,
onChanged: enabled ? (_) {} : null,
),
),
);
}
// default selected radio
await tester.pumpWidget(buildRadio());
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
paints..circle(color: colors.primary.withOpacity(1))
);
// selected radio in pressed state
await tester.pumpWidget(buildRadio());
await tester.startGesture(tester.getCenter(find.byType(Radio<bool>)));
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
paints..circle(color: colors.onSurface.withOpacity(0.12))
..circle(color: colors.primary.withOpacity(1))
);
// unselected radio in pressed state
await tester.pumpWidget(buildRadio(selected: false));
await tester.startGesture(tester.getCenter(find.byType(Radio<bool>)));
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
paints..circle(color: colors.primary.withOpacity(0.12))..circle(color: colors.onSurfaceVariant.withOpacity(1))
);
// selected radio in focused state
await tester.pumpWidget(Container()); // reset test
await tester.pumpWidget(buildRadio(focused: true));
await tester.pumpAndSettle();
expect(focusNode.hasPrimaryFocus, isTrue);
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
paints..circle(color: colors.primary.withOpacity(0.12))..circle(color: colors.primary.withOpacity(1))
);
// unselected radio in focused state
await tester.pumpWidget(Container()); // reset test
await tester.pumpWidget(buildRadio(focused: true, selected: false));
await tester.pumpAndSettle();
expect(focusNode.hasPrimaryFocus, isTrue);
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
paints..circle(color: colors.onSurface.withOpacity(0.12))..circle(color: colors.onSurface.withOpacity(1))
);
// selected radio in hovered state
await tester.pumpWidget(Container()); // reset test
await tester.pumpWidget(buildRadio());
final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
await gesture.addPointer();
await gesture.moveTo(tester.getCenter(find.byType(Radio<bool>)));
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
paints..circle(color: colors.primary.withOpacity(0.08))..circle(color: colors.primary.withOpacity(1))
); );
}); });
...@@ -1445,10 +1829,75 @@ void main() { ...@@ -1445,10 +1829,75 @@ void main() {
} }
}); });
testWidgets('Radio default overlayColor and fillColor resolves pressed state', (WidgetTester tester) async { testWidgets('Material2 - Radio default overlayColor and fillColor resolves pressed state', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Radio');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
final ThemeData theme = ThemeData(useMaterial3: false);
Finder findRadio() {
return find.byWidgetPredicate((Widget widget) => widget is Radio<bool>);
}
MaterialInkController? getRadioMaterial(WidgetTester tester) {
return Material.of(tester.element(findRadio()));
}
await tester.pumpWidget(MaterialApp(
theme: theme,
home: Scaffold(
body: Radio<bool>(
focusNode: focusNode,
value: true,
groupValue: true,
onChanged: (_) { },
),
),
));
// Hover
final Offset center = tester.getCenter(find.byType(Radio<bool>));
final TestGesture gesture = await tester.createGesture(
kind: PointerDeviceKind.mouse,
);
await gesture.addPointer();
await gesture.moveTo(center);
await tester.pumpAndSettle();
expect(getRadioMaterial(tester),
paints
..circle(color: theme.hoverColor)
..circle(color: theme.colorScheme.secondary)
);
// Highlighted (pressed).
await gesture.down(center);
await tester.pumpAndSettle();
expect(getRadioMaterial(tester),
paints
..circle(color: theme.colorScheme.secondary.withAlpha(kRadialReactionAlpha))
..circle(color: theme.colorScheme.secondary)
);
// Remove pressed and hovered states
await gesture.up();
await tester.pumpAndSettle();
await gesture.moveTo(const Offset(0, 50));
await tester.pumpAndSettle();
// Focused.
focusNode.requestFocus();
await tester.pumpAndSettle();
expect(getRadioMaterial(tester),
paints
..circle(color: theme.focusColor)
..circle(color: theme.colorScheme.secondary)
);
});
testWidgets('Material3 - Radio default overlayColor and fillColor resolves pressed state', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Radio'); final FocusNode focusNode = FocusNode(debugLabel: 'Radio');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional; tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
final bool material3 = theme.useMaterial3; final ThemeData theme = ThemeData(useMaterial3: true);
Finder findRadio() { Finder findRadio() {
return find.byWidgetPredicate((Widget widget) => widget is Radio<bool>); return find.byWidgetPredicate((Widget widget) => widget is Radio<bool>);
...@@ -1480,8 +1929,8 @@ void main() { ...@@ -1480,8 +1929,8 @@ void main() {
expect(getRadioMaterial(tester), expect(getRadioMaterial(tester),
paints paints
..circle(color: material3 ? theme.colorScheme.primary.withOpacity(0.08) : theme.hoverColor) ..circle(color: theme.colorScheme.primary.withOpacity(0.08))
..circle(color: material3 ? theme.colorScheme.primary : theme.colorScheme.secondary) ..circle(color: theme.colorScheme.primary)
); );
// Highlighted (pressed). // Highlighted (pressed).
...@@ -1490,8 +1939,8 @@ void main() { ...@@ -1490,8 +1939,8 @@ void main() {
expect(getRadioMaterial(tester), expect(getRadioMaterial(tester),
paints paints
..circle(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.12) : theme.colorScheme.secondary.withAlpha(kRadialReactionAlpha)) ..circle(color: theme.colorScheme.onSurface.withOpacity(0.12))
..circle(color: material3 ? theme.colorScheme.primary : theme.colorScheme.secondary) ..circle(color: theme.colorScheme.primary)
); );
// Remove pressed and hovered states // Remove pressed and hovered states
await gesture.up(); await gesture.up();
...@@ -1505,8 +1954,8 @@ void main() { ...@@ -1505,8 +1954,8 @@ void main() {
expect(getRadioMaterial(tester), expect(getRadioMaterial(tester),
paints paints
..circle(color: material3 ? theme.colorScheme.primary.withOpacity(0.12) : theme.focusColor) ..circle(color: theme.colorScheme.primary.withOpacity(0.12))
..circle(color: material3 ? theme.colorScheme.primary : theme.colorScheme.secondary) ..circle(color: theme.colorScheme.primary)
); );
}); });
} }
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