// 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.

// This file is run as part of a reduced test set in CI on Mac and Windows
// machines.
@Tags(<String>['reduced-test-set'])

import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:vector_math/vector_math_64.dart' show Vector3;

import '../rendering/mock_canvas.dart';
import '../widgets/semantics_tester.dart';
import 'feedback_tester.dart';

void main() {
  testWidgets('BottomNavigationBar callback test', (WidgetTester tester) async {
    late int mutatedIndex;

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
            onTap: (int index) {
              mutatedIndex = index;
            },
          ),
        ),
      ),
    );

    await tester.tap(find.text('Alarm'));

    expect(mutatedIndex, 1);
  });

  testWidgets('BottomNavigationBar content test', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    final RenderBox box = tester.renderObject(find.byType(BottomNavigationBar));
    expect(box.size.height, kBottomNavigationBarHeight);
    expect(find.text('AC'), findsOneWidget);
    expect(find.text('Alarm'), findsOneWidget);
  });

  testWidgets('Fixed BottomNavigationBar defaults', (WidgetTester tester) async {
    const Color primaryColor = Color(0xFF000001);
    const Color unselectedWidgetColor = Color(0xFF000002);

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData.light().copyWith(
          colorScheme: const ColorScheme.light().copyWith(primary: primaryColor),
          unselectedWidgetColor: unselectedWidgetColor,
        ),
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    const double selectedFontSize = 14.0;
    const double unselectedFontSize = 12.0;
    final TextStyle selectedFontStyle = tester.renderObject<RenderParagraph>(find.text('AC')).text.style!;
    final TextStyle unselectedFontStyle = tester.renderObject<RenderParagraph>(find.text('Alarm')).text.style!;
    final TextStyle selectedIcon = _iconStyle(tester, Icons.ac_unit);
    final TextStyle unselectedIcon = _iconStyle(tester, Icons.access_alarm);
    expect(selectedFontStyle.color, equals(primaryColor));
    expect(selectedFontStyle.fontSize, selectedFontSize);
    expect(selectedFontStyle.fontWeight, equals(FontWeight.w400));
    expect(selectedFontStyle.height, isNull);
    expect(unselectedFontStyle.color, equals(unselectedWidgetColor));
    expect(unselectedFontStyle.fontWeight, equals(FontWeight.w400));
    expect(unselectedFontStyle.height, isNull);
    // Unselected label has a font size of 14 but is scaled down to be font size 12.
    expect(
      tester.firstWidget<Transform>(find.ancestor(of: find.text('Alarm'), matching: find.byType(Transform))).transform,
      equals(Matrix4.diagonal3(Vector3.all(unselectedFontSize / selectedFontSize))),
    );
    expect(selectedIcon.color, equals(primaryColor));
    expect(selectedIcon.fontSize, equals(24.0));
    expect(unselectedIcon.color, equals(unselectedWidgetColor));
    expect(unselectedIcon.fontSize, equals(24.0));
    // There should not be any [Opacity] or [FadeTransition] widgets
    // since showUnselectedLabels and showSelectedLabels are true.
    final Finder findOpacity = find.descendant(
      of: find.byType(BottomNavigationBar),
      matching: find.byType(Opacity),
    );
    final Finder findFadeTransition = find.descendant(
      of: find.byType(BottomNavigationBar),
      matching: find.byType(FadeTransition),
    );
    expect(findOpacity, findsNothing);
    expect(findFadeTransition, findsNothing);
    expect(_getMaterial(tester).elevation, equals(8.0));
  });

  testWidgets('Custom selected and unselected font styles', (WidgetTester tester) async {
    const TextStyle selectedTextStyle = TextStyle(fontWeight: FontWeight.w200, fontSize: 18.0);
    const TextStyle unselectedTextStyle = TextStyle(fontWeight: FontWeight.w600, fontSize: 12.0);

    await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            bottomNavigationBar: BottomNavigationBar(
              type: BottomNavigationBarType.fixed,
              selectedLabelStyle: selectedTextStyle,
              unselectedLabelStyle: unselectedTextStyle,
              items: const <BottomNavigationBarItem>[
                BottomNavigationBarItem(
                  icon: Icon(Icons.ac_unit),
                  label: 'AC',
                ),
                BottomNavigationBarItem(
                  icon: Icon(Icons.access_alarm),
                  label: 'Alarm',
                ),
              ],
            ),
          ),
        ),
    );

    final TextStyle selectedFontStyle = tester.renderObject<RenderParagraph>(find.text('AC')).text.style!;
    final TextStyle unselectedFontStyle = tester.renderObject<RenderParagraph>(find.text('Alarm')).text.style!;
    expect(selectedFontStyle.fontSize, equals(selectedTextStyle.fontSize));
    expect(selectedFontStyle.fontWeight, equals(selectedTextStyle.fontWeight));
    expect(
      tester.firstWidget<Transform>(find.ancestor(of: find.text('Alarm'), matching: find.byType(Transform))).transform,
      equals(Matrix4.diagonal3(Vector3.all(unselectedTextStyle.fontSize! / selectedTextStyle.fontSize!))),
    );
    expect(unselectedFontStyle.fontWeight, equals(unselectedTextStyle.fontWeight));
  });

  testWidgets('font size on text styles overrides font size params', (WidgetTester tester) async {
    const TextStyle selectedTextStyle = TextStyle(fontSize: 18.0);
    const TextStyle unselectedTextStyle = TextStyle(fontSize: 12.0);
    const double selectedFontSize = 17.0;
    const double unselectedFontSize = 11.0;

    await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            bottomNavigationBar: BottomNavigationBar(
              type: BottomNavigationBarType.fixed,
              selectedLabelStyle: selectedTextStyle,
              unselectedLabelStyle: unselectedTextStyle,
              selectedFontSize: selectedFontSize,
              unselectedFontSize: unselectedFontSize,
              items: const <BottomNavigationBarItem>[
                BottomNavigationBarItem(
                  icon: Icon(Icons.ac_unit),
                  label: 'AC',
                ),
                BottomNavigationBarItem(
                  icon: Icon(Icons.access_alarm),
                  label: 'Alarm',
                ),
              ],
            ),
          ),
        ),
    );

    final TextStyle selectedFontStyle = tester.renderObject<RenderParagraph>(find.text('AC')).text.style!;
    expect(selectedFontStyle.fontSize, equals(selectedTextStyle.fontSize));
    expect(
      tester.firstWidget<Transform>(find.ancestor(of: find.text('Alarm'), matching: find.byType(Transform))).transform,
      equals(Matrix4.diagonal3(Vector3.all(unselectedTextStyle.fontSize! / selectedTextStyle.fontSize!))),
    );
  });

  testWidgets('Custom selected and unselected icon themes', (WidgetTester tester) async {
    const IconThemeData selectedIconTheme = IconThemeData(size: 36, color: Color(0x00000001));
    const IconThemeData unselectedIconTheme = IconThemeData(size: 18, color: Color(0x00000002));

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            selectedIconTheme: selectedIconTheme,
            unselectedIconTheme: unselectedIconTheme,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    final TextStyle selectedIcon = _iconStyle(tester, Icons.ac_unit);
    final TextStyle unselectedIcon = _iconStyle(tester, Icons.access_alarm);
    expect(selectedIcon.color, equals(selectedIconTheme.color));
    expect(selectedIcon.fontSize, equals(selectedIconTheme.size));
    expect(unselectedIcon.color, equals(unselectedIconTheme.color));
    expect(unselectedIcon.fontSize, equals(unselectedIconTheme.size));
  });

  testWidgets('color on icon theme overrides selected and unselected item colors', (WidgetTester tester) async {
    const IconThemeData selectedIconTheme = IconThemeData(size: 36, color: Color(0x00000001));
    const IconThemeData unselectedIconTheme = IconThemeData(size: 18, color: Color(0x00000002));
    const Color selectedItemColor = Color(0x00000003);
    const Color unselectedItemColor = Color(0x00000004);

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            selectedIconTheme: selectedIconTheme,
            unselectedIconTheme: unselectedIconTheme,
            selectedItemColor: selectedItemColor,
            unselectedItemColor: unselectedItemColor,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    final TextStyle selectedFontStyle = tester.renderObject<RenderParagraph>(find.text('AC')).text.style!;
    final TextStyle unselectedFontStyle = tester.renderObject<RenderParagraph>(find.text('Alarm')).text.style!;
    final TextStyle selectedIcon = _iconStyle(tester, Icons.ac_unit);
    final TextStyle unselectedIcon = _iconStyle(tester, Icons.access_alarm);
    expect(selectedIcon.color, equals(selectedIconTheme.color));
    expect(unselectedIcon.color, equals(unselectedIconTheme.color));
    expect(selectedFontStyle.color, equals(selectedItemColor));
    expect(unselectedFontStyle.color, equals(unselectedItemColor));
  });

  testWidgets('Padding is calculated properly on items - all labels', (WidgetTester tester) async {
    const double selectedFontSize = 16.0;
    const double selectedIconSize = 36.0;
    const double unselectedIconSize = 20.0;
    const IconThemeData selectedIconTheme = IconThemeData(size: selectedIconSize);
    const IconThemeData unselectedIconTheme = IconThemeData(size: unselectedIconSize);

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            showSelectedLabels: true,
            showUnselectedLabels: true,
            selectedFontSize: selectedFontSize,
            selectedIconTheme: selectedIconTheme,
            unselectedIconTheme: unselectedIconTheme,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    final EdgeInsets selectedItemPadding = _itemPadding(tester, Icons.ac_unit);
    expect(selectedItemPadding.top, equals(selectedFontSize / 2.0));
    expect(selectedItemPadding.bottom, equals(selectedFontSize / 2.0));
    final EdgeInsets unselectedItemPadding = _itemPadding(tester, Icons.access_alarm);
    const double expectedUnselectedPadding = (selectedIconSize - unselectedIconSize) / 2.0 + selectedFontSize / 2.0;
    expect(unselectedItemPadding.top, equals(expectedUnselectedPadding));
    expect(unselectedItemPadding.bottom, equals(expectedUnselectedPadding));
  });

  testWidgets('Padding is calculated properly on items - selected labels only', (WidgetTester tester) async {
    const double selectedFontSize = 16.0;
    const double selectedIconSize = 36.0;
    const double unselectedIconSize = 20.0;
    const IconThemeData selectedIconTheme = IconThemeData(size: selectedIconSize);
    const IconThemeData unselectedIconTheme = IconThemeData(size: unselectedIconSize);

    await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            bottomNavigationBar: BottomNavigationBar(
              type: BottomNavigationBarType.fixed,
              showSelectedLabels: true,
              showUnselectedLabels: false,
              selectedFontSize: selectedFontSize,
              selectedIconTheme: selectedIconTheme,
              unselectedIconTheme: unselectedIconTheme,
              items: const <BottomNavigationBarItem>[
                BottomNavigationBarItem(
                  icon: Icon(Icons.ac_unit),
                  label: 'AC',
                ),
                BottomNavigationBarItem(
                  icon: Icon(Icons.access_alarm),
                  label: 'Alarm',
                ),
              ],
            ),
          ),
        ),
    );

    final EdgeInsets selectedItemPadding = _itemPadding(tester, Icons.ac_unit);
    expect(selectedItemPadding.top, equals(selectedFontSize / 2.0));
    expect(selectedItemPadding.bottom, equals(selectedFontSize / 2.0));
    final EdgeInsets unselectedItemPadding = _itemPadding(tester, Icons.access_alarm);
    expect(unselectedItemPadding.top, equals((selectedIconSize - unselectedIconSize) / 2.0 + selectedFontSize));
    expect(unselectedItemPadding.bottom, equals((selectedIconSize - unselectedIconSize) / 2.0));
  });

  testWidgets('Padding is calculated properly on items - no labels', (WidgetTester tester) async {
    const double selectedFontSize = 16.0;
    const double selectedIconSize = 36.0;
    const double unselectedIconSize = 20.0;
    const IconThemeData selectedIconTheme = IconThemeData(size: selectedIconSize);
    const IconThemeData unselectedIconTheme = IconThemeData(size: unselectedIconSize);

    await tester.pumpWidget(
        MaterialApp(
          home: Scaffold(
            bottomNavigationBar: BottomNavigationBar(
              type: BottomNavigationBarType.fixed,
              showSelectedLabels: false,
              showUnselectedLabels: false,
              selectedFontSize: selectedFontSize,
              selectedIconTheme: selectedIconTheme,
              unselectedIconTheme: unselectedIconTheme,
              items: const <BottomNavigationBarItem>[
                BottomNavigationBarItem(
                  icon: Icon(Icons.ac_unit),
                  label: 'AC',
                ),
                BottomNavigationBarItem(
                  icon: Icon(Icons.access_alarm),
                  label: 'Alarm',
                ),
              ],
            ),
          ),
        ),
    );

    final EdgeInsets selectedItemPadding = _itemPadding(tester, Icons.ac_unit);
    expect(selectedItemPadding.top, equals(selectedFontSize));
    expect(selectedItemPadding.bottom, equals(0.0));
    final EdgeInsets unselectedItemPadding = _itemPadding(tester, Icons.access_alarm);
    expect(unselectedItemPadding.top, equals((selectedIconSize - unselectedIconSize) / 2.0 + selectedFontSize));
    expect(unselectedItemPadding.bottom, equals((selectedIconSize - unselectedIconSize) / 2.0));
  });

  testWidgets('Shifting BottomNavigationBar defaults', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.shifting,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    const double selectedFontSize = 14.0;
    expect(tester.renderObject<RenderParagraph>(find.text('AC')).text.style!.fontSize, selectedFontSize);
    expect(tester.renderObject<RenderParagraph>(find.text('AC')).text.style!.color, equals(Colors.white));
    expect(_getOpacity(tester, 'Alarm'), equals(0.0));
    expect(_getMaterial(tester).elevation, equals(8.0));
  });

  testWidgets('Fixed BottomNavigationBar custom font size, color', (WidgetTester tester) async {
    const Color primaryColor = Color(0xFF000000);
    const Color unselectedWidgetColor = Color(0xFFD501FF);
    const Color selectedColor = Color(0xFF0004FF);
    const Color unselectedColor = Color(0xFFE5FF00);
    const double selectedFontSize = 18.0;
    const double unselectedFontSize = 14.0;

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(
          primaryColor: primaryColor,
          unselectedWidgetColor: unselectedWidgetColor,
        ),
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            selectedFontSize: selectedFontSize,
            unselectedFontSize: unselectedFontSize,
            selectedItemColor: selectedColor,
            unselectedItemColor: unselectedColor,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    final TextStyle selectedIcon = _iconStyle(tester, Icons.ac_unit);
    final TextStyle unselectedIcon = _iconStyle(tester, Icons.access_alarm);

    expect(tester.renderObject<RenderParagraph>(find.text('AC')).text.style!.fontSize, selectedFontSize);
    // Unselected label has a font size of 18 but is scaled down to be font size 14.
    expect(tester.renderObject<RenderParagraph>(find.text('Alarm')).text.style!.fontSize, selectedFontSize);
    expect(
      tester.firstWidget<Transform>(find.ancestor(of: find.text('Alarm'), matching: find.byType(Transform))).transform,
      equals(Matrix4.diagonal3(Vector3.all(unselectedFontSize / selectedFontSize))),
    );
    expect(tester.renderObject<RenderParagraph>(find.text('AC')).text.style!.color, equals(selectedColor));
    expect(tester.renderObject<RenderParagraph>(find.text('Alarm')).text.style!.color, equals(unselectedColor));
    expect(selectedIcon.color, equals(selectedColor));
    expect(unselectedIcon.color, equals(unselectedColor));
    // There should not be any [Opacity] or [FadeTransition] widgets
    // since showUnselectedLabels and showSelectedLabels are true.
    final Finder findOpacity = find.descendant(
      of: find.byType(BottomNavigationBar),
      matching: find.byType(Opacity),
    );
    final Finder findFadeTransition = find.descendant(
      of: find.byType(BottomNavigationBar),
      matching: find.byType(FadeTransition),
    );
    expect(findOpacity, findsNothing);
    expect(findFadeTransition, findsNothing);
  });


  testWidgets('Shifting BottomNavigationBar custom font size, color', (WidgetTester tester) async {
    const Color primaryColor = Color(0xFF000000);
    const Color unselectedWidgetColor = Color(0xFFD501FF);
    const Color selectedColor = Color(0xFF0004FF);
    const Color unselectedColor = Color(0xFFE5FF00);
    const double selectedFontSize = 18.0;
    const double unselectedFontSize = 14.0;

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(
          primaryColor: primaryColor,
          unselectedWidgetColor: unselectedWidgetColor,
        ),
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.shifting,
            selectedFontSize: selectedFontSize,
            unselectedFontSize: unselectedFontSize,
            selectedItemColor: selectedColor,
            unselectedItemColor: unselectedColor,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    final TextStyle selectedIcon = _iconStyle(tester, Icons.ac_unit);
    final TextStyle unselectedIcon = _iconStyle(tester, Icons.access_alarm);

    expect(tester.renderObject<RenderParagraph>(find.text('AC')).text.style!.fontSize, selectedFontSize);
    expect(tester.renderObject<RenderParagraph>(find.text('AC')).text.style!.color, equals(selectedColor));
    expect(_getOpacity(tester, 'Alarm'), equals(0.0));

    expect(selectedIcon.color, equals(selectedColor));
    expect(unselectedIcon.color, equals(unselectedColor));
  });

  testWidgets('label style color should override itemColor only for the label for BottomNavigationBarType.fixed', (WidgetTester tester) async {
    const Color primaryColor = Color(0xFF000000);
    const Color unselectedWidgetColor = Color(0xFFD501FF);
    const Color selectedColor = Color(0xFF0004FF);
    const Color unselectedColor = Color(0xFFE5FF00);
    const Color selectedLabelColor = Color(0xFFFF9900);
    const Color unselectedLabelColor = Color(0xFF92F74E);

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(
          primaryColor: primaryColor,
          unselectedWidgetColor: unselectedWidgetColor,
        ),
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            selectedLabelStyle: const TextStyle(color: selectedLabelColor),
            unselectedLabelStyle: const TextStyle(color: unselectedLabelColor),
            selectedItemColor: selectedColor,
            unselectedItemColor: unselectedColor,
            useLegacyColorScheme: false,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    final TextStyle selectedIcon = _iconStyle(tester, Icons.ac_unit);
    final TextStyle unselectedIcon = _iconStyle(tester, Icons.access_alarm);

    expect(selectedIcon.color, equals(selectedColor));
    expect(unselectedIcon.color, equals(unselectedColor));
    expect(tester.renderObject<RenderParagraph>(find.text('AC')).text.style!.color, equals(selectedLabelColor));
    expect(tester.renderObject<RenderParagraph>(find.text('Alarm')).text.style!.color, equals(unselectedLabelColor));
  });

  testWidgets('label style color should override itemColor only for the label for BottomNavigationBarType.shifting', (WidgetTester tester) async {
    const Color primaryColor = Color(0xFF000000);
    const Color unselectedWidgetColor = Color(0xFFD501FF);
    const Color selectedColor = Color(0xFF0004FF);
    const Color unselectedColor = Color(0xFFE5FF00);
    const Color selectedLabelColor = Color(0xFFFF9900);
    const Color unselectedLabelColor = Color(0xFF92F74E);

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(
          primaryColor: primaryColor,
          unselectedWidgetColor: unselectedWidgetColor,
        ),
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.shifting,
            selectedLabelStyle: const TextStyle(color: selectedLabelColor),
            unselectedLabelStyle: const TextStyle(color: unselectedLabelColor),
            selectedItemColor: selectedColor,
            unselectedItemColor: unselectedColor,
            useLegacyColorScheme: false,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    final TextStyle selectedIcon = _iconStyle(tester, Icons.ac_unit);
    final TextStyle unselectedIcon = _iconStyle(tester, Icons.access_alarm);

    expect(selectedIcon.color, equals(selectedColor));
    expect(unselectedIcon.color, equals(unselectedColor));
    expect(tester.renderObject<RenderParagraph>(find.text('AC')).text.style!.color, equals(selectedLabelColor));
    expect(tester.renderObject<RenderParagraph>(find.text('Alarm')).text.style!.color, equals(unselectedLabelColor));
  });

  testWidgets('iconTheme color should override itemColor for BottomNavigationBarType.fixed', (WidgetTester tester) async {
    const Color primaryColor = Color(0xFF000000);
    const Color unselectedWidgetColor = Color(0xFFD501FF);
    const Color selectedColor = Color(0xFF0004FF);
    const Color unselectedColor = Color(0xFFE5FF00);
    const Color selectedLabelColor = Color(0xFFFF9900);
    const Color unselectedLabelColor = Color(0xFF92F74E);
    const Color selectedIconThemeColor = Color(0xFF1E7723);
    const Color unselectedIconThemeColor = Color(0xFF009688);
    const IconThemeData selectedIconTheme = IconThemeData(size: 20, color: selectedIconThemeColor);
    const IconThemeData unselectedIconTheme = IconThemeData(size: 18, color: unselectedIconThemeColor);
    const TextStyle selectedTextStyle = TextStyle(fontSize: 18.0, color: selectedLabelColor);
    const TextStyle unselectedTextStyle = TextStyle(fontSize: 18.0, color: unselectedLabelColor);

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(
          primaryColor: primaryColor,
          unselectedWidgetColor: unselectedWidgetColor,
        ),
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            selectedLabelStyle: selectedTextStyle,
            unselectedLabelStyle: unselectedTextStyle,
            selectedIconTheme: selectedIconTheme,
            unselectedIconTheme: unselectedIconTheme,
            selectedItemColor: selectedColor,
            unselectedItemColor: unselectedColor,
            useLegacyColorScheme: false,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    final TextStyle selectedIcon = _iconStyle(tester, Icons.ac_unit);
    final TextStyle unselectedIcon = _iconStyle(tester, Icons.access_alarm);

    expect(selectedIcon.color, equals(selectedIconThemeColor));
    expect(unselectedIcon.color, equals(unselectedIconThemeColor));
  });

  testWidgets('iconTheme color should override itemColor for BottomNavigationBarType.shifted', (WidgetTester tester) async {
    const Color primaryColor = Color(0xFF000000);
    const Color unselectedWidgetColor = Color(0xFFD501FF);
    const Color selectedLabelColor = Color(0xFFFF9900);
    const Color unselectedLabelColor = Color(0xFF92F74E);
    const Color selectedIconThemeColor = Color(0xFF1E7723);
    const Color unselectedIconThemeColor = Color(0xFF009688);
    const IconThemeData selectedIconTheme = IconThemeData(size: 20, color: selectedIconThemeColor);
    const IconThemeData unselectedIconTheme = IconThemeData(size: 18, color: unselectedIconThemeColor);
    const TextStyle selectedTextStyle = TextStyle(fontSize: 18.0, color: selectedLabelColor);
    const TextStyle unselectedTextStyle = TextStyle(fontSize: 18.0, color: unselectedLabelColor);

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(
          primaryColor: primaryColor,
          unselectedWidgetColor: unselectedWidgetColor,
        ),
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.shifting,
            selectedLabelStyle: selectedTextStyle,
            unselectedLabelStyle: unselectedTextStyle,
            selectedIconTheme: selectedIconTheme,
            unselectedIconTheme: unselectedIconTheme,
            useLegacyColorScheme: false,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    final TextStyle selectedIcon = _iconStyle(tester, Icons.ac_unit);
    final TextStyle unselectedIcon = _iconStyle(tester, Icons.access_alarm);

    expect(selectedIcon.color, equals(selectedIconThemeColor));
    expect(unselectedIcon.color, equals(unselectedIconThemeColor));
  });

  testWidgets('iconTheme color should override itemColor color for BottomNavigationBarType.fixed', (WidgetTester tester) async {
    const Color primaryColor = Color(0xFF000000);
    const Color unselectedWidgetColor = Color(0xFFD501FF);
    const Color selectedIconThemeColor = Color(0xFF1E7723);
    const Color unselectedIconThemeColor = Color(0xFF009688);
    const IconThemeData selectedIconTheme = IconThemeData(size: 20, color: selectedIconThemeColor);
    const IconThemeData unselectedIconTheme = IconThemeData(size: 18, color: unselectedIconThemeColor);

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(
          primaryColor: primaryColor,
          unselectedWidgetColor: unselectedWidgetColor,
        ),
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            selectedIconTheme: selectedIconTheme,
            unselectedIconTheme: unselectedIconTheme,
            useLegacyColorScheme: false,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    final TextStyle selectedIcon = _iconStyle(tester, Icons.ac_unit);
    final TextStyle unselectedIcon = _iconStyle(tester, Icons.access_alarm);

    expect(selectedIcon.color, equals(selectedIconThemeColor));
    expect(unselectedIcon.color, equals(unselectedIconThemeColor));
  });

  testWidgets('iconTheme color should override itemColor for BottomNavigationBarType.shifted', (WidgetTester tester) async {
    const Color primaryColor = Color(0xFF000000);
    const Color unselectedWidgetColor = Color(0xFFD501FF);
    const Color selectedColor = Color(0xFF0004FF);
    const Color unselectedColor = Color(0xFFE5FF00);
    const Color selectedIconThemeColor = Color(0xFF1E7723);
    const Color unselectedIconThemeColor = Color(0xFF009688);
    const IconThemeData selectedIconTheme = IconThemeData(size: 20, color: selectedIconThemeColor);
    const IconThemeData unselectedIconTheme = IconThemeData(size: 18, color: unselectedIconThemeColor);

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(
          primaryColor: primaryColor,
          unselectedWidgetColor: unselectedWidgetColor,
        ),
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.shifting,
            selectedIconTheme: selectedIconTheme,
            unselectedIconTheme: unselectedIconTheme,
            selectedItemColor: selectedColor,
            unselectedItemColor: unselectedColor,
            useLegacyColorScheme: false,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    final TextStyle selectedIcon = _iconStyle(tester, Icons.ac_unit);
    final TextStyle unselectedIcon = _iconStyle(tester, Icons.access_alarm);

    expect(selectedIcon.color, equals(selectedIconThemeColor));
    expect(unselectedIcon.color, equals(unselectedIconThemeColor));
  });

  testWidgets('Fixed BottomNavigationBar can hide unselected labels', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            showUnselectedLabels: false,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    expect(_getOpacity(tester, 'AC'), equals(1.0));
    expect(_getOpacity(tester, 'Alarm'), equals(0.0));
  });

  testWidgets('Fixed BottomNavigationBar can update background color', (WidgetTester tester) async {
    const Color color = Colors.yellow;

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            backgroundColor: color,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    expect(_getMaterial(tester).color, equals(color));
  });

  testWidgets('Shifting BottomNavigationBar background color is overridden by item color', (WidgetTester tester) async {
    const Color itemColor = Colors.yellow;
    const Color backgroundColor = Colors.blue;

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.shifting,
            backgroundColor: backgroundColor,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
                backgroundColor: itemColor,
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    expect(_getMaterial(tester).color, equals(itemColor));
  });

  testWidgets('Specifying both selectedItemColor and fixedColor asserts', (WidgetTester tester) async {
    expect(
      () {
        return BottomNavigationBar(
          selectedItemColor: Colors.black,
          fixedColor: Colors.black,
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.ac_unit),
              label: 'AC',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.access_alarm),
              label: 'Alarm',
            ),
          ],
        );
      },
      throwsAssertionError,
    );
  });

  testWidgets('Fixed BottomNavigationBar uses fixedColor when selectedItemColor not provided', (WidgetTester tester) async {
    const Color fixedColor = Colors.black;

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            fixedColor: fixedColor,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    expect(tester.renderObject<RenderParagraph>(find.text('AC')).text.style!.color, equals(fixedColor));
  });

  testWidgets('setting selectedFontSize to zero hides all labels', (WidgetTester tester) async {
    const double customElevation = 3.0;

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            elevation: customElevation,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    expect(_getMaterial(tester).elevation, equals(customElevation));
  });

  testWidgets('BottomNavigationBar adds bottom padding to height', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: MediaQuery(
          data: const MediaQueryData(padding: EdgeInsets.only(bottom: 40.0)),
          child: Scaffold(
            bottomNavigationBar: BottomNavigationBar(
              items: const <BottomNavigationBarItem>[
                BottomNavigationBarItem(
                  icon: Icon(Icons.ac_unit),
                  label: 'AC',
                ),
                BottomNavigationBarItem(
                  icon: Icon(Icons.access_alarm),
                  label: 'Alarm',
                ),
              ],
            ),
          ),
        ),
      ),
    );

    const double expectedHeight = kBottomNavigationBarHeight + 40.0;
    expect(tester.getSize(find.byType(BottomNavigationBar)).height, expectedHeight);
  });

  testWidgets('BottomNavigationBar adds bottom padding to height with a custom font size', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: MediaQuery(
          data: const MediaQueryData(padding: EdgeInsets.only(bottom: 40.0)),
          child: Scaffold(
            bottomNavigationBar: BottomNavigationBar(
              selectedFontSize: 8,
              items: const <BottomNavigationBarItem>[
                BottomNavigationBarItem(
                  icon: Icon(Icons.ac_unit),
                  label: 'AC',
                ),
                BottomNavigationBarItem(
                  icon: Icon(Icons.access_alarm),
                  label: 'Alarm',
                ),
              ],
            ),
          ),
        ),
      ),
    );

    const double expectedHeight = kBottomNavigationBarHeight + 40.0;
    expect(tester.getSize(find.byType(BottomNavigationBar)).height, expectedHeight);
  });

  testWidgets('BottomNavigationBar action size test', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.shifting,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    Iterable<RenderBox> actions = tester.renderObjectList(find.byType(InkResponse));
    expect(actions.length, 2);
    expect(actions.elementAt(0).size.width, 480.0);
    expect(actions.elementAt(1).size.width, 320.0);

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            currentIndex: 1,
            type: BottomNavigationBarType.shifting,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
            ],
          ),
        ),
      ),
    );

    await tester.pump(const Duration(milliseconds: 200));

    actions = tester.renderObjectList(find.byType(InkResponse));
    expect(actions.length, 2);
    expect(actions.elementAt(0).size.width, 320.0);
    expect(actions.elementAt(1).size.width, 480.0);
  });

  testWidgets('BottomNavigationBar multiple taps test', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.shifting,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
                label: 'Alarm',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_time),
                label: 'Time',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.add),
                label: 'Add',
              ),
            ],
          ),
        ),
      ),
    );

    // We want to make sure that the last label does not get displaced,
    // irrespective of how many taps happen on the first N - 1 labels and how
    // they grow.

    Iterable<RenderBox> actions = tester.renderObjectList(find.byType(InkResponse));
    final Offset originalOrigin = actions.elementAt(3).localToGlobal(Offset.zero);

    await tester.tap(find.text('AC'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 100));

    actions = tester.renderObjectList(find.byType(InkResponse));
    expect(actions.elementAt(3).localToGlobal(Offset.zero), equals(originalOrigin));

    await tester.tap(find.text('Alarm'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 100));

    actions = tester.renderObjectList(find.byType(InkResponse));
    expect(actions.elementAt(3).localToGlobal(Offset.zero), equals(originalOrigin));

    await tester.tap(find.text('Time'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 100));

    actions = tester.renderObjectList(find.byType(InkResponse));
    expect(actions.elementAt(3).localToGlobal(Offset.zero), equals(originalOrigin));
  });

  testWidgets('BottomNavigationBar inherits shadowed app theme for shifting navbar', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(brightness: Brightness.light),
        home: Theme(
          data: ThemeData(brightness: Brightness.dark),
          child: Scaffold(
            bottomNavigationBar: BottomNavigationBar(
              type: BottomNavigationBarType.shifting,
              items: const <BottomNavigationBarItem>[
                BottomNavigationBarItem(
                  icon: Icon(Icons.ac_unit),
                  label: 'AC',
                ),
                BottomNavigationBarItem(
                  icon: Icon(Icons.access_alarm),
                  label: 'Alarm',
                ),
                BottomNavigationBarItem(
                  icon: Icon(Icons.access_time),
                  label: 'Time',
                ),
                BottomNavigationBarItem(
                  icon: Icon(Icons.add),
                  label: 'Add',
                ),
              ],
            ),
          ),
        ),
      ),
    );

    await tester.tap(find.text('Alarm'));
    await tester.pump(const Duration(seconds: 1));
    expect(Theme.of(tester.element(find.text('Alarm'))).brightness, equals(Brightness.dark));
  });

  testWidgets('BottomNavigationBar inherits shadowed app theme for fixed navbar', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(brightness: Brightness.light),
        home: Theme(
          data: ThemeData(brightness: Brightness.dark),
          child: Scaffold(
            bottomNavigationBar: BottomNavigationBar(
              type: BottomNavigationBarType.fixed,
              items: const <BottomNavigationBarItem>[
                BottomNavigationBarItem(
                  icon: Icon(Icons.ac_unit),
                  label: 'AC',
                ),
                BottomNavigationBarItem(
                  icon: Icon(Icons.access_alarm),
                  label: 'Alarm',
                ),
                BottomNavigationBarItem(
                  icon: Icon(Icons.access_time),
                  label: 'Time',
                ),
                BottomNavigationBarItem(
                  icon: Icon(Icons.add),
                  label: 'Add',
                ),
              ],
            ),
          ),
        ),
      ),
    );

    await tester.tap(find.text('Alarm'));
    await tester.pump(const Duration(seconds: 1));
    expect(Theme.of(tester.element(find.text('Alarm'))).brightness, equals(Brightness.dark));
  });

  testWidgets('BottomNavigationBar iconSize test', (WidgetTester tester) async {
    late double builderIconSize;
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            iconSize: 12.0,
            items: <BottomNavigationBarItem>[
              const BottomNavigationBarItem(
                label: 'A',
                icon: Icon(Icons.ac_unit),
              ),
              BottomNavigationBarItem(
                label: 'B',
                icon: Builder(
                  builder: (BuildContext context) {
                    builderIconSize = IconTheme.of(context).size!;
                    return SizedBox(
                      width: builderIconSize,
                      height: builderIconSize,
                    );
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );

    final RenderBox box = tester.renderObject(find.byType(Icon));
    expect(box.size.width, equals(12.0));
    expect(box.size.height, equals(12.0));
    expect(builderIconSize, 12.0);
  });

  testWidgets('BottomNavigationBar responds to textScaleFactor', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                label: 'A',
                icon: Icon(Icons.ac_unit),
              ),
              BottomNavigationBarItem(
                label: 'B',
                icon: Icon(Icons.battery_alert),
              ),
            ],
          ),
        ),
      ),
    );

    final RenderBox defaultBox = tester.renderObject(find.byType(BottomNavigationBar));
    expect(defaultBox.size.height, equals(kBottomNavigationBarHeight));

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.shifting,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                label: 'A',
                icon: Icon(Icons.ac_unit),
              ),
              BottomNavigationBarItem(
                label: 'B',
                icon: Icon(Icons.battery_alert),
              ),
            ],
          ),
        ),
      ),
    );

    final RenderBox shiftingBox = tester.renderObject(find.byType(BottomNavigationBar));
    expect(shiftingBox.size.height, equals(kBottomNavigationBarHeight));

    await tester.pumpWidget(
      MaterialApp(
        home: MediaQuery(
          data: const MediaQueryData(textScaleFactor: 2.0),
          child: Scaffold(
            bottomNavigationBar: BottomNavigationBar(
              items: const <BottomNavigationBarItem>[
                BottomNavigationBarItem(
                  label: 'A',
                  icon: Icon(Icons.ac_unit),
                ),
                BottomNavigationBarItem(
                  label: 'B',
                  icon: Icon(Icons.battery_alert),
                ),
              ],
            ),
          ),
        ),
      ),
    );

    final RenderBox box = tester.renderObject(find.byType(BottomNavigationBar));
    expect(box.size.height, equals(56.0));
  });

  testWidgets('BottomNavigationBar does not grow with textScaleFactor when labels are provided', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                label: 'A',
                icon: Icon(Icons.ac_unit),
              ),
              BottomNavigationBarItem(
                label: 'B',
                icon: Icon(Icons.battery_alert),
              ),
            ],
          ),
        ),
      ),
    );

    final RenderBox defaultBox = tester.renderObject(find.byType(BottomNavigationBar));
    expect(defaultBox.size.height, equals(kBottomNavigationBarHeight));

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.shifting,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                label: 'A',
                icon: Icon(Icons.ac_unit),
              ),
              BottomNavigationBarItem(
                label: 'B',
                icon: Icon(Icons.battery_alert),
              ),
            ],
          ),
        ),
      ),
    );

    final RenderBox shiftingBox = tester.renderObject(find.byType(BottomNavigationBar));
    expect(shiftingBox.size.height, equals(kBottomNavigationBarHeight));

    await tester.pumpWidget(
      MaterialApp(
        home: MediaQuery(
          data: const MediaQueryData(textScaleFactor: 2.0),
          child: Scaffold(
            bottomNavigationBar: BottomNavigationBar(
              items: const <BottomNavigationBarItem>[
                BottomNavigationBarItem(
                  label: 'A',
                  icon: Icon(Icons.ac_unit),
                ),
                BottomNavigationBarItem(
                  label: 'B',
                  icon: Icon(Icons.battery_alert),
                ),
              ],
            ),
          ),
        ),
      ),
    );

    final RenderBox box = tester.renderObject(find.byType(BottomNavigationBar));
    expect(box.size.height, equals(kBottomNavigationBarHeight));
  });

  testWidgets('BottomNavigationBar shows tool tips with text scaling on long press when labels are provided', (WidgetTester tester) async {
    const String label = 'Foo';

    Widget buildApp({ required double textScaleFactor }) {
      return MediaQuery(
        data: MediaQueryData(textScaleFactor: textScaleFactor),
        child: Localizations(
          locale: const Locale('en', 'US'),
          delegates: const <LocalizationsDelegate<dynamic>>[
            DefaultMaterialLocalizations.delegate,
            DefaultWidgetsLocalizations.delegate,
          ],
          child: Directionality(
            textDirection: TextDirection.ltr,
            child: Navigator(
              onGenerateRoute: (RouteSettings settings) {
                return MaterialPageRoute<void>(
                  builder: (BuildContext context) {
                    return Scaffold(
                      bottomNavigationBar: BottomNavigationBar(
                        items: const <BottomNavigationBarItem>[
                          BottomNavigationBarItem(
                            label: label,
                            icon: Icon(Icons.ac_unit),
                            tooltip: label,
                          ),
                          BottomNavigationBarItem(
                            label: 'B',
                            icon: Icon(Icons.battery_alert),
                          ),
                        ],
                      ),
                    );
                  },
                );
              },
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildApp(textScaleFactor: 1.0));
    expect(find.text(label), findsOneWidget);
    await tester.longPress(find.text(label));
    expect(find.text(label), findsNWidgets(2));
    expect(tester.getSize(find.text(label).last), equals(const Size(42.0, 14.0)));
    await tester.pumpAndSettle(const Duration(seconds: 2));

    await tester.pumpWidget(buildApp(textScaleFactor: 4.0));
    expect(find.text(label), findsOneWidget);
    await tester.longPress(find.text(label));
    expect(tester.getSize(find.text(label).last), equals(const Size(168.0, 56.0)));
  });

  testWidgets('Different behaviour of tool tip in BottomNavigationBarItem', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                label: 'A',
                tooltip: 'A tooltip',
                icon: Icon(Icons.ac_unit),
              ),
              BottomNavigationBarItem(
                label: 'B',
                icon: Icon(Icons.battery_alert),
              ),
              BottomNavigationBarItem(
                label: 'C',
                icon: Icon(Icons.cake),
                tooltip: '',
              ),
            ],
          ),
        ),
      ),
    );

    expect(find.text('A'), findsOneWidget);
    await tester.longPress(find.text('A'));
    expect(find.byTooltip('A tooltip'), findsOneWidget);

    expect(find.text('B'), findsOneWidget);
    await tester.longPress(find.text('B'));
    expect(find.byTooltip('B'), findsNothing);

    expect(find.text('C'), findsOneWidget);
    await tester.longPress(find.text('C'));
    expect(find.byTooltip('C'), findsNothing);
  });

  testWidgets('BottomNavigationBar limits width of tiles with long labels', (WidgetTester tester) async {
    final String longTextA = List<String>.generate(100, (int index) => 'A').toString();
    final String longTextB = List<String>.generate(100, (int index) => 'B').toString();

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            items: <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                label: longTextA,
                icon: const Icon(Icons.ac_unit),
              ),
              BottomNavigationBarItem(
                label: longTextB,
                icon: const Icon(Icons.battery_alert),
              ),
            ],
          ),
        ),
      ),
    );

    final RenderBox box = tester.renderObject(find.byType(BottomNavigationBar));
    expect(box.size.height, equals(kBottomNavigationBarHeight));

    final RenderBox itemBoxA = tester.renderObject(find.text(longTextA));
    expect(itemBoxA.size, equals(const Size(400.0, 14.0)));
    final RenderBox itemBoxB = tester.renderObject(find.text(longTextB));
    expect(itemBoxB.size, equals(const Size(400.0, 14.0)));
  });

  testWidgets('BottomNavigationBar paints circles', (WidgetTester tester) async {
    await tester.pumpWidget(
      boilerplate(
        textDirection: TextDirection.ltr,
        bottomNavigationBar: BottomNavigationBar(
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              label: 'A',
              icon: Icon(Icons.ac_unit),
            ),
            BottomNavigationBarItem(
              label: 'B',
              icon: Icon(Icons.battery_alert),
            ),
          ],
        ),
      ),
    );

    final RenderBox box = tester.renderObject(find.byType(BottomNavigationBar));
    expect(box, isNot(paints..circle()));

    await tester.tap(find.text('A'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 20));
    expect(box, paints..circle(x: 200.0));

    await tester.tap(find.text('B'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 20));
    expect(box, paints..circle(x: 200.0)..translate(x: 400.0)..circle(x: 200.0));

    // Now we flip the directionality and verify that the circles switch positions.
    await tester.pumpWidget(
      boilerplate(
        textDirection: TextDirection.rtl,
        bottomNavigationBar: BottomNavigationBar(
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              label: 'A',
              icon: Icon(Icons.ac_unit),
            ),
            BottomNavigationBarItem(
              label: 'B',
              icon: Icon(Icons.battery_alert),
            ),
          ],
        ),
      ),
    );

    expect(box, paints..translate()..save()..translate(x: 400.0)..circle(x: 200.0)..restore()..circle(x: 200.0));

    await tester.tap(find.text('A'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 20));
    expect(
        box,
        paints
          ..translate(x: 0.0, y: 0.0)
          ..save()
          ..translate(x: 400.0)
          ..circle(x: 200.0)
          ..restore()
          ..circle(x: 200.0)
          ..translate(x: 400.0)
          ..circle(x: 200.0),
    );
  });

  testWidgets('BottomNavigationBar inactiveIcon shown', (WidgetTester tester) async {
    const Key filled = Key('filled');
    const Key stroked = Key('stroked');
    int selectedItem = 0;

    await tester.pumpWidget(
      boilerplate(
        textDirection: TextDirection.ltr,
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: selectedItem,
          items:  const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              activeIcon: Icon(Icons.favorite, key: filled),
              icon: Icon(Icons.favorite_border, key: stroked),
              label: 'Favorite',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.access_alarm),
              label: 'Alarm',
            ),
          ],
        ),
      ),
    );

    expect(find.byKey(filled), findsOneWidget);
    expect(find.byKey(stroked), findsNothing);
    selectedItem = 1;

    await tester.pumpWidget(
      boilerplate(
        textDirection: TextDirection.ltr,
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: selectedItem,
          items:  const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              activeIcon: Icon(Icons.favorite, key: filled),
              icon: Icon(Icons.favorite_border, key: stroked),
              label: 'Favorite',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.access_alarm),
              label: 'Alarm',
            ),
          ],
        ),
      ),
    );

    expect(find.byKey(filled), findsNothing);
    expect(find.byKey(stroked), findsOneWidget);
  });

  testWidgets('BottomNavigationBar.fixed semantics', (WidgetTester tester) async {
    await tester.pumpWidget(
      boilerplate(
        textDirection: TextDirection.ltr,
        bottomNavigationBar: BottomNavigationBar(
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.ac_unit),
              label: 'AC',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.access_alarm),
              label: 'Alarm',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.hot_tub),
              label: 'Hot Tub',
            ),
          ],
        ),
      ),
    );

    expect(
      tester.getSemantics(find.text('AC')),
      matchesSemantics(
        label: 'AC\nTab 1 of 3',
        textDirection: TextDirection.ltr,
        isFocusable: true,
        isSelected: true,
        hasTapAction: true,
      ),
    );
    expect(
      tester.getSemantics(find.text('Alarm')),
      matchesSemantics(
        label: 'Alarm\nTab 2 of 3',
        textDirection: TextDirection.ltr,
        isFocusable: true,
        hasTapAction: true,
      ),
    );
    expect(
      tester.getSemantics(find.text('Hot Tub')),
      matchesSemantics(
        label: 'Hot Tub\nTab 3 of 3',
        textDirection: TextDirection.ltr,
        isFocusable: true,
        hasTapAction: true,
      ),
    );
  });

  testWidgets('BottomNavigationBar.shifting semantics', (WidgetTester tester) async {
    await tester.pumpWidget(
      boilerplate(
        textDirection: TextDirection.ltr,
        bottomNavigationBar: BottomNavigationBar(
          type: BottomNavigationBarType.shifting,
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.ac_unit),
              label: 'AC',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.access_alarm),
              label: 'Alarm',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.hot_tub),
              label: 'Hot Tub',
            ),
          ],
        ),
      ),
    );

    expect(
      tester.getSemantics(find.text('AC')),
      matchesSemantics(
        label: 'AC\nTab 1 of 3',
        textDirection: TextDirection.ltr,
        isFocusable: true,
        isSelected: true,
        hasTapAction: true,
      ),
    );
    expect(
      tester.getSemantics(find.text('Alarm')),
      matchesSemantics(
        label: 'Alarm\nTab 2 of 3',
        textDirection: TextDirection.ltr,
        isFocusable: true,
        hasTapAction: true,
      ),
    );
    expect(
      tester.getSemantics(find.text('Hot Tub')),
      matchesSemantics(
        label: 'Hot Tub\nTab 3 of 3',
        textDirection: TextDirection.ltr,
        isFocusable: true,
        hasTapAction: true,
      ),
    );
  });

  testWidgets('BottomNavigationBar handles items.length changes', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/10322

    Widget buildFrame(int itemCount) {
      return MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            items: List<BottomNavigationBarItem>.generate(itemCount, (int itemIndex) {
              return BottomNavigationBarItem(
                icon: const Icon(Icons.android),
                label: 'item $itemIndex',
              );
            }),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildFrame(3));
    expect(find.text('item 0'), findsOneWidget);
    expect(find.text('item 1'), findsOneWidget);
    expect(find.text('item 2'), findsOneWidget);
    expect(find.text('item 3'), findsNothing);

    await tester.pumpWidget(buildFrame(4));
    expect(find.text('item 0'), findsOneWidget);
    expect(find.text('item 1'), findsOneWidget);
    expect(find.text('item 2'), findsOneWidget);
    expect(find.text('item 3'), findsOneWidget);

    await tester.pumpWidget(buildFrame(2));
    expect(find.text('item 0'), findsOneWidget);
    expect(find.text('item 1'), findsOneWidget);
    expect(find.text('item 2'), findsNothing);
    expect(find.text('item 3'), findsNothing);
  });

  testWidgets('BottomNavigationBar change backgroundColor test', (WidgetTester tester) async {
    // Regression test for: https://github.com/flutter/flutter/issues/19653

    Color backgroundColor = Colors.red;

    await tester.pumpWidget(
      MaterialApp(
        home: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return Scaffold(
              body: Center(
                child: ElevatedButton(
                  child: const Text('green'),
                  onPressed: () {
                    setState(() {
                      backgroundColor = Colors.green;
                    });
                  },
                ),
              ),
              bottomNavigationBar: BottomNavigationBar(
                type: BottomNavigationBarType.shifting,
                items: <BottomNavigationBarItem>[
                  BottomNavigationBarItem(
                    label: 'Page 1',
                    backgroundColor: backgroundColor,
                    icon: const Icon(Icons.dashboard),
                  ),
                  BottomNavigationBarItem(
                    label: 'Page 2',
                    backgroundColor: backgroundColor,
                    icon: const Icon(Icons.menu),
                  ),
                ],
              ),
            );
          },
        ),
      ),
    );

    final Finder backgroundMaterial = find.descendant(
      of: find.byType(BottomNavigationBar),
      matching: find.byWidgetPredicate((Widget w) {
        if (w is Material) {
          return w.type == MaterialType.canvas;
        }
        return false;
      }),
    );

    expect(backgroundColor, Colors.red);
    expect(tester.widget<Material>(backgroundMaterial).color, Colors.red);
    await tester.tap(find.text('green'));
    await tester.pumpAndSettle();
    expect(backgroundColor, Colors.green);
    expect(tester.widget<Material>(backgroundMaterial).color, Colors.green);
  });

  group('BottomNavigationBar shifting backgroundColor with transition', () {
    // Regression test for: https://github.com/flutter/flutter/issues/22226
    Widget runTest() {
      int currentIndex = 0;
      return MaterialApp(
        home: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return Scaffold(
              bottomNavigationBar: RepaintBoundary(
                child: BottomNavigationBar(
                  type: BottomNavigationBarType.shifting,
                  currentIndex: currentIndex,
                  onTap: (int index) {
                    setState(() {
                      currentIndex = index;
                    });
                  },
                  items: const <BottomNavigationBarItem>[
                    BottomNavigationBarItem(
                      label: 'Red',
                      backgroundColor: Colors.red,
                      icon: Icon(Icons.dashboard),
                    ),
                    BottomNavigationBarItem(
                      label: 'Green',
                      backgroundColor: Colors.green,
                      icon: Icon(Icons.menu),
                    ),
                  ],
                ),
              ),
            );
          },
        ),
      );
    }
    for (int pump = 1; pump < 9; pump++) {
      testWidgets('pump $pump', (WidgetTester tester) async {
        await tester.pumpWidget(runTest());
        await tester.tap(find.text('Green'));

        for (int i = 0; i < pump; i++) {
          await tester.pump(const Duration(milliseconds: 30));
        }
        await expectLater(
          find.byType(BottomNavigationBar),
          matchesGoldenFile('bottom_navigation_bar.shifting_transition.${pump - 1}.png'),
        );
      });
    }
  });

  testWidgets('BottomNavigationBar item label should not be nullable', (WidgetTester tester) async {
    expect(() {
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.shifting,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.ac_unit),
                label: 'AC',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.access_alarm),
              ),
            ],
          ),
        ),
      );
    }, throwsAssertionError);
  });

  testWidgets(
    'BottomNavigationBar [showSelectedLabels]=false and [showUnselectedLabels]=false '
    'for shifting navbar, expect that there is no rendered text',
    (WidgetTester tester) async {
      final Widget widget = MaterialApp(
        home: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return Scaffold(
              bottomNavigationBar: BottomNavigationBar(
                showSelectedLabels: false,
                showUnselectedLabels: false,
                type: BottomNavigationBarType.shifting,
                items: const <BottomNavigationBarItem>[
                  BottomNavigationBarItem(
                    label: 'Red',
                    backgroundColor: Colors.red,
                    icon: Icon(Icons.dashboard),
                  ),
                  BottomNavigationBarItem(
                    label: 'Green',
                    backgroundColor: Colors.green,
                    icon: Icon(Icons.menu),
                  ),
                ],
              ),
            );
          },
        ),
      );
      await tester.pumpWidget(widget);
      expect(find.text('Red'), findsOneWidget);
      expect(find.text('Green'), findsOneWidget);
      expect(tester.widget<Opacity>(find.byType(Opacity).first).opacity, 0.0);
      expect(tester.widget<Opacity>(find.byType(Opacity).last).opacity, 0.0);
    },
  );

  testWidgets(
    'BottomNavigationBar [showSelectedLabels]=false and [showUnselectedLabels]=false '
    'for fixed navbar, expect that there is no rendered text',
    (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          home: StatefulBuilder(
            builder: (BuildContext context, StateSetter setState) {
              return Scaffold(
                bottomNavigationBar: BottomNavigationBar(
                  showSelectedLabels: false,
                  showUnselectedLabels: false,
                  type: BottomNavigationBarType.fixed,
                  items: const <BottomNavigationBarItem>[
                    BottomNavigationBarItem(
                      label: 'Red',
                      backgroundColor: Colors.red,
                      icon: Icon(Icons.dashboard),
                    ),
                    BottomNavigationBarItem(
                      label: 'Green',
                      backgroundColor: Colors.green,
                      icon: Icon(Icons.menu),
                    ),
                  ],
                ),
              );
            },
          ),
        ),
      );
      expect(find.text('Red'), findsOneWidget);
      expect(find.text('Green'), findsOneWidget);
      expect(tester.widget<Opacity>(find.byType(Opacity).first).opacity, 0.0);
      expect(tester.widget<Opacity>(find.byType(Opacity).last).opacity, 0.0);
    },
  );

  testWidgets('BottomNavigationBar.fixed [showSelectedLabels]=false and [showUnselectedLabels]=false semantics', (WidgetTester tester) async {
    await tester.pumpWidget(
      boilerplate(
        textDirection: TextDirection.ltr,
        bottomNavigationBar: BottomNavigationBar(
          showSelectedLabels: false,
          showUnselectedLabels: false,
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.ac_unit),
              label: 'Red',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.access_alarm),
              label: 'Green',
            ),
          ],
        ),
      ),
    );

    expect(
      tester.getSemantics(find.text('Red')),
      matchesSemantics(
        label: 'Red\nTab 1 of 2',
        textDirection: TextDirection.ltr,
        isFocusable: true,
        isSelected: true,
        hasTapAction: true,
      ),
    );
    expect(
      tester.getSemantics(find.text('Green')),
      matchesSemantics(
        label: 'Green\nTab 2 of 2',
        textDirection: TextDirection.ltr,
        isFocusable: true,
        hasTapAction: true,
      ),
    );
  });

  testWidgets('BottomNavigationBar.shifting [showSelectedLabels]=false and [showUnselectedLabels]=false semantics', (WidgetTester tester) async {
    await tester.pumpWidget(
      boilerplate(
        textDirection: TextDirection.ltr,
        bottomNavigationBar: BottomNavigationBar(
          showSelectedLabels: false,
          showUnselectedLabels: false,
          type: BottomNavigationBarType.shifting,
          items: const <BottomNavigationBarItem>[
            BottomNavigationBarItem(
              icon: Icon(Icons.ac_unit),
              label: 'Red',
            ),
            BottomNavigationBarItem(
              icon: Icon(Icons.access_alarm),
              label: 'Green',
            ),
          ],
        ),
      ),
    );

    expect(
      tester.getSemantics(find.text('Red')),
      matchesSemantics(
        label: 'Red\nTab 1 of 2',
        textDirection: TextDirection.ltr,
        isFocusable: true,
        isSelected: true,
        hasTapAction: true,
      ),
    );
    expect(
      tester.getSemantics(find.text('Green')),
      matchesSemantics(
        label: 'Green\nTab 2 of 2',
        textDirection: TextDirection.ltr,
        isFocusable: true,
        hasTapAction: true,
      ),
    );
  });

  testWidgets('BottomNavigationBar changes mouse cursor when the tile is hovered over', (WidgetTester tester) async {
    // Test BottomNavigationBar() constructor
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: MouseRegion(
            cursor: SystemMouseCursors.forbidden,
            child: BottomNavigationBar(
              mouseCursor: SystemMouseCursors.text,
              items: const <BottomNavigationBarItem>[
                BottomNavigationBarItem(icon: Icon(Icons.ac_unit), label: 'AC'),
                BottomNavigationBarItem(icon: Icon(Icons.access_alarm), label: 'Alarm'),
              ],
            ),
          ),
        ),
      ),
    );

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1);
    await gesture.addPointer(location: tester.getCenter(find.text('AC')));

    await tester.pumpAndSettle();

    expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.text);

    // Test default cursor
    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: MouseRegion(
            cursor: SystemMouseCursors.forbidden,
            child: BottomNavigationBar(
              items: const <BottomNavigationBarItem>[
                BottomNavigationBarItem(icon: Icon(Icons.ac_unit), label: 'AC'),
                BottomNavigationBarItem(icon: Icon(Icons.access_alarm), label: 'Alarm'),
              ],
            ),
          ),
        ),
      ),
    );

    expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.click);
  });

  group('feedback', () {
    late FeedbackTester feedback;

    setUp(() {
      feedback = FeedbackTester();
    });

    tearDown(() {
      feedback.dispose();
    });

    Widget feedbackBoilerplate({bool? enableFeedback, bool? enableFeedbackTheme}) {
      return MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBarTheme(
            data: BottomNavigationBarThemeData(
              enableFeedback: enableFeedbackTheme,
            ),
            child: BottomNavigationBar(
              enableFeedback: enableFeedback,
              items: const <BottomNavigationBarItem>[
                BottomNavigationBarItem(icon: Icon(Icons.ac_unit), label: 'AC'),
                BottomNavigationBarItem(icon: Icon(Icons.access_alarm), label: 'Alarm'),
              ],
            ),
          ),
        ),
      );
    }

    testWidgets('BottomNavigationBar with enabled feedback', (WidgetTester tester) async {
      const bool enableFeedback = true;

      await tester.pumpWidget(feedbackBoilerplate(enableFeedback: enableFeedback));

      await tester.tap(find.byType(InkResponse).first);
      await tester.pumpAndSettle();
      expect(feedback.clickSoundCount, 1);
      expect(feedback.hapticCount, 0);
    });

    testWidgets('BottomNavigationBar with disabled feedback', (WidgetTester tester) async {
      const bool enableFeedback = false;

      await tester.pumpWidget(feedbackBoilerplate(enableFeedback: enableFeedback));

      await tester.tap(find.byType(InkResponse).first);
      await tester.pumpAndSettle();
      expect(feedback.clickSoundCount, 0);
      expect(feedback.hapticCount, 0);
    });

    testWidgets('BottomNavigationBar with enabled feedback by default', (WidgetTester tester) async {
      await tester.pumpWidget(feedbackBoilerplate());

      await tester.tap(find.byType(InkResponse).first);
      await tester.pumpAndSettle();
      expect(feedback.clickSoundCount, 1);
      expect(feedback.hapticCount, 0);
    });

    testWidgets('BottomNavigationBar with disabled feedback using BottomNavigationBarTheme', (WidgetTester tester) async {
      const bool enableFeedbackTheme = false;

      await tester.pumpWidget(feedbackBoilerplate(enableFeedbackTheme: enableFeedbackTheme));

      await tester.tap(find.byType(InkResponse).first);
      await tester.pumpAndSettle();
      expect(feedback.clickSoundCount, 0);
      expect(feedback.hapticCount, 0);
    });

    testWidgets('BottomNavigationBar.enableFeedback overrides BottomNavigationBarTheme.enableFeedback', (WidgetTester tester) async {
      const bool enableFeedbackTheme = false;
      const bool enableFeedback = true;

      await tester.pumpWidget(feedbackBoilerplate(
        enableFeedbackTheme: enableFeedbackTheme,
        enableFeedback: enableFeedback,
      ));

      await tester.tap(find.byType(InkResponse).first);
      await tester.pumpAndSettle();
      expect(feedback.clickSoundCount, 1);
      expect(feedback.hapticCount, 0);
    });
  });

  testWidgets('BottomNavigationBar excludes semantics', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          bottomNavigationBar: BottomNavigationBar(
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                label: 'A',
                icon: Icon(Icons.ac_unit),
              ),
              BottomNavigationBarItem(
                label: 'B',
                icon: Icon(Icons.battery_alert),
              ),
            ],
          ),
        ),
      ),
    );

    expect(
      semantics,
      hasSemantics(
        TestSemantics.root(
          children: <TestSemantics>[
            TestSemantics(
              textDirection: TextDirection.ltr,
              children: <TestSemantics>[
                TestSemantics(
                  children: <TestSemantics>[
                    TestSemantics(
                      flags: <SemanticsFlag>[SemanticsFlag.scopesRoute],
                      children: <TestSemantics>[
                        TestSemantics(
                          children: <TestSemantics>[
                            TestSemantics(
                              flags: <SemanticsFlag>[
                                SemanticsFlag.isSelected,
                                SemanticsFlag.isFocusable,
                              ],
                              actions: <SemanticsAction>[SemanticsAction.tap],
                              label: 'A\nTab 1 of 2',
                              textDirection: TextDirection.ltr,
                            ),
                            TestSemantics(
                              flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
                              actions: <SemanticsAction>[SemanticsAction.tap],
                              label: 'B\nTab 2 of 2',
                              textDirection: TextDirection.ltr,
                            ),
                          ],
                        ),
                      ],
                    ),
                  ],
                ),
              ],
            ),
          ],
        ),
        ignoreId: true,
        ignoreRect: true,
        ignoreTransform: true,
      ),
    );

    semantics.dispose();
  });

  testWidgets('BottomNavigationBar default layout', (WidgetTester tester) async {
    final Key icon0 = UniqueKey();
    final Key icon1 = UniqueKey();

    await tester.pumpWidget(
      MaterialApp(
        home: Builder(
          builder: (BuildContext context) {
            return Scaffold(
              bottomNavigationBar: BottomNavigationBar(
                items: <BottomNavigationBarItem>[
                  BottomNavigationBarItem(
                    icon: SizedBox(key: icon0, width: 200, height: 10),
                    label: 'Title0',
                  ),
                  BottomNavigationBarItem(
                    icon: SizedBox(key: icon1, width: 200, height: 10),
                    label: 'Title1',
                  ),
                ],
              ),
            );
          },
        ),
      ),
    );
    expect(tester.getSize(find.byType(BottomNavigationBar)), const Size(800, kBottomNavigationBarHeight));
    expect(tester.getRect(find.byType(BottomNavigationBar)), const Rect.fromLTRB(0, 600 - kBottomNavigationBarHeight, 800, 600));

    // The height of the navigation bar is kBottomNavigationBarHeight = 56
    // The top of the navigation bar is 600 - 56 = 544
    // The top and bottom of the selected item is defined by its centered icon/label column:
    //   top = 544 + ((56 - (10 + 10)) / 2) = 562
    //   bottom = top + 10 + 10 = 582
    expect(tester.getRect(find.byKey(icon0)).top, 560.0);
    expect(tester.getRect(find.text('Title0')).bottom, 584.0);

    // The items are padded horizontally according to
    // MainAxisAlignment.spaceAround. Left/right padding is:
    // 800 - (200 * 2) / 4 = 100
    // The layout of the unselected item's label is slightly different; not
    // checking that here.
    expect(tester.getRect(find.text('Title0')), const Rect.fromLTRB(158.0, 570.0, 242.0, 584.0));
    expect(tester.getRect(find.byKey(icon0)), const Rect.fromLTRB(100.0, 560.0, 300.0, 570.0));
    expect(tester.getRect(find.byKey(icon1)), const Rect.fromLTRB(500.0, 560.0, 700.0, 570.0));
  });

  testWidgets('BottomNavigationBar centered landscape layout', (WidgetTester tester) async {
    final Key icon0 = UniqueKey();
    final Key icon1 = UniqueKey();

    await tester.pumpWidget(
      MaterialApp(
        home: Builder(
          builder: (BuildContext context) {
            return Scaffold(
              bottomNavigationBar: BottomNavigationBar(
                landscapeLayout: BottomNavigationBarLandscapeLayout.centered,
                items: <BottomNavigationBarItem>[
                  BottomNavigationBarItem(
                    icon: SizedBox(key: icon0, width: 200, height: 10),
                    label: 'Title0',
                  ),
                  BottomNavigationBarItem(
                    icon: SizedBox(key: icon1, width: 200, height: 10),
                    label: 'Title1',
                  ),
                ],
              ),
            );
          },
        ),
      ),
    );

    expect(tester.getSize(find.byType(BottomNavigationBar)), const Size(800, kBottomNavigationBarHeight));
    expect(tester.getRect(find.byType(BottomNavigationBar)), const Rect.fromLTRB(0, 600 - kBottomNavigationBarHeight, 800, 600));

    // The items are laid out as in the default case, within width = 600
    // (the "portrait" width) and the result is centered with the
    // landscape width = 800.
    // So item 0's left edges are:
    // ((800 - 600) / 2) + ((600 - 400) / 4) = 150.
    // Item 1's right edge is:
    // 800 - 150 = 650
    // The layout of the unselected item's label is slightly different; not
    // checking that here.
    expect(tester.getRect(find.text('Title0')), const Rect.fromLTRB(208.0, 570.0, 292.0, 584.0));
    expect(tester.getRect(find.byKey(icon0)), const Rect.fromLTRB(150.0, 560.0, 350.0, 570.0));
    expect(tester.getRect(find.byKey(icon1)), const Rect.fromLTRB(450.0, 560.0, 650.0, 570.0));
  });

  testWidgets('BottomNavigationBar linear landscape layout', (WidgetTester tester) async {
    final Key icon0 = UniqueKey();
    final Key icon1 = UniqueKey();

    await tester.pumpWidget(
      MaterialApp(
        home: Builder(
          builder: (BuildContext context) {
            return Scaffold(
              bottomNavigationBar: BottomNavigationBar(
                landscapeLayout: BottomNavigationBarLandscapeLayout.linear,
                items: <BottomNavigationBarItem>[
                  BottomNavigationBarItem(
                    icon: SizedBox(key: icon0, width: 100, height: 20),
                    label: 'Title0',
                  ),
                  BottomNavigationBarItem(
                    icon: SizedBox(key: icon1, width: 100, height: 20),
                    label: 'Title1',
                  ),
                ],
              ),
            );
          },
        ),
      ),
    );

    expect(tester.getSize(find.byType(BottomNavigationBar)), const Size(800, kBottomNavigationBarHeight));
    expect(tester.getRect(find.byType(BottomNavigationBar)), const Rect.fromLTRB(0, 600 - kBottomNavigationBarHeight, 800, 600));

    // The items are laid out as in the default case except each
    // item's icon/label is arranged in a row, with 8 pixels in
    // between the icon and label.  The layout of the unselected
    // item's label is slightly different; not checking that here.
    expect(tester.getRect(find.text('Title0')), const Rect.fromLTRB(212.0, 565.0, 296.0, 579.0));
    expect(tester.getRect(find.byKey(icon0)), const Rect.fromLTRB(104.0, 562.0, 204.0, 582.0));
    expect(tester.getRect(find.byKey(icon1)), const Rect.fromLTRB(504.0, 562.0, 604.0, 582.0));
  });
}

