From da127f15ad54f3396e475540dbfb3fda790a0e1d Mon Sep 17 00:00:00 2001 From: Hans Muller Date: Fri, 9 Jun 2023 06:57:21 -0700 Subject: [PATCH] Updated material button theme tests for Material3 (#128543) --- .../lib/src/material/outlined_button.dart | 2 +- .../flutter/lib/src/material/text_button.dart | 2 +- .../material/elevated_button_theme_test.dart | 118 ++++++++++++++++- .../floating_action_button_theme_test.dart | 117 +++++++++++++++-- .../material/outlined_button_theme_test.dart | 120 +++++++++++++++++- .../test/material/text_button_theme_test.dart | 116 ++++++++++++++++- 6 files changed, 451 insertions(+), 24 deletions(-) diff --git a/packages/flutter/lib/src/material/outlined_button.dart b/packages/flutter/lib/src/material/outlined_button.dart index 9657547198..8ee11e3b3e 100644 --- a/packages/flutter/lib/src/material/outlined_button.dart +++ b/packages/flutter/lib/src/material/outlined_button.dart @@ -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` diff --git a/packages/flutter/lib/src/material/text_button.dart b/packages/flutter/lib/src/material/text_button.dart index 30dab7bc1d..8e5c2db548 100644 --- a/packages/flutter/lib/src/material/text_button.dart +++ b/packages/flutter/lib/src/material/text_button.dart @@ -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` diff --git a/packages/flutter/test/material/elevated_button_theme_test.dart b/packages/flutter/test/material/elevated_button_theme_test.dart index 7c6dfa3035..1957b74638 100644 --- a/packages/flutter/test/material/elevated_button_theme_test.dart +++ b/packages/flutter/test/material/elevated_button_theme_test.dart @@ -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(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(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( @@ -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( @@ -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(colorScheme: colorScheme).copyWith( + 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(buttonMaterialFinder); + expect(material.shadowColor, Colors.black); //default + + await tester.pumpWidget(buildFrame(overallShadowColor: shadowColor)); + await tester.pumpAndSettle(); // theme animation + material = tester.widget(buttonMaterialFinder); + expect(material.shadowColor, shadowColor); + + await tester.pumpWidget(buildFrame(themeShadowColor: shadowColor)); + await tester.pumpAndSettle(); // theme animation + material = tester.widget(buttonMaterialFinder); + expect(material.shadowColor, shadowColor); + + await tester.pumpWidget(buildFrame(shadowColor: shadowColor)); + await tester.pumpAndSettle(); // theme animation + material = tester.widget(buttonMaterialFinder); + expect(material.shadowColor, shadowColor); + + await tester.pumpWidget(buildFrame(overallShadowColor: overriddenColor, themeShadowColor: shadowColor)); + await tester.pumpAndSettle(); // theme animation + material = tester.widget(buttonMaterialFinder); + expect(material.shadowColor, shadowColor); + + await tester.pumpWidget(buildFrame(themeShadowColor: overriddenColor, shadowColor: shadowColor)); + await tester.pumpAndSettle(); // theme animation + material = tester.widget(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(useMaterial3: false, colorScheme: colorScheme).copyWith( shadowColor: overallShadowColor, ), home: Scaffold( diff --git a/packages/flutter/test/material/floating_action_button_theme_test.dart b/packages/flutter/test/material/floating_action_button_theme_test.dart index e88e67e6ee..f3d54f6995 100644 --- a/packages/flutter/test/material/floating_action_button_theme_test.dart +++ b/packages/flutter/test/material/floating_action_button_theme_test.dart @@ -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: () { }, @@ -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); @@ -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); @@ -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, @@ -225,7 +287,8 @@ 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; @@ -233,7 +296,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( + 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), diff --git a/packages/flutter/test/material/outlined_button_theme_test.dart b/packages/flutter/test/material/outlined_button_theme_test.dart index fb06b126b9..93e10033f7 100644 --- a/packages/flutter/test/material/outlined_button_theme_test.dart +++ b/packages/flutter/test/material/outlined_button_theme_test.dart @@ -12,11 +12,52 @@ void main() { expect(identical(OutlinedButtonThemeData.lerp(data, data, 0.5), data), true); }); - testWidgets('Passing no OutlinedButtonTheme returns defaults', (WidgetTester tester) async { + testWidgets('Material3: Passing no OutlinedButtonTheme returns defaults', (WidgetTester tester) async { const ColorScheme colorScheme = ColorScheme.light(); await tester.pumpWidget( MaterialApp( - theme: ThemeData.from(colorScheme: colorScheme), + theme: ThemeData.from(useMaterial3: true, colorScheme: colorScheme), + home: Scaffold( + body: Center( + child: OutlinedButton( + onPressed: () { }, + child: const Text('button'), + ), + ), + ), + ), + ); + + final Finder buttonMaterial = find.descendant( + of: find.byType(OutlinedButton), + matching: find.byType(Material), + ); + + final Material material = tester.widget(buttonMaterial); + expect(material.animationDuration, const Duration(milliseconds: 200)); + expect(material.borderRadius, null); + expect(material.color, Colors.transparent); + expect(material.elevation, 0.0); + expect(material.shadowColor, Colors.transparent); + + expect(material.shape, isInstanceOf()); + final StadiumBorder materialShape = material.shape! as StadiumBorder; + expect(materialShape.side, BorderSide(color: colorScheme.outline)); + + 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(find.ancestor(of: find.text('button'), matching: find.byType(Align))); + expect(align.alignment, Alignment.center); + }); + + testWidgets('Material2: Passing no OutlinedButtonTheme returns defaults', (WidgetTester tester) async { + const ColorScheme colorScheme = ColorScheme.light(); + await tester.pumpWidget( + MaterialApp( + theme: ThemeData.from(useMaterial3: false, colorScheme: colorScheme), home: Scaffold( body: Center( child: OutlinedButton( @@ -194,14 +235,85 @@ void main() { }); }); - testWidgets('Theme shadowColor', (WidgetTester tester) async { + testWidgets('Material3: 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: true, + colorScheme: colorScheme.copyWith(shadow: overallShadowColor), + ), + home: Scaffold( + body: Center( + child: OutlinedButtonTheme( + data: OutlinedButtonThemeData( + style: OutlinedButton.styleFrom( + shadowColor: themeShadowColor, + ), + ), + child: Builder( + builder: (BuildContext context) { + return OutlinedButton( + style: OutlinedButton.styleFrom( + shadowColor: shadowColor, + ), + onPressed: () { }, + child: const Text('button'), + ); + }, + ), + ), + ), + ), + ); + } + + final Finder buttonMaterialFinder = find.descendant( + of: find.byType(OutlinedButton), + matching: find.byType(Material), + ); + + await tester.pumpWidget(buildFrame()); + Material material = tester.widget(buttonMaterialFinder); + expect(material.shadowColor, Colors.transparent); + + await tester.pumpWidget(buildFrame(overallShadowColor: shadowColor)); + await tester.pumpAndSettle(); // theme animation + material = tester.widget(buttonMaterialFinder); + expect(material.shadowColor, Colors.transparent); + + await tester.pumpWidget(buildFrame(themeShadowColor: shadowColor)); + await tester.pumpAndSettle(); // theme animation + material = tester.widget(buttonMaterialFinder); + expect(material.shadowColor, shadowColor); + + await tester.pumpWidget(buildFrame(shadowColor: shadowColor)); + await tester.pumpAndSettle(); // theme animation + material = tester.widget(buttonMaterialFinder); + expect(material.shadowColor, shadowColor); + + await tester.pumpWidget(buildFrame(overallShadowColor: overriddenColor, themeShadowColor: shadowColor)); + await tester.pumpAndSettle(); // theme animation + material = tester.widget(buttonMaterialFinder); + expect(material.shadowColor, shadowColor); + + await tester.pumpWidget(buildFrame(themeShadowColor: overriddenColor, shadowColor: shadowColor)); + await tester.pumpAndSettle(); // theme animation + material = tester.widget(buttonMaterialFinder); + expect(material.shadowColor, shadowColor); + }); + + testWidgets('Material2: 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: false, colorScheme: colorScheme).copyWith( shadowColor: overallShadowColor, ), home: Scaffold( diff --git a/packages/flutter/test/material/text_button_theme_test.dart b/packages/flutter/test/material/text_button_theme_test.dart index b7b6a7de50..473e0a6447 100644 --- a/packages/flutter/test/material/text_button_theme_test.dart +++ b/packages/flutter/test/material/text_button_theme_test.dart @@ -12,11 +12,48 @@ void main() { expect(identical(TextButtonThemeData.lerp(data, data, 0.5), data), true); }); - testWidgets('Passing no TextButtonTheme returns defaults', (WidgetTester tester) async { + testWidgets('Material3: Passing no TextButtonTheme returns defaults', (WidgetTester tester) async { const ColorScheme colorScheme = ColorScheme.light(); await tester.pumpWidget( MaterialApp( - theme: ThemeData.from(colorScheme: colorScheme), + theme: ThemeData.from(useMaterial3: true, colorScheme: colorScheme), + home: Scaffold( + body: Center( + child: TextButton( + onPressed: () { }, + child: const Text('button'), + ), + ), + ), + ), + ); + + final Finder buttonMaterial = find.descendant( + of: find.byType(TextButton), + matching: find.byType(Material), + ); + + final Material material = tester.widget(buttonMaterial); + expect(material.animationDuration, const Duration(milliseconds: 200)); + expect(material.borderRadius, null); + expect(material.color, Colors.transparent); + expect(material.elevation, 0.0); + expect(material.shadowColor, Colors.transparent); + 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(find.ancestor(of: find.text('button'), matching: find.byType(Align))); + expect(align.alignment, Alignment.center); + }); + + testWidgets('Material2: Passing no TextButtonTheme returns defaults', (WidgetTester tester) async { + const ColorScheme colorScheme = ColorScheme.light(); + await tester.pumpWidget( + MaterialApp( + theme: ThemeData.from(useMaterial3: false, colorScheme: colorScheme), home: Scaffold( body: Center( child: TextButton( @@ -189,14 +226,85 @@ void main() { }); }); - testWidgets('Theme shadowColor', (WidgetTester tester) async { + testWidgets('Material3: 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: true, + colorScheme: colorScheme.copyWith(shadow: overallShadowColor), + ), + home: Scaffold( + body: Center( + child: TextButtonTheme( + data: TextButtonThemeData( + style: TextButton.styleFrom( + shadowColor: themeShadowColor, + ), + ), + child: Builder( + builder: (BuildContext context) { + return TextButton( + style: TextButton.styleFrom( + shadowColor: shadowColor, + ), + onPressed: () { }, + child: const Text('button'), + ); + }, + ), + ), + ), + ), + ); + } + + final Finder buttonMaterialFinder = find.descendant( + of: find.byType(TextButton), + matching: find.byType(Material), + ); + + await tester.pumpWidget(buildFrame()); + Material material = tester.widget(buttonMaterialFinder); + expect(material.shadowColor, Colors.transparent); + + await tester.pumpWidget(buildFrame(overallShadowColor: shadowColor)); + await tester.pumpAndSettle(); // theme animation + material = tester.widget(buttonMaterialFinder); + expect(material.shadowColor, Colors.transparent); + + await tester.pumpWidget(buildFrame(themeShadowColor: shadowColor)); + await tester.pumpAndSettle(); // theme animation + material = tester.widget(buttonMaterialFinder); + expect(material.shadowColor, shadowColor); + + await tester.pumpWidget(buildFrame(shadowColor: shadowColor)); + await tester.pumpAndSettle(); // theme animation + material = tester.widget(buttonMaterialFinder); + expect(material.shadowColor, shadowColor); + + await tester.pumpWidget(buildFrame(overallShadowColor: overriddenColor, themeShadowColor: shadowColor)); + await tester.pumpAndSettle(); // theme animation + material = tester.widget(buttonMaterialFinder); + expect(material.shadowColor, shadowColor); + + await tester.pumpWidget(buildFrame(themeShadowColor: overriddenColor, shadowColor: shadowColor)); + await tester.pumpAndSettle(); // theme animation + material = tester.widget(buttonMaterialFinder); + expect(material.shadowColor, shadowColor); + }); + + testWidgets('Material2: 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: false, colorScheme: colorScheme).copyWith( shadowColor: overallShadowColor, ), home: Scaffold(