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

Update tests in material library for Material 3 by default (#128300)

parent ce248e87
......@@ -119,6 +119,7 @@ void main() {
testWidgets('ThemeData properties are used when no CardTheme is set', (WidgetTester tester) async {
final ThemeData themeData = _themeData();
final bool material3 = themeData.useMaterial3;
await tester.pumpWidget(MaterialApp(
theme: themeData,
......@@ -128,7 +129,7 @@ void main() {
));
final Material material = _getCardMaterial(tester);
expect(material.color, themeData.cardColor);
expect(material.color, material3 ? themeData.colorScheme.surface: themeData.cardColor);
});
testWidgets('CardTheme customizes shape', (WidgetTester tester) async {
......
......@@ -474,14 +474,16 @@ void main() {
});
testWidgets('Checkbox color rendering', (WidgetTester tester) async {
final ThemeData theme = ThemeData();
const Color borderColor = Color(0xff2196f3);
const Color m3BorderColor = Color(0xFF6750A4);
Color checkColor = const Color(0xffFFFFFF);
Color activeColor;
Widget buildFrame({Color? activeColor, Color? checkColor, ThemeData? themeData}) {
return Material(
child: Theme(
data: themeData ?? ThemeData(),
data: themeData ?? theme,
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Checkbox(
......@@ -502,13 +504,13 @@ void main() {
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)
expect(getCheckboxRenderer(), paints..path(color: theme.useMaterial3 ? m3BorderColor : 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)
expect(getCheckboxRenderer(), paints..path(color: theme.useMaterial3 ? m3BorderColor : borderColor)..path(color: checkColor)); // paints's color is 0xFF000000 (params)
activeColor = const Color(0xFF00FF00);
......@@ -520,7 +522,7 @@ void main() {
themeData = themeData.copyWith(colorScheme: colorScheme);
await tester.pumpWidget(buildFrame(
themeData: themeData),
);
);
await tester.pumpAndSettle();
expect(getCheckboxRenderer(), paints..path(color: activeColor)); // paints's color is 0xFF00FF00 (theme)
......@@ -567,7 +569,7 @@ void main() {
material3
? (paints
..circle(color: Colors.orange[500])
..path(color: const Color(0xff2196f3))
..path(color: theme.colorScheme.primary)
..path(color: theme.colorScheme.onPrimary))
: (paints
..circle(color: Colors.orange[500])
......@@ -586,7 +588,7 @@ void main() {
..circle(color: Colors.orange[500])
..drrect(
color: material3 ? theme.colorScheme.onSurface : const Color(0x8a000000),
outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(1.0)),
outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, material3 ? const Radius.circular(2.0) : const Radius.circular(1.0)),
inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero),
),
);
......@@ -601,7 +603,7 @@ void main() {
paints
..drrect(
color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000),
outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, const Radius.circular(1.0)),
outer: RRect.fromLTRBR(15.0, 15.0, 33.0, 33.0, material3 ? const Radius.circular(2.0) : const Radius.circular(1.0)),
inner: RRect.fromLTRBR(17.0, 17.0, 31.0, 31.0, Radius.zero),
),
);
......@@ -697,7 +699,7 @@ void main() {
expect(
Material.of(tester.element(find.byType(Checkbox))),
paints
..path(color: const Color(0xff2196f3))
..path(color: material3 ? const Color(0xff6750a4) : const Color(0xff2196f3))
..path(color: material3 ? theme.colorScheme.onPrimary : const Color(0xffffffff), style: PaintingStyle.stroke, strokeWidth: 2.0),
);
......@@ -710,7 +712,7 @@ void main() {
expect(
Material.of(tester.element(find.byType(Checkbox))),
paints
..path(color: const Color(0xff2196f3))
..path(color: material3 ? const Color(0xff6750a4) : const Color(0xff2196f3))
..path(color: material3 ? theme.colorScheme.onPrimary : const Color(0xffffffff), style: PaintingStyle.stroke, strokeWidth: 2.0),
);
......@@ -1450,7 +1452,7 @@ void main() {
await gesture.up();
});
testWidgets('Checkbox BorderSide side only applies when unselected', (WidgetTester tester) async {
testWidgets('Checkbox BorderSide side only applies when unselected in M2', (WidgetTester tester) async {
const Color borderColor = Color(0xfff44336);
const Color activeColor = Color(0xff123456);
const BorderSide side = BorderSide(
......@@ -1460,7 +1462,7 @@ void main() {
Widget buildApp({ bool? value, bool enabled = true }) {
return MaterialApp(
theme: theme,
theme: ThemeData(useMaterial3: false),
home: Material(
child: Center(
child: Checkbox(
......@@ -1520,6 +1522,7 @@ void main() {
width: 4,
color: borderColor,
);
final bool material3 = theme.useMaterial3;
Widget buildApp({ bool? value, bool enabled = true }) {
return MaterialApp(
......@@ -1543,7 +1546,7 @@ void main() {
paints
..drrect(
color: borderColor,
outer: RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(1)),
outer: material3 ? RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(2)) : RRect.fromLTRBR(15, 15, 33, 33, const Radius.circular(1)),
inner: RRect.fromLTRBR(19, 19, 29, 29, Radius.zero),
),
);
......
......@@ -60,9 +60,11 @@ void main() {
testWidgets('Default values are used when no Drawer or DrawerThemeData properties are specified', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
final bool useMaterial3 = ThemeData().useMaterial3;
final ThemeData theme = ThemeData();
final bool useMaterial3 = theme.useMaterial3;
await tester.pumpWidget(
MaterialApp(
theme: theme,
home: Scaffold(
key: scaffoldKey,
drawer: const Drawer(),
......@@ -72,10 +74,10 @@ void main() {
scaffoldKey.currentState!.openDrawer();
await tester.pumpAndSettle();
expect(_drawerMaterial(tester).color, null);
expect(_drawerMaterial(tester).elevation, 16.0);
expect(_drawerMaterial(tester).color, useMaterial3 ? theme.colorScheme.surface : null);
expect(_drawerMaterial(tester).elevation, useMaterial3 ? 1.0 : 16.0);
expect(_drawerMaterial(tester).shadowColor, useMaterial3 ? Colors.transparent : ThemeData().shadowColor);
expect(_drawerMaterial(tester).surfaceTintColor, useMaterial3 ? ThemeData().colorScheme.surfaceTint : null);
expect(_drawerMaterial(tester).surfaceTintColor, useMaterial3 ? theme.colorScheme.surfaceTint : null);
expect(
_drawerMaterial(tester).shape,
useMaterial3
......@@ -88,9 +90,11 @@ void main() {
testWidgets('Default values are used when no Drawer or DrawerThemeData properties are specified in end drawer', (WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
final bool useMaterial3 = ThemeData().useMaterial3;
final ThemeData theme = ThemeData();
final bool useMaterial3 = theme.useMaterial3;
await tester.pumpWidget(
MaterialApp(
theme: theme,
home: Scaffold(
key: scaffoldKey,
endDrawer: const Drawer(),
......@@ -100,8 +104,8 @@ void main() {
scaffoldKey.currentState!.openEndDrawer();
await tester.pumpAndSettle();
expect(_drawerMaterial(tester).color, null);
expect(_drawerMaterial(tester).elevation, 16.0);
expect(_drawerMaterial(tester).color, useMaterial3 ? theme.colorScheme.surface : null);
expect(_drawerMaterial(tester).elevation, useMaterial3 ? 1.0 : 16.0);
expect(_drawerMaterial(tester).shadowColor, useMaterial3 ? Colors.transparent : ThemeData().shadowColor);
expect(_drawerMaterial(tester).surfaceTintColor, useMaterial3 ? ThemeData().colorScheme.surfaceTint : null);
expect(
......
......@@ -113,6 +113,7 @@ void main() {
(WidgetTester tester) async {
final ThemeData themeData = ThemeData();
final bool useMaterial3 = themeData.useMaterial3;
await tester.pumpWidget(
MaterialApp(
theme: themeData,
......@@ -128,7 +129,7 @@ void main() {
final Finder textField = find.byType(TextField);
final Size anchorSize = tester.getSize(textField);
expect(anchorSize, const Size(180.0, 56.0));
expect(anchorSize, useMaterial3 ? const Size(195.0, 60.0) : const Size(180.0, 56.0));
await tester.tap(find.byType(DropdownMenu<TestMenu>));
await tester.pumpAndSettle();
......@@ -138,7 +139,7 @@ void main() {
matching: find.byType(Material),
);
final Size menuSize = tester.getSize(menuMaterial);
expect(menuSize, const Size(180.0, 304.0));
expect(menuSize, useMaterial3 ? const Size(195.0, 304.0) : const Size(180.0, 304.0));
// The text field should have same width as the menu
// when the width property is not null.
......@@ -146,7 +147,7 @@ void main() {
final Finder anchor = find.byType(TextField);
final Size size = tester.getSize(anchor);
expect(size, const Size(200.0, 56.0));
expect(size, useMaterial3 ? const Size(200.0, 60.0) : const Size(200.0, 56.0));
await tester.tap(anchor);
await tester.pumpAndSettle();
......@@ -218,6 +219,7 @@ void main() {
testWidgets('The menuHeight property can be used to show a shorter scrollable menu list instead of the complete list',
(WidgetTester tester) async {
final ThemeData themeData = ThemeData();
final bool material3 = themeData.useMaterial3;
await tester.pumpWidget(buildTest(themeData, menuChildren));
await tester.tap(find.byType(DropdownMenu<TestMenu>));
......@@ -237,7 +239,7 @@ void main() {
matching: find.byType(Padding),
).first;
final Size menuViewSize = tester.getSize(menuView);
expect(menuViewSize, const Size(180.0, 304.0)); // 304 = 288 + vertical padding(2 * 8)
expect(menuViewSize, material3 ? const Size(195.0, 304.0) : const Size(180.0, 304.0)); // 304 = 288 + vertical padding(2 * 8)
// Constrains the menu height.
await tester.pumpWidget(Container());
......@@ -253,7 +255,7 @@ void main() {
).first;
final Size updatedMenuSize = tester.getSize(updatedMenu);
expect(updatedMenuSize, const Size(180.0, 100.0));
expect(updatedMenuSize, material3 ? const Size(195.0, 100.0) : const Size(180.0, 100.0));
});
testWidgets('The text in the menu button should be aligned with the text of '
......
......@@ -246,8 +246,8 @@ void main() {
);
});
testWidgets('NavigationBar uses proper defaults when no parameters are given', (WidgetTester tester) async {
// Pre-M3 settings that were hand coded.
testWidgets('NavigationBar uses proper defaults when no parameters are given - M2', (WidgetTester tester) async {
// M2 settings that were hand coded.
await tester.pumpWidget(
_buildWidget(
NavigationBar(
......@@ -263,6 +263,7 @@ void main() {
],
onDestinationSelected: (int i) {},
),
useMaterial3: false,
),
);
......@@ -272,13 +273,14 @@ void main() {
expect(tester.getSize(find.byType(NavigationBar)).height, 80);
expect(_getIndicatorDecoration(tester)?.color, const Color(0x3d2196f3));
expect(_getIndicatorDecoration(tester)?.shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)));
});
testWidgets('NavigationBar uses proper defaults when no parameters are given - M3', (WidgetTester tester) async {
// M3 settings from the token database.
final ThemeData theme = ThemeData(useMaterial3: true);
await tester.pumpWidget(
_buildWidget(
Theme(
data: ThemeData.light().copyWith(useMaterial3: true),
child: NavigationBar(
NavigationBar(
destinations: const <Widget>[
NavigationDestination(
icon: Icon(Icons.ac_unit),
......@@ -291,15 +293,15 @@ void main() {
],
onDestinationSelected: (int i) {},
),
),
useMaterial3: theme.useMaterial3
),
);
expect(_getMaterial(tester).color, ThemeData().colorScheme.surface);
expect(_getMaterial(tester).surfaceTintColor, ThemeData().colorScheme.surfaceTint);
expect(_getMaterial(tester).color, theme.colorScheme.surface);
expect(_getMaterial(tester).surfaceTintColor, theme.colorScheme.surfaceTint);
expect(_getMaterial(tester).elevation, 3);
expect(tester.getSize(find.byType(NavigationBar)).height, 80);
expect(_getIndicatorDecoration(tester)?.color, const Color(0xff2196f3));
expect(_getIndicatorDecoration(tester)?.color, theme.colorScheme.secondaryContainer);
expect(_getIndicatorDecoration(tester)?.shape, const StadiumBorder());
});
......@@ -315,9 +317,9 @@ void main() {
DefaultMaterialLocalizations.delegate,
DefaultWidgetsLocalizations.delegate,
],
child: Directionality(
textDirection: TextDirection.ltr,
child: Navigator(
child: MaterialApp(
theme: ThemeData(useMaterial3: false),
home: Navigator(
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute<void>(
builder: (BuildContext context) {
......@@ -1269,9 +1271,9 @@ void main() {
});
}
Widget _buildWidget(Widget child) {
Widget _buildWidget(Widget child, { bool? useMaterial3 }) {
return MaterialApp(
theme: ThemeData.light(),
theme: ThemeData(useMaterial3: useMaterial3),
home: Scaffold(
bottomNavigationBar: Center(
child: child,
......
......@@ -115,40 +115,37 @@ void main() {
});
testWidgets(
'NavigationDrawer uses proper defaults when no parameters are given',
'M3 NavigationDrawer uses proper defaults when no parameters are given',
(WidgetTester tester) async {
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
final ThemeData theme= ThemeData.from(colorScheme: const ColorScheme.light());
// M3 settings from the token database.
final ThemeData theme = ThemeData(useMaterial3: true);
await tester.pumpWidget(
_buildWidget(
scaffoldKey,
Theme(
data: ThemeData.light().copyWith(useMaterial3: true),
child: NavigationDrawer(
children: <Widget>[
Text('Headline', style: theme.textTheme.bodyLarge),
NavigationDrawerDestination(
icon: Icon(Icons.ac_unit, color: theme.iconTheme.color),
label: Text('AC', style: theme.textTheme.bodySmall),
),
NavigationDrawerDestination(
icon: Icon(Icons.access_alarm, color: theme.iconTheme.color),
label: Text('Alarm', style: theme.textTheme.bodySmall),
),
],
onDestinationSelected: (int i) {},
),
NavigationDrawer(
children: <Widget>[
Text('Headline', style: theme.textTheme.bodyLarge),
NavigationDrawerDestination(
icon: Icon(Icons.ac_unit, color: theme.iconTheme.color),
label: Text('AC', style: theme.textTheme.bodySmall),
),
NavigationDrawerDestination(
icon: Icon(Icons.access_alarm, color: theme.iconTheme.color),
label: Text('Alarm', style: theme.textTheme.bodySmall),
),
],
onDestinationSelected: (int i) {},
),
useMaterial3: theme.useMaterial3,
),
);
scaffoldKey.currentState!.openDrawer();
await tester.pump(const Duration(seconds: 1));
expect(_getMaterial(tester).color, ThemeData().colorScheme.surface);
expect(_getMaterial(tester).surfaceTintColor, ThemeData().colorScheme.surfaceTint);
expect(_getMaterial(tester).color, theme.colorScheme.surface);
expect(_getMaterial(tester).surfaceTintColor, theme.colorScheme.surfaceTint);
expect(_getMaterial(tester).elevation, 1);
expect(_getIndicatorDecoration(tester)?.color, const Color(0xff2196f3));
expect(_getIndicatorDecoration(tester)?.color, theme.colorScheme.secondaryContainer);
expect(_getIndicatorDecoration(tester)?.shape, const StadiumBorder());
});
......@@ -385,9 +382,9 @@ void main() {
});
}
Widget _buildWidget(GlobalKey<ScaffoldState> scaffoldKey, Widget child) {
Widget _buildWidget(GlobalKey<ScaffoldState> scaffoldKey, Widget child, { bool? useMaterial3 }) {
return MaterialApp(
theme: ThemeData.light(),
theme: ThemeData(useMaterial3: useMaterial3),
home: Scaffold(
key: scaffoldKey,
drawer: child,
......
......@@ -13,10 +13,11 @@ void main() {
});
testWidgets('Default values are used when no NavigationRail or NavigationRailThemeData properties are specified', (WidgetTester tester) async {
final ThemeData theme = ThemeData.light(useMaterial3: true);
// Material 3 defaults
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.light().copyWith(useMaterial3: true),
theme: theme,
home: Scaffold(
body: NavigationRail(
selectedIndex: 0,
......@@ -26,21 +27,21 @@ void main() {
),
);
expect(_railMaterial(tester).color, ThemeData().colorScheme.surface);
expect(_railMaterial(tester).color, theme.colorScheme.surface);
expect(_railMaterial(tester).elevation, 0);
expect(_destinationSize(tester).width, 80.0);
expect(_selectedIconTheme(tester).size, 24.0);
expect(_selectedIconTheme(tester).color, ThemeData().colorScheme.onSecondaryContainer);
expect(_selectedIconTheme(tester).color, theme.colorScheme.onSecondaryContainer);
expect(_selectedIconTheme(tester).opacity, null);
expect(_unselectedIconTheme(tester).size, 24.0);
expect(_unselectedIconTheme(tester).color, ThemeData().colorScheme.onSurface);
expect(_unselectedIconTheme(tester).color, theme.colorScheme.onSurfaceVariant);
expect(_unselectedIconTheme(tester).opacity, null);
expect(_selectedLabelStyle(tester).fontSize, 14.0);
expect(_unselectedLabelStyle(tester).fontSize, 14.0);
expect(_destinationsAlign(tester).alignment, Alignment.topCenter);
expect(_labelType(tester), NavigationRailLabelType.none);
expect(find.byType(NavigationIndicator), findsWidgets);
expect(_indicatorDecoration(tester)?.color, ThemeData().colorScheme.secondaryContainer);
expect(_indicatorDecoration(tester)?.color, theme.colorScheme.secondaryContainer);
expect(_indicatorDecoration(tester)?.shape, const StadiumBorder());
final InkResponse inkResponse = tester.allWidgets.firstWhere((Widget object) => object.runtimeType.toString() == '_IndicatorInkWell') as InkResponse;
expect(inkResponse.customBorder, const StadiumBorder());
......
......@@ -1016,20 +1016,25 @@ void main() {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
int? groupValue = 0;
final Color? hoverColor = Colors.orange[500];
final ThemeData theme = ThemeData();
final bool material3 = theme.useMaterial3;
Widget buildApp({bool enabled = true}) {
return wrap(
child: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
return RadioListTile<int>(
value: 0,
onChanged: enabled ? (int? newValue) {
setState(() {
groupValue = newValue;
});
} : null,
hoverColor: hoverColor,
groupValue: groupValue,
);
}),
child: MaterialApp(
theme: theme,
home: StatefulBuilder(builder: (BuildContext context, StateSetter setState) {
return RadioListTile<int>(
value: 0,
onChanged: enabled ? (int? newValue) {
setState(() {
groupValue = newValue;
});
} : null,
hoverColor: hoverColor,
groupValue: groupValue,
);
}),
),
);
}
await tester.pumpWidget(buildApp());
......@@ -1040,8 +1045,8 @@ void main() {
Material.of(tester.element(find.byType(Radio<int>))),
paints
..rect()
..circle(color: const Color(0xff2196f3))
..circle(color: const Color(0xff2196f3)),
..circle(color: material3 ? theme.colorScheme.primary : const Color(0xff2196f3))
..circle(color: material3 ? theme.colorScheme.primary : const Color(0xff2196f3)),
);
// Start hovering
......@@ -1069,8 +1074,8 @@ void main() {
Material.of(tester.element(find.byType(Radio<int>))),
paints
..rect()
..circle(color: const Color(0x61000000))
..circle(color: const Color(0x61000000)),
..circle(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000))
..circle(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000)),
);
});
......@@ -1096,15 +1101,20 @@ void main() {
return null;
}
final ThemeData theme = ThemeData();
final bool material3 = theme.useMaterial3;
Widget buildRadio({bool active = false, bool useOverlay = true}) {
return wrap(
child: RadioListTile<bool>(
value: active,
groupValue: true,
onChanged: (_) { },
fillColor: const MaterialStatePropertyAll<Color>(fillColor),
overlayColor: useOverlay ? MaterialStateProperty.resolveWith(getOverlayColor) : null,
hoverColor: hoverColor,
child: MaterialApp(
theme: theme,
home: RadioListTile<bool>(
value: active,
groupValue: true,
onChanged: (_) { },
fillColor: const MaterialStatePropertyAll<Color>(fillColor),
overlayColor: useOverlay ? MaterialStateProperty.resolveWith(getOverlayColor) : null,
hoverColor: hoverColor,
),
),
);
}
......@@ -1115,11 +1125,13 @@ void main() {
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
paints..circle()
..circle(
color: fillColor.withAlpha(kRadialReactionAlpha),
radius: 20,
),
material3 ? (paints..circle(
color: fillColor.withAlpha(kRadialReactionAlpha),
radius: 20,
)) : (paints..circle()..circle(
color: fillColor.withAlpha(kRadialReactionAlpha),
radius: 20,
)),
reason: 'Default inactive pressed Radio should have overlay color from fillColor',
);
......@@ -1129,11 +1141,13 @@ void main() {
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
paints..circle()
..circle(
color: fillColor.withAlpha(kRadialReactionAlpha),
radius: 20,
),
material3 ? (paints..circle(
color: fillColor.withAlpha(kRadialReactionAlpha),
radius: 20,
)) : (paints..circle()..circle(
color: fillColor.withAlpha(kRadialReactionAlpha),
radius: 20,
)),
reason: 'Default active pressed Radio should have overlay color from fillColor',
);
......@@ -1143,11 +1157,13 @@ void main() {
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
paints..circle()
..circle(
color: inactivePressedOverlayColor,
radius: 20,
),
material3 ? (paints..circle(
color: inactivePressedOverlayColor,
radius: 20,
)) : (paints..circle()..circle(
color: inactivePressedOverlayColor,
radius: 20,
)),
reason: 'Inactive pressed Radio should have overlay color: $inactivePressedOverlayColor',
);
......@@ -1157,11 +1173,13 @@ void main() {
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
paints..circle()
..circle(
color: activePressedOverlayColor,
radius: 20,
),
material3 ? (paints..circle(
color: activePressedOverlayColor,
radius: 20,
)) : (paints..circle()..circle(
color: activePressedOverlayColor,
radius: 20,
)),
reason: 'Active pressed Radio should have overlay color: $activePressedOverlayColor',
);
......@@ -1177,11 +1195,13 @@ void main() {
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
paints
..circle(
color: hoverOverlayColor,
radius: 20,
),
material3 ? (paints..circle(
color: hoverOverlayColor,
radius: 20,
)) : (paints..circle(
color: hoverOverlayColor,
radius: 20,
)),
reason: 'Hovered Radio should use overlay color $hoverOverlayColor over $hoverColor',
);
});
......
......@@ -474,6 +474,7 @@ void main() {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
int? groupValue = 0;
const Key radioKey = Key('radio');
final bool material3 = theme.useMaterial3;
Widget buildApp({bool enabled = true}) {
return MaterialApp(
theme: theme,
......@@ -511,12 +512,12 @@ void main() {
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),
)
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(0xff2196f3))
..circle(color: const Color(0xff2196f3)),
..circle(color: material3 ? theme.colorScheme.primary : const Color(0xff2196f3))
..circle(color: material3 ? theme.colorScheme.primary : const Color(0xff2196f3)),
);
// Check when the radio isn't selected.
......@@ -549,8 +550,8 @@ void main() {
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)),
..circle(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000))
..circle(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000)),
);
});
......@@ -558,6 +559,7 @@ void main() {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
int? groupValue = 0;
const Key radioKey = Key('radio');
final bool material3 = theme.useMaterial3;
Widget buildApp({bool enabled = true}) {
return MaterialApp(
theme: theme,
......@@ -596,8 +598,8 @@ void main() {
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)),
..circle(color: material3 ? theme.colorScheme.primary : const Color(0xff2196f3))
..circle(color: material3 ? theme.colorScheme.primary : const Color(0xff2196f3)),
);
// Start hovering
......@@ -632,8 +634,8 @@ void main() {
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)),
..circle(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000))
..circle(color: material3 ? theme.colorScheme.onSurface.withOpacity(0.38) : const Color(0x61000000)),
);
});
......@@ -1262,6 +1264,7 @@ void main() {
});
testWidgets('Radio button default colors', (WidgetTester tester) async {
final bool material3 = theme.useMaterial3;
Widget buildRadio({bool enabled = true, bool selected = true}) {
return MaterialApp(
theme: theme,
......@@ -1281,8 +1284,8 @@ void main() {
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
paints
..circle(color: const Color(0xFF2196F3)) // Outer circle - blue primary value
..circle(color: const Color(0xFF2196F3))..restore(), // Inner circle - blue primary value
..circle(color: material3 ? theme.colorScheme.primary : const Color(0xFF2196F3)) // Outer circle - primary value
..circle(color: material3 ? theme.colorScheme.primary : const Color(0xFF2196F3))..restore(), // Inner circle - primary value
);
await tester.pumpWidget(Container());
......@@ -1293,7 +1296,7 @@ void main() {
Material.of(tester.element(find.byType(Radio<bool>))),
paints
..save()
..circle(color: const Color(0xFF2196F3))
..circle(color: material3 ? theme.colorScheme.primary : const Color(0xFF2196F3))
..restore(),
);
......@@ -1365,7 +1368,7 @@ void main() {
expect(
Material.of(tester.element(find.byType(Radio<bool>))),
material3
? (paints..circle(color: colors.primary.withOpacity(0.12))..circle(color: colors.onSurface.withOpacity(1)))
? (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))
);
......
......@@ -98,7 +98,10 @@ void main() {
testWidgets('Passing no SnackBarThemeData returns defaults', (WidgetTester tester) async {
const String text = 'I am a snack bar.';
final ThemeData theme = ThemeData();
final bool material3 = theme.useMaterial3;
await tester.pumpWidget(MaterialApp(
theme: theme,
home: Scaffold(
body: Builder(
builder: (BuildContext context) {
......@@ -123,8 +126,10 @@ void main() {
final Material material = _getSnackBarMaterial(tester);
final RenderParagraph content = _getSnackBarTextRenderObject(tester, text);
expect(content.text.style, Typography.material2018().white.titleMedium);
expect(material.color, const Color(0xFF333333));
expect(content.text.style, material3
? Typography.material2021().englishLike.bodyMedium?.merge(Typography.material2021().black.bodyMedium).copyWith(color: theme.colorScheme.onInverseSurface, decorationColor: theme.colorScheme.onSurface)
: Typography.material2018().white.titleMedium);
expect(material.color, material3 ? theme.colorScheme.inverseSurface : const Color(0xFF333333));
expect(material.elevation, 6.0);
expect(material.shape, null);
});
......
......@@ -217,9 +217,12 @@ void main() {
testWidgets('Stepper button test', (WidgetTester tester) async {
bool continuePressed = false;
bool cancelPressed = false;
final ThemeData theme = ThemeData();
final bool material3 = theme.useMaterial3;
await tester.pumpWidget(
MaterialApp(
theme: theme,
home: Material(
child: Stepper(
type: StepperType.horizontal,
......@@ -250,8 +253,8 @@ void main() {
),
);
await tester.tap(find.text('CONTINUE'));
await tester.tap(find.text('CANCEL'));
await tester.tap(find.text(material3 ? 'Continue' : 'CONTINUE'));
await tester.tap(find.text(material3 ? 'Cancel' : 'CANCEL'));
expect(continuePressed, isTrue);
expect(cancelPressed, isTrue);
......@@ -857,33 +860,39 @@ testWidgets('Stepper custom indexed controls test', (WidgetTester tester) async
}
const OutlinedBorder buttonShape = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2)));
const Rect continueButtonRect = Rect.fromLTRB(24.0, 212.0, 168.0, 260.0);
const Rect cancelButtonRect = Rect.fromLTRB(176.0, 212.0, 292.0, 260.0);
await tester.pumpWidget(buildFrame(ThemeData.light()));
expect(buttonMaterial('CONTINUE').color!.value, 0xff2196f3);
expect(buttonMaterial('CONTINUE').textStyle!.color!.value, 0xffffffff);
expect(buttonMaterial('CONTINUE').shape, buttonShape);
expect(tester.getRect(find.widgetWithText(TextButton, 'CONTINUE')), continueButtonRect);
expect(buttonMaterial('CANCEL').color!.value, 0);
expect(buttonMaterial('CANCEL').textStyle!.color!.value, 0x8a000000);
expect(buttonMaterial('CANCEL').shape, buttonShape);
expect(tester.getRect(find.widgetWithText(TextButton, 'CANCEL')), cancelButtonRect);
await tester.pumpWidget(buildFrame(ThemeData.dark()));
final ThemeData themeLight = ThemeData.light();
final bool material3Light = themeLight.useMaterial3;
await tester.pumpWidget(buildFrame(themeLight));
final String continueStr = material3Light ? 'Continue' : 'CONTINUE';
final String cancelStr = material3Light ? 'Cancel' : 'CANCEL';
final Rect continueButtonRect = material3Light ? const Rect.fromLTRB(24.0, 212.0, 169.0, 260.0) : const Rect.fromLTRB(24.0, 212.0, 168.0, 260.0);
final Rect cancelButtonRect = material3Light ? const Rect.fromLTRB(177.0, 212.0, 294.0, 260.0) : const Rect.fromLTRB(176.0, 212.0, 292.0, 260.0);
expect(buttonMaterial(continueStr).color!.value, material3Light ? themeLight.colorScheme.primary.value : 0xff2196f3);
expect(buttonMaterial(continueStr).textStyle!.color!.value, 0xffffffff);
expect(buttonMaterial(continueStr).shape, buttonShape);
expect(tester.getRect(find.widgetWithText(TextButton, continueStr)), continueButtonRect);
expect(buttonMaterial(cancelStr).color!.value, 0);
expect(buttonMaterial(cancelStr).textStyle!.color!.value, 0x8a000000);
expect(buttonMaterial(cancelStr).shape, buttonShape);
expect(tester.getRect(find.widgetWithText(TextButton, cancelStr)), cancelButtonRect);
final ThemeData themeDark = ThemeData.dark();
final bool material3Dark = themeDark.useMaterial3;
await tester.pumpWidget(buildFrame(themeDark));
await tester.pumpAndSettle(); // Complete the theme animation.
expect(buttonMaterial('CONTINUE').color!.value, 0);
expect(buttonMaterial('CONTINUE').textStyle!.color!.value, 0xffffffff);
expect(buttonMaterial('CONTINUE').shape, buttonShape);
expect(tester.getRect(find.widgetWithText(TextButton, 'CONTINUE')), continueButtonRect);
expect(buttonMaterial(continueStr).color!.value, 0);
expect(buttonMaterial(continueStr).textStyle!.color!.value, material3Dark ? themeDark.colorScheme.onSurface.value : 0xffffffff);
expect(buttonMaterial(continueStr).shape, buttonShape);
expect(tester.getRect(find.widgetWithText(TextButton, continueStr)), continueButtonRect);
expect(buttonMaterial('CANCEL').color!.value, 0);
expect(buttonMaterial('CANCEL').textStyle!.color!.value, 0xb3ffffff);
expect(buttonMaterial('CANCEL').shape, buttonShape);
expect(tester.getRect(find.widgetWithText(TextButton, 'CANCEL')), cancelButtonRect);
expect(buttonMaterial(cancelStr).color!.value, 0);
expect(buttonMaterial(cancelStr).textStyle!.color!.value, 0xb3ffffff);
expect(buttonMaterial(cancelStr).shape, buttonShape);
expect(tester.getRect(find.widgetWithText(TextButton, cancelStr)), cancelButtonRect);
});
testWidgets('Stepper disabled button styles', (WidgetTester tester) async {
......@@ -910,22 +919,28 @@ testWidgets('Stepper custom indexed controls test', (WidgetTester tester) async
);
}
await tester.pumpWidget(buildFrame(ThemeData.light()));
final ThemeData themeLight = ThemeData.light();
final bool material3Light = themeLight.useMaterial3;
await tester.pumpWidget(buildFrame(themeLight));
expect(buttonMaterial('CONTINUE').color!.value, 0);
expect(buttonMaterial('CONTINUE').textStyle!.color!.value, 0x61000000);
final String continueStr = material3Light ? 'Continue' : 'CONTINUE';
final String cancelStr = material3Light ? 'Cancel' : 'CANCEL';
expect(buttonMaterial(continueStr).color!.value, 0);
expect(buttonMaterial(continueStr).textStyle!.color!.value, material3Light ? themeLight.colorScheme.onSurface.withOpacity(0.38).value : 0x61000000);
expect(buttonMaterial('CANCEL').color!.value, 0);
expect(buttonMaterial('CANCEL').textStyle!.color!.value, 0x61000000);
expect(buttonMaterial(cancelStr).color!.value, 0);
expect(buttonMaterial(cancelStr).textStyle!.color!.value, material3Light ? themeLight.colorScheme.onSurface.withOpacity(0.38).value : 0x61000000);
await tester.pumpWidget(buildFrame(ThemeData.dark()));
final ThemeData themeDark = ThemeData.dark();
final bool material3Dark = themeDark.useMaterial3;
await tester.pumpWidget(buildFrame(themeDark));
await tester.pumpAndSettle(); // Complete the theme animation.
expect(buttonMaterial('CONTINUE').color!.value, 0);
expect(buttonMaterial('CONTINUE').textStyle!.color!.value, 0x61ffffff);
expect(buttonMaterial(continueStr).color!.value, 0);
expect(buttonMaterial(continueStr).textStyle!.color!.value, material3Dark ? themeDark.colorScheme.onSurface.withOpacity(0.38).value : 0x61ffffff);
expect(buttonMaterial('CANCEL').color!.value, 0);
expect(buttonMaterial('CANCEL').textStyle!.color!.value, 0x61ffffff);
expect(buttonMaterial(cancelStr).color!.value, 0);
expect(buttonMaterial(cancelStr).textStyle!.color!.value, material3Dark ? themeDark.colorScheme.onSurface.withOpacity(0.38).value : 0x61ffffff);
});
testWidgets('Vertical and Horizontal Stepper physics test', (WidgetTester tester) async {
......
......@@ -118,27 +118,32 @@ void main() {
testWidgets('SwitchListTile has the right colors', (WidgetTester tester) async {
bool value = false;
final ThemeData theme = ThemeData();
final bool material3 = theme.useMaterial3;
await tester.pumpWidget(
MediaQuery(
data: const MediaQueryData(padding: EdgeInsets.all(8.0)),
child: Directionality(
textDirection: TextDirection.ltr,
child:
StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Material(
child: SwitchListTile(
value: value,
onChanged: (bool newValue) {
setState(() { value = newValue; });
},
activeColor: Colors.red[500],
activeTrackColor: Colors.green[500],
inactiveThumbColor: Colors.yellow[500],
inactiveTrackColor: Colors.blue[500],
),
);
},
child: Theme(
data: theme,
child: Directionality(
textDirection: TextDirection.ltr,
child:
StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Material(
child: SwitchListTile(
value: value,
onChanged: (bool newValue) {
setState(() { value = newValue; });
},
activeColor: Colors.red[500],
activeTrackColor: Colors.green[500],
inactiveThumbColor: Colors.yellow[500],
inactiveTrackColor: Colors.blue[500],
),
);
},
),
),
),
),
......@@ -146,12 +151,17 @@ void main() {
expect(
find.byType(Switch),
paints
..rrect(color: Colors.blue[500])
..rrect(color: const Color(0x33000000))
..rrect(color: const Color(0x24000000))
..rrect(color: const Color(0x1f000000))
..rrect(color: Colors.yellow[500]),
material3
? (paints
..rrect(color: Colors.blue[500])
..rrect()
..rrect(color: Colors.yellow[500]))
: (paints
..rrect(color: Colors.blue[500])
..rrect(color: const Color(0x33000000))
..rrect(color: const Color(0x24000000))
..rrect(color: const Color(0x1f000000))
..rrect(color: Colors.yellow[500])),
);
await tester.tap(find.byType(Switch));
......@@ -159,12 +169,17 @@ void main() {
expect(
Material.of(tester.element(find.byType(Switch))),
paints
..rrect(color: Colors.green[500])
..rrect(color: const Color(0x33000000))
..rrect(color: const Color(0x24000000))
..rrect(color: const Color(0x1f000000))
..rrect(color: Colors.red[500]),
material3
? (paints
..rrect(color: Colors.green[500])
..rrect()
..rrect(color: Colors.red[500]))
: (paints
..rrect(color: Colors.green[500])
..rrect(color: const Color(0x33000000))
..rrect(color: const Color(0x24000000))
..rrect(color: const Color(0x1f000000))
..rrect(color: Colors.red[500])),
);
});
......@@ -586,7 +601,7 @@ void main() {
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Container(
width: 100,
width: 500,
height: 100,
color: Colors.white,
child: SwitchListTile(
......@@ -613,7 +628,7 @@ void main() {
Material.of(tester.element(find.byKey(key))),
paints..rect()..rect(
color: Colors.orange[500],
rect: const Rect.fromLTRB(350.0, 250.0, 450.0, 350.0),
rect: const Rect.fromLTRB(150.0, 250.0, 650.0, 350.0),
)
);
});
......@@ -623,6 +638,8 @@ void main() {
const Color activeDisabledThumbColor = Color(0xFF000002);
const Color inactiveEnabledThumbColor = Color(0xFF000003);
const Color inactiveDisabledThumbColor = Color(0xFF000004);
final ThemeData theme = ThemeData();
final bool material3 = theme.useMaterial3;
Color getThumbColor(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
......@@ -655,19 +672,19 @@ void main() {
await tester.pumpWidget(buildSwitchListTile(enabled: false, selected: false));
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Switch))),
paints
..rrect()..rrect()..rrect()..rrect()
..rrect(color: inactiveDisabledThumbColor),
Material.of(tester.element(find.byType(Switch))),
material3
? (paints..rrect()..rrect()..rrect(color: inactiveDisabledThumbColor))
: (paints..rrect()..rrect()..rrect()..rrect()..rrect(color: inactiveDisabledThumbColor)),
);
await tester.pumpWidget(buildSwitchListTile(enabled: false, selected: true));
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Switch))),
paints
..rrect()..rrect()..rrect()..rrect()
..rrect(color: activeDisabledThumbColor),
material3
? (paints..rrect()..rrect()..rrect(color: activeDisabledThumbColor))
: (paints..rrect()..rrect()..rrect()..rrect()..rrect(color: activeDisabledThumbColor)),
);
await tester.pumpWidget(buildSwitchListTile(enabled: true, selected: false));
......@@ -675,9 +692,9 @@ void main() {
expect(
Material.of(tester.element(find.byType(Switch))),
paints
..rrect()..rrect()..rrect()..rrect()
..rrect(color: inactiveEnabledThumbColor),
material3
? (paints..rrect()..rrect()..rrect(color: inactiveEnabledThumbColor))
: (paints..rrect()..rrect()..rrect()..rrect()..rrect(color: inactiveEnabledThumbColor)),
);
await tester.pumpWidget(buildSwitchListTile(enabled: true, selected: true));
......@@ -685,9 +702,9 @@ void main() {
expect(
Material.of(tester.element(find.byType(Switch))),
paints
..rrect()..rrect()..rrect()..rrect()
..rrect(color: activeEnabledThumbColor),
material3
? (paints..rrect()..rrect()..rrect(color: activeEnabledThumbColor))
: (paints..rrect()..rrect()..rrect()..rrect()..rrect(color: activeEnabledThumbColor)),
);
});
......@@ -695,6 +712,8 @@ void main() {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
const Color hoveredThumbColor = Color(0xFF4caf50);
const Color pressedThumbColor = Color(0xFFF44336);
final ThemeData theme = ThemeData();
final bool material3 = theme.useMaterial3;
Color getThumbColor(Set<MaterialState> states) {
if (states.contains(MaterialState.pressed)) {
......@@ -710,7 +729,7 @@ void main() {
Widget buildSwitchListTile() {
return MaterialApp(
theme: ThemeData(),
theme: theme,
home: wrap(
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
......@@ -735,9 +754,9 @@ void main() {
expect(
Material.of(tester.element(find.byType(Switch))),
paints
..rrect()..rrect()..rrect()..rrect()
..rrect(color: hoveredThumbColor),
material3
? (paints..rrect()..rrect()..rrect(color: hoveredThumbColor))
: (paints..rrect()..rrect()..rrect()..rrect()..rrect(color: hoveredThumbColor)),
);
// On pressed state
......@@ -745,9 +764,9 @@ void main() {
await tester.pumpAndSettle();
expect(
Material.of(tester.element(find.byType(Switch))),
paints
..rrect()..rrect()..rrect()..rrect()
..rrect(color: pressedThumbColor),
material3
? (paints..rrect()..rrect()..rrect(color: pressedThumbColor))
: (paints..rrect()..rrect()..rrect()..rrect()..rrect(color: pressedThumbColor)),
);
});
......@@ -943,28 +962,33 @@ void main() {
});
testWidgets('SwitchListTile respects materialTapTargetSize', (WidgetTester tester) async {
final ThemeData theme = ThemeData();
final bool material3 = theme.useMaterial3;
Widget buildSwitchListTile(MaterialTapTargetSize materialTapTargetSize) {
return wrap(
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return SwitchListTile(
materialTapTargetSize: materialTapTargetSize,
value: false,
onChanged: (_) {},
);
}),
return MaterialApp(
theme: theme,
home: Material(
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return SwitchListTile(
materialTapTargetSize: materialTapTargetSize,
value: false,
onChanged: (_) {},
);
}),
),
);
}
await tester.pumpWidget(buildSwitchListTile(MaterialTapTargetSize.padded));
final Switch switchWidget = tester.widget<Switch>(find.byType(Switch));
expect(switchWidget.materialTapTargetSize, MaterialTapTargetSize.padded);
expect(tester.getSize(find.byType(Switch)), const Size(59.0, 48.0));
expect(tester.getSize(find.byType(Switch)), material3 ? const Size(60.0, 48.0) : const Size(59.0, 48.0));
await tester.pumpWidget(buildSwitchListTile(MaterialTapTargetSize.shrinkWrap));
final Switch switchWidget1 = tester.widget<Switch>(find.byType(Switch));
expect(switchWidget1.materialTapTargetSize, MaterialTapTargetSize.shrinkWrap);
expect(tester.getSize(find.byType(Switch)), const Size(59.0, 40.0));
expect(tester.getSize(find.byType(Switch)), material3 ? const Size(60.0, 40.0) : const Size(59.0, 40.0));
});
testWidgets('SwitchListTile.adaptive respects applyCupertinoTheme', (WidgetTester tester) async {
......@@ -1005,28 +1029,33 @@ void main() {
});
testWidgets('SwitchListTile respects materialTapTargetSize', (WidgetTester tester) async {
final ThemeData theme = ThemeData();
final bool material3 = theme.useMaterial3;
Widget buildSwitchListTile(MaterialTapTargetSize materialTapTargetSize) {
return wrap(
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return SwitchListTile(
materialTapTargetSize: materialTapTargetSize,
value: false,
onChanged: (_) {},
);
}),
return MaterialApp(
theme: theme,
home: Material(
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return SwitchListTile(
materialTapTargetSize: materialTapTargetSize,
value: false,
onChanged: (_) {},
);
}),
),
);
}
await tester.pumpWidget(buildSwitchListTile(MaterialTapTargetSize.padded));
final Switch switchWidget = tester.widget<Switch>(find.byType(Switch));
expect(switchWidget.materialTapTargetSize, MaterialTapTargetSize.padded);
expect(tester.getSize(find.byType(Switch)), const Size(59.0, 48.0));
expect(tester.getSize(find.byType(Switch)), material3 ? const Size(60.0, 48.0) : const Size(59.0, 48.0));
await tester.pumpWidget(buildSwitchListTile(MaterialTapTargetSize.shrinkWrap));
final Switch switchWidget1 = tester.widget<Switch>(find.byType(Switch));
expect(switchWidget1.materialTapTargetSize, MaterialTapTargetSize.shrinkWrap);
expect(tester.getSize(find.byType(Switch)), const Size(59.0, 40.0));
expect(tester.getSize(find.byType(Switch)), material3 ? const Size(60.0, 40.0) : const Size(59.0, 40.0));
});
testWidgets('SwitchListTile passes the value of dragStartBehavior to Switch', (WidgetTester tester) async {
......
......@@ -114,6 +114,7 @@ void main() {
Widget buildSwitch({required double width, required double height}) {
return MaterialApp(
theme: ThemeData(useMaterial3: false),
home: Scaffold(
body: Directionality(
textDirection: TextDirection.ltr,
......@@ -347,27 +348,30 @@ void main() {
expect(value, isFalse);
});
testWidgets('Switch has default colors when enabled', (WidgetTester tester) async {
testWidgets('Switch has default colors when enabled - M2', (WidgetTester tester) async {
bool value = false;
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.rtl,
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Material(
child: Center(
child: Switch(
dragStartBehavior: DragStartBehavior.down,
value: value,
onChanged: (bool newValue) {
setState(() {
value = newValue;
});
},
MaterialApp(
theme: ThemeData(useMaterial3: false),
home: Directionality(
textDirection: TextDirection.rtl,
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Material(
child: Center(
child: Switch(
dragStartBehavior: DragStartBehavior.down,
value: value,
onChanged: (bool newValue) {
setState(() {
value = newValue;
});
},
),
),
),
);
},
);
},
),
),
),
);
......@@ -403,18 +407,21 @@ void main() {
);
});
testWidgets('Switch has default colors when disabled', (WidgetTester tester) async {
testWidgets('Switch has default colors when disabled - M2', (WidgetTester tester) async {
await tester.pumpWidget(
const Directionality(
textDirection: TextDirection.rtl,
child: Material(
child: Center(
child: Switch(
value: false,
onChanged: null,
MaterialApp(
theme: ThemeData(useMaterial3: false),
home: const Directionality(
textDirection: TextDirection.rtl,
child: Material(
child: Center(
child: Switch(
value: false,
onChanged: null,
),
),
),
)
)
),
),
);
......@@ -433,13 +440,16 @@ void main() {
);
await tester.pumpWidget(
const Directionality(
textDirection: TextDirection.rtl,
child: Material(
child: Center(
child: Switch(
value: true,
onChanged: null,
MaterialApp(
theme: ThemeData(useMaterial3: false),
home: const Directionality(
textDirection: TextDirection.rtl,
child: Material(
child: Center(
child: Switch(
value: true,
onChanged: null,
),
),
),
),
......@@ -507,31 +517,34 @@ void main() {
);
});
testWidgets('Switch can be set color', (WidgetTester tester) async {
testWidgets('Switch can be set color - M2', (WidgetTester tester) async {
bool value = false;
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.rtl,
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Material(
child: Center(
child: Switch(
dragStartBehavior: DragStartBehavior.down,
value: value,
onChanged: (bool newValue) {
setState(() {
value = newValue;
});
},
activeColor: Colors.red[500],
activeTrackColor: Colors.green[500],
inactiveThumbColor: Colors.yellow[500],
inactiveTrackColor: Colors.blue[500],
MaterialApp(
theme: ThemeData(useMaterial3: false),
home: Directionality(
textDirection: TextDirection.rtl,
child: StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
return Material(
child: Center(
child: Switch(
dragStartBehavior: DragStartBehavior.down,
value: value,
onChanged: (bool newValue) {
setState(() {
value = newValue;
});
},
activeColor: Colors.red[500],
activeTrackColor: Colors.green[500],
inactiveThumbColor: Colors.yellow[500],
inactiveTrackColor: Colors.blue[500],
),
),
),
);
},
);
},
),
),
),
);
......@@ -849,12 +862,13 @@ void main() {
}
});
testWidgets('Switch is focusable and has correct focus color', (WidgetTester tester) async {
testWidgets('Switch is focusable and has correct focus color - M2', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Switch');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
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) {
......@@ -957,11 +971,12 @@ void main() {
);
});
testWidgets('Switch can be hovered and has correct hover color', (WidgetTester tester) async {
testWidgets('Switch can be hovered and has correct hover color - M2', (WidgetTester tester) async {
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
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) {
......@@ -1224,7 +1239,7 @@ void main() {
expect(updatedSwitchState.position.isDismissed, false);
});
testWidgets('Switch thumb color resolves in active/enabled states', (WidgetTester tester) async {
testWidgets('Switch thumb color resolves in active/enabled states - M2', (WidgetTester tester) async {
const Color activeEnabledThumbColor = Color(0xFF000001);
const Color activeDisabledThumbColor = Color(0xFF000002);
const Color inactiveEnabledThumbColor = Color(0xFF000003);
......@@ -1247,14 +1262,17 @@ void main() {
MaterialStateColor.resolveWith(getThumbColor);
Widget buildSwitch({required bool enabled, required bool active}) {
return Directionality(
textDirection: TextDirection.rtl,
child: Material(
child: Center(
child: Switch(
thumbColor: thumbColor,
value: active,
onChanged: enabled ? (_) { } : null,
return MaterialApp(
theme: ThemeData(useMaterial3: false),
home: Directionality(
textDirection: TextDirection.rtl,
child: Material(
child: Center(
child: Switch(
thumbColor: thumbColor,
value: active,
onChanged: enabled ? (_) { } : null,
),
),
),
),
......@@ -1329,7 +1347,7 @@ void main() {
);
});
testWidgets('Switch thumb color resolves in hovered/focused states', (WidgetTester tester) async {
testWidgets('Switch thumb color resolves in hovered/focused states - M2', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Switch');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
const Color hoveredThumbColor = Color(0xFF000001);
......@@ -1349,9 +1367,9 @@ void main() {
MaterialStateColor.resolveWith(getThumbColor);
Widget buildSwitch() {
return Directionality(
textDirection: TextDirection.rtl,
child: Material(
return MaterialApp(
theme: ThemeData(useMaterial3: false),
home: Material(
child: Center(
child: Switch(
focusNode: focusNode,
......@@ -1405,7 +1423,7 @@ void main() {
);
});
testWidgets('Track color resolves in active/enabled states', (WidgetTester tester) async {
testWidgets('Track color resolves in active/enabled states - M2', (WidgetTester tester) async {
const Color activeEnabledTrackColor = Color(0xFF000001);
const Color activeDisabledTrackColor = Color(0xFF000002);
const Color inactiveEnabledTrackColor = Color(0xFF000003);
......@@ -1428,9 +1446,9 @@ void main() {
MaterialStateColor.resolveWith(getTrackColor);
Widget buildSwitch({required bool enabled, required bool active}) {
return Directionality(
textDirection: TextDirection.rtl,
child: Material(
return MaterialApp(
theme: ThemeData(useMaterial3: false),
home: Material(
child: Center(
child: Switch(
trackColor: trackColor,
......@@ -1494,7 +1512,7 @@ void main() {
);
});
testWidgets('Switch track color resolves in hovered/focused states', (WidgetTester tester) async {
testWidgets('Switch track color resolves in hovered/focused states - M2', (WidgetTester tester) async {
final FocusNode focusNode = FocusNode(debugLabel: 'Switch');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
const Color hoveredTrackColor = Color(0xFF000001);
......@@ -1514,16 +1532,19 @@ void main() {
MaterialStateColor.resolveWith(getTrackColor);
Widget buildSwitch() {
return Directionality(
textDirection: TextDirection.rtl,
child: Material(
child: Center(
child: Switch(
focusNode: focusNode,
autofocus: true,
value: true,
trackColor: trackColor,
onChanged: (_) { },
return MaterialApp(
theme: ThemeData(useMaterial3: false),
home: Directionality(
textDirection: TextDirection.rtl,
child: Material(
child: Center(
child: Switch(
focusNode: focusNode,
autofocus: true,
value: true,
trackColor: trackColor,
onChanged: (_) { },
),
),
),
),
......@@ -1560,9 +1581,9 @@ void main() {
);
});
testWidgets('Switch thumb color is blended against surface color', (WidgetTester tester) async {
testWidgets('Switch thumb color is blended against surface color - M2', (WidgetTester tester) async {
final Color activeDisabledThumbColor = Colors.blue.withOpacity(.60);
final ThemeData theme = ThemeData.light();
final ThemeData theme = ThemeData.light(useMaterial3: false);
Color getThumbColor(Set<MaterialState> states) {
if (states.contains(MaterialState.disabled)) {
......@@ -2820,7 +2841,7 @@ void main() {
);
});
testWidgets('Switch track color resolves in hovered/focused states', (WidgetTester tester) async {
testWidgets('Switch track color resolves in hovered/focused states - M3', (WidgetTester tester) async {
final ThemeData themeData = ThemeData(useMaterial3: true, colorSchemeSeed: const Color(0xff6750a4), brightness: Brightness.light);
final FocusNode focusNode = FocusNode(debugLabel: 'Switch');
tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
......
......@@ -358,7 +358,7 @@ void main() {
? (paints
..rrect(color: defaultTrackColor)
..rrect(color: defaultOutlineColor, strokeWidth: defaultOutlineWidth)
..rrect(color: defaultThumbColor)..paragraph(offset: const Offset(12, 16)))
..rrect(color: defaultThumbColor)..paragraph(offset: const Offset(12, 12)))
: (paints
..rrect(color: defaultTrackColor)
..rrect(color: defaultOutlineColor, strokeWidth: defaultOutlineWidth)
......@@ -475,6 +475,7 @@ void main() {
material3
? (paints
..rrect(color: selectedTrackColor)
..rrect()
..rrect(color: selectedThumbColor))
: (paints
..rrect(color: selectedTrackColor)
......
......@@ -60,9 +60,11 @@ void main() {
});
testWidgets('Empty textSelectionTheme will use defaults', (WidgetTester tester) async {
const Color defaultCursorColor = Color(0xff2196f3);
const Color defaultSelectionColor = Color(0x662196f3);
const Color defaultSelectionHandleColor = Color(0xff2196f3);
final ThemeData theme = ThemeData();
final bool material3 = theme.useMaterial3;
final Color defaultCursorColor = material3 ? theme.colorScheme.primary : const Color(0xff2196f3);
final Color defaultSelectionColor = material3 ? theme.colorScheme.primary.withOpacity(0.40) : const Color(0x662196f3);
final Color defaultSelectionHandleColor = material3 ? theme.colorScheme.primary : const Color(0xff2196f3);
EditableText.debugDeterministicCursor = true;
addTearDown(() {
......@@ -70,8 +72,9 @@ void main() {
});
// Test TextField's cursor & selection color.
await tester.pumpWidget(
const MaterialApp(
home: Material(
MaterialApp(
theme: theme,
home: const Material(
child: TextField(autofocus: true),
),
),
......@@ -82,7 +85,7 @@ void main() {
final EditableTextState editableTextState = tester.firstState(find.byType(EditableText));
final RenderEditable renderEditable = editableTextState.renderEditable;
expect(renderEditable.cursorColor, defaultCursorColor);
expect(renderEditable.selectionColor?.value, defaultSelectionColor.value);
expect(renderEditable.selectionColor, defaultSelectionColor);
// Test the selection handle color.
await tester.pumpWidget(
......
......@@ -11,12 +11,15 @@ void main() {
group('FloatingActionButton', () {
const BoxConstraints defaultFABConstraints = BoxConstraints.tightFor(width: 56.0, height: 56.0);
const ShapeBorder defaultFABShape = CircleBorder();
const ShapeBorder defaultFABShapeM3 = RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0)));
const EdgeInsets defaultFABPadding = EdgeInsets.zero;
testWidgets('theme: ThemeData.light(), enabled: true', (WidgetTester tester) async {
final ThemeData theme = ThemeData.light();
final bool material3 = theme.useMaterial3;
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.light(),
theme: theme,
home: Center(
child: FloatingActionButton(
onPressed: () { }, // button.enabled == true
......@@ -28,22 +31,24 @@ void main() {
final RawMaterialButton raw = tester.widget<RawMaterialButton>(find.byType(RawMaterialButton));
expect(raw.enabled, true);
expect(raw.textStyle!.color, const Color(0xffffffff));
expect(raw.fillColor, const Color(0xff2196f3));
expect(raw.textStyle!.color, material3 ? theme.colorScheme.onPrimaryContainer : const Color(0xffffffff));
expect(raw.fillColor, material3 ? theme.colorScheme.primaryContainer : const Color(0xff2196f3));
expect(raw.elevation, 6.0);
expect(raw.highlightElevation, 12.0);
expect(raw.highlightElevation, material3 ? 6.0 : 12.0);
expect(raw.disabledElevation, 6.0);
expect(raw.constraints, defaultFABConstraints);
expect(raw.padding, defaultFABPadding);
expect(raw.shape, defaultFABShape);
expect(raw.shape, material3 ? defaultFABShapeM3 : defaultFABShape);
expect(raw.animationDuration, defaultButtonDuration);
expect(raw.materialTapTargetSize, MaterialTapTargetSize.padded);
});
testWidgets('theme: ThemeData.light(), enabled: false', (WidgetTester tester) async {
final ThemeData theme = ThemeData.light();
final bool material3 = theme.useMaterial3;
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.light(),
theme: theme,
home: const Center(
child: FloatingActionButton(
onPressed: null, // button.enabled == false
......@@ -55,16 +60,16 @@ void main() {
final RawMaterialButton raw = tester.widget<RawMaterialButton>(find.byType(RawMaterialButton));
expect(raw.enabled, false);
expect(raw.textStyle!.color, const Color(0xffffffff));
expect(raw.fillColor, const Color(0xff2196f3));
expect(raw.textStyle!.color, material3 ? theme.colorScheme.onPrimaryContainer : const Color(0xffffffff));
expect(raw.fillColor, material3 ? theme.colorScheme.primaryContainer : const Color(0xff2196f3));
// highlightColor, disabled button can't be pressed
// splashColor, disabled button doesn't splash
expect(raw.elevation, 6.0);
expect(raw.highlightElevation, 12.0);
expect(raw.highlightElevation, material3 ? 6.0 : 12.0);
expect(raw.disabledElevation, 6.0);
expect(raw.constraints, defaultFABConstraints);
expect(raw.padding, defaultFABPadding);
expect(raw.shape, defaultFABShape);
expect(raw.shape, material3 ? defaultFABShapeM3 : defaultFABShape);
expect(raw.animationDuration, defaultButtonDuration);
expect(raw.materialTapTargetSize, MaterialTapTargetSize.padded);
});
......
......@@ -10,6 +10,7 @@ import 'package:flutter_test/flutter_test.dart';
void main() {
const TextTheme defaultGeometryTheme = Typography.englishLike2014;
const TextTheme defaultGeometryThemeM3 = Typography.englishLike2021;
test('ThemeDataTween control test', () {
final ThemeData light = ThemeData.light();
......@@ -96,17 +97,37 @@ void main() {
});
testWidgets('Fallback theme', (WidgetTester tester) async {
// For material 2
late BuildContext capturedContext;
await tester.pumpWidget(
Builder(
builder: (BuildContext context) {
capturedContext = context;
return Container();
},
Theme(
data: ThemeData(useMaterial3: false),
child: Builder(
builder: (BuildContext context) {
capturedContext = context;
return Container();
},
),
),
);
expect(Theme.of(capturedContext), equals(ThemeData.localize(ThemeData.fallback(), defaultGeometryTheme)));
expect(Theme.of(capturedContext), equals(ThemeData.localize(ThemeData.fallback(useMaterial3: false), defaultGeometryTheme)));
// For material 3
late BuildContext capturedContextM3;
await tester.pumpWidget(
Theme(
data: ThemeData(useMaterial3: true),
child: Builder(
builder: (BuildContext context) {
capturedContextM3 = context;
return Container();
},
),
),
);
expect(Theme.of(capturedContextM3), equals(ThemeData.localize(ThemeData.fallback(useMaterial3: true), defaultGeometryThemeM3)));
});
testWidgets('ThemeData.localize memoizes the result', (WidgetTester tester) async {
......@@ -133,7 +154,8 @@ void main() {
});
testWidgets('ThemeData with null typography uses proper defaults', (WidgetTester tester) async {
expect(ThemeData().typography, Typography.material2014());
final ThemeData m2Theme = ThemeData(useMaterial3: false);
expect(m2Theme.typography, Typography.material2014());
final ThemeData m3Theme = ThemeData(useMaterial3: true);
expect(m3Theme.typography, Typography.material2021(colorScheme: m3Theme.colorScheme));
});
......@@ -414,15 +436,18 @@ void main() {
expect(actualFontSize, kMagicFontSize);
});
testWidgets('Default Theme provides all basic TextStyle properties', (WidgetTester tester) async {
testWidgets('Default Theme provides all basic TextStyle properties - M2', (WidgetTester tester) async {
late ThemeData theme;
await tester.pumpWidget(Directionality(
textDirection: TextDirection.ltr,
child: Builder(
builder: (BuildContext context) {
theme = Theme.of(context);
return const Text('A');
},
await tester.pumpWidget(Theme(
data: ThemeData(useMaterial3: false),
child: Directionality(
textDirection: TextDirection.ltr,
child: Builder(
builder: (BuildContext context) {
theme = Theme.of(context);
return const Text('A');
},
),
),
));
......@@ -441,6 +466,7 @@ void main() {
textTheme.bodySmall!,
textTheme.labelLarge!,
textTheme.labelMedium!,
// textTheme.labelSmall!,
];
}
......@@ -468,6 +494,63 @@ void main() {
expect(theme.textTheme.displayLarge!.debugLabel, '(englishLike displayLarge 2014).merge(blackMountainView displayLarge)');
});
testWidgets('Default Theme provides all basic TextStyle properties - M3', (WidgetTester tester) async {
late ThemeData theme;
await tester.pumpWidget(Theme(
data: ThemeData(useMaterial3: true),
child: Directionality(
textDirection: TextDirection.ltr,
child: Builder(
builder: (BuildContext context) {
theme = Theme.of(context);
return const Text('A');
},
),
),
));
List<TextStyle> extractStyles(TextTheme textTheme) {
return <TextStyle>[
textTheme.displayLarge!,
textTheme.displayMedium!,
textTheme.displaySmall!,
textTheme.headlineLarge!,
textTheme.headlineMedium!,
textTheme.headlineSmall!,
textTheme.titleLarge!,
textTheme.titleMedium!,
textTheme.bodyLarge!,
textTheme.bodyMedium!,
textTheme.bodySmall!,
textTheme.labelLarge!,
textTheme.labelMedium!,
];
}
for (final TextTheme textTheme in <TextTheme>[theme.textTheme, theme.primaryTextTheme]) {
for (final TextStyle style in extractStyles(textTheme).map<TextStyle>((TextStyle style) => _TextStyleProxy(style))) {
expect(style.inherit, false);
expect(style.color, isNotNull);
expect(style.fontFamily, isNotNull);
expect(style.fontSize, isNotNull);
expect(style.fontWeight, isNotNull);
expect(style.fontStyle, null);
expect(style.letterSpacing, isNotNull);
expect(style.wordSpacing, null);
expect(style.textBaseline, isNotNull);
expect(style.height, isNotNull);
expect(style.decoration, TextDecoration.none);
expect(style.decorationColor, isNotNull);
expect(style.decorationStyle, null);
expect(style.debugLabel, isNotNull);
expect(style.locale, null);
expect(style.background, null);
}
}
expect(theme.textTheme.displayLarge!.debugLabel, '(englishLike displayLarge 2021).merge((blackMountainView displayLarge).apply)');
});
group('Cupertino theme', () {
late int buildCount;
CupertinoThemeData? actualTheme;
......@@ -496,26 +579,42 @@ void main() {
context = null;
});
testWidgets('Default theme has defaults', (WidgetTester tester) async {
final CupertinoThemeData theme = await testTheme(tester, ThemeData.light());
expect(theme.brightness, Brightness.light);
expect(theme.primaryColor, Colors.blue);
expect(theme.scaffoldBackgroundColor, Colors.grey[50]);
expect(theme.primaryContrastingColor, Colors.white);
expect(theme.textTheme.textStyle.fontFamily, '.SF Pro Text');
expect(theme.textTheme.textStyle.fontSize, 17.0);
testWidgets('Default light theme has defaults', (WidgetTester tester) async {
final CupertinoThemeData themeM2 = await testTheme(tester, ThemeData(useMaterial3: false));
final CupertinoThemeData themeM3 = await testTheme(tester, ThemeData(useMaterial3: true));
expect(themeM2.brightness, Brightness.light);
expect(themeM2.primaryColor, Colors.blue);
expect(themeM2.scaffoldBackgroundColor, Colors.grey[50]);
expect(themeM2.primaryContrastingColor, Colors.white);
expect(themeM2.textTheme.textStyle.fontFamily, '.SF Pro Text');
expect(themeM2.textTheme.textStyle.fontSize, 17.0);
expect(themeM3.brightness, Brightness.light);
expect(themeM3.primaryColor, const Color(0xff6750a4));
expect(themeM3.scaffoldBackgroundColor, const Color(0xfffffbfe)); // ColorScheme.background
expect(themeM3.primaryContrastingColor, Colors.white);
expect(themeM3.textTheme.textStyle.fontFamily, '.SF Pro Text');
expect(themeM3.textTheme.textStyle.fontSize, 17.0);
});
testWidgets('Dark theme has defaults', (WidgetTester tester) async {
final CupertinoThemeData theme = await testTheme(tester, ThemeData.dark());
expect(theme.brightness, Brightness.dark);
expect(theme.primaryColor, Colors.blue);
expect(theme.primaryContrastingColor, Colors.white);
expect(theme.scaffoldBackgroundColor, Colors.grey[850]);
expect(theme.textTheme.textStyle.fontFamily, '.SF Pro Text');
expect(theme.textTheme.textStyle.fontSize, 17.0);
final CupertinoThemeData themeM2 = await testTheme(tester, ThemeData.dark(useMaterial3: false));
final CupertinoThemeData themeM3 = await testTheme(tester, ThemeData.dark(useMaterial3: true));
expect(themeM2.brightness, Brightness.dark);
expect(themeM2.primaryColor, Colors.blue);
expect(themeM2.primaryContrastingColor, Colors.white);
expect(themeM2.scaffoldBackgroundColor, Colors.grey[850]);
expect(themeM2.textTheme.textStyle.fontFamily, '.SF Pro Text');
expect(themeM2.textTheme.textStyle.fontSize, 17.0);
expect(themeM3.brightness, Brightness.dark);
expect(themeM3.primaryColor, const Color(0xffd0bcff));
expect(themeM3.primaryContrastingColor, const Color(0xff381e72));
expect(themeM3.scaffoldBackgroundColor, const Color(0xff1c1b1f));
expect(themeM3.textTheme.textStyle.fontFamily, '.SF Pro Text');
expect(themeM3.textTheme.textStyle.fontSize, 17.0);
});
testWidgets('MaterialTheme overrides the brightness', (WidgetTester tester) async {
......@@ -540,49 +639,103 @@ void main() {
});
testWidgets('Can override material theme', (WidgetTester tester) async {
final CupertinoThemeData theme = await testTheme(tester, ThemeData(
final CupertinoThemeData themeM2 = await testTheme(tester, ThemeData(
cupertinoOverrideTheme: const CupertinoThemeData(
scaffoldBackgroundColor: CupertinoColors.lightBackgroundGray,
),
useMaterial3: false,
));
expect(theme.brightness, Brightness.light);
expect(themeM2.brightness, Brightness.light);
// We took the scaffold background override but the rest are still cascaded
// to the material theme.
expect(theme.primaryColor, Colors.blue);
expect(theme.primaryContrastingColor, Colors.white);
expect(theme.scaffoldBackgroundColor, CupertinoColors.lightBackgroundGray);
expect(theme.textTheme.textStyle.fontFamily, '.SF Pro Text');
expect(theme.textTheme.textStyle.fontSize, 17.0);
// to the material themeM2.
expect(themeM2.primaryColor, Colors.blue);
expect(themeM2.primaryContrastingColor, Colors.white);
expect(themeM2.scaffoldBackgroundColor, CupertinoColors.lightBackgroundGray);
expect(themeM2.textTheme.textStyle.fontFamily, '.SF Pro Text');
expect(themeM2.textTheme.textStyle.fontSize, 17.0);
final CupertinoThemeData themeM3 = await testTheme(tester, ThemeData(
cupertinoOverrideTheme: const CupertinoThemeData(
scaffoldBackgroundColor: CupertinoColors.lightBackgroundGray,
),
useMaterial3: true,
));
expect(themeM3.brightness, Brightness.light);
// We took the scaffold background override but the rest are still cascaded
// to the material themeM3.
expect(themeM3.primaryColor, const Color(0xff6750a4));
expect(themeM3.primaryContrastingColor, Colors.white);
expect(themeM3.scaffoldBackgroundColor, CupertinoColors.lightBackgroundGray);
expect(themeM3.textTheme.textStyle.fontFamily, '.SF Pro Text');
expect(themeM3.textTheme.textStyle.fontSize, 17.0);
});
testWidgets('Can override properties that are independent of material', (WidgetTester tester) async {
final CupertinoThemeData theme = await testTheme(tester, ThemeData(
final CupertinoThemeData themeM2 = await testTheme(tester, ThemeData(
cupertinoOverrideTheme: const CupertinoThemeData(
// The bar colors ignore all things material except brightness.
barBackgroundColor: CupertinoColors.black,
),
useMaterial3: false,
));
expect(theme.primaryColor, Colors.blue);
expect(themeM2.primaryColor, Colors.blue);
// MaterialBasedCupertinoThemeData should also function like a normal CupertinoThemeData.
expect(theme.barBackgroundColor, CupertinoColors.black);
expect(themeM2.barBackgroundColor, CupertinoColors.black);
final CupertinoThemeData themeM3 = await testTheme(tester, ThemeData(
cupertinoOverrideTheme: const CupertinoThemeData(
// The bar colors ignore all things material except brightness.
barBackgroundColor: CupertinoColors.black,
),
useMaterial3: true
));
expect(themeM3.primaryColor, const Color(0xff6750a4));
// MaterialBasedCupertinoThemeData should also function like a normal CupertinoThemeData.
expect(themeM3.barBackgroundColor, CupertinoColors.black);
});
testWidgets('Changing material theme triggers rebuilds', (WidgetTester tester) async {
CupertinoThemeData theme = await testTheme(tester, ThemeData(
testWidgets('Changing material theme triggers rebuilds - M2', (WidgetTester tester) async {
CupertinoThemeData themeM2 = await testTheme(tester, ThemeData(
useMaterial3: false,
primarySwatch: Colors.red,
));
expect(buildCount, 1);
expect(theme.primaryColor, Colors.red);
expect(themeM2.primaryColor, Colors.red);
theme = await testTheme(tester, ThemeData(
themeM2 = await testTheme(tester, ThemeData(
useMaterial3: false,
primarySwatch: Colors.orange,
));
expect(buildCount, 2);
expect(theme.primaryColor, Colors.orange);
expect(themeM2.primaryColor, Colors.orange);
});
testWidgets('Changing material theme triggers rebuilds - M3', (WidgetTester tester) async {
CupertinoThemeData themeM3 = await testTheme(tester, ThemeData(
useMaterial3: true,
colorScheme: const ColorScheme.light(
primary: Colors.red
),
));
expect(buildCount, 1);
expect(themeM3.primaryColor, Colors.red);
themeM3 = await testTheme(tester, ThemeData(
useMaterial3: true,
colorScheme: const ColorScheme.light(
primary: Colors.orange
),
));
expect(buildCount, 2);
expect(themeM3.primaryColor, Colors.orange);
});
testWidgets(
......@@ -654,9 +807,10 @@ void main() {
);
testWidgets(
'Cupertino overrides do not block derivatives triggering rebuilds when derivatives are not overridden',
'Cupertino overrides do not block derivatives triggering rebuilds when derivatives are not overridden - M2',
(WidgetTester tester) async {
CupertinoThemeData theme = await testTheme(tester, ThemeData(
useMaterial3: false,
primarySwatch: Colors.purple,
cupertinoOverrideTheme: const CupertinoThemeData(
primaryContrastingColor: CupertinoColors.destructiveRed,
......@@ -668,6 +822,7 @@ void main() {
expect(theme.primaryContrastingColor, CupertinoColors.destructiveRed);
theme = await testTheme(tester, ThemeData(
useMaterial3: false,
primarySwatch: Colors.green,
cupertinoOverrideTheme: const CupertinoThemeData(
primaryContrastingColor: CupertinoColors.destructiveRed,
......@@ -681,9 +836,43 @@ void main() {
);
testWidgets(
'copyWith only copies the overrides, not the material or cupertino derivatives',
'Cupertino overrides do not block derivatives triggering rebuilds when derivatives are not overridden - M3',
(WidgetTester tester) async {
CupertinoThemeData theme = await testTheme(tester, ThemeData(
useMaterial3: true,
colorScheme: const ColorScheme.light(
primary: Colors.purple,
),
cupertinoOverrideTheme: const CupertinoThemeData(
primaryContrastingColor: CupertinoColors.destructiveRed,
),
));
expect(buildCount, 1);
expect(theme.textTheme.actionTextStyle.color, Colors.purple);
expect(theme.primaryContrastingColor, CupertinoColors.destructiveRed);
theme = await testTheme(tester, ThemeData(
useMaterial3: true,
colorScheme: const ColorScheme.light(
primary: Colors.green,
),
cupertinoOverrideTheme: const CupertinoThemeData(
primaryContrastingColor: CupertinoColors.destructiveRed,
),
));
expect(buildCount, 2);
expect(theme.textTheme.actionTextStyle.color, Colors.green);
expect(theme.primaryContrastingColor, CupertinoColors.destructiveRed);
},
);
testWidgets(
'copyWith only copies the overrides, not the material or cupertino derivatives - M2',
(WidgetTester tester) async {
final CupertinoThemeData originalTheme = await testTheme(tester, ThemeData(
useMaterial3: false,
primarySwatch: Colors.purple,
cupertinoOverrideTheme: const CupertinoThemeData(
primaryContrastingColor: CupertinoColors.activeOrange,
......@@ -695,6 +884,7 @@ void main() {
);
final CupertinoThemeData theme = await testTheme(tester, ThemeData(
useMaterial3: false,
primarySwatch: Colors.blue,
cupertinoOverrideTheme: copiedTheme,
));
......@@ -706,9 +896,37 @@ void main() {
);
testWidgets(
"Material themes with no cupertino overrides can also be copyWith'ed",
'copyWith only copies the overrides, not the material or cupertino derivatives - M3',
(WidgetTester tester) async {
final CupertinoThemeData originalTheme = await testTheme(tester, ThemeData(
useMaterial3: true,
colorScheme: const ColorScheme.light(primary: Colors.purple),
cupertinoOverrideTheme: const CupertinoThemeData(
primaryContrastingColor: CupertinoColors.activeOrange,
),
));
final CupertinoThemeData copiedTheme = originalTheme.copyWith(
barBackgroundColor: CupertinoColors.destructiveRed,
);
final CupertinoThemeData theme = await testTheme(tester, ThemeData(
useMaterial3: true,
colorScheme: const ColorScheme.light(primary: Colors.blue),
cupertinoOverrideTheme: copiedTheme,
));
expect(theme.primaryColor, Colors.blue);
expect(theme.primaryContrastingColor, CupertinoColors.activeOrange);
expect(theme.barBackgroundColor, CupertinoColors.destructiveRed);
},
);
testWidgets(
"Material themes with no cupertino overrides can also be copyWith'ed - M2",
(WidgetTester tester) async {
final CupertinoThemeData originalTheme = await testTheme(tester, ThemeData(
useMaterial3: false,
primarySwatch: Colors.purple,
));
......@@ -717,6 +935,7 @@ void main() {
);
final CupertinoThemeData theme = await testTheme(tester, ThemeData(
useMaterial3: false,
primarySwatch: Colors.blue,
cupertinoOverrideTheme: copiedTheme,
));
......@@ -725,6 +944,29 @@ void main() {
expect(theme.primaryContrastingColor, CupertinoColors.destructiveRed);
},
);
testWidgets(
"Material themes with no cupertino overrides can also be copyWith'ed - M3",
(WidgetTester tester) async {
final CupertinoThemeData originalTheme = await testTheme(tester, ThemeData(
useMaterial3: true,
colorScheme: const ColorScheme.light(primary: Colors.purple),
));
final CupertinoThemeData copiedTheme = originalTheme.copyWith(
primaryContrastingColor: CupertinoColors.destructiveRed,
);
final CupertinoThemeData theme = await testTheme(tester, ThemeData(
useMaterial3: true,
colorScheme: const ColorScheme.light(primary: Colors.blue),
cupertinoOverrideTheme: copiedTheme,
));
expect(theme.primaryColor, Colors.blue);
expect(theme.primaryContrastingColor, CupertinoColors.destructiveRed);
},
);
});
}
......
......@@ -5,6 +5,7 @@
@TestOn('!chrome')
library;
import 'dart:math' as math;
import 'dart:ui';
import 'package:flutter/material.dart';
......@@ -710,7 +711,7 @@ void main() {
testWidgets('OK Cancel button and helpText layout', (WidgetTester tester) async {
Widget buildFrame(TextDirection textDirection) {
return MaterialApp(
theme: ThemeData.light().copyWith(useMaterial3: materialType == MaterialType.material3),
theme: ThemeData(useMaterial3: materialType == MaterialType.material3),
home: Material(
child: Center(
child: Builder(
......@@ -752,8 +753,8 @@ void main() {
expect(tester.getBottomRight(find.text(cancelString)).dx, 582);
case MaterialType.material3:
expect(tester.getTopLeft(find.text(selectTimeString)), equals(const Offset(138, 129)));
expect(tester.getBottomRight(find.text(selectTimeString)), equals(const Offset(292.0, 143.0)));
expect(tester.getBottomLeft(find.text(okString)).dx, 616);
expect(tester.getBottomRight(find.text(selectTimeString)), equals(const Offset(295.0, 149.0)));
expect(tester.getBottomLeft(find.text(okString)).dx, 615.5);
expect(tester.getBottomRight(find.text(cancelString)).dx, 578);
}
......@@ -774,10 +775,10 @@ void main() {
expect(tester.getBottomRight(find.text(okString)).dx, 184);
expect(tester.getBottomLeft(find.text(cancelString)).dx, 218);
case MaterialType.material3:
expect(tester.getTopLeft(find.text(selectTimeString)), equals(const Offset(508, 129)));
expect(tester.getBottomRight(find.text(selectTimeString)), equals(const Offset(662, 143)));
expect(tester.getBottomLeft(find.text(okString)).dx, 156);
expect(tester.getBottomRight(find.text(okString)).dx, 184);
expect(tester.getTopLeft(find.text(selectTimeString)), equals(const Offset(505.0, 129.0)));
expect(tester.getBottomRight(find.text(selectTimeString)), equals(const Offset(662, 149)));
expect(tester.getBottomLeft(find.text(okString)).dx, 155.5);
expect(tester.getBottomRight(find.text(okString)).dx, 184.5);
expect(tester.getBottomLeft(find.text(cancelString)).dx, 222);
}
......@@ -808,7 +809,7 @@ void main() {
final double amHeight2x = tester.getSize(find.text(amString)).height;
expect(tester.getSize(find.text('41')).height, equals(minutesDisplayHeight));
expect(amHeight2x, greaterThanOrEqualTo(amHeight * 2));
expect(amHeight2x, math.min(38.0, amHeight * 2));
await tester.tap(find.text(okString)); // dismiss the dialog
await tester.pumpAndSettle();
......@@ -822,7 +823,7 @@ void main() {
);
expect(tester.getSize(find.text('41')).height, equals(minutesDisplayHeight));
expect(tester.getSize(find.text(amString)).height, equals(amHeight2x));
expect(tester.getSize(find.text(amString)).height, math.min(38.0, amHeight * 2));
});
group('showTimePicker avoids overlapping display features', () {
......@@ -1694,55 +1695,53 @@ Future<void> mediaQueryBoilerplate(
Orientation? orientation,
}) async {
await tester.pumpWidget(
Builder(builder: (BuildContext context) {
return Theme(
data: Theme.of(context).copyWith(useMaterial3: materialType == MaterialType.material3),
child: Localizations(
locale: const Locale('en', 'US'),
delegates: const <LocalizationsDelegate<dynamic>>[
DefaultMaterialLocalizations.delegate,
DefaultWidgetsLocalizations.delegate,
],
child: MediaQuery(
data: MediaQueryData(
alwaysUse24HourFormat: alwaysUse24HourFormat,
textScaleFactor: textScaleFactor,
accessibleNavigation: accessibleNavigation,
size: tester.view.physicalSize / tester.view.devicePixelRatio,
),
child: Material(
child: Center(
child: Directionality(
textDirection: TextDirection.ltr,
child: Navigator(
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute<void>(builder: (BuildContext context) {
return TextButton(
onPressed: () {
showTimePicker(
context: context,
initialTime: initialTime,
initialEntryMode: entryMode,
helpText: helpText,
hourLabelText: hourLabelText,
minuteLabelText: minuteLabelText,
errorInvalidText: errorInvalidText,
onEntryModeChanged: onEntryModeChange,
orientation: orientation,
);
},
child: const Text('X'),
);
});
},
),
Theme(
data: ThemeData(useMaterial3: materialType == MaterialType.material3),
child: Localizations(
locale: const Locale('en', 'US'),
delegates: const <LocalizationsDelegate<dynamic>>[
DefaultMaterialLocalizations.delegate,
DefaultWidgetsLocalizations.delegate,
],
child: MediaQuery(
data: MediaQueryData(
alwaysUse24HourFormat: alwaysUse24HourFormat,
textScaleFactor: textScaleFactor,
accessibleNavigation: accessibleNavigation,
size: tester.view.physicalSize / tester.view.devicePixelRatio,
),
child: Material(
child: Center(
child: Directionality(
textDirection: TextDirection.ltr,
child: Navigator(
onGenerateRoute: (RouteSettings settings) {
return MaterialPageRoute<void>(builder: (BuildContext context) {
return TextButton(
onPressed: () {
showTimePicker(
context: context,
initialTime: initialTime,
initialEntryMode: entryMode,
helpText: helpText,
hourLabelText: hourLabelText,
minuteLabelText: minuteLabelText,
errorInvalidText: errorInvalidText,
onEntryModeChanged: onEntryModeChange,
orientation: orientation,
);
},
child: const Text('X'),
);
});
},
),
),
),
),
),
);
}),
),
),
);
if (tapButton) {
await tester.tap(find.text('X'));
......
......@@ -99,60 +99,88 @@ void main() {
});
testWidgets('Passing no TimePickerThemeData uses defaults', (WidgetTester tester) async {
final ThemeData defaultTheme = ThemeData.fallback();
await tester.pumpWidget(const _TimePickerLauncher());
final ThemeData defaultTheme = ThemeData();
final bool material3 = defaultTheme.useMaterial3;
await tester.pumpWidget(_TimePickerLauncher(themeData: defaultTheme));
await tester.tap(find.text('X'));
await tester.pumpAndSettle(const Duration(seconds: 1));
final Material dialogMaterial = _dialogMaterial(tester);
expect(dialogMaterial.color, defaultTheme.colorScheme.surface);
expect(dialogMaterial.shape, const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0))));
expect(dialogMaterial.shape, material3
? const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(28.0)))
: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0)))
);
final RenderBox dial = tester.firstRenderObject<RenderBox>(find.byType(CustomPaint));
expect(
dial,
paints
..circle(color: defaultTheme.colorScheme.onSurface.withOpacity(0.08)) // Dial background color.
..circle(color: Color(defaultTheme.colorScheme.primary.value)), // Dial hand color.
material3
? (paints
..circle(color: defaultTheme.colorScheme.surfaceVariant.withOpacity(0.08)) // Dial background color.
..circle(color: Color(defaultTheme.colorScheme.primary.value)))
: (paints
..circle(color: defaultTheme.colorScheme.onSurface.withOpacity(0.08)) // Dial background color.
..circle(color: Color(defaultTheme.colorScheme.primary.value))), // Dial hand color.
);
final RenderParagraph hourText = _textRenderParagraph(tester, '7');
expect(
hourText.text.style,
Typography.material2014().englishLike.displayMedium!
material3
? (Typography.material2021().englishLike.displayLarge!
.merge(Typography.material2021().black.displayLarge)
.copyWith(color: defaultTheme.colorScheme.onPrimaryContainer, decorationColor: defaultTheme.colorScheme.onSurface))
: (Typography.material2014().englishLike.displayMedium!
.merge(Typography.material2014().black.displayMedium)
.copyWith(color: defaultTheme.colorScheme.primary),
.copyWith(color: defaultTheme.colorScheme.primary)),
);
final RenderParagraph minuteText = _textRenderParagraph(tester, '15');
expect(
minuteText.text.style,
Typography.material2014().englishLike.displayMedium!
material3
? (Typography.material2021().englishLike.displayLarge!
.merge(Typography.material2021().black.displayLarge)
.copyWith(color: defaultTheme.colorScheme.onSurface, decorationColor: defaultTheme.colorScheme.onSurface))
: (Typography.material2014().englishLike.displayMedium!
.merge(Typography.material2014().black.displayMedium)
.copyWith(color: defaultTheme.colorScheme.onSurface),
.copyWith(color: defaultTheme.colorScheme.onSurface)),
);
final RenderParagraph amText = _textRenderParagraph(tester, 'AM');
expect(
amText.text.style,
Typography.material2014().englishLike.titleMedium!
material3
? (Typography.material2021().englishLike.titleMedium!
.merge(Typography.material2021().black.titleMedium)
.copyWith(color: defaultTheme.colorScheme.onTertiaryContainer, decorationColor: defaultTheme.colorScheme.onSurface))
: (Typography.material2014().englishLike.titleMedium!
.merge(Typography.material2014().black.titleMedium)
.copyWith(color: defaultTheme.colorScheme.primary),
.copyWith(color: defaultTheme.colorScheme.primary)),
);
final RenderParagraph pmText = _textRenderParagraph(tester, 'PM');
expect(
pmText.text.style,
Typography.material2014().englishLike.titleMedium!
material3
? (Typography.material2021().englishLike.titleMedium!
.merge(Typography.material2021().black.titleMedium)
.copyWith(color: defaultTheme.colorScheme.onTertiaryContainer, decorationColor: defaultTheme.colorScheme.onSurface))
: (Typography.material2014().englishLike.titleMedium!
.merge(Typography.material2014().black.titleMedium)
.copyWith(color: defaultTheme.colorScheme.onSurface.withOpacity(0.6)),
.copyWith(color: defaultTheme.colorScheme.onSurface.withOpacity(0.6))),
);
final RenderParagraph helperText = _textRenderParagraph(tester, 'SELECT TIME');
final RenderParagraph helperText = _textRenderParagraph(tester, material3 ? 'Select time' : 'SELECT TIME');
expect(
helperText.text.style,
Typography.material2014().englishLike.labelSmall!
.merge(Typography.material2014().black.labelSmall),
material3
? (Typography.material2021().englishLike.bodyMedium!
.merge(Typography.material2021().black.bodyMedium)
.copyWith(color: defaultTheme.colorScheme.onSurface, decorationColor: defaultTheme.colorScheme.onSurface))
: (Typography.material2014().englishLike.labelSmall!
.merge(Typography.material2014().black.labelSmall)),
);
final CustomPaint dialPaint = tester.widget(findDialPaint);
......@@ -162,30 +190,44 @@ void main() {
expect(
// ignore: avoid_dynamic_calls
primaryLabels.first.painter.text.style,
Typography.material2014().englishLike.bodyLarge!
.merge(Typography.material2014().black.bodyLarge)
.copyWith(color: defaultTheme.colorScheme.onSurface),
material3
? (Typography.material2021().englishLike.bodyLarge!
.merge(Typography.material2021().black.bodyLarge)
.copyWith(color: defaultTheme.colorScheme.onSurface, decorationColor: defaultTheme.colorScheme.onSurface))
: (Typography.material2014().englishLike.bodyLarge!
.merge(Typography.material2014().black.bodyLarge)
.copyWith(color: defaultTheme.colorScheme.onSurface)),
);
// ignore: avoid_dynamic_calls
final List<dynamic> selectedLabels = dialPainter.selectedLabels as List<dynamic>;
expect(
// ignore: avoid_dynamic_calls
selectedLabels.first.painter.text.style,
Typography.material2014().englishLike.bodyLarge!
.merge(Typography.material2014().white.bodyLarge)
.copyWith(color: defaultTheme.colorScheme.onPrimary),
material3
? (Typography.material2021().englishLike.bodyLarge!
.merge(Typography.material2021().black.bodyLarge)
.copyWith(color: defaultTheme.colorScheme.onPrimary, decorationColor: defaultTheme.colorScheme.onSurface))
: (Typography.material2014().englishLike.bodyLarge!
.merge(Typography.material2014().white.bodyLarge)
.copyWith(color: defaultTheme.colorScheme.onPrimary)),
);
final Material hourMaterial = _textMaterial(tester, '7');
expect(hourMaterial.color, defaultTheme.colorScheme.primary.withOpacity(0.12));
expect(hourMaterial.shape, const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0))));
expect(hourMaterial.color, material3 ? defaultTheme.colorScheme.primaryContainer : defaultTheme.colorScheme.primary.withOpacity(0.12));
expect(hourMaterial.shape, material3
? const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0)))
: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0)))
);
final Material minuteMaterial = _textMaterial(tester, '15');
expect(minuteMaterial.color, defaultTheme.colorScheme.onSurface.withOpacity(0.12));
expect(minuteMaterial.shape, const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0))));
expect(minuteMaterial.color, material3 ? defaultTheme.colorScheme.surfaceVariant : defaultTheme.colorScheme.onSurface.withOpacity(0.12));
expect(minuteMaterial.shape, material3
? const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0)))
: const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0)))
);
final Material amMaterial = _textMaterial(tester, 'AM');
expect(amMaterial.color, defaultTheme.colorScheme.primary.withOpacity(0.12));
expect(amMaterial.color, material3 ? defaultTheme.colorScheme.tertiaryContainer : defaultTheme.colorScheme.primary.withOpacity(0.12));
final Material pmMaterial = _textMaterial(tester, 'PM');
expect(pmMaterial.color, Colors.transparent);
......@@ -197,49 +239,61 @@ void main() {
final Material dayPeriodMaterial = _dayPeriodMaterial(tester);
expect(
dayPeriodMaterial.shape,
RoundedRectangleBorder(
borderRadius: const BorderRadius.all(Radius.circular(4.0)),
side: BorderSide(color: expectedBorderColor),
),
material3
? RoundedRectangleBorder(
borderRadius: const BorderRadius.all(Radius.circular(8.0)),
side: BorderSide(color: defaultTheme.colorScheme.outline),
) : RoundedRectangleBorder(
borderRadius: const BorderRadius.all(Radius.circular(4.0)),
side: BorderSide(color: expectedBorderColor),
),
);
final Container dayPeriodDivider = _dayPeriodDivider(tester);
expect(
dayPeriodDivider.decoration,
BoxDecoration(border: Border(left: BorderSide(color: expectedBorderColor))),
material3
? BoxDecoration(border: Border(left: BorderSide(color: defaultTheme.colorScheme.outline)))
: BoxDecoration(border: Border(left: BorderSide(color: expectedBorderColor))),
);
final IconButton entryModeIconButton = _entryModeIconButton(tester);
expect(
entryModeIconButton.color,
defaultTheme.colorScheme.onSurface.withOpacity(0.6),
material3 ? null : defaultTheme.colorScheme.onSurface.withOpacity(0.6),
);
});
testWidgets('Passing no TimePickerThemeData uses defaults - input mode', (WidgetTester tester) async {
final ThemeData defaultTheme = ThemeData.fallback();
await tester.pumpWidget(const _TimePickerLauncher(entryMode: TimePickerEntryMode.input));
final ThemeData defaultTheme = ThemeData();
final bool material3 = defaultTheme.useMaterial3;
await tester.pumpWidget(_TimePickerLauncher(themeData: defaultTheme, entryMode: TimePickerEntryMode.input));
await tester.tap(find.text('X'));
await tester.pumpAndSettle(const Duration(seconds: 1));
final InputDecoration hourDecoration = _textField(tester, '7').decoration!;
expect(hourDecoration.filled, true);
expect(hourDecoration.fillColor, MaterialStateColor.resolveWith((Set<MaterialState> states) => defaultTheme.colorScheme.onSurface.withOpacity(0.12)));
expect(hourDecoration.enabledBorder, const OutlineInputBorder(borderSide: BorderSide(color: Colors.transparent)));
expect(hourDecoration.errorBorder, OutlineInputBorder(borderSide: BorderSide(color: defaultTheme.colorScheme.error, width: 2)));
expect(hourDecoration.focusedBorder, OutlineInputBorder(borderSide: BorderSide(color: defaultTheme.colorScheme.primary, width: 2)));
expect(hourDecoration.focusedErrorBorder, OutlineInputBorder(borderSide: BorderSide(color: defaultTheme.colorScheme.error, width: 2)));
expect(hourDecoration.fillColor, material3
? defaultTheme.colorScheme.surfaceVariant
: MaterialStateColor.resolveWith((Set<MaterialState> states) => defaultTheme.colorScheme.onSurface.withOpacity(0.12)));
expect(hourDecoration.enabledBorder, material3 ? const OutlineInputBorder(borderRadius: BorderRadius.all(Radius.circular(8.0)), borderSide: BorderSide(color: Colors.transparent)) : const OutlineInputBorder(borderSide: BorderSide(color: Colors.transparent)));
expect(hourDecoration.errorBorder, material3 ? OutlineInputBorder(borderRadius: const BorderRadius.all(Radius.circular(8.0)), borderSide: BorderSide(color: defaultTheme.colorScheme.error, width: 2.0)) : OutlineInputBorder(borderSide: BorderSide(color: defaultTheme.colorScheme.error, width: 2)));
expect(hourDecoration.focusedBorder, material3 ? OutlineInputBorder(borderRadius: const BorderRadius.all(Radius.circular(8.0)), borderSide: BorderSide(color: defaultTheme.colorScheme.primary, width: 2.0)) : OutlineInputBorder(borderSide: BorderSide(color: defaultTheme.colorScheme.primary, width: 2)));
expect(hourDecoration.focusedErrorBorder, material3 ? OutlineInputBorder(borderRadius: const BorderRadius.all(Radius.circular(8.0)), borderSide: BorderSide(color: defaultTheme.colorScheme.error, width: 2.0)) : OutlineInputBorder(borderSide: BorderSide(color: defaultTheme.colorScheme.error, width: 2)));
expect(
hourDecoration.hintStyle,
Typography.material2014().englishLike.displayMedium!
.merge(defaultTheme.textTheme.displayMedium!.copyWith(color: defaultTheme.colorScheme.onSurface.withOpacity(0.36))),
material3
? TextStyle(color: defaultTheme.colorScheme.onSurface.withOpacity(0.36))
: (Typography.material2014().englishLike.displayMedium!
.merge(defaultTheme.textTheme.displayMedium!.copyWith(color: defaultTheme.colorScheme.onSurface.withOpacity(0.36)))),
);
});
testWidgets('Time picker uses values from TimePickerThemeData', (WidgetTester tester) async {
final TimePickerThemeData timePickerTheme = _timePickerTheme();
final ThemeData theme = ThemeData(timePickerTheme: timePickerTheme);
final bool material3 = theme.useMaterial3;
await tester.pumpWidget(_TimePickerLauncher(themeData: theme));
await tester.tap(find.text('X'));
await tester.pumpAndSettle(const Duration(seconds: 1));
......@@ -259,45 +313,69 @@ void main() {
final RenderParagraph hourText = _textRenderParagraph(tester, '7');
expect(
hourText.text.style,
Typography.material2014().englishLike.bodyMedium!
material3
? (Typography.material2021().englishLike.bodyMedium!
.merge(Typography.material2021().black.bodyMedium)
.merge(timePickerTheme.hourMinuteTextStyle)
.copyWith(color: _selectedColor, decorationColor: const Color(0xff1c1b1f)))
: (Typography.material2014().englishLike.bodyMedium!
.merge(Typography.material2014().black.bodyMedium)
.merge(timePickerTheme.hourMinuteTextStyle)
.copyWith(color: _selectedColor),
.copyWith(color: _selectedColor)),
);
final RenderParagraph minuteText = _textRenderParagraph(tester, '15');
expect(
minuteText.text.style,
Typography.material2014().englishLike.bodyMedium!
material3
? (Typography.material2021().englishLike.bodyMedium!
.merge(Typography.material2021().black.bodyMedium)
.merge(timePickerTheme.hourMinuteTextStyle)
.copyWith(color: _unselectedColor, decorationColor: const Color(0xff1c1b1f)))
: (Typography.material2014().englishLike.bodyMedium!
.merge(Typography.material2014().black.bodyMedium)
.merge(timePickerTheme.hourMinuteTextStyle)
.copyWith(color: _unselectedColor),
.copyWith(color: _unselectedColor)),
);
final RenderParagraph amText = _textRenderParagraph(tester, 'AM');
expect(
amText.text.style,
Typography.material2014().englishLike.titleMedium!
material3
? (Typography.material2021().englishLike.bodyMedium!
.merge(Typography.material2021().black.bodyMedium)
.merge(timePickerTheme.hourMinuteTextStyle)
.copyWith(color: _selectedColor, decorationColor: const Color(0xff1c1b1f)))
: (Typography.material2014().englishLike.titleMedium!
.merge(Typography.material2014().black.titleMedium)
.merge(timePickerTheme.dayPeriodTextStyle)
.copyWith(color: _selectedColor),
.copyWith(color: _selectedColor)),
);
final RenderParagraph pmText = _textRenderParagraph(tester, 'PM');
expect(
pmText.text.style,
Typography.material2014().englishLike.titleMedium!
material3
? (Typography.material2021().englishLike.bodyMedium!
.merge(Typography.material2021().black.bodyMedium)
.merge(timePickerTheme.hourMinuteTextStyle)
.copyWith(color: _unselectedColor, decorationColor: const Color(0xff1c1b1f)))
: (Typography.material2014().englishLike.titleMedium!
.merge(Typography.material2014().black.titleMedium)
.merge(timePickerTheme.dayPeriodTextStyle)
.copyWith(color: _unselectedColor),
.copyWith(color: _unselectedColor)),
);
final RenderParagraph helperText = _textRenderParagraph(tester, 'SELECT TIME');
final RenderParagraph helperText = _textRenderParagraph(tester, material3 ? 'Select time' : 'SELECT TIME');
expect(
helperText.text.style,
Typography.material2014().englishLike.bodyMedium!
material3
? (Typography.material2021().englishLike.bodyMedium!
.merge(Typography.material2021().black.bodyMedium)
.merge(timePickerTheme.helpTextStyle).copyWith(color: theme.colorScheme.onSurface, decorationColor: theme.colorScheme.onSurface))
: (Typography.material2014().englishLike.bodyMedium!
.merge(Typography.material2014().black.bodyMedium)
.merge(timePickerTheme.helpTextStyle),
.merge(timePickerTheme.helpTextStyle)),
);
final CustomPaint dialPaint = tester.widget(findDialPaint);
......@@ -307,18 +385,26 @@ void main() {
expect(
// ignore: avoid_dynamic_calls
primaryLabels.first.painter.text.style,
Typography.material2014().englishLike.bodyLarge!
material3
? (Typography.material2021().englishLike.bodyLarge!
.merge(Typography.material2021().black.bodyLarge)
.copyWith(color: _unselectedColor, decorationColor: theme.colorScheme.onSurface))
: (Typography.material2014().englishLike.bodyLarge!
.merge(Typography.material2014().black.bodyLarge)
.copyWith(color: _unselectedColor),
.copyWith(color: _unselectedColor)),
);
// ignore: avoid_dynamic_calls
final List<dynamic> selectedLabels = dialPainter.selectedLabels as List<dynamic>;
expect(
// ignore: avoid_dynamic_calls
selectedLabels.first.painter.text.style,
Typography.material2014().englishLike.bodyLarge!
material3
? (Typography.material2021().englishLike.bodyLarge!
.merge(Typography.material2021().black.bodyLarge)
.copyWith(color: _selectedColor, decorationColor: theme.colorScheme.onSurface))
: (Typography.material2014().englishLike.bodyLarge!
.merge(Typography.material2014().white.bodyLarge)
.copyWith(color: _selectedColor),
.copyWith(color: _selectedColor)),
);
final Material hourMaterial = _textMaterial(tester, '7');
......@@ -350,7 +436,7 @@ void main() {
final IconButton entryModeIconButton = _entryModeIconButton(tester);
expect(
entryModeIconButton.color,
timePickerTheme.entryModeIconColor,
material3 ? null : timePickerTheme.entryModeIconColor,
);
});
......@@ -379,7 +465,7 @@ void main() {
await tester.pumpAndSettle(const Duration(seconds: 1));
final InputDecoration hourDecoration = _textField(tester, '7').decoration!;
expect(hourDecoration.fillColor, timePickerTheme.hourMinuteColor);
expect(hourDecoration.fillColor?.value, timePickerTheme.hourMinuteColor?.value);
});
}
......
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