Widget boilerplate({ Widget? bottomNavigationBar, required TextDirection textDirection }) {
  assert(textDirection != null);
  return MaterialApp(
    home: Localizations(
      locale: const Locale('en', 'US'),
      delegates: const <LocalizationsDelegate<dynamic>>[
        DefaultMaterialLocalizations.delegate,
        DefaultWidgetsLocalizations.delegate,
      ],
      child: Directionality(
        textDirection: textDirection,
        child: MediaQuery(
          data: const MediaQueryData(),
          child: Material(
            child: Scaffold(
              bottomNavigationBar: bottomNavigationBar,
            ),
          ),
        ),
      ),
    ),
  );
}

double _getOpacity(WidgetTester tester, String textValue) {
  final FadeTransition opacityWidget = tester.widget<FadeTransition>(
      find.ancestor(
        of: find.text(textValue),
        matching: find.byType(FadeTransition),
      ).first,
  );
  return opacityWidget.opacity.value;
}

Material _getMaterial(WidgetTester tester) {
  return tester.firstWidget<Material>(
    find.descendant(of: find.byType(BottomNavigationBar), matching: find.byType(Material)),
  );
}

TextStyle _iconStyle(WidgetTester tester, IconData icon) {
  final RichText iconRichText = tester.widget<RichText>(
      find.descendant(of: find.byIcon(icon), matching: find.byType(RichText)),
  );
  return iconRichText.text.style!;
}

EdgeInsets _itemPadding(WidgetTester tester, IconData icon) {
  return tester.widget<Padding>(
      find.descendant(
        of: find.ancestor(of: find.byIcon(icon), matching: find.byType(InkResponse)),
        matching: find.byType(Padding),
      ).first,
    ).padding.resolve(TextDirection.ltr);
}
