// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  test('AppBarTheme copyWith, ==, hashCode basics', () {
    expect(const AppBarTheme(), const AppBarTheme().copyWith());
    expect(const AppBarTheme().hashCode, const AppBarTheme().copyWith().hashCode);
  });

  testWidgets('Passing no AppBarTheme returns defaults', (WidgetTester tester) async {
    final ThemeData theme = ThemeData();
    await tester.pumpWidget(
      MaterialApp(
        theme: theme,
        home: Scaffold(
          appBar: AppBar(
            actions: <Widget>[
              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);

    if (theme.useMaterial3) {
      expect(SystemChrome.latestStyle!.statusBarBrightness, Brightness.light);
      expect(widget.color, theme.colorScheme.surface);
      expect(widget.elevation, 0);
      expect(widget.shadowColor, 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, Colors.black);
      expect(text.style, 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);
    }
  });

  testWidgets('AppBar uses values from AppBarTheme', (WidgetTester tester) async {
    final AppBarTheme appBarTheme = _appBarTheme();

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(appBarTheme: appBarTheme),
        home: Scaffold(
          appBar: AppBar(
            title: const Text('App Bar Title'),
            actions: <Widget>[
              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, appBarTheme.brightness);
    expect(widget.color, appBarTheme.backgroundColor);
    expect(widget.elevation, appBarTheme.elevation);
    expect(widget.shadowColor, appBarTheme.shadowColor);
    expect(widget.surfaceTintColor, appBarTheme.surfaceTintColor);
    expect(widget.shape, const StadiumBorder());
    expect(iconTheme.data, appBarTheme.iconTheme);
    expect(actionsIconTheme.data, appBarTheme.actionsIconTheme);
    expect(actionIconText.text.style!.color, appBarTheme.actionsIconTheme!.color);
    expect(text.style, appBarTheme.toolbarTextStyle);
    expect(tester.getSize(find.byType(AppBar)).height, appBarTheme.toolbarHeight);
    expect(tester.getSize(find.byType(AppBar)).width, 800);
  });

  testWidgets('SliverAppBar allows AppBar to determine backwardsCompatibility', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/77016
    const AppBarTheme appBarTheme = AppBarTheme(
      backwardsCompatibility: false,
      backgroundColor: Colors.lightBlue,
      foregroundColor: Colors.black,
    );

    Widget buildWithBackwardsCompatibility([bool? enabled]) => MaterialApp(
      theme: ThemeData(appBarTheme: appBarTheme),
      home: Scaffold(body: CustomScrollView(
        slivers: <Widget>[
          SliverAppBar(
            title: const Text('App Bar Title'),
            backwardsCompatibility: enabled,
            actions: <Widget>[
              IconButton(icon: const Icon(Icons.share), onPressed: () { }),
            ],
          ),
        ],
      )),
    );

    // Backwards compatibility enabled, AppBar should be built with true.
    await tester.pumpWidget(buildWithBackwardsCompatibility(true));
    AppBar appBar = tester.widget<AppBar>(find.byType(AppBar));
    expect(appBar.backwardsCompatibility, true);

    // Backwards compatibility disabled, AppBar should be built with false.
    await tester.pumpWidget(buildWithBackwardsCompatibility(false));
    appBar = tester.widget<AppBar>(find.byType(AppBar));
    expect(appBar.backwardsCompatibility, false);

    // Backwards compatibility unspecified, AppBar should be built with null.
    await tester.pumpWidget(buildWithBackwardsCompatibility());
    appBar = tester.widget<AppBar>(find.byType(AppBar));
    expect(appBar.backwardsCompatibility, null);

    // AppBar should use the backwardsCompatibility of AppBarTheme.
    // Since backwardsCompatibility is false, the text color should match the
    // foreground color of the AppBarTheme.
    final DefaultTextStyle text = _getAppBarText(tester);
    expect(text.style.color, appBarTheme.foregroundColor);
  });

  testWidgets('AppBar widget properties take priority over theme', (WidgetTester tester) async {
    const Brightness brightness = Brightness.dark;
    const SystemUiOverlayStyle systemOverlayStyle = SystemUiOverlayStyle.light;
    const Color color = Colors.orange;
    const double elevation = 3.0;
    const Color shadowColor = Colors.purple;
    const Color surfaceTintColor = Colors.brown;
    const ShapeBorder shape = RoundedRectangleBorder();
    const IconThemeData iconThemeData = IconThemeData(color: Colors.green);
    const IconThemeData actionsIconThemeData = IconThemeData(color: Colors.lightBlue);
    const TextStyle toolbarTextStyle = TextStyle(color: Colors.pink);
    const TextStyle titleTextStyle = TextStyle(color: Colors.orange);

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData.from(colorScheme: const ColorScheme.light()).copyWith(
          appBarTheme: _appBarTheme(),
        ),
        home: Scaffold(
          appBar: AppBar(
            backgroundColor: color,
            brightness: brightness,
            systemOverlayStyle: systemOverlayStyle,
            elevation: elevation,
            shadowColor: shadowColor,
            surfaceTintColor: surfaceTintColor,
            shape: shape,
            iconTheme: iconThemeData,
            actionsIconTheme: actionsIconThemeData,
            toolbarTextStyle: toolbarTextStyle,
            titleTextStyle: titleTextStyle,
            actions: <Widget>[
              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);
    expect(widget.color, color);
    expect(widget.elevation, elevation);
    expect(widget.shadowColor, shadowColor);
    expect(widget.surfaceTintColor, surfaceTintColor);
    expect(widget.shape, shape);
    expect(iconTheme.data, iconThemeData);
    expect(actionsIconTheme.data, actionsIconThemeData);
    expect(actionIconText.text.style!.color, actionsIconThemeData.color);
    expect(text.style, toolbarTextStyle);
  });

  testWidgets('AppBar icon color takes priority over everything', (WidgetTester tester) async {
    const Color color = Colors.lime;
    const IconThemeData iconThemeData = IconThemeData(color: Colors.green);
    const IconThemeData actionsIconThemeData = IconThemeData(color: Colors.lightBlue);

    await tester.pumpWidget(MaterialApp(
      theme: ThemeData.from(colorScheme: const ColorScheme.light()),
      home: Scaffold(appBar: AppBar(
        iconTheme: iconThemeData,
        actionsIconTheme: actionsIconThemeData,
        actions: <Widget>[
          IconButton(icon: const Icon(Icons.share), color: color, onPressed: () { }),
        ],
      )),
    ));

    final RichText actionIconText = _getAppBarIconRichText(tester);
    expect(actionIconText.text.style!.color, color);
  });

  testWidgets('AppBarTheme properties take priority over ThemeData properties', (WidgetTester tester) async {
    final AppBarTheme appBarTheme = _appBarTheme();

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData.from(colorScheme: const ColorScheme.light())
          .copyWith(appBarTheme: _appBarTheme()),
        home: Scaffold(
          appBar: AppBar(
            actions: <Widget>[
              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, appBarTheme.brightness);
    expect(widget.color, appBarTheme.backgroundColor);
    expect(widget.elevation, appBarTheme.elevation);
    expect(widget.shadowColor, appBarTheme.shadowColor);
    expect(widget.surfaceTintColor, appBarTheme.surfaceTintColor);
    expect(iconTheme.data, appBarTheme.iconTheme);
    expect(actionsIconTheme.data, appBarTheme.actionsIconTheme);
    expect(actionIconText.text.style!.color, appBarTheme.actionsIconTheme!.color);
    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());
    Widget buildFrame(ThemeData appTheme) {
      return MaterialApp(
        theme: appTheme,
        home: Builder(
          builder: (BuildContext context) {
            return Scaffold(
              appBar: AppBar(
                actions: <Widget>[
                  IconButton(icon: const Icon(Icons.share), onPressed: () { }),
                ],
              ),
            );
          },
        ),
      );
    }

    if (lightTheme.useMaterial3) {
      // M3 AppBar defaults for light themes:
      // - elevation: 0
      // - shadow color: null
      // - 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));

        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, lightTheme.colorScheme.surface);
        expect(widget.elevation, 0);
        expect(widget.shadowColor, null);
        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: null
      // - 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(ThemeData.from(colorScheme: const ColorScheme.dark())));
        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, Brightness.dark);
        expect(widget.color, darkTheme.colorScheme.surface);
        expect(widget.elevation, 0);
        expect(widget.shadowColor, null);
        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));
      }
    } else {
      // AppBar 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);

        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 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('AppBar iconTheme with color=null defers to outer IconTheme', (WidgetTester tester) async {
    // Verify claim made in https://github.com/flutter/flutter/pull/71184#issuecomment-737419215

    Widget buildFrame({ Color? appIconColor, Color? appBarIconColor }) {
      return MaterialApp(
        theme: ThemeData.from(useMaterial3: false, colorScheme: const ColorScheme.light()),
        home: IconTheme(
          data: IconThemeData(color: appIconColor),
          child: Builder(
            builder: (BuildContext context) {
              return Scaffold(
                appBar: AppBar(
                  iconTheme: IconThemeData(color: appBarIconColor),
                  actions: <Widget>[
                    IconButton(icon: const Icon(Icons.share), onPressed: () { }),
                  ],
                ),
              );
            },
          ),
        ),
      );
    }

    RichText getIconText() {
      return tester.widget<RichText>(
        find.descendant(
          of: find.byType(Icon),
          matching: find.byType(RichText),
        ),
      );
    }

    await tester.pumpWidget(buildFrame(appIconColor: Colors.lime));
    expect(getIconText().text.style!.color, Colors.lime);

    await tester.pumpWidget(buildFrame(appIconColor: Colors.lime, appBarIconColor: Colors.purple));
    expect(getIconText().text.style!.color, Colors.purple);
  });

  testWidgets('AppBar uses AppBarTheme.centerTitle when centerTitle is null', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(
      theme: ThemeData(appBarTheme: const AppBarTheme(centerTitle: true)),
      home: Scaffold(appBar: AppBar(
        title: const Text('Title'),
      )),
    ));

    final NavigationToolbar navToolBar = tester.widget(find.byType(NavigationToolbar));
    expect(navToolBar.centerMiddle, true);
  });

  testWidgets('AppBar.centerTitle takes priority over AppBarTheme.centerTitle', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(
      theme: ThemeData(appBarTheme: const AppBarTheme(centerTitle: true)),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Title'),
          centerTitle: false,
        ),
      ),
    ));

    final NavigationToolbar navToolBar = tester.widget(find.byType(NavigationToolbar));
    // The AppBar.centerTitle should be used instead of AppBarTheme.centerTitle.
    expect(navToolBar.centerMiddle, false);
  });

  testWidgets('AppBar.centerTitle adapts to TargetPlatform when AppBarTheme.centerTitle is null', (WidgetTester tester) async{
    await tester.pumpWidget(MaterialApp(
      theme: ThemeData(platform: TargetPlatform.iOS),
      home: Scaffold(appBar: AppBar(
        title: const Text('Title'),
      )),
    ));

    final NavigationToolbar navToolBar = tester.widget(find.byType(NavigationToolbar));
    // When ThemeData.platform is TargetPlatform.iOS, and AppBarTheme is null,
    // the value of NavigationToolBar.centerMiddle should be true.
    expect(navToolBar.centerMiddle, true);
  });

  testWidgets('AppBar.shadowColor takes priority over AppBarTheme.shadowColor', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(
      theme: ThemeData(appBarTheme: const AppBarTheme(shadowColor: Colors.red)),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Title'),
          shadowColor: Colors.yellow,
        ),
      ),
    ));

    final AppBar appBar = tester.widget(find.byType(AppBar));
    // The AppBar.shadowColor should be used instead of AppBarTheme.shadowColor.
    expect(appBar.shadowColor, Colors.yellow);
  });

  testWidgets('AppBar.surfaceTintColor takes priority over AppBarTheme.surfaceTintColor', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(
      theme: ThemeData(appBarTheme: const AppBarTheme(surfaceTintColor: Colors.red)),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Title'),
          surfaceTintColor: Colors.yellow,
        ),
      ),
    ));

    final AppBar appBar = tester.widget(find.byType(AppBar));
    // The AppBar.surfaceTintColor should be used instead of AppBarTheme.surfaceTintColor.
    expect(appBar.surfaceTintColor, Colors.yellow);
  });

  testWidgets('AppBar uses AppBarTheme.titleSpacing', (WidgetTester tester) async {
    const double kTitleSpacing = 10;
    await tester.pumpWidget(MaterialApp(
      theme: ThemeData(appBarTheme: const AppBarTheme(titleSpacing: kTitleSpacing)),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Title'),
        ),
      ),
    ));

    final NavigationToolbar navToolBar = tester.widget(find.byType(NavigationToolbar));
    expect(navToolBar.middleSpacing, kTitleSpacing);
  });

  testWidgets('AppBar.titleSpacing takes priority over AppBarTheme.titleSpacing', (WidgetTester tester) async {
    const double kTitleSpacing = 10;
    await tester.pumpWidget(MaterialApp(
      theme: ThemeData(appBarTheme: const AppBarTheme(titleSpacing: kTitleSpacing)),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Title'),
          titleSpacing: 40,
        ),
      ),
    ));

    final NavigationToolbar navToolBar = tester.widget(find.byType(NavigationToolbar));
    expect(navToolBar.middleSpacing, 40);
  });

  testWidgets('SliverAppBar uses AppBarTheme.titleSpacing', (WidgetTester tester) async {
    const double kTitleSpacing = 10;
    await tester.pumpWidget(MaterialApp(
      theme: ThemeData(appBarTheme: const AppBarTheme(titleSpacing: kTitleSpacing)),
      home: const CustomScrollView(
        slivers: <Widget>[
          SliverAppBar(
            title: Text('Title'),
          ),
        ],
      ),
    ));

    final NavigationToolbar navToolBar = tester.widget(find.byType(NavigationToolbar));
    expect(navToolBar.middleSpacing, kTitleSpacing);
  });

  testWidgets('SliverAppBar.titleSpacing takes priority over AppBarTheme.titleSpacing ', (WidgetTester tester) async {
    const double kTitleSpacing = 10;
    await tester.pumpWidget(MaterialApp(
      theme: ThemeData(appBarTheme: const AppBarTheme(titleSpacing: kTitleSpacing)),
      home: const CustomScrollView(
        slivers: <Widget>[
          SliverAppBar(
            title: Text('Title'),
            titleSpacing: 40,
          ),
        ],
      ),
    ));

    final NavigationToolbar navToolbar = tester.widget(find.byType(NavigationToolbar));
    expect(navToolbar.middleSpacing, 40);
  });

  testWidgets('Default AppBarTheme debugFillProperties', (WidgetTester tester) async {
    final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
    const AppBarTheme().debugFillProperties(builder);

    final List<String> description = builder.properties
      .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
      .map((DiagnosticsNode node) => node.toString())
      .toList();

    expect(description, <String>[]);
  });

  testWidgets('AppBarTheme implements debugFillProperties', (WidgetTester tester) async {
    final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
    const AppBarTheme(
      brightness: Brightness.dark,
      backgroundColor: Color(0xff000001),
      elevation: 8.0,
      shadowColor: Color(0xff000002),
      surfaceTintColor: Color(0xff000003),
      centerTitle: true,
      titleSpacing: 40.0,
    ).debugFillProperties(builder);

    final List<String> description = builder.properties
      .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
      .map((DiagnosticsNode node) => node.toString())
      .toList();

    expect(description, <String>[
      'brightness: Brightness.dark',
      'backgroundColor: Color(0xff000001)',
      'elevation: 8.0',
      'shadowColor: Color(0xff000002)',
      'surfaceTintColor: Color(0xff000003)',
      'centerTitle: true',
      'titleSpacing: 40.0',
    ]);

    // 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
    // to "4", which results in the web evaluating to the value "4" regardless of which
    // one is used. This results in a difference for doubles in debugFillProperties between
    // the web and the rest of Flutter's target platforms.
  }, skip: kIsWeb); // https://github.com/flutter/flutter/issues/87364
}

