From b460d49199e56459cc8a27688a71075bbb3cfbbc Mon Sep 17 00:00:00 2001 From: Taha Tesser Date: Tue, 18 Jul 2023 19:24:11 +0300 Subject: [PATCH] Update `AppBar` and `AppBarTheme` tests for M2/M3 (#130790) Updated unit tests for `AppBar` and `AppBarTheme` to have M2 and M3 versions. More info in https://github.com/flutter/flutter/issues/127064 --- .../flutter/test/material/app_bar_test.dart | 461 +++++++++++++++--- .../test/material/app_bar_theme_test.dart | 371 ++++++++------ 2 files changed, 597 insertions(+), 235 deletions(-) diff --git a/packages/flutter/test/material/app_bar_test.dart b/packages/flutter/test/material/app_bar_test.dart index 79e60bce01a..eb51024e1de 100644 --- a/packages/flutter/test/material/app_bar_test.dart +++ b/packages/flutter/test/material/app_bar_test.dart @@ -559,10 +559,11 @@ void main() { ); }); - testWidgets('AppBar drawer icon has default color', (WidgetTester tester) async { - final ThemeData themeData = ThemeData.from(colorScheme: const ColorScheme.light()); - final bool useMaterial3 = themeData.useMaterial3; - + testWidgets('Material2 - AppBar drawer icon has default color', (WidgetTester tester) async { + final ThemeData themeData = ThemeData.from( + colorScheme: const ColorScheme.light(), + useMaterial3: false, + ); await tester.pumpWidget( MaterialApp( theme: themeData, @@ -575,10 +576,27 @@ void main() { ), ); - Color? iconColor() => _iconStyle(tester, Icons.menu)?.color; - final Color iconColorM2 = themeData.colorScheme.onPrimary; - final Color iconColorM3 = themeData.colorScheme.onSurfaceVariant; - expect(iconColor(), useMaterial3 ? iconColorM3 : iconColorM2); + expect(_iconStyle(tester, Icons.menu)?.color, themeData.colorScheme.onPrimary); + }); + + testWidgets('Material3 - AppBar drawer icon has default color', (WidgetTester tester) async { + final ThemeData themeData = ThemeData.from( + colorScheme: const ColorScheme.light(), + useMaterial3: true, + ); + await tester.pumpWidget( + MaterialApp( + theme: themeData, + home: Scaffold( + appBar: AppBar( + title: const Text('Howdy!'), + ), + drawer: const Drawer(), + ), + ), + ); + + expect(_iconStyle(tester, Icons.menu)?.color, themeData.colorScheme.onSurfaceVariant); }); testWidgets('AppBar drawer icon is sized by iconTheme', (WidgetTester tester) async { @@ -616,9 +634,7 @@ void main() { ), ); - Color? iconColor() => _iconStyle(tester, Icons.menu)?.color; - - expect(iconColor(), color); + expect(_iconStyle(tester, Icons.menu)?.color, color); }); testWidgets('AppBar endDrawer icon has default size', (WidgetTester tester) async { @@ -632,6 +648,7 @@ void main() { ), ), ); + final double iconSize = const IconThemeData.fallback().size!; expect( tester.getSize(find.byIcon(Icons.menu)), @@ -639,10 +656,11 @@ void main() { ); }); - testWidgets('AppBar endDrawer icon has default color', (WidgetTester tester) async { - final ThemeData themeData = ThemeData.from(colorScheme: const ColorScheme.light()); - final bool useMaterial3 = themeData.useMaterial3; - + testWidgets('Material2 - AppBar endDrawer icon has default color', (WidgetTester tester) async { + final ThemeData themeData = ThemeData.from( + colorScheme: const ColorScheme.light(), + useMaterial3: false, + ); await tester.pumpWidget( MaterialApp( theme: themeData, @@ -655,10 +673,27 @@ void main() { ), ); - Color? iconColor() => _iconStyle(tester, Icons.menu)?.color; - final Color iconColorM2 = themeData.colorScheme.onPrimary; - final Color iconColorM3 = themeData.colorScheme.onSurfaceVariant; - expect(iconColor(), useMaterial3 ? iconColorM3 : iconColorM2); + expect(_iconStyle(tester, Icons.menu)?.color, themeData.colorScheme.onPrimary); + }); + + testWidgets('Material3 - AppBar endDrawer icon has default color', (WidgetTester tester) async { + final ThemeData themeData = ThemeData.from( + colorScheme: const ColorScheme.light(), + useMaterial3: true, + ); + await tester.pumpWidget( + MaterialApp( + theme: themeData, + home: Scaffold( + appBar: AppBar( + title: const Text('Howdy!'), + ), + endDrawer: const Drawer(), + ), + ), + ); + + expect(_iconStyle(tester, Icons.menu)?.color, themeData.colorScheme.onSurfaceVariant); }); testWidgets('AppBar endDrawer icon is sized by iconTheme', (WidgetTester tester) async { @@ -696,14 +731,14 @@ void main() { ), ); - Color? iconColor() => _iconStyle(tester, Icons.menu)?.color; - - expect(iconColor(), color); + expect(_iconStyle(tester, Icons.menu)?.color, color); }); - testWidgets('leading widget extends to edge and is square', (WidgetTester tester) async { - final ThemeData themeData = ThemeData(platform: TargetPlatform.android); - final bool material3 = themeData.useMaterial3; + testWidgets('Material2 - leading widget extends to edge and is square', (WidgetTester tester) async { + final ThemeData themeData = ThemeData( + platform: TargetPlatform.android, + useMaterial3: false, + ); await tester.pumpWidget( MaterialApp( theme: themeData, @@ -717,10 +752,10 @@ void main() { ), ); - // Default IconButton has a size of (48x48) in M3, (56x56) in M2 + // Default IconButton has a size of (56x56). final Finder hamburger = find.byType(IconButton); - expect(tester.getTopLeft(hamburger), material3 ? const Offset(4.0, 4.0) : Offset.zero); - expect(tester.getSize(hamburger), material3 ? const Size(48.0, 48.0) : const Size(56.0, 56.0)); + expect(tester.getTopLeft(hamburger), Offset.zero); + expect(tester.getSize(hamburger), const Size(56.0, 56.0)); await tester.pumpWidget( MaterialApp( @@ -734,7 +769,7 @@ void main() { ), ); - // Default leading widget has a size of (56x56) for both M2 and M3 + // Default leading widget has a size of (56x56). final Finder leadingBox = find.byType(Container); expect(tester.getTopLeft(leadingBox), Offset.zero); expect(tester.getSize(leadingBox), const Size(56.0, 56.0)); @@ -757,9 +792,69 @@ void main() { expect(tester.getSize(leading), const Size(56.0, 56.0)); }); - testWidgets('test action is 4dp from edge and 48dp min', (WidgetTester tester) async { - final ThemeData theme = ThemeData(platform: TargetPlatform.android); - final bool material3 = theme.useMaterial3; + testWidgets('Material3 - leading widget extends to edge and is square', (WidgetTester tester) async { + final ThemeData themeData = ThemeData( + platform: TargetPlatform.android, + useMaterial3: true, + ); + await tester.pumpWidget( + MaterialApp( + theme: themeData, + home: Scaffold( + appBar: AppBar( + leading: IconButton(icon: const Icon(Icons.menu), onPressed: () {}), + title: const Text('X'), + ), + drawer: const Column(), // Doesn't really matter. Triggers a hamburger regardless. + ), + ), + ); + + // Default IconButton has a size of (48x48). + final Finder hamburger = find.byType(IconButton); + expect(tester.getTopLeft(hamburger), const Offset(4.0, 4.0)); + expect(tester.getSize(hamburger), const Size(48.0, 48.0)); + + await tester.pumpWidget( + MaterialApp( + theme: themeData, + home: Scaffold( + appBar: AppBar( + leading: Container(), + title: const Text('X'), + ), + ), + ), + ); + + // Default leading widget has a size of (56x56). + final Finder leadingBox = find.byType(Container); + expect(tester.getTopLeft(leadingBox), Offset.zero); + expect(tester.getSize(leadingBox), const Size(56.0, 56.0)); + + // The custom leading widget should still be 56x56 even if its size is smaller. + await tester.pumpWidget( + MaterialApp( + theme: themeData, + home: Scaffold( + appBar: AppBar( + leading: const SizedBox(height: 36, width: 36,), + title: const Text('X'), + ), // Doesn't really matter. Triggers a hamburger regardless. + ), + ), + ); + + final Finder leading = find.byType(SizedBox); + expect(tester.getTopLeft(leading), Offset.zero); + expect(tester.getSize(leading), const Size(56.0, 56.0)); + }); + + testWidgets('Material2 - Action is 4dp from edge and 48dp min', (WidgetTester tester) async { + final ThemeData theme = ThemeData( + platform: TargetPlatform.android, + useMaterial3: false, + ); await tester.pumpWidget( MaterialApp( theme: theme, @@ -792,7 +887,47 @@ void main() { final Finder shareButton = find.widgetWithIcon(IconButton, Icons.share); // The 20dp icon is expanded to fill the IconButton's touch target to 48dp. - expect(tester.getSize(shareButton), material3 ? const Size(48.0, 48.0) : const Size(48.0, 56.0)); + expect(tester.getSize(shareButton), const Size(48.0, 56.0)); + }); + + testWidgets('Material3 - Action is 4dp from edge and 48dp min', (WidgetTester tester) async { + final ThemeData theme = ThemeData( + platform: TargetPlatform.android, + useMaterial3: true, + ); + await tester.pumpWidget( + MaterialApp( + theme: theme, + home: Scaffold( + appBar: AppBar( + title: const Text('X'), + actions: const [ + IconButton( + icon: Icon(Icons.share), + onPressed: null, + tooltip: 'Share', + iconSize: 20.0, + ), + IconButton( + icon: Icon(Icons.add), + onPressed: null, + tooltip: 'Add', + iconSize: 60.0, + ), + ], + ), + ), + ), + ); + + final Finder addButton = find.widgetWithIcon(IconButton, Icons.add); + expect(tester.getTopRight(addButton), const Offset(800.0, 0.0)); + // It's still the size it was plus the 2 * 8dp padding from IconButton. + expect(tester.getSize(addButton), const Size(60.0 + 2 * 8.0, 56.0)); + + final Finder shareButton = find.widgetWithIcon(IconButton, Icons.share); + // The 20dp icon is expanded to fill the IconButton's touch target to 48dp. + expect(tester.getSize(shareButton), const Size(48.0, 48.0)); }); testWidgets('SliverAppBar default configuration', (WidgetTester tester) async { @@ -828,7 +963,6 @@ void main() { }); testWidgets('SliverAppBar expandedHeight, pinned', (WidgetTester tester) async { - await tester.pumpWidget(buildSliverAppBarApp( pinned: true, expandedHeight: 128.0, @@ -860,7 +994,6 @@ void main() { }); testWidgets('SliverAppBar expandedHeight, pinned and floating', (WidgetTester tester) async { - await tester.pumpWidget(buildSliverAppBarApp( floating: true, pinned: true, @@ -1096,7 +1229,7 @@ void main() { expect(tabBarHeight(tester), initialTabBarHeight); }); - testWidgets('SliverAppBar.medium defaults', (WidgetTester tester) async { + testWidgets('Material3 - SliverAppBar.medium defaults', (WidgetTester tester) async { final ThemeData theme = ThemeData(useMaterial3: true); const double collapsedAppBarHeight = 64; const double expandedAppBarHeight = 112; @@ -1183,7 +1316,7 @@ void main() { expect(tester.getSize(expandedTitleClip).height, expandedAppBarHeight - collapsedAppBarHeight); }); - testWidgets('SliverAppBar.large defaults', (WidgetTester tester) async { + testWidgets('Material3 - SliverAppBar.large defaults', (WidgetTester tester) async { final ThemeData theme = ThemeData(useMaterial3: true); const double collapsedAppBarHeight = 64; const double expandedAppBarHeight = 152; @@ -1276,11 +1409,10 @@ void main() { expect(tester.getSize(expandedTitleClip).height, expandedAppBarHeight - collapsedAppBarHeight); }); - testWidgets('AppBar uses the specified elevation or defaults to 4.0', (WidgetTester tester) async { - final bool useMaterial3 = ThemeData().useMaterial3; - + testWidgets('Material2 - AppBar uses the specified elevation or defaults to 4.0', (WidgetTester tester) async { Widget buildAppBar([double? elevation]) { return MaterialApp( + theme: ThemeData(useMaterial3: false), home: Scaffold( appBar: AppBar(title: const Text('Title'), elevation: elevation), ), @@ -1294,7 +1426,31 @@ void main() { // Default elevation should be used for the material. await tester.pumpWidget(buildAppBar()); - expect(getMaterial().elevation, useMaterial3 ? 0 : 4); + expect(getMaterial().elevation, 4); + + // AppBar should use the specified elevation. + await tester.pumpWidget(buildAppBar(8.0)); + expect(getMaterial().elevation, 8.0); + }); + + testWidgets('Material3 - AppBar uses the specified elevation or defaults to 0', (WidgetTester tester) async { + Widget buildAppBar([double? elevation]) { + return MaterialApp( + theme: ThemeData(useMaterial3: true), + home: Scaffold( + appBar: AppBar(title: const Text('Title'), elevation: elevation), + ), + ); + } + + Material getMaterial() => tester.widget(find.descendant( + of: find.byType(AppBar), + matching: find.byType(Material), + )); + + // Default elevation should be used for the material. + await tester.pumpWidget(buildAppBar()); + expect(getMaterial().elevation, 0); // AppBar should use the specified elevation. await tester.pumpWidget(buildAppBar(8.0)); @@ -1334,7 +1490,7 @@ void main() { expect(getMaterial().elevation, 10); }); - testWidgets('scrolledUnderElevation with nested scroll view', (WidgetTester tester) async { + testWidgets('Material3 - scrolledUnderElevation with nested scroll view', (WidgetTester tester) async { Widget buildAppBar({double? scrolledUnderElevation}) { return MaterialApp( theme: ThemeData(useMaterial3: true), @@ -1840,7 +1996,7 @@ void main() { ); }); - testWidgets('AppBar ink splash draw on the correct canvas', (WidgetTester tester) async { + testWidgets('Material2 - AppBar ink splash draw on the correct canvas', (WidgetTester tester) async { // This is a regression test for https://github.com/flutter/flutter/issues/58665 final Key key = UniqueKey(); await tester.pumpWidget( @@ -1887,6 +2043,53 @@ void main() { expect(painter, paints..save()..translate()..save()..translate()..circle(x: 24.0, y: 28.0)); }); + testWidgets('Material3 - AppBar ink splash draw on the correct canvas', (WidgetTester tester) async { + // This is a regression test for https://github.com/flutter/flutter/issues/58665 + final Key key = UniqueKey(); + await tester.pumpWidget( + MaterialApp( + // Test was designed against InkSplash so need to make sure that is used. + theme: ThemeData( + useMaterial3: true, + splashFactory: InkSplash.splashFactory + ), + home: Center( + child: AppBar( + title: const Text('Abc'), + actions: [ + IconButton( + key: key, + icon: const Icon(Icons.add_circle), + tooltip: 'First button', + onPressed: () {}, + ), + ], + flexibleSpace: DecoratedBox( + decoration: BoxDecoration( + gradient: LinearGradient( + begin: Alignment.topCenter, + end: const Alignment(-0.04, 1.0), + colors: [Colors.blue.shade500, Colors.blue.shade800], + ), + ), + ), + ), + ), + ), + ); + final RenderObject painter = tester.renderObject( + find.descendant( + of: find.descendant( + of: find.byType(AppBar), + matching: find.byType(Stack), + ), + matching: find.byType(Material).last, + ), + ); + await tester.tap(find.byKey(key)); + expect(painter, paints..save()..translate()..save()..translate()..circle(x: 20.0, y: 20.0)); + }); + testWidgets('AppBar handles loose children 0', (WidgetTester tester) async { final GlobalKey key = GlobalKey(); await tester.pumpWidget( @@ -2011,7 +2214,6 @@ void main() { testWidgets('AppBar positioning of leading and trailing widgets with top padding', (WidgetTester tester) async { const MediaQueryData topPadding100 = MediaQueryData(padding: EdgeInsets.only(top: 100)); - final Key leadingKey = UniqueKey(); final Key titleKey = UniqueKey(); final Key trailingKey = UniqueKey(); @@ -2055,7 +2257,6 @@ void main() { testWidgets('SliverAppBar positioning of leading and trailing widgets with top padding', (WidgetTester tester) async { const MediaQueryData topPadding100 = MediaQueryData(padding: EdgeInsets.only(top: 100.0)); - final Key leadingKey = UniqueKey(); final Key titleKey = UniqueKey(); final Key trailingKey = UniqueKey(); @@ -2093,7 +2294,6 @@ void main() { testWidgets('SliverAppBar positioning of leading and trailing widgets with bottom padding', (WidgetTester tester) async { const MediaQueryData topPadding100 = MediaQueryData(padding: EdgeInsets.only(top: 100.0, bottom: 50.0)); - final Key leadingKey = UniqueKey(); final Key titleKey = UniqueKey(); final Key trailingKey = UniqueKey(); @@ -2503,7 +2703,7 @@ void main() { semantics.dispose(); }); - testWidgets('AppBar draws a light system bar for a dark background', (WidgetTester tester) async { + testWidgets('Material2 - AppBar draws a light system bar for a dark background', (WidgetTester tester) async { final ThemeData darkTheme = ThemeData.dark(useMaterial3: false); await tester.pumpWidget(MaterialApp( theme: darkTheme, @@ -2521,7 +2721,26 @@ void main() { )); }); - testWidgets('AppBar draws a dark system bar for a light background', (WidgetTester tester) async { + testWidgets('Material3 - AppBar draws a light system bar for a dark background', (WidgetTester tester) async { + final ThemeData darkTheme = ThemeData.dark(useMaterial3: true); + await tester.pumpWidget(MaterialApp( + theme: darkTheme, + home: Scaffold( + appBar: AppBar( + title: const Text('test'), + ), + ), + )); + + expect(darkTheme.colorScheme.brightness, Brightness.dark); + expect(SystemChrome.latestStyle, const SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + statusBarBrightness: Brightness.dark, + statusBarIconBrightness: Brightness.light, + )); + }); + + testWidgets('Material2 - AppBar draws a dark system bar for a light background', (WidgetTester tester) async { final ThemeData lightTheme = ThemeData(primarySwatch: Colors.lightBlue, useMaterial3: false); await tester.pumpWidget( MaterialApp( @@ -2541,7 +2760,28 @@ void main() { )); }); - testWidgets('Default system bar brightness based on AppBar background color brightness.', (WidgetTester tester) async { + testWidgets('Material3 - AppBar draws a dark system bar for a light background', (WidgetTester tester) async { + final ThemeData lightTheme = ThemeData(useMaterial3: true); + await tester.pumpWidget( + MaterialApp( + theme: lightTheme, + home: Scaffold( + appBar: AppBar( + title: const Text('test'), + ), + ), + ), + ); + + expect(lightTheme.colorScheme.brightness, Brightness.light); + expect(SystemChrome.latestStyle, const SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + statusBarBrightness: Brightness.light, + statusBarIconBrightness: Brightness.dark, + )); + }); + + testWidgets('Material2 - Default system bar brightness based on AppBar background color brightness.', (WidgetTester tester) async { Widget buildAppBar(ThemeData theme) { return MaterialApp( theme: theme, @@ -2592,27 +2832,94 @@ void main() { } }); - testWidgets('Default status bar color', (WidgetTester tester) async { - Future pumpBoilerplate({required bool useMaterial3}) async { - await tester.pumpWidget( - MaterialApp( - key: GlobalKey(), - theme: ThemeData.light().copyWith( - useMaterial3: useMaterial3, - appBarTheme: const AppBarTheme(), - ), - home: Scaffold( - appBar: AppBar( - title: const Text('title'), - ), - ), + testWidgets('Material3 - Default system bar brightness based on AppBar background color brightness.', (WidgetTester tester) async { + Widget buildAppBar(ThemeData theme) { + return MaterialApp( + theme: theme, + home: Scaffold( + appBar: AppBar(title: const Text('Title')), ), ); } - await pumpBoilerplate(useMaterial3: false); + // Using a light theme. + { + await tester.pumpWidget(buildAppBar(ThemeData(useMaterial3: true))); + final Material appBarMaterial = tester.widget( + find.descendant( + of: find.byType(AppBar), + matching: find.byType(Material), + ), + ); + final Brightness appBarBrightness = ThemeData.estimateBrightnessForColor(appBarMaterial.color!); + final Brightness onAppBarBrightness = appBarBrightness == Brightness.light + ? Brightness.dark + : Brightness.light; + + expect(SystemChrome.latestStyle, SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + statusBarBrightness: appBarBrightness, + statusBarIconBrightness: onAppBarBrightness, + )); + } + + // Using a dark theme. + { + await tester.pumpWidget(buildAppBar(ThemeData.dark(useMaterial3: true))); + final Material appBarMaterial = tester.widget( + find.descendant( + of: find.byType(AppBar), + matching: find.byType(Material), + ), + ); + final Brightness appBarBrightness = ThemeData.estimateBrightnessForColor(appBarMaterial.color!); + final Brightness onAppBarBrightness = appBarBrightness == Brightness.light + ? Brightness.dark + : Brightness.light; + + expect(SystemChrome.latestStyle, SystemUiOverlayStyle( + statusBarColor: Colors.transparent, + statusBarBrightness: appBarBrightness, + statusBarIconBrightness: onAppBarBrightness, + )); + } + }); + + testWidgets('Material2 - Default status bar color', (WidgetTester tester) async { + await tester.pumpWidget( + MaterialApp( + key: GlobalKey(), + theme: ThemeData.light().copyWith( + useMaterial3: false, + appBarTheme: const AppBarTheme(), + ), + home: Scaffold( + appBar: AppBar( + title: const Text('title'), + ), + ), + ), + ); + expect(SystemChrome.latestStyle!.statusBarColor, null); - await pumpBoilerplate(useMaterial3: true); + }); + + testWidgets('Material3 - Default status bar color', (WidgetTester tester) async { + await tester.pumpWidget( + MaterialApp( + key: GlobalKey(), + theme: ThemeData.light().copyWith( + useMaterial3: true, + appBarTheme: const AppBarTheme(), + ), + home: Scaffold( + appBar: AppBar( + title: const Text('title'), + ), + ), + ), + ); + expect(SystemChrome.latestStyle!.statusBarColor, Colors.transparent); }); @@ -3167,8 +3474,8 @@ void main() { }); // Regression test for https://github.com/flutter/flutter/issues/107305 - group('Icons are colored correctly by IconTheme and ActionIconTheme in M3', () { - testWidgets('Icons and IconButtons are colored by IconTheme in M3', (WidgetTester tester) async { + group('Material3 - Icons are colored correctly by IconTheme and ActionIconTheme', () { + testWidgets('Material3 - Icons and IconButtons are colored by IconTheme', (WidgetTester tester) async { const Color iconColor = Color(0xff00ff00); final Key leadingIconKey = UniqueKey(); final Key actionIconKey = UniqueKey(); @@ -3200,7 +3507,7 @@ void main() { expect(actionIconButtonColor(), iconColor); }); - testWidgets('Action icons and IconButtons are colored by ActionIconTheme - M3', (WidgetTester tester) async { + testWidgets('Material3 - Action icons and IconButtons are colored by ActionIconTheme', (WidgetTester tester) async { final ThemeData themeData = ThemeData.from( colorScheme: const ColorScheme.light(), useMaterial3: true, @@ -3236,7 +3543,7 @@ void main() { expect(actionIconButtonColor(), actionsIconColor); }); - testWidgets('The actionIconTheme property overrides iconTheme - M3', (WidgetTester tester) async { + testWidgets('Material3 - The actionIconTheme property overrides iconTheme', (WidgetTester tester) async { final ThemeData themeData = ThemeData.from( colorScheme: const ColorScheme.light(), useMaterial3: true, @@ -3274,7 +3581,7 @@ void main() { expect(actionIconButtonColor(), actionsIconColor); }); - testWidgets('AppBar.iconTheme should override any IconButtonTheme present in the theme - M3', (WidgetTester tester) async { + testWidgets('Material3 - AppBar.iconTheme should override any IconButtonTheme present in the theme', (WidgetTester tester) async { final ThemeData themeData = ThemeData( iconButtonTheme: IconButtonThemeData( style: IconButton.styleFrom( @@ -3313,7 +3620,7 @@ void main() { expect(actionIconButtonSize(), 30.0); }); - testWidgets('AppBar.iconTheme should override any IconButtonTheme present in the theme for widgets containing an iconButton - M3', (WidgetTester tester) async { + testWidgets('Material3 - AppBar.iconTheme should override any IconButtonTheme present in the theme for widgets containing an iconButton', (WidgetTester tester) async { final ThemeData themeData = ThemeData( iconButtonTheme: IconButtonThemeData( style: IconButton.styleFrom( @@ -3346,7 +3653,7 @@ void main() { }); - testWidgets('AppBar.actionsIconTheme should override any IconButtonTheme present in the theme - M3', (WidgetTester tester) async { + testWidgets('Material3 - AppBar.actionsIconTheme should override any IconButtonTheme present in the theme', (WidgetTester tester) async { final ThemeData themeData = ThemeData( iconButtonTheme: IconButtonThemeData( style: IconButton.styleFrom( @@ -3386,7 +3693,7 @@ void main() { expect(actionIconButtonSize(), 30.0); }); - testWidgets('AppBar.actionsIconTheme should override any IconButtonTheme present in the theme for widgets containing an iconButton - M3', (WidgetTester tester) async { + testWidgets('Material3 - AppBar.actionsIconTheme should override any IconButtonTheme present in the theme for widgets containing an iconButton', (WidgetTester tester) async { final ThemeData themeData = ThemeData( iconButtonTheme: IconButtonThemeData( style: IconButton.styleFrom( @@ -3420,7 +3727,7 @@ void main() { expect(actionIconButtonSize(), 30.0); }); - testWidgets('The foregroundColor property of the AppBar overrides any IconButtonTheme present in the theme - M3', (WidgetTester tester) async { + testWidgets('Material3 - The foregroundColor property of the AppBar overrides any IconButtonTheme present in the theme', (WidgetTester tester) async { final ThemeData themeData = ThemeData( iconButtonTheme: IconButtonThemeData( style: IconButton.styleFrom( @@ -5104,7 +5411,7 @@ void main() { // support is deprecated and the APIs are removed, these tests // can be deleted. - testWidgets('SliverAppBar.medium defaults', (WidgetTester tester) async { + testWidgets('Material2 - SliverAppBar.medium defaults', (WidgetTester tester) async { final ThemeData theme = ThemeData(useMaterial3: false); const double collapsedAppBarHeight = 64; const double expandedAppBarHeight = 112; @@ -5188,13 +5495,13 @@ void main() { expect(tester.getSize(expandedTitleClip).height, expandedAppBarHeight - collapsedAppBarHeight); }); - testWidgets('SliverAppBar.large defaults', (WidgetTester tester) async { + testWidgets('Material2 - SliverAppBar.large defaults', (WidgetTester tester) async { final ThemeData theme = ThemeData(useMaterial3: false); const double collapsedAppBarHeight = 64; const double expandedAppBarHeight = 152; await tester.pumpWidget(MaterialApp( - theme: ThemeData(useMaterial3: false), + theme: theme, home: Scaffold( body: CustomScrollView( primary: true, diff --git a/packages/flutter/test/material/app_bar_theme_test.dart b/packages/flutter/test/material/app_bar_theme_test.dart index fca54545930..3f1c076fb3b 100644 --- a/packages/flutter/test/material/app_bar_theme_test.dart +++ b/packages/flutter/test/material/app_bar_theme_test.dart @@ -42,9 +42,8 @@ void main() { expect(identical(AppBarTheme.lerp(data, data, 0.5), data), true); }); - testWidgets('Passing no AppBarTheme returns defaults', (WidgetTester tester) async { - final ThemeData theme = ThemeData(); - final bool material3 = theme.useMaterial3; + testWidgets('Material2 - Passing no AppBarTheme returns defaults', (WidgetTester tester) async { + final ThemeData theme = ThemeData(useMaterial3: false); await tester.pumpWidget( MaterialApp( theme: theme, @@ -64,35 +63,58 @@ void main() { final RichText actionIconText = _getAppBarIconRichText(tester); final DefaultTextStyle text = _getAppBarText(tester); - if (theme.useMaterial3) { - expect(SystemChrome.latestStyle!.statusBarBrightness, Brightness.light); - expect(widget.color, theme.colorScheme.surface); - expect(widget.elevation, 0); - expect(widget.shadowColor, material3 ? Colors.transparent : null); - expect(widget.surfaceTintColor, theme.colorScheme.surfaceTint); - expect(widget.shape, null); - expect(iconTheme.data, IconThemeData(color: theme.colorScheme.onSurface, size: 24)); - expect(actionsIconTheme.data, IconThemeData(color: theme.colorScheme.onSurfaceVariant, size: 24)); - expect(actionIconText.text.style!.color, material3 ? theme.colorScheme.onSurfaceVariant : Colors.black); - expect(text.style, material3 - ? Typography.material2021().englishLike.bodyMedium!.merge(Typography.material2021().black.bodyMedium).copyWith(color: theme.colorScheme.onSurface, decorationColor: theme.colorScheme.onSurface) - : Typography.material2021().englishLike.bodyMedium!.merge(Typography.material2021().black.bodyMedium).copyWith(color: theme.colorScheme.onSurface)); - expect(tester.getSize(find.byType(AppBar)).height, kToolbarHeight); - expect(tester.getSize(find.byType(AppBar)).width, 800); - } else { - expect(SystemChrome.latestStyle!.statusBarBrightness, SystemUiOverlayStyle.light.statusBarBrightness); - expect(widget.color, Colors.blue); - expect(widget.elevation, 4.0); - expect(widget.shadowColor, Colors.black); - expect(widget.surfaceTintColor, null); - expect(widget.shape, null); - expect(iconTheme.data, const IconThemeData(color: Colors.white)); - expect(actionsIconTheme.data, const IconThemeData(color: Colors.white)); - expect(actionIconText.text.style!.color, Colors.white); - expect(text.style, Typography.material2014().englishLike.bodyMedium!.merge(Typography.material2014().white.bodyMedium)); - expect(tester.getSize(find.byType(AppBar)).height, kToolbarHeight); - expect(tester.getSize(find.byType(AppBar)).width, 800); - } + expect(SystemChrome.latestStyle!.statusBarBrightness, SystemUiOverlayStyle.light.statusBarBrightness); + expect(widget.color, Colors.blue); + expect(widget.elevation, 4.0); + expect(widget.shadowColor, Colors.black); + expect(widget.surfaceTintColor, null); + expect(widget.shape, null); + expect(iconTheme.data, const IconThemeData(color: Colors.white)); + expect(actionsIconTheme.data, const IconThemeData(color: Colors.white)); + expect(actionIconText.text.style!.color, Colors.white); + expect(text.style, Typography.material2014().englishLike.bodyMedium!.merge(Typography.material2014().white.bodyMedium)); + expect(tester.getSize(find.byType(AppBar)).height, kToolbarHeight); + expect(tester.getSize(find.byType(AppBar)).width, 800); + }); + + testWidgets('Material3 - Passing no AppBarTheme returns defaults', (WidgetTester tester) async { + final ThemeData theme = ThemeData(useMaterial3: true); + await tester.pumpWidget( + MaterialApp( + theme: theme, + home: Scaffold( + appBar: AppBar( + actions: [ + IconButton(icon: const Icon(Icons.share), onPressed: () { }), + ], + ), + ), + ), + ); + + final Material widget = _getAppBarMaterial(tester); + final IconTheme iconTheme = _getAppBarIconTheme(tester); + final IconTheme actionsIconTheme = _getAppBarActionsIconTheme(tester); + final RichText actionIconText = _getAppBarIconRichText(tester); + final DefaultTextStyle text = _getAppBarText(tester); + + expect(SystemChrome.latestStyle!.statusBarBrightness, Brightness.light); + expect(widget.color, theme.colorScheme.surface); + expect(widget.elevation, 0); + expect(widget.shadowColor, Colors.transparent); + expect(widget.surfaceTintColor, theme.colorScheme.surfaceTint); + expect(widget.shape, null); + expect(iconTheme.data, IconThemeData(color: theme.colorScheme.onSurface, size: 24)); + expect(actionsIconTheme.data, IconThemeData(color: theme.colorScheme.onSurfaceVariant, size: 24)); + expect(actionIconText.text.style!.color, theme.colorScheme.onSurfaceVariant); + expect( + text.style, + Typography.material2021().englishLike.bodyMedium! + .merge(Typography.material2021().black.bodyMedium) + .copyWith(color: theme.colorScheme.onSurface, decorationColor: theme.colorScheme.onSurface), + ); + expect(tester.getSize(find.byType(AppBar)).height, kToolbarHeight); + expect(tester.getSize(find.byType(AppBar)).width, 800); }); testWidgets('AppBar uses values from AppBarTheme', (WidgetTester tester) async { @@ -242,9 +264,9 @@ void main() { expect(text.style, appBarTheme.toolbarTextStyle); }); - testWidgets('ThemeData colorScheme is used when no AppBarTheme is set', (WidgetTester tester) async { - final ThemeData lightTheme = ThemeData.from(colorScheme: const ColorScheme.light()); - final ThemeData darkTheme = ThemeData.from(colorScheme: const ColorScheme.dark()); + testWidgets('Material2 - ThemeData colorScheme is used when no AppBarTheme is set', (WidgetTester tester) async { + final ThemeData lightTheme = ThemeData.from(colorScheme: const ColorScheme.light(), useMaterial3: false); + final ThemeData darkTheme = ThemeData.from(colorScheme: const ColorScheme.dark(), useMaterial3: false); Widget buildFrame(ThemeData appTheme) { return MaterialApp( theme: appTheme, @@ -262,121 +284,132 @@ void main() { ); } - if (lightTheme.useMaterial3) { - // M3 AppBar defaults for light themes: - // - elevation: 0 - // - shadow color: Colors.transparent - // - surface tint color: ColorScheme.surfaceTint - // - background color: ColorScheme.surface - // - foreground color: ColorScheme.onSurface - // - actions text: style bodyMedium, foreground color - // - status bar brightness: light (based on color scheme brightness) - { - await tester.pumpWidget(buildFrame(lightTheme)); + // AppBar M2 defaults for light themes: + // - elevation: 4 + // - shadow color: black + // - surface tint color: null + // - background color: ColorScheme.primary + // - foreground color: ColorScheme.onPrimary + // - actions text: style bodyMedium, foreground color + // - status bar brightness: light (based on color scheme brightness) + await tester.pumpWidget(buildFrame(lightTheme)); - final Material widget = _getAppBarMaterial(tester); - final IconTheme iconTheme = _getAppBarIconTheme(tester); - final IconTheme actionsIconTheme = _getAppBarActionsIconTheme(tester); - final RichText actionIconText = _getAppBarIconRichText(tester); - final DefaultTextStyle text = _getAppBarText(tester); + Material widget = _getAppBarMaterial(tester); + IconTheme iconTheme = _getAppBarIconTheme(tester); + IconTheme actionsIconTheme = _getAppBarActionsIconTheme(tester); + RichText actionIconText = _getAppBarIconRichText(tester); + DefaultTextStyle text = _getAppBarText(tester); - expect(SystemChrome.latestStyle!.statusBarBrightness, Brightness.light); - expect(widget.color, lightTheme.colorScheme.surface); - expect(widget.elevation, 0); - expect(widget.shadowColor, Colors.transparent); - expect(widget.surfaceTintColor, lightTheme.colorScheme.surfaceTint); - expect(iconTheme.data.color, lightTheme.colorScheme.onSurface); - expect(actionsIconTheme.data.color, lightTheme.colorScheme.onSurface); - expect(actionIconText.text.style!.color, lightTheme.colorScheme.onSurface); - expect(text.style, Typography.material2021().englishLike.bodyMedium!.merge(Typography.material2021().black.bodyMedium).copyWith(color: lightTheme.colorScheme.onSurface)); - } + expect(SystemChrome.latestStyle!.statusBarBrightness, SystemUiOverlayStyle.light.statusBarBrightness); + expect(widget.color, lightTheme.colorScheme.primary); + expect(widget.elevation, 4.0); + expect(widget.shadowColor, Colors.black); + expect(widget.surfaceTintColor, null); + expect(iconTheme.data.color, lightTheme.colorScheme.onPrimary); + expect(actionsIconTheme.data.color, lightTheme.colorScheme.onPrimary); + expect(actionIconText.text.style!.color, lightTheme.colorScheme.onPrimary); + expect(text.style, Typography.material2014().englishLike.bodyMedium!.merge(Typography.material2014().black.bodyMedium).copyWith(color: lightTheme.colorScheme.onPrimary)); - // M3 AppBar defaults for dark themes: - // - elevation: 0 - // - shadow color: Colors.transparent - // - surface tint color: ColorScheme.surfaceTint - // - background color: ColorScheme.surface - // - foreground color: ColorScheme.onSurface - // - actions text: style bodyMedium, foreground color - // - status bar brightness: dark (based on background color) - { - await tester.pumpWidget(buildFrame(darkTheme)); - await tester.pumpAndSettle(); // Theme change animation + // AppBar M2 defaults for dark themes: + // - elevation: 4 + // - shadow color: black + // - surface tint color: null + // - background color: ColorScheme.surface + // - foreground color: ColorScheme.onSurface + // - actions text: style bodyMedium, foreground color + // - status bar brightness: dark (based on background color) + await tester.pumpWidget(buildFrame(darkTheme)); + await tester.pumpAndSettle(); // Theme change animation - final Material widget = _getAppBarMaterial(tester); - final IconTheme iconTheme = _getAppBarIconTheme(tester); - final IconTheme actionsIconTheme = _getAppBarActionsIconTheme(tester); - final RichText actionIconText = _getAppBarIconRichText(tester); - final DefaultTextStyle text = _getAppBarText(tester); + widget = _getAppBarMaterial(tester); + iconTheme = _getAppBarIconTheme(tester); + actionsIconTheme = _getAppBarActionsIconTheme(tester); + actionIconText = _getAppBarIconRichText(tester); + text = _getAppBarText(tester); - expect(SystemChrome.latestStyle!.statusBarBrightness, Brightness.dark); - expect(widget.color, darkTheme.colorScheme.surface); - expect(widget.elevation, 0); - expect(widget.shadowColor, Colors.transparent); - expect(widget.surfaceTintColor, darkTheme.colorScheme.surfaceTint); - expect(iconTheme.data.color, darkTheme.colorScheme.onSurface); - expect(actionsIconTheme.data.color, darkTheme.colorScheme.onSurface); - expect(actionIconText.text.style!.color, darkTheme.colorScheme.onSurface); - expect(text.style, Typography.material2021().englishLike.bodyMedium!.merge(Typography.material2021().black.bodyMedium).copyWith(color: darkTheme.colorScheme.onSurface, decorationColor: darkTheme.colorScheme.onSurface)); - } - } else { - // AppBar M2 defaults for light themes: - // - elevation: 4 - // - shadow color: black - // - surface tint color: null - // - background color: ColorScheme.primary - // - foreground color: ColorScheme.onPrimary - // - actions text: style bodyMedium, foreground color - // - status bar brightness: light (based on color scheme brightness) - { - await tester.pumpWidget(buildFrame(lightTheme)); + expect(SystemChrome.latestStyle!.statusBarBrightness, SystemUiOverlayStyle.light.statusBarBrightness); + expect(widget.color, darkTheme.colorScheme.surface); + expect(widget.elevation, 4.0); + expect(widget.shadowColor, Colors.black); + expect(widget.surfaceTintColor, null); + expect(iconTheme.data.color, darkTheme.colorScheme.onSurface); + expect(actionsIconTheme.data.color, darkTheme.colorScheme.onSurface); + expect(actionIconText.text.style!.color, darkTheme.colorScheme.onSurface); + expect(text.style, Typography.material2014().englishLike.bodyMedium!.merge(Typography.material2014().black.bodyMedium).copyWith(color: darkTheme.colorScheme.onSurface)); + }); - final Material widget = _getAppBarMaterial(tester); - final IconTheme iconTheme = _getAppBarIconTheme(tester); - final IconTheme actionsIconTheme = _getAppBarActionsIconTheme(tester); - final RichText actionIconText = _getAppBarIconRichText(tester); - final DefaultTextStyle text = _getAppBarText(tester); - - expect(SystemChrome.latestStyle!.statusBarBrightness, SystemUiOverlayStyle.light.statusBarBrightness); - expect(widget.color, lightTheme.colorScheme.primary); - expect(widget.elevation, 4.0); - expect(widget.shadowColor, Colors.black); - expect(widget.surfaceTintColor, null); - expect(iconTheme.data.color, lightTheme.colorScheme.onPrimary); - expect(actionsIconTheme.data.color, lightTheme.colorScheme.onPrimary); - expect(actionIconText.text.style!.color, lightTheme.colorScheme.onPrimary); - expect(text.style, Typography.material2014().englishLike.bodyMedium!.merge(Typography.material2014().black.bodyMedium).copyWith(color: lightTheme.colorScheme.onPrimary)); - } - - // AppBar M2 defaults for dark themes: - // - elevation: 4 - // - shadow color: black - // - surface tint color: null - // - background color: ColorScheme.surface - // - foreground color: ColorScheme.onSurface - // - actions text: style bodyMedium, foreground color - // - status bar brightness: dark (based on background color) - { - await tester.pumpWidget(buildFrame(darkTheme)); - await tester.pumpAndSettle(); // Theme change animation - - final Material widget = _getAppBarMaterial(tester); - final IconTheme iconTheme = _getAppBarIconTheme(tester); - final IconTheme actionsIconTheme = _getAppBarActionsIconTheme(tester); - final RichText actionIconText = _getAppBarIconRichText(tester); - final DefaultTextStyle text = _getAppBarText(tester); - - expect(SystemChrome.latestStyle!.statusBarBrightness, SystemUiOverlayStyle.light.statusBarBrightness); - expect(widget.color, darkTheme.colorScheme.surface); - expect(widget.elevation, 4.0); - expect(widget.shadowColor, Colors.black); - expect(widget.surfaceTintColor, null); - expect(iconTheme.data.color, darkTheme.colorScheme.onSurface); - expect(actionsIconTheme.data.color, darkTheme.colorScheme.onSurface); - expect(actionIconText.text.style!.color, darkTheme.colorScheme.onSurface); - expect(text.style, Typography.material2014().englishLike.bodyMedium!.merge(Typography.material2014().black.bodyMedium).copyWith(color: darkTheme.colorScheme.onSurface)); - } + testWidgets('Material3 - ThemeData colorScheme is used when no AppBarTheme is set', (WidgetTester tester) async { + final ThemeData lightTheme = ThemeData.from(colorScheme: const ColorScheme.light(), useMaterial3: true); + final ThemeData darkTheme = ThemeData.from(colorScheme: const ColorScheme.dark(), useMaterial3: true); + Widget buildFrame(ThemeData appTheme) { + return MaterialApp( + theme: appTheme, + home: Builder( + builder: (BuildContext context) { + return Scaffold( + appBar: AppBar( + actions: [ + IconButton(icon: const Icon(Icons.share), onPressed: () { }), + ], + ), + ); + }, + ), + ); } + + // M3 AppBar defaults for light themes: + // - elevation: 0 + // - shadow color: Colors.transparent + // - surface tint color: ColorScheme.surfaceTint + // - background color: ColorScheme.surface + // - foreground color: ColorScheme.onSurface + // - actions text: style bodyMedium, foreground color + // - status bar brightness: light (based on color scheme brightness) + await tester.pumpWidget(buildFrame(lightTheme)); + + Material widget = _getAppBarMaterial(tester); + IconTheme iconTheme = _getAppBarIconTheme(tester); + IconTheme actionsIconTheme = _getAppBarActionsIconTheme(tester); + RichText actionIconText = _getAppBarIconRichText(tester); + DefaultTextStyle text = _getAppBarText(tester); + + expect(SystemChrome.latestStyle!.statusBarBrightness, Brightness.light); + expect(widget.color, lightTheme.colorScheme.surface); + expect(widget.elevation, 0); + expect(widget.shadowColor, Colors.transparent); + expect(widget.surfaceTintColor, lightTheme.colorScheme.surfaceTint); + expect(iconTheme.data.color, lightTheme.colorScheme.onSurface); + expect(actionsIconTheme.data.color, lightTheme.colorScheme.onSurface); + expect(actionIconText.text.style!.color, lightTheme.colorScheme.onSurface); + expect(text.style, Typography.material2021().englishLike.bodyMedium!.merge(Typography.material2021().black.bodyMedium).copyWith(color: lightTheme.colorScheme.onSurface)); + + // M3 AppBar defaults for dark themes: + // - elevation: 0 + // - shadow color: Colors.transparent + // - surface tint color: ColorScheme.surfaceTint + // - background color: ColorScheme.surface + // - foreground color: ColorScheme.onSurface + // - actions text: style bodyMedium, foreground color + // - status bar brightness: dark (based on background color) + await tester.pumpWidget(buildFrame(darkTheme)); + await tester.pumpAndSettle(); // Theme change animation + + widget = _getAppBarMaterial(tester); + iconTheme = _getAppBarIconTheme(tester); + actionsIconTheme = _getAppBarActionsIconTheme(tester); + actionIconText = _getAppBarIconRichText(tester); + text = _getAppBarText(tester); + + expect(SystemChrome.latestStyle!.statusBarBrightness, Brightness.dark); + expect(widget.color, darkTheme.colorScheme.surface); + expect(widget.elevation, 0); + expect(widget.shadowColor, Colors.transparent); + expect(widget.surfaceTintColor, darkTheme.colorScheme.surfaceTint); + expect(iconTheme.data.color, darkTheme.colorScheme.onSurface); + expect(actionsIconTheme.data.color, darkTheme.colorScheme.onSurface); + expect(actionIconText.text.style!.color, darkTheme.colorScheme.onSurface); + expect(text.style, Typography.material2021().englishLike.bodyMedium!.merge(Typography.material2021().black.bodyMedium).copyWith(color: darkTheme.colorScheme.onSurface, decorationColor: darkTheme.colorScheme.onSurface)); }); testWidgets('AppBar iconTheme with color=null defers to outer IconTheme', (WidgetTester tester) async { @@ -384,7 +417,7 @@ void main() { Widget buildFrame({ Color? appIconColor, Color? appBarIconColor }) { return MaterialApp( - theme: ThemeData.from(useMaterial3: false, colorScheme: const ColorScheme.light()), + theme: ThemeData.from(colorScheme: const ColorScheme.light()), home: IconTheme( data: IconThemeData(color: appIconColor), child: Builder( @@ -493,7 +526,7 @@ void main() { expect(appBar.surfaceTintColor, Colors.yellow); }); - testWidgets('AppBarTheme.iconTheme.color takes priority over IconButtonTheme.foregroundColor - M3', (WidgetTester tester) async { + testWidgets('Material3 - AppBarTheme.iconTheme.color takes priority over IconButtonTheme.foregroundColor', (WidgetTester tester) async { const IconThemeData overallIconTheme = IconThemeData(color: Colors.yellow); await tester.pumpWidget(MaterialApp( theme: ThemeData( @@ -519,7 +552,7 @@ void main() { expect(actionIconButtonColor, overallIconTheme.color); }); - testWidgets('AppBarTheme.iconTheme.size takes priority over IconButtonTheme.iconSize - M3', (WidgetTester tester) async { + testWidgets('Material3 - AppBarTheme.iconTheme.size takes priority over IconButtonTheme.iconSize', (WidgetTester tester) async { const IconThemeData overallIconTheme = IconThemeData(size: 30.0); await tester.pumpWidget(MaterialApp( theme: ThemeData( @@ -546,7 +579,7 @@ void main() { }); - testWidgets('AppBarTheme.actionsIconTheme.color takes priority over IconButtonTheme.foregroundColor - M3', (WidgetTester tester) async { + testWidgets('Material3 - AppBarTheme.actionsIconTheme.color takes priority over IconButtonTheme.foregroundColor', (WidgetTester tester) async { const IconThemeData actionsIconTheme = IconThemeData(color: Colors.yellow); final IconButtonThemeData iconButtonTheme = IconButtonThemeData( style: IconButton.styleFrom(foregroundColor: Colors.red), @@ -574,7 +607,7 @@ void main() { expect(actionIconButtonColor, actionsIconTheme.color); }); - testWidgets('AppBarTheme.actionsIconTheme.size takes priority over IconButtonTheme.iconSize - M3', (WidgetTester tester) async { + testWidgets('Material3 - AppBarTheme.actionsIconTheme.size takes priority over IconButtonTheme.iconSize', (WidgetTester tester) async { const IconThemeData actionsIconTheme = IconThemeData(size: 30.0); final IconButtonThemeData iconButtonTheme = IconButtonThemeData( style: IconButton.styleFrom(iconSize: 32.0), @@ -601,7 +634,7 @@ void main() { expect(actionIconButtonSize, actionsIconTheme.size); }); - testWidgets('AppBarTheme.foregroundColor takes priority over IconButtonTheme.foregroundColor - M3', (WidgetTester tester) async { + testWidgets('Material3 - AppBarTheme.foregroundColor takes priority over IconButtonTheme.foregroundColor', (WidgetTester tester) async { final IconButtonThemeData iconButtonTheme = IconButtonThemeData( style: IconButton.styleFrom(foregroundColor: Colors.red), ); @@ -1027,12 +1060,22 @@ void main() { testWidgets('AppBarTheme implements debugFillProperties', (WidgetTester tester) async { final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); const AppBarTheme( - backgroundColor: Color(0xff000001), + backgroundColor: Color(0xff000000), + foregroundColor: Color(0xff000001), elevation: 8.0, + scrolledUnderElevation: 3, shadowColor: Color(0xff000002), surfaceTintColor: Color(0xff000003), + shape: StadiumBorder(), + iconTheme: IconThemeData(color: Color(0xff000004)), centerTitle: true, titleSpacing: 40.0, + toolbarHeight: 96, + toolbarTextStyle: TextStyle(color: Color(0xff000005)), + titleTextStyle: TextStyle(color: Color(0xff000006)), + systemOverlayStyle: SystemUiOverlayStyle( + systemNavigationBarColor: Color(0xff000007), + ), ).debugFillProperties(builder); final List description = builder.properties @@ -1040,14 +1083,26 @@ void main() { .map((DiagnosticsNode node) => node.toString()) .toList(); - expect(description, [ - 'backgroundColor: Color(0xff000001)', - 'elevation: 8.0', - 'shadowColor: Color(0xff000002)', - 'surfaceTintColor: Color(0xff000003)', - 'centerTitle: true', - 'titleSpacing: 40.0', - ]); + expect( + description, + equalsIgnoringHashCodes( + [ + 'backgroundColor: Color(0xff000000)', + 'foregroundColor: Color(0xff000001)', + 'elevation: 8.0', + 'scrolledUnderElevation: 3.0', + 'shadowColor: Color(0xff000002)', + 'surfaceTintColor: Color(0xff000003)', + 'shape: StadiumBorder(BorderSide(width: 0.0, style: none))', + 'iconTheme: IconThemeData#00000(color: Color(0xff000004))', + 'centerTitle: true', + 'titleSpacing: 40.0', + 'toolbarHeight: 96.0', + 'toolbarTextStyle: TextStyle(inherit: true, color: Color(0xff000005))', + 'titleTextStyle: TextStyle(inherit: true, color: Color(0xff000006))' + ], + ), + ); // On the web, Dart doubles and ints are backed by the same kind of object because // JavaScript does not support integers. So, the Dart double "4.0" is identical