Skip to content

Commit

Permalink
Updated material button theme tests for Material3 (flutter#128543)
Browse files Browse the repository at this point in the history
  • Loading branch information
HansMuller authored Jun 9, 2023
1 parent befd86d commit da127f1
Show file tree
Hide file tree
Showing 6 changed files with 451 additions and 24 deletions.
2 changes: 1 addition & 1 deletion packages/flutter/lib/src/material/outlined_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ class OutlinedButton extends ButtonStyleButton {
/// * hovered - Theme.colorScheme.primary(0.08)
/// * focused or pressed - Theme.colorScheme.primary(0.12)
/// * others - null
/// * `shadowColor` - null
/// * `shadowColor` - Colors.transparent,
/// * `surfaceTintColor` - null
/// * `elevation` - 0
/// * `padding`
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter/lib/src/material/text_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ class TextButton extends ButtonStyleButton {
/// * hovered - Theme.colorScheme.primary(0.08)
/// * focused or pressed - Theme.colorScheme.primary(0.12)
/// * others - null
/// * `shadowColor` - null
/// * `shadowColor` - Colors.transparent,
/// * `surfaceTintColor` - null
/// * `elevation` - 0
/// * `padding`
Expand Down
118 changes: 113 additions & 5 deletions packages/flutter/test/material/elevated_button_theme_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,48 @@ void main() {
expect(identical(ElevatedButtonThemeData.lerp(data, data, 0.5), data), true);
});

testWidgets('Passing no ElevatedButtonTheme returns defaults', (WidgetTester tester) async {
testWidgets('Material3: Passing no ElevatedButtonTheme returns defaults', (WidgetTester tester) async {
const ColorScheme colorScheme = ColorScheme.light();
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.from(colorScheme: colorScheme),
theme: ThemeData.from(colorScheme: colorScheme, useMaterial3: true),
home: Scaffold(
body: Center(
child: ElevatedButton(
onPressed: () { },
child: const Text('button'),
),
),
),
),
);

final Finder buttonMaterial = find.descendant(
of: find.byType(ElevatedButton),
matching: find.byType(Material),
);

final Material material = tester.widget<Material>(buttonMaterial);
expect(material.animationDuration, const Duration(milliseconds: 200));
expect(material.borderRadius, null);
expect(material.color, colorScheme.surface);
expect(material.elevation, 1);
expect(material.shadowColor, colorScheme.shadow);
expect(material.shape, const StadiumBorder());
expect(material.textStyle!.color, colorScheme.primary);
expect(material.textStyle!.fontFamily, 'Roboto');
expect(material.textStyle!.fontSize, 14);
expect(material.textStyle!.fontWeight, FontWeight.w500);

final Align align = tester.firstWidget<Align>(find.ancestor(of: find.text('button'), matching: find.byType(Align)));
expect(align.alignment, Alignment.center);
});

testWidgets('Material2: Passing no ElevatedButtonTheme returns defaults', (WidgetTester tester) async {
const ColorScheme colorScheme = ColorScheme.light();
await tester.pumpWidget(
MaterialApp(
theme: ThemeData.from(colorScheme: colorScheme, useMaterial3: false),
home: Scaffold(
body: Center(
child: ElevatedButton(
Expand Down Expand Up @@ -98,7 +135,7 @@ void main() {
},
);
return MaterialApp(
theme: ThemeData.from(colorScheme: const ColorScheme.light()).copyWith(
theme: ThemeData.from(useMaterial3: false, colorScheme: const ColorScheme.light()).copyWith(
elevatedButtonTheme: ElevatedButtonThemeData(style: overallStyle),
),
home: Scaffold(
Expand Down Expand Up @@ -191,14 +228,85 @@ void main() {
});
});

testWidgets('Theme shadowColor', (WidgetTester tester) async {
testWidgets('Material 3: Theme shadowColor', (WidgetTester tester) async {
const ColorScheme colorScheme = ColorScheme.light();
const Color shadowColor = Color(0xff000001);
const Color overriddenColor = Color(0xff000002);

Widget buildFrame({ Color? overallShadowColor, Color? themeShadowColor, Color? shadowColor }) {
return MaterialApp(
theme: ThemeData.from(
useMaterial3: true,
colorScheme: colorScheme.copyWith(shadow: overallShadowColor),
),
home: Scaffold(
body: Center(
child: ElevatedButtonTheme(
data: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
shadowColor: themeShadowColor,
),
),
child: Builder(
builder: (BuildContext context) {
return ElevatedButton(
style: ElevatedButton.styleFrom(
shadowColor: shadowColor,
),
onPressed: () { },
child: const Text('button'),
);
},
),
),
),
),
);
}

final Finder buttonMaterialFinder = find.descendant(
of: find.byType(ElevatedButton),
matching: find.byType(Material),
);

await tester.pumpWidget(buildFrame());
Material material = tester.widget<Material>(buttonMaterialFinder);
expect(material.shadowColor, Colors.black); //default

await tester.pumpWidget(buildFrame(overallShadowColor: shadowColor));
await tester.pumpAndSettle(); // theme animation
material = tester.widget<Material>(buttonMaterialFinder);
expect(material.shadowColor, shadowColor);

await tester.pumpWidget(buildFrame(themeShadowColor: shadowColor));
await tester.pumpAndSettle(); // theme animation
material = tester.widget<Material>(buttonMaterialFinder);
expect(material.shadowColor, shadowColor);

await tester.pumpWidget(buildFrame(shadowColor: shadowColor));
await tester.pumpAndSettle(); // theme animation
material = tester.widget<Material>(buttonMaterialFinder);
expect(material.shadowColor, shadowColor);

await tester.pumpWidget(buildFrame(overallShadowColor: overriddenColor, themeShadowColor: shadowColor));
await tester.pumpAndSettle(); // theme animation
material = tester.widget<Material>(buttonMaterialFinder);
expect(material.shadowColor, shadowColor);

await tester.pumpWidget(buildFrame(themeShadowColor: overriddenColor, shadowColor: shadowColor));
await tester.pumpAndSettle(); // theme animation
material = tester.widget<Material>(buttonMaterialFinder);
expect(material.shadowColor, shadowColor);
});

testWidgets('Material 2: Theme shadowColor', (WidgetTester tester) async {
const ColorScheme colorScheme = ColorScheme.light();
const Color shadowColor = Color(0xff000001);
const Color overriddenColor = Color(0xff000002);

Widget buildFrame({ Color? overallShadowColor, Color? themeShadowColor, Color? shadowColor }) {
return MaterialApp(
theme: ThemeData.from(colorScheme: colorScheme).copyWith(
theme: ThemeData.from(useMaterial3: false, colorScheme: colorScheme).copyWith(
shadowColor: overallShadowColor,
),
home: Scaffold(
Expand Down
117 changes: 108 additions & 9 deletions packages/flutter/test/material/floating_action_button_theme_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ void main() {
expect(identical(FloatingActionButtonThemeData.lerp(data, data, 0.5), data), true);
});

testWidgets('Default values are used when no FloatingActionButton or FloatingActionButtonThemeData properties are specified', (WidgetTester tester) async {
testWidgets('Material3: Default values are used when no FloatingActionButton or FloatingActionButtonThemeData properties are specified', (WidgetTester tester) async {
const ColorScheme colorScheme = ColorScheme.light();
await tester.pumpWidget(MaterialApp(
theme: ThemeData.from(useMaterial3: true, colorScheme: colorScheme),
home: Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () { },
Expand All @@ -29,10 +31,33 @@ void main() {
),
));

// The color scheme values are guaranteed to be non null since the default
// [ThemeData] creates it with [ColorScheme.fromSwatch].
expect(_getRawMaterialButton(tester).fillColor, ThemeData().colorScheme.secondary);
expect(_getRichText(tester).text.style!.color, ThemeData().colorScheme.onSecondary);
expect(_getRawMaterialButton(tester).fillColor, colorScheme.primaryContainer);
expect(_getRichText(tester).text.style!.color, colorScheme.onPrimaryContainer);

// These defaults come directly from the [FloatingActionButton].
expect(_getRawMaterialButton(tester).elevation, 6);
expect(_getRawMaterialButton(tester).highlightElevation, 6);
expect(_getRawMaterialButton(tester).shape, const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16.0))));
expect(_getRawMaterialButton(tester).splashColor, colorScheme.onPrimaryContainer.withOpacity(0.12));
expect(_getRawMaterialButton(tester).constraints, const BoxConstraints.tightFor(width: 56.0, height: 56.0));
expect(_getIconSize(tester).width, 24.0);
expect(_getIconSize(tester).height, 24.0);
});

testWidgets('Material2: Default values are used when no FloatingActionButton or FloatingActionButtonThemeData properties are specified', (WidgetTester tester) async {
const ColorScheme colorScheme = ColorScheme.light();
await tester.pumpWidget(MaterialApp(
theme: ThemeData.from(useMaterial3: false, colorScheme: colorScheme),
home: Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () { },
child: const Icon(Icons.add),
),
),
));

expect(_getRawMaterialButton(tester).fillColor, colorScheme.secondary);
expect(_getRichText(tester).text.style!.color, colorScheme.onSecondary);

// These defaults come directly from the [FloatingActionButton].
expect(_getRawMaterialButton(tester).elevation, 6);
Expand Down Expand Up @@ -191,7 +216,8 @@ void main() {
expect(_getIconSize(tester).height, iconSize);
});

testWidgets('FloatingActionButton.extended uses custom properties when specified in the theme', (WidgetTester tester) async {
testWidgets('Material3: FloatingActionButton.extended uses custom properties when specified in the theme', (WidgetTester tester) async {
const ColorScheme colorScheme = ColorScheme.light();
const Key iconKey = Key('icon');
const Key labelKey = Key('label');
const BoxConstraints constraints = BoxConstraints.tightFor(height: 100.0);
Expand All @@ -200,7 +226,43 @@ void main() {
const TextStyle textStyle = TextStyle(letterSpacing: 2.0);

await tester.pumpWidget(MaterialApp(
theme: ThemeData().copyWith(
theme: ThemeData(
useMaterial3: true,
colorScheme: colorScheme,
).copyWith(
floatingActionButtonTheme: const FloatingActionButtonThemeData(
extendedSizeConstraints: constraints,
extendedIconLabelSpacing: iconLabelSpacing,
extendedPadding: padding,
extendedTextStyle: textStyle,
),
),
home: Scaffold(
floatingActionButton: FloatingActionButton.extended(
onPressed: () { },
label: const Text('Extended', key: labelKey),
icon: const Icon(Icons.add, key: iconKey),
),
),
));

expect(_getRawMaterialButton(tester).constraints, constraints);
expect(tester.getTopLeft(find.byKey(labelKey)).dx - tester.getTopRight(find.byKey(iconKey)).dx, iconLabelSpacing);
expect(tester.getTopLeft(find.byKey(iconKey)).dx - tester.getTopLeft(find.byType(FloatingActionButton)).dx, padding.start);
expect(tester.getTopRight(find.byType(FloatingActionButton)).dx - tester.getTopRight(find.byKey(labelKey)).dx, padding.end);
expect(_getRawMaterialButton(tester).textStyle, textStyle.copyWith(color: colorScheme.onPrimaryContainer));
});

testWidgets('Material2: FloatingActionButton.extended uses custom properties when specified in the theme', (WidgetTester tester) async {
const Key iconKey = Key('icon');
const Key labelKey = Key('label');
const BoxConstraints constraints = BoxConstraints.tightFor(height: 100.0);
const double iconLabelSpacing = 33.0;
const EdgeInsetsDirectional padding = EdgeInsetsDirectional.only(start: 5.0, end: 6.0);
const TextStyle textStyle = TextStyle(letterSpacing: 2.0);

await tester.pumpWidget(MaterialApp(
theme: ThemeData(useMaterial3: false).copyWith(
floatingActionButtonTheme: const FloatingActionButtonThemeData(
extendedSizeConstraints: constraints,
extendedIconLabelSpacing: iconLabelSpacing,
Expand All @@ -225,15 +287,52 @@ void main() {
expect(_getRawMaterialButton(tester).textStyle, textStyle.copyWith(color: const Color(0xffffffff)));
});

testWidgets('FloatingActionButton.extended custom properties takes priority over FloatingActionButtonThemeData spacing', (WidgetTester tester) async {
testWidgets('Material3: FloatingActionButton.extended custom properties takes priority over FloatingActionButtonThemeData spacing', (WidgetTester tester) async {
const ColorScheme colorScheme = ColorScheme.light();
const Key iconKey = Key('icon');
const Key labelKey = Key('label');
const double iconLabelSpacing = 33.0;
const EdgeInsetsDirectional padding = EdgeInsetsDirectional.only(start: 5.0, end: 6.0);
const TextStyle textStyle = TextStyle(letterSpacing: 2.0);

await tester.pumpWidget(MaterialApp(
theme: ThemeData().copyWith(
theme: ThemeData(
useMaterial3: true,
colorScheme: colorScheme,
).copyWith(
floatingActionButtonTheme: const FloatingActionButtonThemeData(
extendedIconLabelSpacing: 25.0,
extendedPadding: EdgeInsetsDirectional.only(start: 7.0, end: 8.0),
extendedTextStyle: TextStyle(letterSpacing: 3.0),
),
),
home: Scaffold(
floatingActionButton: FloatingActionButton.extended(
onPressed: () { },
label: const Text('Extended', key: labelKey),
icon: const Icon(Icons.add, key: iconKey),
extendedIconLabelSpacing: iconLabelSpacing,
extendedPadding: padding,
extendedTextStyle: textStyle,
),
),
));

expect(tester.getTopLeft(find.byKey(labelKey)).dx - tester.getTopRight(find.byKey(iconKey)).dx, iconLabelSpacing);
expect(tester.getTopLeft(find.byKey(iconKey)).dx - tester.getTopLeft(find.byType(FloatingActionButton)).dx, padding.start);
expect(tester.getTopRight(find.byType(FloatingActionButton)).dx - tester.getTopRight(find.byKey(labelKey)).dx, padding.end);
expect(_getRawMaterialButton(tester).textStyle, textStyle.copyWith(color: colorScheme.onPrimaryContainer));
});

testWidgets('Material2: FloatingActionButton.extended custom properties takes priority over FloatingActionButtonThemeData spacing', (WidgetTester tester) async {
const Key iconKey = Key('icon');
const Key labelKey = Key('label');
const double iconLabelSpacing = 33.0;
const EdgeInsetsDirectional padding = EdgeInsetsDirectional.only(start: 5.0, end: 6.0);
const TextStyle textStyle = TextStyle(letterSpacing: 2.0);

await tester.pumpWidget(MaterialApp(
theme: ThemeData(useMaterial3: false).copyWith(
floatingActionButtonTheme: const FloatingActionButtonThemeData(
extendedIconLabelSpacing: 25.0,
extendedPadding: EdgeInsetsDirectional.only(start: 7.0, end: 8.0),
Expand Down
Loading

0 comments on commit da127f1

Please sign in to comment.