AppBarTheme _appBarTheme() {
  const Brightness brightness = Brightness.light;
  const Color backgroundColor = Colors.lightBlue;
  const double elevation = 6.0;
  const Color shadowColor = Colors.red;
  const Color surfaceTintColor = Colors.green;
  const IconThemeData iconThemeData = IconThemeData(color: Colors.black);
  const IconThemeData actionsIconThemeData = IconThemeData(color: Colors.pink);
  return const AppBarTheme(
    actionsIconTheme: actionsIconThemeData,
    brightness: brightness,
    backgroundColor: backgroundColor,
    elevation: elevation,
    shadowColor: shadowColor,
    surfaceTintColor: surfaceTintColor,
    shape: StadiumBorder(),
    iconTheme: iconThemeData,
    toolbarHeight: 96,
    toolbarTextStyle: TextStyle(color: Colors.yellow),
    titleTextStyle: TextStyle(color: Colors.pink),
  );
}

Material _getAppBarMaterial(WidgetTester tester) {
  return tester.widget<Material>(
    find.descendant(
      of: find.byType(AppBar),
      matching: find.byType(Material),
    ),
  );
}

IconTheme _getAppBarIconTheme(WidgetTester tester) {
  return tester.widget<IconTheme>(
    find.descendant(
      of: find.byType(AppBar),
      matching: find.byType(IconTheme),
    ).first,
  );
}

IconTheme _getAppBarActionsIconTheme(WidgetTester tester) {
  return tester.widget<IconTheme>(
    find.descendant(
      of: find.byType(NavigationToolbar),
      matching: find.byType(IconTheme),
    ).first,
  );
}

RichText _getAppBarIconRichText(WidgetTester tester) {
  return tester.widget<RichText>(
    find.descendant(
      of: find.byType(Icon),
      matching: find.byType(RichText),
    ).first,
  );
}

DefaultTextStyle _getAppBarText(WidgetTester tester) {
  return tester.widget<DefaultTextStyle>(
    find.descendant(
      of: find.byType(CustomSingleChildLayout),
      matching: find.byType(DefaultTextStyle),
    ).first,
  );
}
