// 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/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

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

Widget boilerplate({ Widget? child, TextDirection textDirection = TextDirection.ltr }) {
  return Localizations(
    locale: const Locale('en', 'US'),
    delegates: const <LocalizationsDelegate<dynamic>>[
      DefaultMaterialLocalizations.delegate,
      DefaultWidgetsLocalizations.delegate,
    ],
    child: Directionality(
      textDirection: textDirection,
      child: Material(
        child: child,
      ),
    ),
  );
}

class StateMarker extends StatefulWidget {
  const StateMarker({ super.key, this.child });

  final Widget? child;

  @override
  StateMarkerState createState() => StateMarkerState();
}

class StateMarkerState extends State<StateMarker> {
  String? marker;

  @override
  Widget build(BuildContext context) {
    if (widget.child != null) {
      return widget.child!;
    }
    return Container();
  }
}

class AlwaysKeepAliveWidget extends StatefulWidget {
  const AlwaysKeepAliveWidget({ super.key});
  static String text = 'AlwaysKeepAlive';
  @override
  AlwaysKeepAliveState createState() => AlwaysKeepAliveState();
}

class AlwaysKeepAliveState extends State<AlwaysKeepAliveWidget>
    with AutomaticKeepAliveClientMixin {
  @override
  bool get wantKeepAlive => true;

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Text(AlwaysKeepAliveWidget.text);
  }
}

class _NestedTabBarContainer extends StatelessWidget {
  const _NestedTabBarContainer({
    this.tabController,
  });

  final TabController? tabController;

  @override
  Widget build(BuildContext context) {
    return ColoredBox(
      color: Colors.blue,
      child: Column(
        children: <Widget>[
          TabBar(
            controller: tabController,
            tabs: const <Tab>[
              Tab(text: 'Yellow'),
              Tab(text: 'Grey'),
            ],
          ),
          Expanded(
            child: TabBarView(
              controller: tabController,
              children: <Widget>[
                Container(color: Colors.yellow),
                Container(color: Colors.grey),
              ],
            ),
          ),
        ],
      ),
    );
  }
}

Widget buildFrame({
  Key? tabBarKey,
  required List<String> tabs,
  required String value,
  bool isScrollable = false,
  Color? indicatorColor,
  Duration? animationDuration,
  EdgeInsetsGeometry? padding,
  TextDirection textDirection = TextDirection.ltr,
}) {
  return boilerplate(
    textDirection: textDirection,
    child: DefaultTabController(
      animationDuration: animationDuration,
      initialIndex: tabs.indexOf(value),
      length: tabs.length,
      child: TabBar(
        key: tabBarKey,
        tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
        isScrollable: isScrollable,
        indicatorColor: indicatorColor,
        padding: padding,
      ),
    ),
  );
}

typedef TabControllerFrameBuilder = Widget Function(BuildContext context, TabController controller);

class TabControllerFrame extends StatefulWidget {
  const TabControllerFrame({
    super.key,
    required this.length,
    this.initialIndex = 0,
    required this.builder,
  });

  final int length;
  final int initialIndex;
  final TabControllerFrameBuilder builder;

  @override
  TabControllerFrameState createState() => TabControllerFrameState();
}

class TabControllerFrameState extends State<TabControllerFrame> with SingleTickerProviderStateMixin {
  late TabController _controller;

  @override
  void initState() {
    super.initState();
    _controller = TabController(
      vsync: this,
      length: widget.length,
      initialIndex: widget.initialIndex,
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return widget.builder(context, _controller);
  }
}

Widget buildLeftRightApp({required List<String> tabs, required String value, bool automaticIndicatorColorAdjustment = true}) {
  return MaterialApp(
    theme: ThemeData(platform: TargetPlatform.android),
    home: DefaultTabController(
      initialIndex: tabs.indexOf(value),
      length: tabs.length,
      child: Scaffold(
        appBar: AppBar(
          title: const Text('tabs'),
          bottom: TabBar(
            tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
            automaticIndicatorColorAdjustment: automaticIndicatorColorAdjustment,
          ),
        ),
        body: const TabBarView(
          children: <Widget>[
            Center(child: Text('LEFT CHILD')),
            Center(child: Text('RIGHT CHILD')),
          ],
        ),
      ),
    ),
  );
}

class TabIndicatorRecordingCanvas extends TestRecordingCanvas {
  TabIndicatorRecordingCanvas(this.indicatorColor);

  final Color indicatorColor;
  late Rect indicatorRect;

  @override
  void drawLine(Offset p1, Offset p2, Paint paint) {
    // Assuming that the indicatorWeight is 2.0, the default.
    const double indicatorWeight = 2.0;
    if (paint.color == indicatorColor) {
      indicatorRect = Rect.fromPoints(p1, p2).inflate(indicatorWeight / 2.0);
    }
  }
}

class TestScrollPhysics extends ScrollPhysics {
  const TestScrollPhysics({ super.parent });

  @override
  TestScrollPhysics applyTo(ScrollPhysics? ancestor) {
    return TestScrollPhysics(parent: buildParent(ancestor));
  }

  @override
  double applyPhysicsToUserOffset(ScrollMetrics position, double offset) {
    return offset == 10 ? 20 : offset;
  }

  static final SpringDescription _kDefaultSpring = SpringDescription.withDampingRatio(
    mass: 0.5,
    stiffness: 500.0,
    ratio: 1.1,
  );

  @override
  SpringDescription get spring => _kDefaultSpring;
}

void main() {
  setUp(() {
    debugResetSemanticsIdCounter();
  });

  testWidgets('indicatorPadding update test', (WidgetTester tester) async {
    // Regressing test for https://github.com/flutter/flutter/issues/108102
    const Tab tab = Tab(text: 'A');
    const EdgeInsets indicatorPadding = EdgeInsets.only(left: 7.0, right: 7.0);

    await tester.pumpWidget(boilerplate(
      child: const DefaultTabController(
        length: 1,
        child: TabBar(
          tabs: <Tab>[tab],
          indicatorPadding: indicatorPadding,
        ),
      ),
    ));

    // Change the indicatorPadding
    await tester.pumpWidget(boilerplate(
      child: DefaultTabController(
        length: 1,
        child: TabBar(
          tabs: const <Tab>[tab],
          indicatorPadding: indicatorPadding + const EdgeInsets.all(7.0),
        ),
      ),
    ), Duration.zero, EnginePhase.build);

    expect(tester.renderObject(find.byType(CustomPaint)).debugNeedsPaint, true);
  });

  testWidgets('Tab sizing - icon', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(home: Center(child: Material(child: Tab(icon: SizedBox(width: 10.0, height: 10.0))))),
    );
    expect(tester.getSize(find.byType(Tab)), const Size(10.0, 46.0));
  });

  testWidgets('Tab sizing - child', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(home: Center(child: Material(child: Tab(child: SizedBox(width: 10.0, height: 10.0))))),
    );
    expect(tester.getSize(find.byType(Tab)), const Size(10.0, 46.0));
  });

  testWidgets('Tab sizing - text', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(theme: ThemeData(fontFamily: 'Ahem'), home: const Center(child: Material(child: Tab(text: 'x')))),
    );
    expect(tester.renderObject<RenderParagraph>(find.byType(RichText)).text.style!.fontFamily, 'Ahem');
    expect(tester.getSize(find.byType(Tab)), const Size(14.0, 46.0));
  });

  testWidgets('Tab sizing - icon and text', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(theme: ThemeData(fontFamily: 'Ahem'), home: const Center(child: Material(child: Tab(icon: SizedBox(width: 10.0, height: 10.0), text: 'x')))),
    );
    expect(tester.renderObject<RenderParagraph>(find.byType(RichText)).text.style!.fontFamily, 'Ahem');
    expect(tester.getSize(find.byType(Tab)), const Size(14.0, 72.0));
  });

  testWidgets('Tab sizing - icon, iconMargin and text', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(fontFamily: 'Ahem'),
        home: const Center(
          child: Material(
            child: Tab(
              icon: SizedBox(
                width: 10.0,
                height: 10.0,
              ),
              iconMargin: EdgeInsets.symmetric(
                horizontal: 100.0,
              ),
              text: 'x',
            ),
          ),
        ),
      ),
    );
    expect(tester.renderObject<RenderParagraph>(find.byType(RichText)).text.style!.fontFamily, 'Ahem');
    expect(tester.getSize(find.byType(Tab)), const Size(210.0, 72.0));
  });

  testWidgets('Tab sizing - icon and child', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(theme: ThemeData(fontFamily: 'Ahem'), home: const Center(child: Material(child: Tab(icon: SizedBox(width: 10.0, height: 10.0), child: Text('x'))))),
    );
    expect(tester.renderObject<RenderParagraph>(find.byType(RichText)).text.style!.fontFamily, 'Ahem');
    expect(tester.getSize(find.byType(Tab)), const Size(14.0, 72.0));
  });

  testWidgets('Tab color - normal', (WidgetTester tester) async {
    final Widget tabBar = TabBar(tabs: const <Widget>[SizedBox.shrink()], controller: TabController(length: 1, vsync: tester));
    await tester.pumpWidget(
      MaterialApp(home: Material(child: tabBar)),
    );
    expect(find.byType(TabBar), paints..line(color: Colors.blue[500]));
  });

  testWidgets('Tab color - match', (WidgetTester tester) async {
    final Widget tabBar = TabBar(tabs: const <Widget>[SizedBox.shrink()], controller: TabController(length: 1, vsync: tester));
    await tester.pumpWidget(
      MaterialApp(home: Material(color: const Color(0xff2196f3), child: tabBar)),
    );
    expect(find.byType(TabBar), paints..line(color: Colors.white));
  });

  testWidgets('Tab color - transparency', (WidgetTester tester) async {
    final Widget tabBar = TabBar(tabs: const <Widget>[SizedBox.shrink()], controller: TabController(length: 1, vsync: tester));
    await tester.pumpWidget(
      MaterialApp(home: Material(type: MaterialType.transparency, child: tabBar)),
    );
    expect(find.byType(TabBar), paints..line(color: Colors.blue[500]));
  });

  testWidgets('TabBar default selected/unselected text style', (WidgetTester tester) async {
    final ThemeData theme = ThemeData(useMaterial3: true);
    final List<String> tabs = <String>['A', 'B', 'C'];

    const String selectedValue = 'A';
    const String unSelectedValue = 'C';
    await tester.pumpWidget(
      Theme(
        data: theme,
        child: buildFrame(tabs: tabs, value: selectedValue),
      ),
    );
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsOneWidget);
    expect(find.text('C'), findsOneWidget);

    // Test selected label text style.
    expect(tester.renderObject<RenderParagraph>(find.text(selectedValue)).text.style!.fontFamily, 'Roboto');
    expect(tester.renderObject<RenderParagraph>(find.text(selectedValue)).text.style!.fontSize, 14.0);
    expect(tester.renderObject<RenderParagraph>(
      find.text(selectedValue)).text.style!.color,
      theme.colorScheme.primary,
    );

    // Test unselected label text style.
    expect(tester.renderObject<RenderParagraph>(find.text(unSelectedValue)).text.style!.fontFamily, 'Roboto');
    expect(tester.renderObject<RenderParagraph>(find.text(unSelectedValue)).text.style!.fontSize, 14.0);
    expect(tester.renderObject<RenderParagraph>(
      find.text(unSelectedValue)).text.style!.color,
      theme.colorScheme.onSurfaceVariant,
    );
  });

  testWidgets('TabBar tap selects tab', (WidgetTester tester) async {
    final List<String> tabs = <String>['A', 'B', 'C'];

    await tester.pumpWidget(buildFrame(tabs: tabs, value: 'C'));
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsOneWidget);
    expect(find.text('C'), findsOneWidget);
    final TabController controller = DefaultTabController.of(tester.element(find.text('A')));
    expect(controller, isNotNull);
    expect(controller.index, 2);
    expect(controller.previousIndex, 2);

    await tester.pumpWidget(buildFrame(tabs: tabs, value: 'C'));
    await tester.tap(find.text('B'));
    await tester.pump();
    expect(controller.indexIsChanging, true);
    await tester.pump(const Duration(seconds: 1)); // finish the animation
    expect(controller.index, 1);
    expect(controller.previousIndex, 2);
    expect(controller.indexIsChanging, false);

    await tester.pumpWidget(buildFrame(tabs: tabs, value: 'C'));
    await tester.tap(find.text('C'));
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(controller.index, 2);
    expect(controller.previousIndex, 1);

    await tester.pumpWidget(buildFrame(tabs: tabs, value: 'C'));
    await tester.tap(find.text('A'));
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    expect(controller.index, 0);
    expect(controller.previousIndex, 2);
  });

  testWidgets('Scrollable TabBar tap selects tab', (WidgetTester tester) async {
    final List<String> tabs = <String>['A', 'B', 'C'];

    await tester.pumpWidget(buildFrame(tabs: tabs, value: 'C', isScrollable: true));
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsOneWidget);
    expect(find.text('C'), findsOneWidget);
    final TabController controller = DefaultTabController.of(tester.element(find.text('A')));
    expect(controller.index, 2);
    expect(controller.previousIndex, 2);

    await tester.tap(find.text('C'));
    await tester.pumpAndSettle();
    expect(controller.index, 2);

    await tester.tap(find.text('B'));
    await tester.pumpAndSettle();
    expect(controller.index, 1);

    await tester.tap(find.text('A'));
    await tester.pumpAndSettle();
    expect(controller.index, 0);
  });

  testWidgets('Scrollable TabBar tap centers selected tab', (WidgetTester tester) async {
    final List<String> tabs = <String>['AAAAAA', 'BBBBBB', 'CCCCCC', 'DDDDDD', 'EEEEEE', 'FFFFFF', 'GGGGGG', 'HHHHHH', 'IIIIII', 'JJJJJJ', 'KKKKKK', 'LLLLLL'];
    const Key tabBarKey = Key('TabBar');
    await tester.pumpWidget(buildFrame(tabs: tabs, value: 'AAAAAA', isScrollable: true, tabBarKey: tabBarKey));
    final TabController controller = DefaultTabController.of(tester.element(find.text('AAAAAA')));
    expect(controller, isNotNull);
    expect(controller.index, 0);

    expect(tester.getSize(find.byKey(tabBarKey)).width, equals(800.0));
    // The center of the FFFFFF item is to the right of the TabBar's center
    expect(tester.getCenter(find.text('FFFFFF')).dx, greaterThan(401.0));

    await tester.tap(find.text('FFFFFF'));
    await tester.pumpAndSettle();
    expect(controller.index, 5);
    // The center of the FFFFFF item is now at the TabBar's center
    expect(tester.getCenter(find.text('FFFFFF')).dx, moreOrLessEquals(400.0, epsilon: 1.0));
  });

  testWidgets('Scrollable TabBar, with padding, tap centers selected tab', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/112776
    final List<String> tabs = <String>['AAAAAA', 'BBBBBB', 'CCCCCC', 'DDDDDD', 'EEEEEE', 'FFFFFF', 'GGGGGG', 'HHHHHH', 'IIIIII', 'JJJJJJ', 'KKKKKK', 'LLLLLL'];
    const Key tabBarKey = Key('TabBar');
    const EdgeInsetsGeometry padding = EdgeInsets.only(right: 30, left: 60);
    await tester.pumpWidget(buildFrame(tabs: tabs, value: 'AAAAAA', isScrollable: true, tabBarKey: tabBarKey, padding: padding));
    final TabController controller = DefaultTabController.of(tester.element(find.text('AAAAAA')));
    expect(controller, isNotNull);
    expect(controller.index, 0);

    expect(tester.getSize(find.byKey(tabBarKey)).width, equals(800.0));
    // The center of the FFFFFF item is to the right of the TabBar's center
    expect(tester.getCenter(find.text('FFFFFF')).dx, greaterThan(401.0));

    await tester.tap(find.text('FFFFFF'));
    await tester.pumpAndSettle();
    expect(controller.index, 5);
    // The center of the FFFFFF item is now at the TabBar's center
    expect(tester.getCenter(find.text('FFFFFF')).dx, moreOrLessEquals(400.0, epsilon: 1.0));
  });

  testWidgets('Scrollable TabBar, with padding and TextDirection.rtl, tap centers selected tab', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/112776
    final List<String> tabs = <String>['AAAAAA', 'BBBBBB', 'CCCCCC', 'DDDDDD', 'EEEEEE', 'FFFFFF', 'GGGGGG', 'HHHHHH', 'IIIIII', 'JJJJJJ', 'KKKKKK', 'LLLLLL'];
    const Key tabBarKey = Key('TabBar');
    const EdgeInsetsGeometry padding = EdgeInsets.only(right: 30, left: 60);
    await tester.pumpWidget(buildFrame(
      tabs: tabs,
      value: 'AAAAAA',
      isScrollable: true,
      tabBarKey: tabBarKey,
      padding: padding,
      textDirection: TextDirection.rtl,
    ));
    final TabController controller = DefaultTabController.of(tester.element(find.text('AAAAAA')));
    expect(controller, isNotNull);
    expect(controller.index, 0);

    expect(tester.getSize(find.byKey(tabBarKey)).width, equals(800.0));
    // The center of the FFFFFF item is to the left of the TabBar's center
    expect(tester.getCenter(find.text('FFFFFF')).dx, lessThan(401.0));

    await tester.tap(find.text('FFFFFF'));
    await tester.pumpAndSettle();
    expect(controller.index, 5);
    // The center of the FFFFFF item is now at the TabBar's center
    expect(tester.getCenter(find.text('FFFFFF')).dx, moreOrLessEquals(400.0, epsilon: 1.0));
  });

  testWidgets('TabBar can be scrolled independent of the selection', (WidgetTester tester) async {
    final List<String> tabs = <String>['AAAA', 'BBBB', 'CCCC', 'DDDD', 'EEEE', 'FFFF', 'GGGG', 'HHHH', 'IIII', 'JJJJ', 'KKKK', 'LLLL'];
    const Key tabBarKey = Key('TabBar');
    await tester.pumpWidget(buildFrame(tabs: tabs, value: 'AAAA', isScrollable: true, tabBarKey: tabBarKey));
    final TabController controller = DefaultTabController.of(tester.element(find.text('AAAA')));
    expect(controller, isNotNull);
    expect(controller.index, 0);

    // Fling-scroll the TabBar to the left
    expect(tester.getCenter(find.text('HHHH')).dx, lessThan(700.0));
    await tester.fling(find.byKey(tabBarKey), const Offset(-200.0, 0.0), 10000.0);
    await tester.pump();
    await tester.pump(const Duration(seconds: 1)); // finish the scroll animation
    expect(tester.getCenter(find.text('HHHH')).dx, lessThan(500.0));

    // Scrolling the TabBar doesn't change the selection
    expect(controller.index, 0);
  });

  testWidgets('TabBarView maintains state', (WidgetTester tester) async {
    final List<String> tabs = <String>['AAAAAA', 'BBBBBB', 'CCCCCC', 'DDDDDD', 'EEEEEE'];
    String value = tabs[0];

    Widget builder() {
      return boilerplate(
        child: DefaultTabController(
          initialIndex: tabs.indexOf(value),
          length: tabs.length,
          child: TabBarView(
            children: tabs.map<Widget>((String name) {
              return StateMarker(
                child: Text(name),
              );
            }).toList(),
          ),
        ),
      );
    }

    StateMarkerState findStateMarkerState(String name) {
      return tester.state(find.widgetWithText(StateMarker, name, skipOffstage: false));
    }

    await tester.pumpWidget(builder());
    final TabController controller = DefaultTabController.of(tester.element(find.text('AAAAAA')));

    TestGesture gesture = await tester.startGesture(tester.getCenter(find.text(tabs[0])));
    await gesture.moveBy(const Offset(-600.0, 0.0));
    await tester.pump();
    expect(value, equals(tabs[0]));
    findStateMarkerState(tabs[1]).marker = 'marked';
    await gesture.up();
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    value = tabs[controller.index];
    expect(value, equals(tabs[1]));
    await tester.pumpWidget(builder());
    expect(findStateMarkerState(tabs[1]).marker, equals('marked'));

    // Move to the third tab.

    gesture = await tester.startGesture(tester.getCenter(find.text(tabs[1])));
    await gesture.moveBy(const Offset(-600.0, 0.0));
    await gesture.up();
    await tester.pump();
    expect(findStateMarkerState(tabs[1]).marker, equals('marked'));
    await tester.pump(const Duration(seconds: 1));
    value = tabs[controller.index];
    expect(value, equals(tabs[2]));
    await tester.pumpWidget(builder());

    // The state is now gone.

    expect(find.text(tabs[1]), findsNothing);

    // Move back to the second tab.

    gesture = await tester.startGesture(tester.getCenter(find.text(tabs[2])));
    await gesture.moveBy(const Offset(600.0, 0.0));
    await tester.pump();
    final StateMarkerState markerState = findStateMarkerState(tabs[1]);
    expect(markerState.marker, isNull);
    markerState.marker = 'marked';
    await gesture.up();
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    value = tabs[controller.index];
    expect(value, equals(tabs[1]));
    await tester.pumpWidget(builder());
    expect(findStateMarkerState(tabs[1]).marker, equals('marked'));
  });

  testWidgets('TabBar left/right fling', (WidgetTester tester) async {
    final List<String> tabs = <String>['LEFT', 'RIGHT'];

    await tester.pumpWidget(buildLeftRightApp(tabs: tabs, value: 'LEFT'));
    expect(find.text('LEFT'), findsOneWidget);
    expect(find.text('RIGHT'), findsOneWidget);
    expect(find.text('LEFT CHILD'), findsOneWidget);
    expect(find.text('RIGHT CHILD'), findsNothing);

    final TabController controller = DefaultTabController.of(tester.element(find.text('LEFT')));
    expect(controller.index, 0);

    // Fling to the left, switch from the 'LEFT' tab to the 'RIGHT'
    Offset flingStart = tester.getCenter(find.text('LEFT CHILD'));
    await tester.flingFrom(flingStart, const Offset(-200.0, 0.0), 10000.0);
    await tester.pumpAndSettle();
    expect(controller.index, 1);
    expect(find.text('LEFT CHILD'), findsNothing);
    expect(find.text('RIGHT CHILD'), findsOneWidget);

    // Fling to the right, switch back to the 'LEFT' tab
    flingStart = tester.getCenter(find.text('RIGHT CHILD'));
    await tester.flingFrom(flingStart, const Offset(200.0, 0.0), 10000.0);
    await tester.pumpAndSettle();
    expect(controller.index, 0);
    expect(find.text('LEFT CHILD'), findsOneWidget);
    expect(find.text('RIGHT CHILD'), findsNothing);
  });

  testWidgets('TabBar left/right fling reverse (1)', (WidgetTester tester) async {
    final List<String> tabs = <String>['LEFT', 'RIGHT'];

    await tester.pumpWidget(buildLeftRightApp(tabs: tabs, value: 'LEFT'));
    expect(find.text('LEFT'), findsOneWidget);
    expect(find.text('RIGHT'), findsOneWidget);
    expect(find.text('LEFT CHILD'), findsOneWidget);
    expect(find.text('RIGHT CHILD'), findsNothing);

    final TabController controller = DefaultTabController.of(tester.element(find.text('LEFT')));
    expect(controller.index, 0);

    final Offset flingStart = tester.getCenter(find.text('LEFT CHILD'));
    await tester.flingFrom(flingStart, const Offset(200.0, 0.0), 10000.0);
    await tester.pump();
    await tester.pump(const Duration(seconds: 1)); // finish the scroll animation
    expect(controller.index, 0);
    expect(find.text('LEFT CHILD'), findsOneWidget);
    expect(find.text('RIGHT CHILD'), findsNothing);
  });

  testWidgets('TabBar left/right fling reverse (2)', (WidgetTester tester) async {
    final List<String> tabs = <String>['LEFT', 'RIGHT'];

    await tester.pumpWidget(buildLeftRightApp(tabs: tabs, value: 'LEFT'));
    expect(find.text('LEFT'), findsOneWidget);
    expect(find.text('RIGHT'), findsOneWidget);
    expect(find.text('LEFT CHILD'), findsOneWidget);
    expect(find.text('RIGHT CHILD'), findsNothing);

    final TabController controller = DefaultTabController.of(tester.element(find.text('LEFT')));
    expect(controller.index, 0);

    final Offset flingStart = tester.getCenter(find.text('LEFT CHILD'));
    await tester.flingFrom(flingStart, const Offset(-200.0, 0.0), 10000.0);
    await tester.pump();
    // this is similar to a test above, but that one does many more pumps
    await tester.pump(const Duration(seconds: 1)); // finish the scroll animation
    expect(controller.index, 1);
    expect(find.text('LEFT CHILD'), findsNothing);
    expect(find.text('RIGHT CHILD'), findsOneWidget);
  });

  // A regression test for https://github.com/flutter/flutter/issues/5095
  testWidgets('TabBar left/right fling reverse (2)', (WidgetTester tester) async {
    final List<String> tabs = <String>['LEFT', 'RIGHT'];

    await tester.pumpWidget(buildLeftRightApp(tabs: tabs, value: 'LEFT'));
    expect(find.text('LEFT'), findsOneWidget);
    expect(find.text('RIGHT'), findsOneWidget);
    expect(find.text('LEFT CHILD'), findsOneWidget);
    expect(find.text('RIGHT CHILD'), findsNothing);

    final TabController controller = DefaultTabController.of(tester.element(find.text('LEFT')));
    expect(controller.index, 0);

    final Offset flingStart = tester.getCenter(find.text('LEFT CHILD'));
    final TestGesture gesture = await tester.startGesture(flingStart);
    for (int index = 0; index > 50; index += 1) {
      await gesture.moveBy(const Offset(-10.0, 0.0));
      await tester.pump(const Duration(milliseconds: 1));
    }
    // End the fling by reversing direction. This should cause not cause
    // a change to the selected tab, everything should just settle back to
    // to where it started.
    for (int index = 0; index > 50; index += 1) {
      await gesture.moveBy(const Offset(10.0, 0.0));
      await tester.pump(const Duration(milliseconds: 1));
    }
    await gesture.up();
    await tester.pump();
    await tester.pump(const Duration(seconds: 1)); // finish the scroll animation
    expect(controller.index, 0);
    expect(find.text('LEFT CHILD'), findsOneWidget);
    expect(find.text('RIGHT CHILD'), findsNothing);
  });

  // A regression test for https://github.com/flutter/flutter/pull/88878.
  testWidgets('TabController notifies the index to change when left flinging', (WidgetTester tester) async {
    final List<String> tabs = <String>['A', 'B', 'C'];
    late TabController tabController;

    Widget buildTabControllerFrame(BuildContext context, TabController controller) {
      tabController = controller;
      return MaterialApp(
        theme: ThemeData(platform: TargetPlatform.iOS),
        home: Scaffold(
          appBar: AppBar(
            title: const Text('tabs'),
            bottom: TabBar(
              controller: controller,
              tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
            ),
          ),
          body: TabBarView(
            controller: controller,
            children: const <Widget>[
              Center(child: Text('CHILD A')),
              Center(child: Text('CHILD B')),
              Center(child: Text('CHILD C')),
            ],
          ),
        ),
      );
    }

    await tester.pumpWidget(TabControllerFrame(
      builder: buildTabControllerFrame,
      length: tabs.length,
      initialIndex: tabs.indexOf('C'),
    ));
    expect(tabController.index, tabs.indexOf('C'));

    tabController.addListener(() {
      final int indexOfB = tabs.indexOf('B');
      expect(tabController.index, indexOfB);
    });
    final Offset flingStart = tester.getCenter(find.text('CHILD C'));
    await tester.flingFrom(flingStart, const Offset(600, 0.0), 10000.0);
    await tester.pumpAndSettle();
  });

  // A regression test for https://github.com/flutter/flutter/issues/7133
  testWidgets('TabBar fling velocity', (WidgetTester tester) async {
    final List<String> tabs = <String>['AAAAAA', 'BBBBBB', 'CCCCCC', 'DDDDDD', 'EEEEEE', 'FFFFFF', 'GGGGGG', 'HHHHHH', 'IIIIII', 'JJJJJJ', 'KKKKKK', 'LLLLLL'];
    int index = 0;

    await tester.pumpWidget(
      MaterialApp(
        home: Align(
          alignment: Alignment.topLeft,
          child: SizedBox(
            width: 300.0,
            height: 200.0,
            child: DefaultTabController(
              length: tabs.length,
              child: Scaffold(
                appBar: AppBar(
                  title: const Text('tabs'),
                  bottom: TabBar(
                    isScrollable: true,
                    tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
                  ),
                ),
                body: TabBarView(
                  children: tabs.map<Widget>((String name) => Text('${index++}')).toList(),
                ),
              ),
            ),
          ),
        ),
      ),
    );

    // After a small slow fling to the left, we expect the second item to still be visible.
    await tester.fling(find.text('AAAAAA'), const Offset(-25.0, 0.0), 100.0);
    await tester.pump();
    await tester.pump(const Duration(seconds: 1)); // finish the scroll animation
    final RenderBox box = tester.renderObject(find.text('BBBBBB'));
    expect(box.localToGlobal(Offset.zero).dx, greaterThan(0.0));
  });

  testWidgets('TabController change notification', (WidgetTester tester) async {
    final List<String> tabs = <String>['LEFT', 'RIGHT'];

    await tester.pumpWidget(buildLeftRightApp(tabs: tabs, value: 'LEFT'));
    final TabController controller = DefaultTabController.of(tester.element(find.text('LEFT')));

    expect(controller, isNotNull);
    expect(controller.index, 0);

    late String value;
    controller.addListener(() {
      value = tabs[controller.index];
    });

    await tester.tap(find.text('RIGHT'));
    await tester.pumpAndSettle();
    expect(value, 'RIGHT');

    await tester.tap(find.text('LEFT'));
    await tester.pumpAndSettle();
    expect(value, 'LEFT');

    final Offset leftFlingStart = tester.getCenter(find.text('LEFT CHILD'));
    await tester.flingFrom(leftFlingStart, const Offset(-200.0, 0.0), 10000.0);
    await tester.pumpAndSettle();
    expect(value, 'RIGHT');

    final Offset rightFlingStart = tester.getCenter(find.text('RIGHT CHILD'));
    await tester.flingFrom(rightFlingStart, const Offset(200.0, 0.0), 10000.0);
    await tester.pumpAndSettle();
    expect(value, 'LEFT');
  });

  testWidgets('Explicit TabController', (WidgetTester tester) async {
    final List<String> tabs = <String>['LEFT', 'RIGHT'];
    late TabController tabController;

    Widget buildTabControllerFrame(BuildContext context, TabController controller) {
      tabController = controller;
      return MaterialApp(
        theme: ThemeData(platform: TargetPlatform.android),
        home: Scaffold(
          appBar: AppBar(
            title: const Text('tabs'),
            bottom: TabBar(
              controller: controller,
              tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
            ),
          ),
          body: TabBarView(
            controller: controller,
            children: const <Widget>[
              Center(child: Text('LEFT CHILD')),
              Center(child: Text('RIGHT CHILD')),
            ],
          ),
        ),
      );
    }

    await tester.pumpWidget(TabControllerFrame(
      builder: buildTabControllerFrame,
      length: tabs.length,
      initialIndex: 1,
    ));

    expect(find.text('LEFT'), findsOneWidget);
    expect(find.text('RIGHT'), findsOneWidget);
    expect(find.text('LEFT CHILD'), findsNothing);
    expect(find.text('RIGHT CHILD'), findsOneWidget);
    expect(tabController.index, 1);
    expect(tabController.previousIndex, 1);
    expect(tabController.indexIsChanging, false);
    expect(tabController.animation!.value, 1.0);
    expect(tabController.animation!.status, AnimationStatus.forward);

    tabController.index = 0;
    await tester.pump(const Duration(milliseconds: 500));
    await tester.pump(const Duration(milliseconds: 500));
    expect(find.text('LEFT CHILD'), findsOneWidget);
    expect(find.text('RIGHT CHILD'), findsNothing);

    tabController.index = 1;
    await tester.pump(const Duration(milliseconds: 500));
    await tester.pump(const Duration(milliseconds: 500));
    expect(find.text('LEFT CHILD'), findsNothing);
    expect(find.text('RIGHT CHILD'), findsOneWidget);
  });

  testWidgets('TabController listener resets index', (WidgetTester tester) async {
    // This is a regression test for the scenario brought up here
    // https://github.com/flutter/flutter/pull/7387#pullrequestreview-15630946

    final List<String> tabs = <String>['A', 'B', 'C'];
    late TabController tabController;

    Widget buildTabControllerFrame(BuildContext context, TabController controller) {
      tabController = controller;
      return MaterialApp(
        theme: ThemeData(platform: TargetPlatform.android),
        home: Scaffold(
          appBar: AppBar(
            title: const Text('tabs'),
            bottom: TabBar(
              controller: controller,
              tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
            ),
          ),
          body: TabBarView(
            controller: controller,
            children: const <Widget>[
              Center(child: Text('CHILD A')),
              Center(child: Text('CHILD B')),
              Center(child: Text('CHILD C')),
            ],
          ),
        ),
      );
    }

    await tester.pumpWidget(TabControllerFrame(
      builder: buildTabControllerFrame,
      length: tabs.length,
    ));

    tabController.animation!.addListener(() {
      if (tabController.animation!.status == AnimationStatus.forward) {
        tabController.index = 2;
      }
      expect(tabController.indexIsChanging, true);
    });

    expect(tabController.index, 0);
    expect(tabController.indexIsChanging, false);

    tabController.animateTo(1, duration: const Duration(milliseconds: 200), curve: Curves.linear);
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 300));

    expect(tabController.index, 2);
    expect(tabController.indexIsChanging, false);
  });

  testWidgets('TabBar unselectedLabelColor control test', (WidgetTester tester) async {
    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: 2,
    );

    late Color firstColor;
    late Color secondColor;

    await tester.pumpWidget(
      boilerplate(
        child: TabBar(
          controller: controller,
          labelColor: Colors.green[500],
          unselectedLabelColor: Colors.blue[500],
          tabs: <Widget>[
            Builder(
              builder: (BuildContext context) {
                firstColor = IconTheme.of(context).color!;
                return const Text('First');
              },
            ),
            Builder(
              builder: (BuildContext context) {
                secondColor = IconTheme.of(context).color!;
                return const Text('Second');
              },
            ),
          ],
        ),
      ),
    );

    expect(firstColor, equals(Colors.green[500]));
    expect(secondColor, equals(Colors.blue[500]));
  });

  testWidgets('TabBarView page left and right test', (WidgetTester tester) async {
    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: 2,
    );

    await tester.pumpWidget(
      boilerplate(
        child: TabBarView(
          controller: controller,
          children: const <Widget>[ Text('First'), Text('Second') ],
        ),
      ),
    );

    expect(controller.index, equals(0));

    TestGesture gesture = await tester.startGesture(const Offset(100.0, 100.0));
    expect(controller.index, equals(0));

    // Drag to the left and right, by less than the TabBarView's width.
    // The selected index (controller.index) should not change.
    await gesture.moveBy(const Offset(-100.0, 0.0));
    await gesture.moveBy(const Offset(100.0, 0.0));
    expect(controller.index, equals(0));
    expect(find.text('First'), findsOneWidget);
    expect(find.text('Second'), findsNothing);

    // Drag more than the TabBarView's width to the right. This forces
    // the selected index to change to 1.
    await gesture.moveBy(const Offset(-500.0, 0.0));
    await gesture.up();
    await tester.pump(); // start the scroll animation
    await tester.pump(const Duration(seconds: 1)); // finish the scroll animation
    expect(controller.index, equals(1));
    expect(find.text('First'), findsNothing);
    expect(find.text('Second'), findsOneWidget);

    gesture = await tester.startGesture(const Offset(100.0, 100.0));
    expect(controller.index, equals(1));

    // Drag to the left and right, by less than the TabBarView's width.
    // The selected index (controller.index) should not change.
    await gesture.moveBy(const Offset(-100.0, 0.0));
    await gesture.moveBy(const Offset(100.0, 0.0));
    expect(controller.index, equals(1));
    expect(find.text('First'), findsNothing);
    expect(find.text('Second'), findsOneWidget);

    // Drag more than the TabBarView's width to the left. This forces
    // the selected index to change back to 0.
    await gesture.moveBy(const Offset(500.0, 0.0));
    await gesture.up();
    await tester.pump(); // start the scroll animation
    await tester.pump(const Duration(seconds: 1)); // finish the scroll animation
    expect(controller.index, equals(0));
    expect(find.text('First'), findsOneWidget);
    expect(find.text('Second'), findsNothing);
  });

  testWidgets('TabBar animationDuration sets indicator animation duration', (WidgetTester tester) async {
    const Duration animationDuration = Duration(milliseconds: 100);
    final List<String> tabs = <String>['A', 'B', 'C'];

    await tester.pumpWidget(buildFrame(tabs: tabs, value: 'B', animationDuration: animationDuration));
    final TabController controller = DefaultTabController.of(tester.element(find.text('A')));

    await tester.tap(find.text('A'));
    await tester.pump();
    expect(controller.indexIsChanging, true);
    await tester.pump(const Duration(milliseconds: 50));
    await tester.pump(animationDuration);
    expect(controller.index, 0);
    expect(controller.previousIndex, 1);
    expect(controller.indexIsChanging, false);

    //Test when index diff is greater than 1
    await tester.pumpWidget(buildFrame(tabs: tabs, value: 'B', animationDuration: animationDuration));
    await tester.tap(find.text('C'));
    await tester.pump();
    expect(controller.indexIsChanging, true);
    await tester.pump(const Duration(milliseconds: 50));
    await tester.pump(animationDuration);
    expect(controller.index, 2);
    expect(controller.previousIndex, 0);
    expect(controller.indexIsChanging, false);
  });

  testWidgets('TabBarView controller sets animation duration', (WidgetTester tester) async {
    const Duration animationDuration = Duration(milliseconds: 100);
    final List<String> tabs = <String>['A', 'B', 'C'];

    final TabController tabController = TabController(
      vsync: const TestVSync(),
      initialIndex: 1,
      length: tabs.length,
      animationDuration: animationDuration,
    );
    await tester.pumpWidget(boilerplate(
      child: Column(
        children: <Widget>[
          TabBar(
            tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
            controller: tabController,
          ),
          SizedBox(
            width: 400.0,
            height: 400.0,
            child: TabBarView(
              controller: tabController,
              children: const <Widget>[
                Center(child: Text('0')),
                Center(child: Text('1')),
                Center(child: Text('2')),
              ],
            ),
          ),
        ],
      ),
    ));

    expect(tabController.index, 1);

    final PageView pageView = tester.widget(find.byType(PageView));
    final PageController pageController = pageView.controller;
    final ScrollPosition position = pageController.position;

    // The TabBarView's page width is 400, so page 0 is at scroll offset 0.0,
    // page 1 is at 400.0, page 2 is at 800.0.
    expect(position.pixels, 400);
    await tester.tap(find.text('C'));
    await tester.pump();
    expect(position.pixels, 400);
    await tester.pump(const Duration(milliseconds: 50));
    await tester.pump(animationDuration);
    expect(position.pixels, 800);
  });

  testWidgets('TabBarView viewportFraction sets PageView viewport fraction', (WidgetTester tester) async {
    const Duration animationDuration = Duration(milliseconds: 100);
    final List<String> tabs = <String>['A', 'B', 'C'];

    final TabController tabController = TabController(
      vsync: const TestVSync(),
      initialIndex: 1,
      length: tabs.length,
      animationDuration: animationDuration,
    );
    await tester.pumpWidget(boilerplate(
      child: Column(
        children: <Widget>[
          TabBar(
            tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
            controller: tabController,
          ),
          SizedBox(
            width: 400.0,
            height: 400.0,
            child: TabBarView(
              viewportFraction: 0.8,
              controller: tabController,
              children: const <Widget>[
                Center(child: Text('0')),
                Center(child: Text('1')),
                Center(child: Text('2')),
              ],
            ),
          ),
        ],
      ),
    ));

    expect(tabController.index, 1);

    final PageView pageView = tester.widget(find.byType(PageView));
    final PageController pageController = pageView.controller;

    // The TabView was initialized with viewportFraction as 0.8
    // So it's expected the PageView inside would obtain the same viewportFraction
    expect(pageController.viewportFraction, 0.8);
  });

  testWidgets('TabBarView viewportFraction is 1 by default', (WidgetTester tester) async {
    const Duration animationDuration = Duration(milliseconds: 100);
    final List<String> tabs = <String>['A', 'B', 'C'];

    final TabController tabController = TabController(
      vsync: const TestVSync(),
      initialIndex: 1,
      length: tabs.length,
      animationDuration: animationDuration,
    );
    await tester.pumpWidget(boilerplate(
      child: Column(
        children: <Widget>[
          TabBar(
            tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
            controller: tabController,
          ),
          SizedBox(
            width: 400.0,
            height: 400.0,
            child: TabBarView(
              controller: tabController,
              children: const <Widget>[
                Center(child: Text('0')),
                Center(child: Text('1')),
                Center(child: Text('2')),
              ],
            ),
          ),
        ],
      ),
    ));

    expect(tabController.index, 1);

    final PageView pageView = tester.widget(find.byType(PageView));
    final PageController pageController = pageView.controller;

    // The TabView was initialized with default viewportFraction
    // So it's expected the PageView inside would obtain the value 1
    expect(pageController.viewportFraction, 1);
  });

  testWidgets('TabBarView has clipBehavior Clip.hardEdge by default', (WidgetTester tester) async {
    final List<Widget> tabs = <Widget>[const Text('First'), const Text('Second')];

    Widget builder() {
      return boilerplate(
        child: DefaultTabController(
          length: tabs.length,
          child: TabBarView(
            children: tabs,
          ),
        ),
      );
    }

    await tester.pumpWidget(builder());
    final TabBarView tabBarView = tester.widget(find.byType(TabBarView));
    expect(tabBarView.clipBehavior, Clip.hardEdge);
  });

  testWidgets('TabBarView sets clipBehavior correctly', (WidgetTester tester) async {
    final List<Widget> tabs = <Widget>[const Text('First'), const Text('Second')];

    Widget builder() {
      return boilerplate(
        child: DefaultTabController(
          length: tabs.length,
          child: TabBarView(
            clipBehavior: Clip.none,
            children: tabs,
          ),
        ),
      );
    }

    await tester.pumpWidget(builder());
    final PageView pageView = tester.widget(find.byType(PageView));
    expect(pageView.clipBehavior, Clip.none);
  });

  testWidgets('TabBar tap skips indicator animation when disabled in controller', (WidgetTester tester) async {
    final List<String> tabs = <String>['A', 'B'];

    const Color indicatorColor = Color(0xFFFF0000);
    await tester.pumpWidget(buildFrame(tabs: tabs, value: 'A', indicatorColor: indicatorColor, animationDuration: Duration.zero));

    final RenderBox box = tester.renderObject(find.byType(TabBar));
    final TabIndicatorRecordingCanvas canvas = TabIndicatorRecordingCanvas(indicatorColor);
    final TestRecordingPaintingContext context = TestRecordingPaintingContext(canvas);

    box.paint(context, Offset.zero);
    final Rect indicatorRect0 = canvas.indicatorRect;
    expect(indicatorRect0.left, 0.0);
    expect(indicatorRect0.width, 400.0);
    expect(indicatorRect0.height, 2.0);

    await tester.tap(find.text('B'));
    await tester.pump();
    box.paint(context, Offset.zero);
    final Rect indicatorRect2 = canvas.indicatorRect;
    expect(indicatorRect2.left, 400.0);
    expect(indicatorRect2.width, 400.0);
    expect(indicatorRect2.height, 2.0);
  });

  testWidgets('TabBar tap changes index instantly when animation is disabled in controller', (WidgetTester tester) async {
    final List<String> tabs = <String>['A', 'B', 'C'];

    await tester.pumpWidget(buildFrame(tabs: tabs, value: 'B', animationDuration: Duration.zero));
    final TabController controller = DefaultTabController.of(tester.element(find.text('A')));

    await tester.tap(find.text('A'));
    await tester.pump();
    expect(controller.index, 0);
    expect(controller.previousIndex, 1);
    expect(controller.indexIsChanging, false);

    //Test when index diff is greater than 1
    await tester.pumpWidget(buildFrame(tabs: tabs, value: 'B', animationDuration: Duration.zero));
    await tester.tap(find.text('C'));
    await tester.pump();
    expect(controller.index, 2);
    expect(controller.previousIndex, 0);
    expect(controller.indexIsChanging, false);
  });

  testWidgets('TabBar should not throw when animation is disabled in controller', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/102600
    final List<String> tabs = <String>['A'];

    Widget buildWithTabBarView() {
      return boilerplate(
        child: DefaultTabController(
          animationDuration: Duration.zero,
          length: tabs.length,
          child: Column(
            children: <Widget>[
              TabBar(
                tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
                isScrollable: true,
              ),
              Flexible(
                child: TabBarView(
                  children: List<Widget>.generate(
                    tabs.length,
                    (int index) => Text('Tab $index'),
                  ),
                ),
              ),
            ],
          ),
        ),
      );
    }

    await tester.pumpWidget(buildWithTabBarView());
    TabController controller = DefaultTabController.of(tester.element(find.text('A')));
    expect(controller.index, 0);

    tabs.add('B');
    await tester.pumpWidget(buildWithTabBarView());
    tabs.add('C');
    await tester.pumpWidget(buildWithTabBarView());
    await tester.tap(find.text('C'));
    await tester.pumpAndSettle();
    controller = DefaultTabController.of(tester.element(find.text('A')));
    expect(controller.index, 2);

    expect(tester.takeException(), isNull);
  });

  testWidgets('TabBarView skips animation when disabled in controller', (WidgetTester tester) async {
    final List<String> tabs = <String>['A', 'B', 'C'];
    final TabController tabController = TabController(
      vsync: const TestVSync(),
      initialIndex: 1,
      length: tabs.length,
      animationDuration: Duration.zero,
    );
    await tester.pumpWidget(boilerplate(
      child: Column(
        children: <Widget>[
          TabBar(
            tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
            controller: tabController,
          ),
          SizedBox(
            width: 400.0,
            height: 400.0,
            child: TabBarView(
              controller: tabController,
              children: const <Widget>[
                Center(child: Text('0')),
                Center(child: Text('1')),
                Center(child: Text('2')),
              ],
            ),
          ),
        ],
      ),
    ));

    expect(tabController.index, 1);

    final PageView pageView = tester.widget(find.byType(PageView));
    final PageController pageController = pageView.controller;
    final ScrollPosition position = pageController.position;

    // The TabBarView's page width is 400, so page 0 is at scroll offset 0.0,
    // page 1 is at 400.0, page 2 is at 800.0.
    expect(position.pixels, 400);
    await tester.tap(find.text('C'));
    await tester.pump();
    expect(position.pixels, 800);
  });

  testWidgets('TabBarView skips animation when disabled in controller - skip tabs', (WidgetTester tester) async {
    final List<String> tabs = <String>['A', 'B', 'C'];
    final TabController tabController = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
      animationDuration: Duration.zero,
    );
    await tester.pumpWidget(boilerplate(
      child: Column(
        children: <Widget>[
          TabBar(
            tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
            controller: tabController,
          ),
          SizedBox(
            width: 400.0,
            height: 400.0,
            child: TabBarView(
              controller: tabController,
              children: const <Widget>[
                Center(child: Text('0')),
                Center(child: Text('1')),
                Center(child: Text('2')),
              ],
            ),
          ),
        ],
      ),
    ));

    expect(tabController.index, 0);

    final PageView pageView = tester.widget(find.byType(PageView));
    final PageController pageController = pageView.controller;
    final ScrollPosition position = pageController.position;

    // The TabBarView's page width is 400, so page 0 is at scroll offset 0.0,
    // page 1 is at 400.0, page 2 is at 800.0.
    expect(position.pixels, 0);
    await tester.tap(find.text('C'));
    await tester.pump();
    expect(position.pixels, 800);
  });

  testWidgets('TabBarView skips animation when disabled in controller - skip tabs twice', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/110970
    final List<String> tabs = <String>['A', 'B', 'C'];
    final TabController tabController = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
      animationDuration: Duration.zero,
    );
    await tester.pumpWidget(boilerplate(
      child: Column(
        children: <Widget>[
          TabBar(
            tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
            controller: tabController,
          ),
          SizedBox(
            width: 400.0,
            height: 400.0,
            child: TabBarView(
              controller: tabController,
              children: const <Widget>[
                Center(child: Text('0')),
                Center(child: Text('1')),
                Center(child: Text('2')),
              ],
            ),
          ),
        ],
      ),
    ));

    expect(tabController.index, 0);

    final PageView pageView = tester.widget(find.byType(PageView));
    final PageController pageController = pageView.controller;
    final ScrollPosition position = pageController.position;

    // The TabBarView's page width is 400, so page 0 is at scroll offset 0.0,
    // page 1 is at 400.0, page 2 is at 800.0.
    expect(position.pixels, 0);
    await tester.tap(find.text('C'));
    await tester.pump();
    expect(position.pixels, 800);

    await tester.tap(find.text('A'));
    await tester.pump();
    expect(position.pixels, 0);
  });

  testWidgets('TabBarView skips animation when disabled in controller - skip tabs followed by single tab navigation', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/110970
    final List<String> tabs = <String>['A', 'B', 'C'];
    final TabController tabController = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
      animationDuration: Duration.zero,
    );
    await tester.pumpWidget(boilerplate(
      child: Column(
        children: <Widget>[
          TabBar(
            tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
            controller: tabController,
          ),
          SizedBox(
            width: 400.0,
            height: 400.0,
            child: TabBarView(
              controller: tabController,
              children: const <Widget>[
                Center(child: Text('0')),
                Center(child: Text('1')),
                Center(child: Text('2')),
              ],
            ),
          ),
        ],
      ),
    ));

    expect(tabController.index, 0);

    final PageView pageView = tester.widget(find.byType(PageView));
    final PageController pageController = pageView.controller;
    final ScrollPosition position = pageController.position;

    // The TabBarView's page width is 400, so page 0 is at scroll offset 0.0,
    // page 1 is at 400.0, page 2 is at 800.0.
    expect(position.pixels, 0);
    await tester.tap(find.text('C'));
    await tester.pump();
    expect(position.pixels, 800);

    await tester.tap(find.text('B'));
    await tester.pump();
    expect(position.pixels, 400);

    await tester.tap(find.text('A'));
    await tester.pump();
    expect(position.pixels, 0);
  });

  testWidgets('TabBarView skips animation when disabled in controller - two tabs', (WidgetTester tester) async {
    final List<String> tabs = <String>['A', 'B'];
    final TabController tabController = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
      animationDuration: Duration.zero,
    );
    await tester.pumpWidget(boilerplate(
      child: Column(
        children: <Widget>[
          TabBar(
            tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
            controller: tabController,
          ),
          SizedBox(
            width: 400.0,
            height: 400.0,
            child: TabBarView(
              controller: tabController,
              children: const <Widget>[
                Center(child: Text('0')),
                Center(child: Text('1')),
              ],
            ),
          ),
        ],
      ),
    ));

    expect(tabController.index, 0);

    final PageView pageView = tester.widget(find.byType(PageView));
    final PageController pageController = pageView.controller;
    final ScrollPosition position = pageController.position;

    // The TabBarView's page width is 400, so page 0 is at scroll offset 0.0,
    // page 1 is at 400.0, page 2 is at 800.0.
    expect(position.pixels, 0);
    await tester.tap(find.text('B'));
    await tester.pump();
    expect(position.pixels, 400);
  });

  testWidgets('TabBar tap animates the selection indicator', (WidgetTester tester) async {
    // This is a regression test for https://github.com/flutter/flutter/issues/7479

    final List<String> tabs = <String>['A', 'B'];

    const Color indicatorColor = Color(0xFFFF0000);
    await tester.pumpWidget(buildFrame(tabs: tabs, value: 'A', indicatorColor: indicatorColor));

    final RenderBox box = tester.renderObject(find.byType(TabBar));
    final TabIndicatorRecordingCanvas canvas = TabIndicatorRecordingCanvas(indicatorColor);
    final TestRecordingPaintingContext context = TestRecordingPaintingContext(canvas);

    box.paint(context, Offset.zero);
    final Rect indicatorRect0 = canvas.indicatorRect;
    expect(indicatorRect0.left, 0.0);
    expect(indicatorRect0.width, 400.0);
    expect(indicatorRect0.height, 2.0);

    await tester.tap(find.text('B'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 50));
    box.paint(context, Offset.zero);
    final Rect indicatorRect1 = canvas.indicatorRect;
    expect(indicatorRect1.left, greaterThan(indicatorRect0.left));
    expect(indicatorRect1.right, lessThan(800.0));
    expect(indicatorRect1.height, 2.0);

    await tester.pump(const Duration(milliseconds: 300));
    box.paint(context, Offset.zero);
    final Rect indicatorRect2 = canvas.indicatorRect;
    expect(indicatorRect2.left, 400.0);
    expect(indicatorRect2.width, 400.0);
    expect(indicatorRect2.height, 2.0);
  });

  testWidgets('TabBarView child disposed during animation', (WidgetTester tester) async {
    // This is a regression test for this patch:
    // https://github.com/flutter/flutter/pull/9015

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: 2,
    );

    Widget buildFrame() {
      return boilerplate(
        child: TabBar(
          key: UniqueKey(),
          controller: controller,
          tabs: const <Widget>[ Text('A'), Text('B') ],
        ),
      );
    }

    await tester.pumpWidget(buildFrame());

    // The original TabBar will be disposed. The controller should no
    // longer have any listeners from the original TabBar.
    await tester.pumpWidget(buildFrame());

    controller.index = 1;
    await tester.pump(const Duration(milliseconds: 300));
  });


  group('TabBarView children updated', () {

    Widget buildFrameWithMarker(List<String> log, String marker) {
      return MaterialApp(
        home: DefaultTabController(
          animationDuration: const Duration(seconds: 1),
          length: 3,
          child: Scaffold(
            appBar: AppBar(
              bottom: const TabBar(
                tabs: <Widget>[
                  Tab(text: 'A'),
                  Tab(text: 'B'),
                  Tab(text: 'C'),
                ],
              ),
              title: const Text('Tabs Test'),
            ),
            body: TabBarView(
              children: <Widget>[
                TabBody(index: 0, log: log, marker: marker),
                TabBody(index: 1, log: log, marker: marker),
                TabBody(index: 2, log: log, marker: marker),
              ],
            ),
          ),
        ),
      );
    }

    testWidgets('TabBarView children can be updated during animation to an adjacent tab', (WidgetTester tester) async {
      // Regression test for https://github.com/flutter/flutter/issues/107399
      final List<String> log = <String>[];

      const String initialMarker = 'before';
      await tester.pumpWidget(buildFrameWithMarker(log, initialMarker));
      expect(log, <String>['init: 0']);
      expect(find.text('0-$initialMarker'), findsOneWidget);

      // Select the second tab and wait until the transition starts
      await tester.tap(find.text('B'));
      await tester.pump(const Duration(milliseconds: 100));

      // Check that both TabBody's are instantiated while the transition is animating
      await tester.pump(const Duration(milliseconds: 400));
      expect(log, <String>['init: 0', 'init: 1']);

      // Update the TabBody's states while the transition is animating
      const String updatedMarker = 'after';
      await tester.pumpWidget(buildFrameWithMarker(log, updatedMarker));

      // Wait until the transition ends
      await tester.pumpAndSettle();

      // The TabBody state of the second TabBar should have been updated
      expect(find.text('1-$initialMarker'), findsNothing);
      expect(find.text('1-$updatedMarker'), findsOneWidget);
    });

    testWidgets('TabBarView children can be updated during animation to a non adjacent tab', (WidgetTester tester) async {
      final List<String> log = <String>[];

      const String initialMarker = 'before';
      await tester.pumpWidget(buildFrameWithMarker(log, initialMarker));
      expect(log, <String>['init: 0']);
      expect(find.text('0-$initialMarker'), findsOneWidget);

      // Select the third tab and wait until the transition starts
      await tester.tap(find.text('C'));
      await tester.pump(const Duration(milliseconds: 100));

      // Check that both TabBody's are instantiated while the transition is animating
      await tester.pump(const Duration(milliseconds: 400));
      expect(log, <String>['init: 0', 'init: 2']);

      // Update the TabBody's states while the transition is animating
      const String updatedMarker = 'after';
      await tester.pumpWidget(buildFrameWithMarker(log, updatedMarker));

      // Wait until the transition ends
      await tester.pumpAndSettle();

      // The TabBody state of the third TabBar should have been updated
      expect(find.text('2-$initialMarker'), findsNothing);
      expect(find.text('2-$updatedMarker'), findsOneWidget);
    });
  });

  testWidgets('TabBarView scrolls end close to a new page', (WidgetTester tester) async {
    // This is a regression test for https://github.com/flutter/flutter/issues/9375

    final TabController tabController = TabController(
      vsync: const TestVSync(),
      initialIndex: 1,
      length: 3,
    );

    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: SizedBox.expand(
        child: Center(
          child: SizedBox(
            width: 400.0,
            height: 400.0,
            child: TabBarView(
              controller: tabController,
              children: const <Widget>[
                Center(child: Text('0')),
                Center(child: Text('1')),
                Center(child: Text('2')),
              ],
            ),
          ),
        ),
      ),
    ));

    expect(tabController.index, 1);

    final PageView pageView = tester.widget(find.byType(PageView));
    final PageController pageController = pageView.controller;
    final ScrollPosition position = pageController.position;

    // The TabBarView's page width is 400, so page 0 is at scroll offset 0.0,
    // page 1 is at 400.0, page 2 is at 800.0.

    expect(position.pixels, 400.0);

    // Not close enough to switch to page 2
    pageController.jumpTo(500.0);
    expect(tabController.index, 1);

    // Close enough to switch to page 2
    pageController.jumpTo(700.0);
    expect(tabController.index, 2);

    // Same behavior going left: not left enough to get to page 0
    pageController.jumpTo(300.0);
    expect(tabController.index, 1);

    // Left enough to get to page 0
    pageController.jumpTo(100.0);
    expect(tabController.index, 0);
  });

  testWidgets('Can switch to non-neighboring tab in nested TabBarView without crashing', (WidgetTester tester) async {
    // This is a regression test for https://github.com/flutter/flutter/issues/18756
    final TabController mainTabController = TabController(length: 4, vsync: const TestVSync());
    final TabController nestedTabController = TabController(length: 2, vsync: const TestVSync());

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            title: const Text('Exception for Nested Tabs'),
            bottom: TabBar(
              controller: mainTabController,
              tabs: const <Widget>[
                Tab(icon: Icon(Icons.add), text: 'A'),
                Tab(icon: Icon(Icons.add), text: 'B'),
                Tab(icon: Icon(Icons.add), text: 'C'),
                Tab(icon: Icon(Icons.add), text: 'D'),
              ],
            ),
          ),
          body: TabBarView(
            controller: mainTabController,
            children: <Widget>[
              Container(color: Colors.red),
              _NestedTabBarContainer(tabController: nestedTabController),
              Container(color: Colors.green),
              Container(color: Colors.indigo),
            ],
          ),
        ),
      ),
    );

    // expect first tab to be selected
    expect(mainTabController.index, 0);

    // tap on third tab
    await tester.tap(find.text('C'));
    await tester.pumpAndSettle();

    // expect third tab to be selected without exceptions
    expect(mainTabController.index, 2);
  });

  testWidgets('TabBarView can warp when child is kept alive and contains ink', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/57662.
    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: 3,
    );

    await tester.pumpWidget(
      boilerplate(
        child: TabBarView(
          controller: controller,
          children: const <Widget>[
            Text('Page 1'),
            Text('Page 2'),
            KeepAliveInk('Page 3'),
          ],
        ),
      ),
    );

    expect(controller.index, equals(0));
    expect(find.text('Page 1'), findsOneWidget);
    expect(find.text('Page 3'), findsNothing);

    controller.index = 2;
    await tester.pumpAndSettle();
    expect(find.text('Page 1'), findsNothing);
    expect(find.text('Page 3'), findsOneWidget);

    controller.index = 0;
    await tester.pumpAndSettle();
    expect(find.text('Page 1'), findsOneWidget);
    expect(find.text('Page 3'), findsNothing);

    expect(tester.takeException(), isNull);
  });

  testWidgets('TabBarView scrolls end close to a new page with custom physics', (WidgetTester tester) async {
    final TabController tabController = TabController(
      vsync: const TestVSync(),
      initialIndex: 1,
      length: 3,
    );

    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: SizedBox.expand(
        child: Center(
          child: SizedBox(
            width: 400.0,
            height: 400.0,
            child: TabBarView(
              controller: tabController,
              physics: const TestScrollPhysics(),
              children: const <Widget>[
                Center(child: Text('0')),
                Center(child: Text('1')),
                Center(child: Text('2')),
              ],
            ),
          ),
        ),
      ),
    ));

    expect(tabController.index, 1);

    final PageView pageView = tester.widget(find.byType(PageView));
    final PageController pageController = pageView.controller;
    final ScrollPosition position = pageController.position;

    // The TabBarView's page width is 400, so page 0 is at scroll offset 0.0,
    // page 1 is at 400.0, page 2 is at 800.0.

    expect(position.pixels, 400.0);

    // Not close enough to switch to page 2
    pageController.jumpTo(500.0);
    expect(tabController.index, 1);

    // Close enough to switch to page 2
    pageController.jumpTo(700.0);
    expect(tabController.index, 2);

    // Same behavior going left: not left enough to get to page 0
    pageController.jumpTo(300.0);
    expect(tabController.index, 1);

    // Left enough to get to page 0
    pageController.jumpTo(100.0);
    expect(tabController.index, 0);
  });

  testWidgets('TabBar accepts custom physics', (WidgetTester tester) async {
    final List<Tab> tabs = List<Tab>.generate(20, (int index) {
      return Tab(text: 'TAB #$index');
    });

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
      initialIndex: tabs.length - 1,
    );

    await tester.pumpWidget(
      boilerplate(
        child: TabBar(
          isScrollable: true,
          controller: controller,
          tabs: tabs,
          physics: const TestScrollPhysics(),
        ),
      ),
    );

    final TabBar tabBar = tester.widget(find.byType(TabBar));
    final double position = tabBar.physics!.applyPhysicsToUserOffset(MockScrollMetrics(), 10);

    expect(position, equals(20));
  });

  testWidgets('Scrollable TabBar with a non-zero TabController initialIndex', (WidgetTester tester) async {
    // This is a regression test for https://github.com/flutter/flutter/issues/9374

    final List<Tab> tabs = List<Tab>.generate(20, (int index) {
      return Tab(text: 'TAB #$index');
    });

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
      initialIndex: tabs.length - 1,
    );

    await tester.pumpWidget(
      boilerplate(
        child: TabBar(
          isScrollable: true,
          controller: controller,
          tabs: tabs,
        ),
      ),
    );

    // The initialIndex tab should be visible and right justified
    expect(find.text('TAB #19'), findsOneWidget);

    // Tabs have a minimum width of 72.0 and 'TAB #19' is wider than
    // that. Tabs are padded horizontally with kTabLabelPadding.
    final double tabRight = 800.0 - kTabLabelPadding.right;

    expect(tester.getTopRight(find.widgetWithText(Tab, 'TAB #19')).dx, tabRight);
  });

  testWidgets('TabBar with indicatorWeight, indicatorPadding (LTR)', (WidgetTester tester) async {
    const Color indicatorColor = Color(0xFF00FF00);
    const double indicatorWeight = 8.0;
    const double padLeft = 8.0;
    const double padRight = 4.0;

    final List<Widget> tabs = List<Widget>.generate(4, (int index) {
      return Tab(text: 'Tab $index');
    });

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );

    await tester.pumpWidget(
      boilerplate(
        child: Container(
          alignment: Alignment.topLeft,
          child: TabBar(
            indicatorWeight: indicatorWeight,
            indicatorColor: indicatorColor,
            indicatorPadding: const EdgeInsets.only(left: padLeft, right: padRight),
            controller: controller,
            tabs: tabs,
          ),
        ),
      ),
    );

    final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
    expect(tabBarBox.size.height, 54.0); // 54 = _kTabHeight(46) + indicatorWeight(8.0)

    const double indicatorY = 54.0 - indicatorWeight / 2.0;
    double indicatorLeft = padLeft + indicatorWeight / 2.0;
    double indicatorRight = 200.0 - (padRight + indicatorWeight / 2.0);

    expect(tabBarBox, paints..line(
      color: indicatorColor,
      strokeWidth: indicatorWeight,
      p1: Offset(indicatorLeft, indicatorY),
      p2: Offset(indicatorRight, indicatorY),
    ));

    // Select tab 3
    controller.index = 3;
    await tester.pumpAndSettle();

    indicatorLeft = 600.0 + padLeft + indicatorWeight / 2.0;
    indicatorRight = 800.0 - (padRight + indicatorWeight / 2.0);

    expect(tabBarBox, paints..line(
      color: indicatorColor,
      strokeWidth: indicatorWeight,
      p1: Offset(indicatorLeft, indicatorY),
      p2: Offset(indicatorRight, indicatorY),
    ));
  });

  testWidgets('TabBar with indicatorWeight, indicatorPadding (RTL)', (WidgetTester tester) async {
    const Color indicatorColor = Color(0xFF00FF00);
    const double indicatorWeight = 8.0;
    const double padLeft = 8.0;
    const double padRight = 4.0;

    final List<Widget> tabs = List<Widget>.generate(4, (int index) {
      return Tab(text: 'Tab $index');
    });

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );

    await tester.pumpWidget(
      boilerplate(
        textDirection: TextDirection.rtl,
        child: Container(
          alignment: Alignment.topLeft,
          child: TabBar(
            indicatorWeight: indicatorWeight,
            indicatorColor: indicatorColor,
            indicatorPadding: const EdgeInsets.only(left: padLeft, right: padRight),
            controller: controller,
            tabs: tabs,
          ),
        ),
      ),
    );

    final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
    expect(tabBarBox.size.height, 54.0); // 54 = _kTabHeight(46) + indicatorWeight(8.0)
    expect(tabBarBox.size.width, 800.0);

    const double indicatorY = 54.0 - indicatorWeight / 2.0;
    double indicatorLeft = 600.0 + padLeft + indicatorWeight / 2.0;
    double indicatorRight = 800.0 - padRight - indicatorWeight / 2.0;

    expect(tabBarBox, paints..line(
      color: indicatorColor,
      strokeWidth: indicatorWeight,
      p1: Offset(indicatorLeft, indicatorY),
      p2: Offset(indicatorRight, indicatorY),
    ));

    // Select tab 3
    controller.index = 3;
    await tester.pumpAndSettle();

    indicatorLeft = padLeft + indicatorWeight / 2.0;
    indicatorRight = 200.0 - padRight -  indicatorWeight / 2.0;

    expect(tabBarBox, paints..line(
      color: indicatorColor,
      strokeWidth: indicatorWeight,
      p1: Offset(indicatorLeft, indicatorY),
      p2: Offset(indicatorRight, indicatorY),
    ));
  });

  testWidgets('TabBar changes indicator attributes', (WidgetTester tester) async {
    final List<Widget> tabs = List<Widget>.generate(4, (int index) {
      return Tab(text: 'Tab $index');
    });

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );

    Color indicatorColor = const Color(0xFF00FF00);
    double indicatorWeight = 8.0;
    double padLeft = 8.0;
    double padRight = 4.0;

    Widget buildFrame() {
      return boilerplate(
        child: Container(
          alignment: Alignment.topLeft,
          child: TabBar(
            indicatorWeight: indicatorWeight,
            indicatorColor: indicatorColor,
            indicatorPadding: EdgeInsets.only(left: padLeft, right: padRight),
            controller: controller,
            tabs: tabs,
          ),
        ),
      );
    }

    await tester.pumpWidget(buildFrame());

    final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
    expect(tabBarBox.size.height, 54.0); // 54 = _kTabHeight(46) + indicatorWeight(8.0)

    double indicatorY = 54.0 - indicatorWeight / 2.0;
    double indicatorLeft = padLeft + indicatorWeight / 2.0;
    double indicatorRight = 200.0 - (padRight + indicatorWeight / 2.0);

    expect(tabBarBox, paints..line(
      color: indicatorColor,
      strokeWidth: indicatorWeight,
      p1: Offset(indicatorLeft, indicatorY),
      p2: Offset(indicatorRight, indicatorY),
    ));

    indicatorColor = const Color(0xFF0000FF);
    indicatorWeight = 4.0;
    padLeft = 4.0;
    padRight = 8.0;

    await tester.pumpWidget(buildFrame());

    expect(tabBarBox.size.height, 50.0); // 54 = _kTabHeight(46) + indicatorWeight(4.0)

    indicatorY = 50.0 - indicatorWeight / 2.0;
    indicatorLeft = padLeft + indicatorWeight / 2.0;
    indicatorRight = 200.0 - (padRight + indicatorWeight / 2.0);

    expect(tabBarBox, paints..line(
      color: indicatorColor,
      strokeWidth: indicatorWeight,
      p1: Offset(indicatorLeft, indicatorY),
      p2: Offset(indicatorRight, indicatorY),
    ));
  });

  testWidgets('TabBar with directional indicatorPadding (LTR)', (WidgetTester tester) async {
    final List<Widget> tabs = <Widget>[
      SizedBox(key: UniqueKey(), width: 130.0, height: 30.0),
      SizedBox(key: UniqueKey(), width: 140.0, height: 40.0),
      SizedBox(key: UniqueKey(), width: 150.0, height: 50.0),
    ];

    const double indicatorWeight = 2.0; // the default

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );

    await tester.pumpWidget(
      boilerplate(
        child: Container(
          alignment: Alignment.topLeft,
          child: TabBar(
            indicatorPadding: const EdgeInsetsDirectional.only(start: 100.0),
            isScrollable: true,
            controller: controller,
            tabs: tabs,
          ),
        ),
      ),
    );

    final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
    const double tabBarHeight = 50.0 + indicatorWeight;  // 50 = max tab height
    expect(tabBarBox.size.height, tabBarHeight);

    // Tab0 width = 130, height = 30
    double tabLeft = kTabLabelPadding.left;
    double tabRight = tabLeft + 130.0;
    double tabTop = (tabBarHeight - indicatorWeight - 30.0) / 2.0;
    double tabBottom = tabTop + 30.0;
    Rect tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[0].key!)), tabRect);


    // Tab1 width = 140, height = 40
    tabLeft = tabRight + kTabLabelPadding.right + kTabLabelPadding.left;
    tabRight = tabLeft + 140.0;
    tabTop = (tabBarHeight - indicatorWeight - 40.0) / 2.0;
    tabBottom = tabTop + 40.0;
    tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[1].key!)), tabRect);


    // Tab2 width = 150, height = 50
    tabLeft = tabRight + kTabLabelPadding.right + kTabLabelPadding.left;
    tabRight = tabLeft + 150.0;
    tabTop = (tabBarHeight - indicatorWeight - 50.0) / 2.0;
    tabBottom = tabTop + 50.0;
    tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[2].key!)), tabRect);

    // Tab 0 selected, indicator padding resolves to left: 100.0
    const double indicatorLeft = 100.0 + indicatorWeight / 2.0;
    final double indicatorRight = 130.0 + kTabLabelPadding.horizontal - indicatorWeight / 2.0;
    final double indicatorY = tabBottom + indicatorWeight / 2.0;
    expect(tabBarBox, paints..line(
      strokeWidth: indicatorWeight,
      p1: Offset(indicatorLeft, indicatorY),
      p2: Offset(indicatorRight, indicatorY),
    ));
  });

  testWidgets('TabBar with directional indicatorPadding (RTL)', (WidgetTester tester) async {
    final List<Widget> tabs = <Widget>[
      SizedBox(key: UniqueKey(), width: 130.0, height: 30.0),
      SizedBox(key: UniqueKey(), width: 140.0, height: 40.0),
      SizedBox(key: UniqueKey(), width: 150.0, height: 50.0),
    ];

    const double indicatorWeight = 2.0; // the default

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );

    await tester.pumpWidget(
      boilerplate(
        textDirection: TextDirection.rtl,
        child: Container(
          alignment: Alignment.topLeft,
          child: TabBar(
            indicatorPadding: const EdgeInsetsDirectional.only(start: 100.0),
            isScrollable: true,
            controller: controller,
            tabs: tabs,
          ),
        ),
      ),
    );

    final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
    const double tabBarHeight = 50.0 + indicatorWeight;  // 50 = max tab height
    expect(tabBarBox.size.height, tabBarHeight);

    // Tab2 width = 150, height = 50
    double tabLeft = kTabLabelPadding.left;
    double tabRight = tabLeft + 150.0;
    double tabTop = (tabBarHeight - indicatorWeight - 50.0) / 2.0;
    double tabBottom = tabTop + 50.0;
    Rect tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[2].key!)), tabRect);

    // Tab1 width = 140, height = 40
    tabLeft = tabRight + kTabLabelPadding.right + kTabLabelPadding.left;
    tabRight = tabLeft + 140.0;
    tabTop = (tabBarHeight - indicatorWeight - 40.0) / 2.0;
    tabBottom = tabTop + 40.0;
    tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[1].key!)), tabRect);

    // Tab0 width = 130, height = 30
    tabLeft = tabRight + kTabLabelPadding.right + kTabLabelPadding.left;
    tabRight = tabLeft + 130.0;
    tabTop = (tabBarHeight - indicatorWeight - 30.0) / 2.0;
    tabBottom = tabTop + 30.0;
    tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[0].key!)), tabRect);

    // Tab 0 selected, indicator padding resolves to right: 100.0
    final double indicatorLeft = tabLeft - kTabLabelPadding.left + indicatorWeight / 2.0;
    final double indicatorRight = tabRight + kTabLabelPadding.left - indicatorWeight / 2.0 - 100.0;
    const double indicatorY = 50.0 + indicatorWeight / 2.0;
    expect(tabBarBox, paints..line(
      strokeWidth: indicatorWeight,
      p1: Offset(indicatorLeft, indicatorY),
      p2: Offset(indicatorRight, indicatorY),
    ));
  });

  testWidgets('TabBar with custom indicator and indicatorPadding(LTR)', (WidgetTester tester) async {
    const Color indicatorColor = Color(0xFF00FF00);
    const double padTop = 10.0;
    const double padBottom = 12.0;
    const double padLeft = 8.0;
    const double padRight = 4.0;
    const Decoration indicator = BoxDecoration(color: indicatorColor);

    final List<Widget> tabs = List<Widget>.generate(4, (int index) {
      return Tab(text: 'Tab $index');
    });

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );

    await tester.pumpWidget(
      boilerplate(
        child: Container(
          alignment: Alignment.topLeft,
          child: TabBar(
            indicator: indicator,
            indicatorPadding:
            const EdgeInsets.fromLTRB(padLeft, padTop, padRight, padBottom),
            controller: controller,
            tabs: tabs,
          ),
        ),
      ),
    );

    final RenderBox tabBarBox =
    tester.firstRenderObject<RenderBox>(find.byType(TabBar));
    expect(tabBarBox.size.height, 48.0);
    // 48 = _kTabHeight(46) + indicatorWeight(2.0) ~default

    const double indicatorBottom = 48.0 - padBottom;
    const double indicatorTop = padTop;
    double indicatorLeft = padLeft;
    double indicatorRight = 200.0 - padRight;

    expect(tabBarBox, paints..rect(
      rect: Rect.fromLTRB(
        indicatorLeft,
        indicatorTop,
        indicatorRight,
        indicatorBottom,
      ),
      color: indicatorColor,
    ));

    // Select tab 3
    controller.index = 3;
    await tester.pumpAndSettle();

    indicatorLeft = 600.0 + padLeft;
    indicatorRight = 800.0 - padRight;

    expect(tabBarBox, paints..rect(
      rect: Rect.fromLTRB(
        indicatorLeft,
        indicatorTop,
        indicatorRight,
        indicatorBottom,
      ),
      color: indicatorColor,
    ));
  });

  testWidgets('TabBar with custom indicator and indicatorPadding (RTL)', (WidgetTester tester) async {
    const Color indicatorColor = Color(0xFF00FF00);
    const double padTop = 10.0;
    const double padBottom = 12.0;
    const double padLeft = 8.0;
    const double padRight = 4.0;
    const Decoration indicator = BoxDecoration(color: indicatorColor);

    final List<Widget> tabs = List<Widget>.generate(4, (int index) {
      return Tab(text: 'Tab $index');
    });

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );

    await tester.pumpWidget(
      boilerplate(
        textDirection: TextDirection.rtl,
        child: Container(
          alignment: Alignment.topLeft,
          child: TabBar(
          indicator: indicator,
          indicatorPadding: const EdgeInsets.fromLTRB(padLeft, padTop, padRight, padBottom),
          controller: controller,
          tabs: tabs,
          ),
        ),
      ),
    );

    final RenderBox tabBarBox =
    tester.firstRenderObject<RenderBox>(find.byType(TabBar));
    expect(tabBarBox.size.height, 48.0);
    // 48 = _kTabHeight(46) + indicatorWeight(2.0) ~default
    expect(tabBarBox.size.width, 800.0);
    const double indicatorBottom = 48.0 - padBottom;
    const double indicatorTop = padTop;
    double indicatorLeft = 600.0 + padLeft;
    double indicatorRight = 800.0 - padRight;

    expect(tabBarBox, paints..rect(
      rect: Rect.fromLTRB(
        indicatorLeft,
        indicatorTop,
        indicatorRight,
        indicatorBottom,
      ),
      color: indicatorColor,
    ));

    // Select tab 3
    controller.index = 3;
    await tester.pumpAndSettle();

    indicatorLeft = padLeft;
    indicatorRight = 200.0 - padRight;

    expect(tabBarBox,paints..rect(
      rect: Rect.fromLTRB(
        indicatorLeft,
        indicatorTop,
        indicatorRight,
        indicatorBottom,
      ),
      color: indicatorColor,
    ));
  });

  testWidgets('TabBar with custom indicator - directional indicatorPadding (LTR)', (WidgetTester tester) async {
    final List<Widget > tabs = <Widget>[
      SizedBox(key: UniqueKey(), width: 130.0, height: 30.0),
      SizedBox(key: UniqueKey(), width: 140.0, height: 40.0),
      SizedBox(key: UniqueKey(), width: 150.0, height: 50.0),
    ];
    const Color indicatorColor = Color(0xFF00FF00);
    const double padTop = 10.0;
    const double padBottom = 12.0;
    const double padStart = 8.0;
    const double padEnd = 4.0;
    const Decoration indicator = BoxDecoration(color: indicatorColor);
    const double indicatorWeight = 2.0; // the default

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );

    await tester.pumpWidget(
      boilerplate(
        child: Container(
          alignment: Alignment.topLeft,
          child: TabBar(
            indicator: indicator,
            indicatorPadding: const EdgeInsetsDirectional.fromSTEB(padStart, padTop, padEnd, padBottom),
            isScrollable: true,
            controller: controller,
            tabs: tabs,
          ),
        ),
      ),
    );

    final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
    const double tabBarHeight = 50.0 + indicatorWeight; // 50 = max tab height
    expect(tabBarBox.size.height, tabBarHeight);

    // Tab0 width = 130, height = 30
    double tabLeft = kTabLabelPadding.left;
    double tabRight = tabLeft + 130.0;
    double tabTop = (tabBarHeight - indicatorWeight - 30.0) / 2.0;
    double tabBottom = tabTop + 30.0;
    Rect tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[0].key!)), tabRect);

    // Tab1 width = 140, height = 40
    tabLeft = tabRight + kTabLabelPadding.right + kTabLabelPadding.left;
    tabRight = tabLeft + 140.0;
    tabTop = (tabBarHeight - indicatorWeight - 40.0) / 2.0;
    tabBottom = tabTop + 40.0;
    tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[1].key!)), tabRect);

    // Tab2 width = 150, height = 50
    tabLeft = tabRight + kTabLabelPadding.right + kTabLabelPadding.left;
    tabRight = tabLeft + 150.0;
    tabTop = (tabBarHeight - indicatorWeight - 50.0) / 2.0;
    tabBottom = tabTop + 50.0;
    tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[2].key!)), tabRect);

    // Tab 0 selected, indicator padding resolves to left: 8.0, right: 4.0
    const double indicatorLeft = padStart;
    final double indicatorRight = 130.0 + kTabLabelPadding.horizontal - padEnd;
    const double indicatorTop = padTop;
    const double indicatorBottom = tabBarHeight - padBottom;
    expect(tabBarBox, paints..rect(
      rect: Rect.fromLTRB(
        indicatorLeft,
        indicatorTop,
        indicatorRight,
        indicatorBottom,
      ),
      color: indicatorColor,
    ));
  });

  testWidgets('TabBar with custom indicator - directional indicatorPadding (RTL)', (WidgetTester tester) async {
    final List<Widget> tabs = <Widget>[
      SizedBox(key: UniqueKey(), width: 130.0, height: 30.0),
      SizedBox(key: UniqueKey(), width: 140.0, height: 40.0),
      SizedBox(key: UniqueKey(), width: 150.0, height: 50.0),
    ];
    const Color indicatorColor = Color(0xFF00FF00);
    const double padTop = 10.0;
    const double padBottom = 12.0;
    const double padStart = 8.0;
    const double padEnd = 4.0;
    const Decoration indicator = BoxDecoration(color: indicatorColor);
    const double indicatorWeight = 2.0; // the default

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );

    await tester.pumpWidget(
      boilerplate(
        textDirection: TextDirection.rtl,
        child: Container(
          alignment: Alignment.topLeft,
          child: TabBar(
            indicator: indicator,
            indicatorPadding: const EdgeInsetsDirectional.fromSTEB(padStart, padTop, padEnd, padBottom),
            isScrollable: true,
            controller: controller,
            tabs: tabs,
          ),
        ),
      ),
    );

    final RenderBox tabBarBox =
    tester.firstRenderObject<RenderBox>(find.byType(TabBar));
    const double tabBarHeight = 50.0 + indicatorWeight; // 50 = max tab height
    expect(tabBarBox.size.height, tabBarHeight);

    // Tab2 width = 150, height = 50
    double tabLeft = kTabLabelPadding.left;
    double tabRight = tabLeft + 150.0;
    double tabTop = (tabBarHeight - indicatorWeight - 50.0) / 2.0;
    double tabBottom = tabTop + 50.0;
    Rect tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[2].key!)), tabRect);

    // Tab1 width = 140, height = 40
    tabLeft = tabRight + kTabLabelPadding.right + kTabLabelPadding.left;
    tabRight = tabLeft + 140.0;
    tabTop = (tabBarHeight - indicatorWeight - 40.0) / 2.0;
    tabBottom = tabTop + 40.0;
    tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[1].key!)), tabRect);

    // Tab0 width = 130, height = 30
    tabLeft = tabRight + kTabLabelPadding.right + kTabLabelPadding.left;
    tabRight = tabLeft + 130.0;
    tabTop = (tabBarHeight - indicatorWeight - 30.0) / 2.0;
    tabBottom = tabTop + 30.0;
    tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[0].key!)), tabRect);

    // Tab 0 selected, indicator padding resolves to left: 4.0, right: 8.0
    final double indicatorLeft = tabLeft - kTabLabelPadding.left + padEnd;
    final double indicatorRight = tabRight + kTabLabelPadding.left - padStart;
    const double indicatorTop = padTop;
    const double indicatorBottom = tabBarHeight - padBottom;

    expect(tabBarBox, paints..rect(
      rect: Rect.fromLTRB(
        indicatorLeft,
        indicatorTop,
        indicatorRight,
        indicatorBottom,
      ),
      color: indicatorColor,
    ));
  });

   testWidgets('TabBar with padding isScrollable: false', (WidgetTester tester) async {
    const double indicatorWeight = 2.0; // default indicator weight
    const EdgeInsets padding = EdgeInsets.only(left: 3.0, top: 7.0, right: 5.0, bottom: 3.0);

    final List<Widget> tabs = <Widget>[
      SizedBox(key: UniqueKey(), width: double.infinity, height: 30.0),
      SizedBox(key: UniqueKey(), width: double.infinity, height: 40.0),
    ];

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );

    await tester.pumpWidget(
      boilerplate(
        child: Container(
          alignment: Alignment.topLeft,
          child: TabBar(
            padding: padding,
            labelPadding: EdgeInsets.zero,
            controller: controller,
            tabs: tabs,
          ),
        ),
      ),
    );

    final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
    final double tabBarHeight = 40.0 + indicatorWeight + padding.top + padding.bottom;  // 40 = max tab height
    expect(tabBarBox.size.height, tabBarHeight);

    final double tabSize = (tabBarBox.size.width - padding.horizontal) / 2.0;

    // Tab0 height = 30
    double tabLeft = padding.left;
    double tabRight = tabLeft + tabSize;
    double tabTop = (tabBarHeight - indicatorWeight + (padding.top - padding.bottom) - 30.0) / 2.0;
    double tabBottom = tabTop + 30.0;
    Rect tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[0].key!)), tabRect);

    // Tab1 height = 40
    tabLeft = tabRight;
    tabRight = tabLeft + tabSize;
    tabTop = (tabBarHeight - indicatorWeight + (padding.top - padding.bottom) - 40.0) / 2.0;
    tabBottom = tabTop + 40.0;
    tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[1].key!)), tabRect);

    tabRight += padding.right;
    expect(tabBarBox.size.width, tabRight);
  });

  testWidgets('TabBar with padding isScrollable: true', (WidgetTester tester) async {
    const double indicatorWeight = 2.0; // default indicator weight
    const EdgeInsets padding = EdgeInsets.only(left: 3.0, top: 7.0, right: 5.0, bottom: 3.0);

    final List<Widget> tabs = <Widget>[
      SizedBox(key: UniqueKey(), width: 130.0, height: 30.0),
      SizedBox(key: UniqueKey(), width: 140.0, height: 40.0),
      SizedBox(key: UniqueKey(), width: 150.0, height: 50.0),
    ];

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );

    await tester.pumpWidget(
      boilerplate(
        child: Container(
          alignment: Alignment.topLeft,
          child: TabBar(
            padding: padding,
            labelPadding: EdgeInsets.zero,
            isScrollable: true,
            controller: controller,
            tabs: tabs,
          ),
        ),
      ),
    );

    final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
    final double tabBarHeight = 50.0 + indicatorWeight + padding.top + padding.bottom;  // 50 = max tab height
    expect(tabBarBox.size.height, tabBarHeight);

    // Tab0 width = 130, height = 30
    double tabLeft = padding.left;
    double tabRight = tabLeft + 130.0;
    double tabTop = (tabBarHeight - indicatorWeight + (padding.top - padding.bottom) - 30.0) / 2.0;
    double tabBottom = tabTop + 30.0;
    Rect tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[0].key!)), tabRect);

    // Tab1 width = 140, height = 40
    tabLeft = tabRight;
    tabRight = tabLeft + 140.0;
    tabTop = (tabBarHeight - indicatorWeight + (padding.top - padding.bottom) - 40.0) / 2.0;
    tabBottom = tabTop + 40.0;
    tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[1].key!)), tabRect);

    // Tab2 width = 150, height = 50
    tabLeft = tabRight;
    tabRight = tabLeft + 150.0;
    tabTop = (tabBarHeight - indicatorWeight + (padding.top - padding.bottom) - 50.0) / 2.0;
    tabBottom = tabTop + 50.0;
    tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[2].key!)), tabRect);

    tabRight += padding.right;
    expect(tabBarBox.size.width, tabRight);
  });

  testWidgets('TabBar with labelPadding', (WidgetTester tester) async {
    const double indicatorWeight = 2.0; // default indicator weight
    const EdgeInsets labelPadding = EdgeInsets.only(left: 3.0, right: 7.0);
    const EdgeInsets indicatorPadding = labelPadding;

    final List<Widget> tabs = <Widget>[
      SizedBox(key: UniqueKey(), width: 130.0, height: 30.0),
      SizedBox(key: UniqueKey(), width: 140.0, height: 40.0),
      SizedBox(key: UniqueKey(), width: 150.0, height: 50.0),
    ];

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );

    await tester.pumpWidget(
      boilerplate(
        child: Container(
          alignment: Alignment.topLeft,
          child: TabBar(
            labelPadding: labelPadding,
            indicatorPadding: labelPadding,
            isScrollable: true,
            controller: controller,
            tabs: tabs,
          ),
        ),
      ),
    );

    final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
    const double tabBarHeight = 50.0 + indicatorWeight;  // 50 = max tab height
    expect(tabBarBox.size.height, tabBarHeight);

    // Tab0 width = 130, height = 30
    double tabLeft = labelPadding.left;
    double tabRight = tabLeft + 130.0;
    double tabTop = (tabBarHeight - indicatorWeight - 30.0) / 2.0;
    double tabBottom = tabTop + 30.0;
    Rect tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[0].key!)), tabRect);

    // Tab1 width = 140, height = 40
    tabLeft = tabRight + labelPadding.right + labelPadding.left;
    tabRight = tabLeft + 140.0;
    tabTop = (tabBarHeight - indicatorWeight - 40.0) / 2.0;
    tabBottom = tabTop + 40.0;
    tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[1].key!)), tabRect);

    // Tab2 width = 150, height = 50
    tabLeft = tabRight + labelPadding.right + labelPadding.left;
    tabRight = tabLeft + 150.0;
    tabTop = (tabBarHeight - indicatorWeight - 50.0) / 2.0;
    tabBottom = tabTop + 50.0;
    tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[2].key!)), tabRect);

    // Tab 0 selected, indicatorPadding == labelPadding
    final double indicatorLeft = indicatorPadding.left + indicatorWeight / 2.0;
    final double indicatorRight = 130.0 + labelPadding.horizontal - indicatorPadding.right - indicatorWeight / 2.0;
    final double indicatorY = tabBottom + indicatorWeight / 2.0;
    expect(tabBarBox, paints..line(
      strokeWidth: indicatorWeight,
      p1: Offset(indicatorLeft, indicatorY),
      p2: Offset(indicatorRight, indicatorY),
    ));
  });

  testWidgets('TabBar with labelPadding(TabBarIndicatorSize.label)', (WidgetTester tester) async {
    const double indicatorWeight = 2.0; // default indicator weight
    const EdgeInsets labelPadding = EdgeInsets.only(left: 7.0, right: 4.0);
    const EdgeInsets indicatorPadding = EdgeInsets.only(left: 3.0, right: 7.0);

    final List<Widget> tabs = <Widget>[
      SizedBox(key: UniqueKey(), width: 130.0, height: 30.0),
      SizedBox(key: UniqueKey(), width: 140.0, height: 40.0),
      SizedBox(key: UniqueKey(), width: 150.0, height: 50.0),
    ];

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );

    await tester.pumpWidget(
      boilerplate(
        child: Container(
          alignment: Alignment.topLeft,
          child: TabBar(
            labelPadding: labelPadding,
            indicatorPadding: indicatorPadding,
            isScrollable: true,
            controller: controller,
            indicatorSize: TabBarIndicatorSize.label,
            tabs: tabs,
          ),
        ),
      ),
    );

    final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
    const double tabBarHeight = 50.0 + indicatorWeight;  // 50 = max tab height
    expect(tabBarBox.size.height, tabBarHeight);

    // Tab0 width = 130, height = 30
    double tabLeft = labelPadding.left;
    double tabRight = tabLeft + 130.0;
    double tabTop = (tabBarHeight - indicatorWeight - 30.0) / 2.0;
    double tabBottom = tabTop + 30.0;
    Rect tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[0].key!)), tabRect);

    // Tab1 width = 140, height = 40
    tabLeft = tabRight + labelPadding.right + labelPadding.left;
    tabRight = tabLeft + 140.0;
    tabTop = (tabBarHeight - indicatorWeight - 40.0) / 2.0;
    tabBottom = tabTop + 40.0;
    tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[1].key!)), tabRect);

    // Tab2 width = 150, height = 50
    tabLeft = tabRight + labelPadding.right + labelPadding.left;
    tabRight = tabLeft + 150.0;
    tabTop = (tabBarHeight - indicatorWeight - 50.0) / 2.0;
    tabBottom = tabTop + 50.0;
    tabRect = Rect.fromLTRB(tabLeft, tabTop, tabRight, tabBottom);
    expect(tester.getRect(find.byKey(tabs[2].key!)), tabRect);

    // Tab 0 selected
    final double indicatorLeft = indicatorPadding.left + labelPadding.left + indicatorWeight / 2.0;
    final double indicatorRight = labelPadding.left + 130.0 - indicatorPadding.right - indicatorWeight / 2.0;
    final double indicatorY = tabBottom + indicatorWeight / 2.0;
    expect(tabBarBox, paints..line(
      strokeWidth: indicatorWeight,
      p1: Offset(indicatorLeft, indicatorY),
      p2: Offset(indicatorRight, indicatorY),
    ));
  });

  testWidgets('Overflowing RTL tab bar', (WidgetTester tester) async {
    final List<Widget> tabs = List<Widget>.filled(100,
      // For convenience padded width of each tab will equal 100:
      // 68 + kTabLabelPadding.horizontal(32)
      SizedBox(key: UniqueKey(), width: 68.0, height: 40.0),
    );

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );

    const double indicatorWeight = 2.0; // the default

    await tester.pumpWidget(
      boilerplate(
        textDirection: TextDirection.rtl,
        child: Container(
          alignment: Alignment.topLeft,
          child: TabBar(
            isScrollable: true,
            controller: controller,
            tabs: tabs,
          ),
        ),
      ),
    );

    final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
    const double tabBarHeight = 40.0 + indicatorWeight;  // 40 = tab height
    expect(tabBarBox.size.height, tabBarHeight);

    // Tab 0 out of 100 selected
    double indicatorLeft = 99.0 * 100.0 + indicatorWeight / 2.0;
    double indicatorRight = 100.0 * 100.0 - indicatorWeight / 2.0;
    const double indicatorY = 40.0 + indicatorWeight / 2.0;
    expect(tabBarBox, paints..line(
      strokeWidth: indicatorWeight,
      p1: Offset(indicatorLeft, indicatorY),
      p2: Offset(indicatorRight, indicatorY),
    ));

    controller.animateTo(tabs.length - 1, duration: const Duration(seconds: 1), curve: Curves.linear);
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 500));

    expect(tabBarBox, paints..line(
      strokeWidth: indicatorWeight,
      p1: const Offset(4951.0, indicatorY),
      p2: const Offset(5049.0, indicatorY),
    ));

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

    // Tab 99 out of 100 selected, appears on the far left because RTL
    indicatorLeft = indicatorWeight / 2.0;
    indicatorRight = 100.0 - indicatorWeight / 2.0;
    expect(tabBarBox, paints..line(
      strokeWidth: indicatorWeight,
      p1: Offset(indicatorLeft, indicatorY),
      p2: Offset(indicatorRight, indicatorY),
    ));
  });

  testWidgets('Tab indicator animation test', (WidgetTester tester) async {
    const double indicatorWeight = 8.0;

    final List<Widget> tabs = List<Widget>.generate(4, (int index) {
      return Tab(text: 'Tab $index');
    });

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );

    await tester.pumpWidget(
      boilerplate(
        child: Container(
          alignment: Alignment.topLeft,
          child: TabBar(
            indicatorWeight: indicatorWeight,
            controller: controller,
            tabs: tabs,
          ),
        ),
      ),
    );

    final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));

    // Initial indicator position.
    const double indicatorY = 54.0 - indicatorWeight / 2.0;
    double indicatorLeft = indicatorWeight / 2.0;
    double indicatorRight = 200.0 - (indicatorWeight / 2.0);

    expect(tabBarBox, paints..line(
      strokeWidth: indicatorWeight,
      p1: Offset(indicatorLeft, indicatorY),
      p2: Offset(indicatorRight, indicatorY),
    ));

    // Select tab 1.
    controller.animateTo(1, duration: const Duration(milliseconds: 1000), curve: Curves.linear);
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 500));
    indicatorLeft = 100.0 + indicatorWeight / 2.0;
    indicatorRight = 300.0 - (indicatorWeight / 2.0);

    expect(tabBarBox, paints..line(
      strokeWidth: indicatorWeight,
      p1: Offset(indicatorLeft, indicatorY),
      p2: Offset(indicatorRight, indicatorY),
    ));

    // Select tab 2 when animation is running.
    controller.animateTo(2, duration: const Duration(milliseconds: 1000), curve: Curves.linear);
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 500));
    indicatorLeft = 250.0 + indicatorWeight / 2.0;
    indicatorRight = 450.0 - (indicatorWeight / 2.0);

    expect(tabBarBox, paints..line(
      strokeWidth: indicatorWeight,
      p1: Offset(indicatorLeft, indicatorY),
      p2: Offset(indicatorRight, indicatorY),
    ));

    // Final indicator position.
    await tester.pumpAndSettle();
    indicatorLeft = 400.0 + indicatorWeight / 2.0;
    indicatorRight = 600.0 - (indicatorWeight / 2.0);

    expect(tabBarBox, paints..line(
      strokeWidth: indicatorWeight,
      p1: Offset(indicatorLeft, indicatorY),
      p2: Offset(indicatorRight, indicatorY),
    ));
  });

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

    final List<Tab> tabs = List<Tab>.generate(2, (int index) {
      return Tab(text: 'TAB #$index');
    });

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );

    await tester.pumpWidget(
      boilerplate(
        child: Semantics(
          container: true,
          child: TabBar(
            isScrollable: true,
            controller: controller,
            tabs: tabs,
          ),
        ),
      ),
    );

    final TestSemantics expectedSemantics = TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          id: 1,
          rect: TestSemantics.fullScreen,
          children: <TestSemantics>[
            TestSemantics(
              id: 2,
              rect: TestSemantics.fullScreen,
              children: <TestSemantics>[
                TestSemantics(
                    id: 3,
                    rect: TestSemantics.fullScreen,
                    flags: <SemanticsFlag>[SemanticsFlag.hasImplicitScrolling],
                    children: <TestSemantics>[
                      TestSemantics(
                        id: 4,
                        actions: <SemanticsAction>[SemanticsAction.tap],
                        flags: <SemanticsFlag>[
                          SemanticsFlag.isSelected,
                          SemanticsFlag.isFocusable,
                        ],
                        label: 'TAB #0\nTab 1 of 2',
                        rect: const Rect.fromLTRB(0.0, 0.0, 116.0, kTextTabBarHeight),
                        transform: Matrix4.translationValues(0.0, 276.0, 0.0),
                      ),
                      TestSemantics(
                        id: 5,
                        flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
                        actions: <SemanticsAction>[SemanticsAction.tap],
                        label: 'TAB #1\nTab 2 of 2',
                        rect: const Rect.fromLTRB(0.0, 0.0, 116.0, kTextTabBarHeight),
                        transform: Matrix4.translationValues(116.0, 276.0, 0.0),
                      ),
                    ],
                ),
              ],
            ),
          ],
        ),
      ],
    );

    expect(semantics, hasSemantics(expectedSemantics));

    semantics.dispose();
  });

  testWidgets('correct scrolling semantics', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);

    final List<Tab> tabs = List<Tab>.generate(20, (int index) {
      return Tab(text: 'This is a very wide tab #$index');
    });

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );

    await tester.pumpWidget(
      boilerplate(
        child: Semantics(
          container: true,
          child: TabBar(
            isScrollable: true,
            controller: controller,
            tabs: tabs,
          ),
        ),
      ),
    );

    const String tab0title = 'This is a very wide tab #0\nTab 1 of 20';
    const String tab10title = 'This is a very wide tab #10\nTab 11 of 20';

    const List<SemanticsFlag> hiddenFlags = <SemanticsFlag>[SemanticsFlag.isHidden, SemanticsFlag.isFocusable];
    expect(semantics, includesNodeWith(actions: <SemanticsAction>[SemanticsAction.scrollLeft]));
    expect(semantics, includesNodeWith(label: tab0title));
    expect(semantics, includesNodeWith(label: tab10title, flags: hiddenFlags));

    controller.index = 10;
    await tester.pumpAndSettle();

    expect(semantics, includesNodeWith(label: tab0title, flags: hiddenFlags));
    expect(semantics, includesNodeWith(actions: <SemanticsAction>[SemanticsAction.scrollLeft, SemanticsAction.scrollRight]));
    expect(semantics, includesNodeWith(label: tab10title));

    controller.index = 19;
    await tester.pumpAndSettle();

    expect(semantics, includesNodeWith(actions: <SemanticsAction>[SemanticsAction.scrollRight]));

    controller.index = 0;
    await tester.pumpAndSettle();

    expect(semantics, includesNodeWith(actions: <SemanticsAction>[SemanticsAction.scrollLeft]));
    expect(semantics, includesNodeWith(label: tab0title));
    expect(semantics, includesNodeWith(label: tab10title, flags: hiddenFlags));

    semantics.dispose();
  });

  testWidgets('TabBar etc with zero tabs', (WidgetTester tester) async {
    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: 0,
    );

    await tester.pumpWidget(
      boilerplate(
        child: Column(
          children: <Widget>[
            TabBar(
              controller: controller,
              tabs: const <Widget>[],
            ),
            Flexible(
              child: TabBarView(
                controller: controller,
                children: const <Widget>[],
              ),
            ),
          ],
        ),
      ),
    );

    expect(controller.index, 0);
    expect(tester.getSize(find.byType(TabBar)), const Size(800.0, 48.0));
    expect(tester.getSize(find.byType(TabBarView)), const Size(800.0, 600.0 - 48.0));

    // A fling in the TabBar or TabBarView, shouldn't do anything.

    await tester.fling(find.byType(TabBar), const Offset(-100.0, 0.0), 5000.0, warnIfMissed: false);
    await tester.pumpAndSettle();

    await tester.fling(find.byType(TabBarView), const Offset(100.0, 0.0), 5000.0);
    await tester.pumpAndSettle();

    expect(controller.index, 0);
  });

  testWidgets('TabBar etc with one tab', (WidgetTester tester) async {
    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: 1,
    );

    await tester.pumpWidget(
      boilerplate(
        child: Column(
          children: <Widget>[
            TabBar(
              controller: controller,
              tabs: const <Widget>[Tab(text: 'TAB')],
            ),
            Flexible(
              child: TabBarView(
                controller: controller,
                children: const <Widget>[Text('PAGE')],
              ),
            ),
          ],
        ),
      ),
    );

    expect(controller.index, 0);
    expect(find.text('TAB'), findsOneWidget);
    expect(find.text('PAGE'), findsOneWidget);
    expect(tester.getSize(find.byType(TabBar)), const Size(800.0, 48.0));
    expect(tester.getSize(find.byType(TabBarView)), const Size(800.0, 600.0 - 48.0));

    // The one tab should be center vis the app's width (800).
    final double tabLeft = tester.getTopLeft(find.widgetWithText(Tab, 'TAB')).dx;
    final double tabRight = tester.getTopRight(find.widgetWithText(Tab, 'TAB')).dx;
    expect(tabLeft + (tabRight - tabLeft) / 2.0, 400.0);

    // A fling in the TabBar or TabBarView, shouldn't move the tab.

    await tester.fling(find.byType(TabBar), const Offset(-100.0, 0.0), 5000.0);
    await tester.pump(const Duration(milliseconds: 50));
    expect(tester.getTopLeft(find.widgetWithText(Tab, 'TAB')).dx, tabLeft);
    expect(tester.getTopRight(find.widgetWithText(Tab, 'TAB')).dx, tabRight);
    await tester.pumpAndSettle();

    await tester.fling(find.byType(TabBarView), const Offset(100.0, 0.0), 5000.0);
    await tester.pump(const Duration(milliseconds: 50));
    expect(tester.getTopLeft(find.widgetWithText(Tab, 'TAB')).dx, tabLeft);
    expect(tester.getTopRight(find.widgetWithText(Tab, 'TAB')).dx, tabRight);
    await tester.pumpAndSettle();

    expect(controller.index, 0);
    expect(find.text('TAB'), findsOneWidget);
    expect(find.text('PAGE'), findsOneWidget);
  });

  testWidgets('can tap on indicator at very bottom of TabBar to switch tabs', (WidgetTester tester) async {
    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: 2,
    );

    await tester.pumpWidget(
      boilerplate(
        child: Column(
          children: <Widget>[
            TabBar(
              controller: controller,
              indicatorWeight: 30.0,
              tabs: const <Widget>[Tab(text: 'TAB1'), Tab(text: 'TAB2')],
            ),
            Flexible(
              child: TabBarView(
                controller: controller,
                children: const <Widget>[Text('PAGE1'), Text('PAGE2')],
              ),
            ),
          ],
        ),
      ),
    );

    expect(controller.index, 0);

    final Offset bottomRight = tester.getBottomRight(find.byType(TabBar)) - const Offset(1.0, 1.0);
    final TestGesture gesture = await tester.startGesture(bottomRight);
    await gesture.up();
    await tester.pumpAndSettle();

    expect(controller.index, 1);
  });

  testWidgets('can override semantics of tabs', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);

    final List<Tab> tabs = List<Tab>.generate(2, (int index) {
      return Tab(
        child: Semantics(
          label: 'Semantics override $index',
          child: ExcludeSemantics(
            child: Text('TAB #$index'),
          ),
        ),
      );
    });

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );

    await tester.pumpWidget(
      boilerplate(
        child: Semantics(
          container: true,
          child: TabBar(
            isScrollable: true,
            controller: controller,
            tabs: tabs,
          ),
        ),
      ),
    );

    final TestSemantics expectedSemantics = TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          id: 1,
          rect: TestSemantics.fullScreen,
          children: <TestSemantics>[
            TestSemantics(
              id: 2,
              rect: TestSemantics.fullScreen,
              children: <TestSemantics>[
                TestSemantics(
                    id: 3,
                    rect: TestSemantics.fullScreen,
                    flags: <SemanticsFlag>[SemanticsFlag.hasImplicitScrolling],
                    children: <TestSemantics>[
                      TestSemantics(
                        id: 4,
                        flags: <SemanticsFlag>[
                          SemanticsFlag.isSelected,
                          SemanticsFlag.isFocusable,
                        ],
                        actions: <SemanticsAction>[SemanticsAction.tap],
                        label: 'Semantics override 0\nTab 1 of 2',
                        rect: const Rect.fromLTRB(0.0, 0.0, 116.0, kTextTabBarHeight),
                        transform: Matrix4.translationValues(0.0, 276.0, 0.0),
                      ),
                      TestSemantics(
                        id: 5,
                        flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
                        actions: <SemanticsAction>[SemanticsAction.tap],
                        label: 'Semantics override 1\nTab 2 of 2',
                        rect: const Rect.fromLTRB(0.0, 0.0, 116.0, kTextTabBarHeight),
                        transform: Matrix4.translationValues(116.0, 276.0, 0.0),
                      ),
                    ],
                ),
              ],
            ),
          ],
        ),
      ],
    );

    expect(semantics, hasSemantics(expectedSemantics));

    semantics.dispose();
  });

  testWidgets('can be notified of TabBar onTap behavior', (WidgetTester tester) async {
    int tabIndex = -1;

    Widget buildFrame({
      required TabController controller,
      required List<String> tabs,
    }) {
      return boilerplate(
        child: TabBar(
          controller: controller,
          tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
          onTap: (int index) {
            tabIndex = index;
          },
        ),
      );
    }

    final List<String> tabs = <String>['A', 'B', 'C'];
    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
      initialIndex: tabs.indexOf('C'),
    );

    await tester.pumpWidget(buildFrame(tabs: tabs, controller: controller));
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsOneWidget);
    expect(find.text('C'), findsOneWidget);
    expect(controller, isNotNull);
    expect(controller.index, 2);
    expect(tabIndex, -1); // no tap so far so tabIndex should reflect that

    // Verify whether the [onTap] notification works when the [TabBar] animates.

    await tester.pumpWidget(buildFrame(tabs: tabs, controller: controller));
    await tester.tap(find.text('B'));
    await tester.pump();
    expect(controller.indexIsChanging, true);
    await tester.pumpAndSettle();
    expect(controller.index, 1);
    expect(controller.previousIndex, 2);
    expect(controller.indexIsChanging, false);
    expect(tabIndex, controller.index);

    tabIndex = -1;

    await tester.pumpWidget(buildFrame(tabs: tabs, controller: controller));
    await tester.tap(find.text('C'));
    await tester.pump();
    await tester.pumpAndSettle();
    expect(controller.index, 2);
    expect(controller.previousIndex, 1);
    expect(tabIndex, controller.index);

    tabIndex = -1;

    await tester.pumpWidget(buildFrame(tabs: tabs, controller: controller));
    await tester.tap(find.text('A'));
    await tester.pump();
    await tester.pumpAndSettle();
    expect(controller.index, 0);
    expect(controller.previousIndex, 2);
    expect(tabIndex, controller.index);

    tabIndex = -1;

    // Verify whether [onTap] is called even when the [TabController] does
    // not change.

    final int currentControllerIndex = controller.index;
    await tester.pumpWidget(buildFrame(tabs: tabs, controller: controller));
    await tester.tap(find.text('A'));
    await tester.pump();
    await tester.pumpAndSettle();
    expect(controller.index, currentControllerIndex); // controller has not changed
    expect(tabIndex, 0);
  });

  test('illegal constructor combinations', () {
    expect(() => Tab(icon: nonconst(null)), throwsAssertionError);
    expect(() => Tab(icon: Container(), text: 'foo', child: Container()), throwsAssertionError);
    expect(() => Tab(text: 'foo', child: Container()), throwsAssertionError);
  });

  testWidgets('Tabs changes mouse cursor when a tab is hovered', (WidgetTester tester) async {
    final List<String> tabs = <String>['A', 'B'];
    await tester.pumpWidget(MaterialApp(home: DefaultTabController(
        length: tabs.length,
        child: Scaffold(
          body: MouseRegion(
            cursor: SystemMouseCursors.forbidden,
            child: TabBar(
              mouseCursor: SystemMouseCursors.text,
              tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
            ),
          ),
        ),
      ),
    ));

    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1);
    await gesture.addPointer(location: tester.getCenter(find.byType(Tab).first));

    await tester.pump();

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

    // Test default cursor
    await tester.pumpWidget(MaterialApp(home: DefaultTabController(
        length: tabs.length,
        child: Scaffold(
          body: MouseRegion(
            cursor: SystemMouseCursors.forbidden,
            child: TabBar(
              tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
            ),
          ),
        ),
      ),
    ));
    expect(RendererBinding.instance.mouseTracker.debugDeviceActiveCursor(1), SystemMouseCursors.click);
  });

  testWidgets('TabController changes', (WidgetTester tester) async {
    // This is a regression test for https://github.com/flutter/flutter/issues/14812

    Widget buildFrame(TabController controller) {
      return boilerplate(
        child: Container(
          alignment: Alignment.topLeft,
          child: TabBar(
            controller: controller,
            tabs: const <Tab>[
              Tab(text: 'LEFT'),
              Tab(text: 'RIGHT'),
            ],
          ),
        ),
      );
    }

    final TabController controller1 = TabController(
      vsync: const TestVSync(),
      length: 2,
    );

    final TabController controller2 = TabController(
      vsync: const TestVSync(),
      length: 2,
    );

    await tester.pumpWidget(buildFrame(controller1));
    await tester.pumpWidget(buildFrame(controller2));
    expect(controller1.index, 0);
    expect(controller2.index, 0);

    const double indicatorWeight = 2.0;
    final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
    expect(tabBarBox.size.height, 48.0); // 48 = _kTabHeight(46) + indicatorWeight(2.0)

    const double indicatorY = 48.0 - indicatorWeight / 2.0;
    double indicatorLeft = indicatorWeight / 2.0;
    double indicatorRight = 400.0 - indicatorWeight / 2.0; // 400 = screen_width / 2
    expect(tabBarBox, paints..line(
      strokeWidth: indicatorWeight,
      p1: Offset(indicatorLeft, indicatorY),
      p2: Offset(indicatorRight, indicatorY),
    ));

    await tester.tap(find.text('RIGHT'));
    await tester.pumpAndSettle();
    expect(controller1.index, 0);
    expect(controller2.index, 1);

    // Verify that the TabBar's _IndicatorPainter is now listening to
    // tabController2.

    indicatorLeft = 400.0 + indicatorWeight / 2.0;
    indicatorRight = 800.0 - indicatorWeight / 2.0;
    expect(tabBarBox, paints..line(
      strokeWidth: indicatorWeight,
      p1: Offset(indicatorLeft, indicatorY),
      p2: Offset(indicatorRight, indicatorY),
    ));
  });

  testWidgets('TabController changes with different initialIndex', (WidgetTester tester) async {
    // This is a regression test for https://github.com/flutter/flutter/issues/115917
    const Key lastTabKey = Key('Last Tab');
    TabController? controller;

    Widget buildFrame(int length) {
      controller = TabController(
        vsync: const TestVSync(),
        length: length,
        initialIndex: length - 1,
      );
      return boilerplate(
        child: TabBar(
          labelPadding: EdgeInsets.zero,
          controller: controller,
          isScrollable: true,
          tabs: List<Widget>.generate(
            length,
            (int index) {
              return SizedBox(
                width: 100,
                child: Tab(
                  key: index == length - 1 ? lastTabKey : null,
                  text: 'Tab $index',
                ),
              );
            },
          ),
        ),
      );
    }

    await tester.pumpWidget(buildFrame(10));
    expect(controller!.index, 9);
    expect(tester.getCenter(find.byKey(lastTabKey)).dx, equals(750.0));

    // Rebuild with a new controller with more tabs and last tab selected.
    // Last tab should be visible and on the right of the window.
    await tester.pumpWidget(buildFrame(15));
    expect(controller!.index, 14);
    expect(tester.getCenter(find.byKey(lastTabKey)).dx, equals(750.0));
  });

  testWidgets('Default tab indicator color is white', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/15958
    final List<String> tabs = <String>['LEFT', 'RIGHT'];
    await tester.pumpWidget(buildLeftRightApp(tabs: tabs, value: 'LEFT'));
    final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
    expect(tabBarBox, paints..line(
      color: Colors.white,
    ));
  });

  testWidgets('Tab indicator color should not be adjusted when disable [automaticIndicatorColorAdjustment]', (WidgetTester tester) async {
     // Regression test for https://github.com/flutter/flutter/issues/68077
     final List<String> tabs = <String>['LEFT', 'RIGHT'];
     await tester.pumpWidget(buildLeftRightApp(tabs: tabs, value: 'LEFT', automaticIndicatorColorAdjustment: false));
     final RenderBox tabBarBox = tester.firstRenderObject<RenderBox>(find.byType(TabBar));
     expect(tabBarBox, paints..line(
       color: const Color(0xff2196f3),
     ));
  });

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

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

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

    testWidgets('Tab feedback is enabled (default)', (WidgetTester tester) async {
      await tester.pumpWidget(
        boilerplate(
          child: const DefaultTabController(
            length: 1,
            child: TabBar(
              tabs: <Tab>[
                Tab(text: 'A'),
              ],
            ),
          ),
        ),
      );
      await tester.tap(find.byType(InkWell), pointer: 1);
      await tester.pump(const Duration(seconds: 1));
      expect(feedback.clickSoundCount, 1);
      expect(feedback.hapticCount, 0);

      await tester.tap(find.byType(InkWell), pointer: 1);
      await tester.pump(const Duration(seconds: 1));
      expect(feedback.clickSoundCount, 2);
      expect(feedback.hapticCount, 0);
    });

    testWidgets('Tab feedback is disabled', (WidgetTester tester) async {
      await tester.pumpWidget(
        boilerplate(
          child: const DefaultTabController(
            length: 1,
            child: TabBar(
              tabs: <Tab>[
                Tab(text: 'A'),
              ],
              enableFeedback: false,
            ),
          ),
        ),
      );
      await tester.tap(find.byType(InkWell), pointer: 1);
      await tester.pump(const Duration(seconds: 1));
      expect(feedback.clickSoundCount, 0);
      expect(feedback.hapticCount, 0);

      await tester.longPress(find.byType(InkWell), pointer: 1);
      await tester.pump(const Duration(seconds: 1));
      expect(feedback.clickSoundCount, 0);
      expect(feedback.hapticCount, 0);
    });
  });

  group('Tab overlayColor affects ink response', () {
    testWidgets("Tab's ink well changes color on hover with Tab overlayColor", (WidgetTester tester) async {
      await tester.pumpWidget(
        boilerplate(
          child: DefaultTabController(
            length: 1,
            child: TabBar(
              tabs: const <Tab>[
                Tab(text: 'A'),
              ],
              overlayColor: MaterialStateProperty.resolveWith<Color>(
                (Set<MaterialState> states) {
                 if (states.contains(MaterialState.hovered)) {
                   return const Color(0xff00ff00);
                 }
                  if (states.contains(MaterialState.pressed)) {
                    return const Color(0xf00fffff);
                  }
                  return const Color(0xffbadbad); // Shouldn't happen.
                },
              ),
            ),
          ),
        ),
      );
      final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
      await gesture.addPointer();
      await gesture.moveTo(tester.getCenter(find.byType(Tab)));
      await tester.pumpAndSettle();
      final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
      expect(inkFeatures, paints..rect(rect: const Rect.fromLTRB(0.0, 276.0, 800.0, 324.0), color: const Color(0xff00ff00)));
    });

    testWidgets(
      "Tab's ink response splashColor matches resolved Tab overlayColor for MaterialState.pressed",
      (WidgetTester tester) async {
        const Color splashColor = Color(0xf00fffff);
        await tester.pumpWidget(
          boilerplate(
            child: DefaultTabController(
              length: 1,
              child: TabBar(
                tabs: const <Tab>[
                  Tab(text: 'A'),
                ],
                overlayColor: MaterialStateProperty.resolveWith<Color>(
                  (Set<MaterialState> states) {
                    if (states.contains(MaterialState.hovered)) {
                      return const Color(0xff00ff00);
                    }
                    if (states.contains(MaterialState.pressed)) {
                      return splashColor;
                    }
                    return const Color(0xffbadbad); // Shouldn't happen.
                  },
                ),
              ),
            ),
          ),
        );
        await tester.pumpAndSettle();
        final TestGesture gesture = await tester.startGesture(tester.getRect(find.byType(InkWell)).center);
        await tester.pump(const Duration(milliseconds: 200)); // unconfirmed splash is well underway
        final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
        expect(inkFeatures, paints..circle(x: 400, y: 24, color: splashColor));
        await gesture.up();
      },
    );
  });

  testWidgets('Skipping tabs with global key does not crash', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/24660
    final List<String> tabs = <String>[
      'Tab1',
      'Tab2',
      'Tab3',
      'Tab4',
    ];
    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );
    await tester.pumpWidget(
      MaterialApp(
        home: Align(
          alignment: Alignment.topLeft,
          child: SizedBox(
            width: 300.0,
            height: 200.0,
            child: Scaffold(
              appBar: AppBar(
                title: const Text('tabs'),
                bottom: TabBar(
                  controller: controller,
                  tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
                ),
              ),
              body: TabBarView(
                controller: controller,
                children: <Widget>[
                  Text('1', key: GlobalKey()),
                  Text('2', key: GlobalKey()),
                  Text('3', key: GlobalKey()),
                  Text('4', key: GlobalKey()),
                ],
              ),
            ),
          ),
        ),
      ),
    );
    expect(find.text('1'), findsOneWidget);
    expect(find.text('4'), findsNothing);
    await tester.tap(find.text('Tab4'));
    await tester.pumpAndSettle();
    expect(controller.index, 3);
    expect(find.text('4'), findsOneWidget);
    expect(find.text('1'), findsNothing);
  });

  testWidgets('Skipping tabs with a KeepAlive child works', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/11895
    final List<String> tabs = <String>[
      'Tab1',
      'Tab2',
      'Tab3',
      'Tab4',
      'Tab5',
    ];
    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: tabs.length,
    );
    await tester.pumpWidget(
      MaterialApp(
        home: Align(
          alignment: Alignment.topLeft,
          child: SizedBox(
            width: 300.0,
            height: 200.0,
            child: Scaffold(
              appBar: AppBar(
                title: const Text('tabs'),
                bottom: TabBar(
                  controller: controller,
                  tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
                ),
              ),
              body: TabBarView(
                controller: controller,
                children: <Widget>[
                  AlwaysKeepAliveWidget(key: UniqueKey()),
                  const Text('2'),
                  const Text('3'),
                  const Text('4'),
                  const Text('5'),
                ],
              ),
            ),
          ),
        ),
      ),
    );
    expect(find.text(AlwaysKeepAliveWidget.text), findsOneWidget);
    expect(find.text('4'), findsNothing);
    await tester.tap(find.text('Tab4'));
    await tester.pumpAndSettle();
    await tester.pump();
    expect(controller.index, 3);
    expect(find.text(AlwaysKeepAliveWidget.text, skipOffstage: false), findsOneWidget);
    expect(find.text('4'), findsOneWidget);
  });

  testWidgets('tabbar does not scroll when viewport dimensions initially change from zero to non-zero', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/10531.

    const List<Widget> tabs = <Widget>[
      Tab(text: 'NEW MEXICO'),
      Tab(text: 'GABBA'),
      Tab(text: 'HEY'),
    ];
    final TabController controller = TabController(vsync: const TestVSync(), length: tabs.length);

    Widget buildTestWidget({double? width, double? height}) {
      return MaterialApp(
        home: Center(
          child: SizedBox(
            height: height,
            width: width,
            child: Scaffold(
              appBar: AppBar(
                title: const Text('AppBarBug'),
                bottom: PreferredSize(
                  preferredSize: const Size.fromHeight(30.0),
                  child: Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 15.0),
                    child: Align(
                      alignment: FractionalOffset.center,
                      child: TabBar(
                        controller: controller,
                        isScrollable: true,
                        tabs: tabs,
                      ),
                    ),
                  ),
                ),
              ),
              body: const Center(
                child: Text('Hello World'),
              ),
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(
      buildTestWidget(
        width: 0.0,
        height: 0.0,
      ),
    );

    await tester.pumpWidget(
      buildTestWidget(
        width: 300.0,
        height: 400.0,
      ),
    );

    expect(tester.hasRunningAnimations, isFalse);
    expect(await tester.pumpAndSettle(), 1); // no more frames are scheduled.
  });

  // Regression test for https://github.com/flutter/flutter/issues/20292.
  testWidgets('Number of tabs can be updated dynamically', (WidgetTester tester) async {
    final List<String> threeTabs = <String>['A', 'B', 'C'];
    final List<String> twoTabs = <String>['A', 'B'];
    final List<String> oneTab = <String>['A'];
    final Key key = UniqueKey();
    Widget buildTabs(List<String> tabs) {
      return boilerplate(
        child: DefaultTabController(
          key: key,
          length: tabs.length,
          child: TabBar(
            tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
          ),
        ),
      );
    }
    TabController getController() => DefaultTabController.of(tester.element(find.text('A')));

    await tester.pumpWidget(buildTabs(threeTabs));
    await tester.tap(find.text('B'));
    await tester.pump();
    TabController controller = getController();
    expect(controller.previousIndex, 0);
    expect(controller.index, 1);
    expect(controller.length, 3);

    await tester.pumpWidget(buildTabs(twoTabs));
    controller = getController();
    expect(controller.previousIndex, 0);
    expect(controller.index, 1);
    expect(controller.length, 2);

    await tester.pumpWidget(buildTabs(oneTab));
    controller = getController();
    expect(controller.previousIndex, 1);
    expect(controller.index, 0);
    expect(controller.length, 1);

    await tester.pumpWidget(buildTabs(twoTabs));
    controller = getController();
    expect(controller.previousIndex, 1);
    expect(controller.index, 0);
    expect(controller.length, 2);
  });

  // Regression test for https://github.com/flutter/flutter/issues/15008.
  testWidgets('TabBar with one tab has correct color', (WidgetTester tester) async {
    const Tab tab = Tab(text: 'A');
    const Color selectedTabColor = Color(0x00000001);
    const Color unselectedTabColor = Color(0x00000002);

    await tester.pumpWidget(boilerplate(
      child: const DefaultTabController(
        length: 1,
        child: TabBar(
          tabs: <Tab>[tab],
          labelColor: selectedTabColor,
          unselectedLabelColor: unselectedTabColor,
        ),
      ),
    ));

    final IconThemeData iconTheme = IconTheme.of(tester.element(find.text('A')));
    expect(iconTheme.color, equals(selectedTabColor));
  });

  testWidgets('Replacing the tabController after disposing the old one', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/32428

    TabController controller = TabController(vsync: const TestVSync(), length: 2);
    await tester.pumpWidget(
      MaterialApp(
        home: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return Scaffold(
              appBar: AppBar(
                bottom: TabBar(
                  controller: controller,
                  tabs: List<Widget>.generate(controller.length, (int index) => Tab(text: 'Tab$index')),
                ),
                actions: <Widget>[
                  TextButton(
                    child: const Text('Change TabController length'),
                    onPressed: () {
                      setState(() {
                        controller.dispose();
                        controller = TabController(vsync: const TestVSync(), length: 3);
                      });
                    },
                  ),
                ],
              ),
              body: TabBarView(
                controller: controller,
                children: List<Widget>.generate(controller.length, (int index) => Center(child: Text('Tab $index'))),
              ),
            );
          },
        ),
      ),
    );

    expect(controller.index, 0);
    expect(controller.length, 2);
    expect(find.text('Tab0'), findsOneWidget);
    expect(find.text('Tab1'), findsOneWidget);
    expect(find.text('Tab2'), findsNothing);

    await tester.tap(find.text('Change TabController length'));
    await tester.pumpAndSettle();
    expect(controller.index, 0);
    expect(controller.length, 3);
    expect(find.text('Tab0'), findsOneWidget);
    expect(find.text('Tab1'), findsOneWidget);
    expect(find.text('Tab2'), findsOneWidget);
  });

  testWidgets('DefaultTabController should allow for a length of zero', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/20292.
    List<String> tabTextContent = <String>[];

    await tester.pumpWidget(
      MaterialApp(
        home: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return DefaultTabController(
              length: tabTextContent.length,
              child: Scaffold(
                appBar: AppBar(
                  title: const Text('Default TabBar Preview'),
                  bottom: tabTextContent.isNotEmpty
                    ? TabBar(
                        isScrollable: true,
                        tabs: tabTextContent.map((String textContent) => Tab(text: textContent)).toList(),
                      )
                    : null,
                ),
                body: tabTextContent.isNotEmpty
                  ? TabBarView(
                      children: tabTextContent.map((String textContent) => Tab(text: "$textContent's view")).toList(),
                    )
                  : const Center(child: Text('No tabs')),
                bottomNavigationBar: BottomAppBar(
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      IconButton(
                        key: const Key('Add tab'),
                        icon: const Icon(Icons.add),
                        onPressed: () {
                          setState(() {
                            tabTextContent = List<String>.from(tabTextContent)
                              ..add('Tab ${tabTextContent.length + 1}');
                          });
                        },
                      ),
                      IconButton(
                        key: const Key('Delete tab'),
                        icon: const Icon(Icons.delete),
                        onPressed: () {
                          setState(() {
                            tabTextContent = List<String>.from(tabTextContent)
                              ..removeLast();
                          });
                        },
                      ),
                    ],
                  ),
                ),
              ),
            );
          },
        ),
      ),
    );

    // Initializes with zero tabs properly
    expect(find.text('No tabs'), findsOneWidget);
    await tester.tap(find.byKey(const Key('Add tab')));
    await tester.pumpAndSettle();
    expect(find.text('Tab 1'), findsOneWidget);
    expect(find.text("Tab 1's view"), findsOneWidget);

    // Dynamically updates to zero tabs properly
    await tester.tap(find.byKey(const Key('Delete tab')));
    await tester.pumpAndSettle();
    expect(find.text('No tabs'), findsOneWidget);
  });

  testWidgets('DefaultTabController should allow dynamic length of tabs', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/94504.
    final List<String> tabTitles = <String>[];

    void onTabAdd(StateSetter setState) {
      setState(() {
        tabTitles.add('Tab ${tabTitles.length + 1}');
      });
    }

    void onTabRemove(StateSetter setState) {
      setState(() {
        tabTitles.removeLast();
      });
    }

    await tester.pumpWidget(
      MaterialApp(
        home: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return DefaultTabController(
              length: tabTitles.length,
              child: Scaffold(
                appBar: AppBar(
                  actions: <Widget>[
                    TextButton(
                      key: const Key('Add tab'),
                      child: const Text('Add tab'),
                      onPressed: () => onTabAdd(setState),
                    ),
                    TextButton(
                      key: const Key('Remove tab'),
                      child: const Text('Remove tab'),
                      onPressed: () => onTabRemove(setState),
                    ),
                  ],
                  bottom: PreferredSize(
                    preferredSize: const Size.fromHeight(40.0),
                    child: Expanded(
                      child: TabBar(
                        tabs: tabTitles
                            .map((String title) => Tab(text: title))
                            .toList(),
                      ),
                    ),
                  ),
                ),
              ),
            );
          },
        ),
      ),
    );

    expect(find.text('Tab 1'), findsNothing);
    expect(find.text('Tab 2'), findsNothing);

    await tester.tap(find.byKey(const Key('Add tab'))); // +1
    await tester.pumpAndSettle();
    expect(find.text('Tab 1'), findsOneWidget);
    expect(find.text('Tab 2'), findsNothing);

    await tester.tap(find.byKey(const Key('Add tab'))); // +2
    await tester.pumpAndSettle();
    expect(find.text('Tab 1'), findsOneWidget);
    expect(find.text('Tab 2'), findsOneWidget);

    await tester.tap(find.byKey(const Key('Remove tab'))); // -2
    await tester.tap(find.byKey(const Key('Remove tab'))); // -1
    await tester.pumpAndSettle();
    expect(find.text('Tab 1'), findsNothing);
    expect(find.text('Tab 2'), findsNothing);
  });

  testWidgets('TabBar - updating to and from zero tabs', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/68962.
    final List<String> tabTitles = <String>[];
    TabController tabController = TabController(length: tabTitles.length, vsync: const TestVSync());

    void onTabAdd(StateSetter setState) {
      setState(() {
        tabTitles.add('Tab ${tabTitles.length + 1}');
        tabController = TabController(length: tabTitles.length, vsync: const TestVSync());
      });
    }

    void onTabRemove(StateSetter setState) {
      setState(() {
        tabTitles.removeLast();
        tabController = TabController(length: tabTitles.length, vsync: const TestVSync());
      });
    }

    await tester.pumpWidget(
      MaterialApp(
        home: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return Scaffold(
              appBar: AppBar(
                actions: <Widget>[
                  TextButton(
                    key: const Key('Add tab'),
                    child: const Text('Add tab'),
                    onPressed: () => onTabAdd(setState),
                  ),
                  TextButton(
                    key: const Key('Remove tab'),
                    child: const Text('Remove tab'),
                    onPressed: () => onTabRemove(setState),
                  ),
                ],
                bottom: PreferredSize(
                  preferredSize: const Size.fromHeight(40.0),
                  child: Expanded(
                    child: TabBar(
                      controller: tabController,
                      tabs: tabTitles
                        .map((String title) => Tab(text: title))
                        .toList(),
                    ),
                  ),
                ),
              ),
            );
          },
        ),
      ),
    );

    expect(find.text('Tab 1'), findsNothing);
    expect(find.text('Add tab'), findsOneWidget);
    await tester.tap(find.byKey(const Key('Add tab')));
    await tester.pumpAndSettle();
    expect(find.text('Tab 1'), findsOneWidget);

    await tester.tap(find.byKey(const Key('Remove tab')));
    await tester.pumpAndSettle();
    expect(find.text('Tab 1'), findsNothing);
  });

   testWidgets('TabBar expands vertically to accommodate the Icon and child Text() pair the same amount it would expand for Icon and text pair.', (WidgetTester tester) async {
    const List<Widget> tabListWithText = <Widget>[
      Tab(icon: Icon(Icons.notifications), text: 'Test'),
    ];
    const List<Widget> tabListWithTextChild = <Widget>[
      Tab(icon: Icon(Icons.notifications), child: Text('Test')),
    ];

    const TabBar tabBarWithText = TabBar(tabs: tabListWithText);
    const TabBar tabBarWithTextChild = TabBar(tabs: tabListWithTextChild);

    expect(tabBarWithText.preferredSize, tabBarWithTextChild.preferredSize);
   });

  testWidgets('Setting TabController index should make TabBar indicator immediately pop into the position', (WidgetTester tester) async {
    const List<Tab> tabs = <Tab>[
      Tab(text: 'A'), Tab(text: 'B'), Tab(text: 'C'),
    ];
    const Color indicatorColor = Color(0xFFFF0000);
    late TabController tabController;

    Widget buildTabControllerFrame(BuildContext context, TabController controller) {
      tabController = controller;
      return MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            bottom: TabBar(
              controller: controller,
              tabs: tabs,
              indicatorColor: indicatorColor,
            ),
          ),
          body: TabBarView(
            controller: controller,
            children: tabs.map((Tab tab) {
              return Center(child: Text(tab.text!));
            }).toList(),
          ),
        ),
      );
    }

    await tester.pumpWidget(TabControllerFrame(
      builder: buildTabControllerFrame,
      length: tabs.length,
    ));

    final RenderBox box = tester.renderObject(find.byType(TabBar));
    final TabIndicatorRecordingCanvas canvas = TabIndicatorRecordingCanvas(indicatorColor);
    final TestRecordingPaintingContext context = TestRecordingPaintingContext(canvas);

    box.paint(context, Offset.zero);
    double expectedIndicatorLeft = canvas.indicatorRect.left;

    final PageView pageView = tester.widget(find.byType(PageView));
    final PageController pageController = pageView.controller;
    void pageControllerListener() {
      // Whenever TabBarView scrolls due to changing TabController's index,
      // check if indicator stays idle in its expectedIndicatorLeft
      box.paint(context, Offset.zero);
      expect(canvas.indicatorRect.left, expectedIndicatorLeft);
    }

    // Moving from index 0 to 2 (distanced tabs)
    tabController.index = 2;
    box.paint(context, Offset.zero);
    expectedIndicatorLeft = canvas.indicatorRect.left;
    pageController.addListener(pageControllerListener);
    await tester.pumpAndSettle();

    // Moving from index 2 to 1 (neighboring tabs)
    tabController.index = 1;
    box.paint(context, Offset.zero);
    expectedIndicatorLeft = canvas.indicatorRect.left;
    await tester.pumpAndSettle();
    pageController.removeListener(pageControllerListener);
  });

  testWidgets('Setting BouncingScrollPhysics on TabBarView does not include ClampingScrollPhysics', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/57708
    await tester.pumpWidget(MaterialApp(
      home: DefaultTabController(
        length: 10,
        child: Scaffold(
          body: TabBarView(
            physics: const BouncingScrollPhysics(),
            children: List<Widget>.generate(10, (int i) => Center(child: Text('index $i'))),
          ),
        ),
      ),
    ));

    final PageView pageView = tester.widget<PageView>(find.byType(PageView));
    expect(pageView.physics.toString().contains('ClampingScrollPhysics'), isFalse);
  });

  testWidgets('TabController changes offset attribute', (WidgetTester tester) async {
    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: 2,
    );

    late Color firstColor;
    late Color secondColor;

    await tester.pumpWidget(
      boilerplate(
        child: TabBar(
          controller: controller,
          labelColor: Colors.white,
          unselectedLabelColor: Colors.black,
          tabs: <Widget>[
            Builder(builder: (BuildContext context) {
              firstColor = DefaultTextStyle.of(context).style.color!;
              return const Text('First');
            }),
            Builder(builder: (BuildContext context) {
              secondColor = DefaultTextStyle.of(context).style.color!;
              return const Text('Second');
            }),
          ],
        ),
      ),
    );

    expect(firstColor, equals(Colors.white));
    expect(secondColor, equals(Colors.black));

    controller.offset = 0.6;
    await tester.pump();

    expect(firstColor, equals(Color.lerp(Colors.white, Colors.black, 0.6)));
    expect(secondColor, equals(Color.lerp(Colors.black, Colors.white, 0.6)));

    controller.index = 1;
    await tester.pump();

    expect(firstColor, equals(Colors.black));
    expect(secondColor, equals(Colors.white));

    controller.offset = 0.6;
    await tester.pump();

    expect(firstColor, equals(Colors.black));
    expect(secondColor, equals(Colors.white));
  });

  testWidgets('Crash on dispose', (WidgetTester tester) async {
    await tester.pumpWidget(const Padding(padding: EdgeInsets.only(right: 200.0), child: TabBarDemo()));
    await tester.tap(find.byIcon(Icons.directions_bike));
    // There was a time where this would throw an exception
    // because we tried to send a notification on dispose.
  });

  testWidgets("TabController's animation value should be in sync with TabBarView's scroll value when user interrupts ballistic scroll", (WidgetTester tester) async {
    final TabController tabController = TabController(
      vsync: const TestVSync(),
      length: 3,
    );

    await tester.pumpWidget(Directionality(
      textDirection: TextDirection.ltr,
      child: SizedBox.expand(
        child: Center(
          child: SizedBox(
            width: 400.0,
            height: 400.0,
            child: TabBarView(
              controller: tabController,
              children: const <Widget>[
                Center(child: Text('0')),
                Center(child: Text('1')),
                Center(child: Text('2')),
              ],
            ),
          ),
        ),
      ),
    ));

    final PageView pageView = tester.widget(find.byType(PageView));
    final PageController pageController = pageView.controller;
    final ScrollPosition position = pageController.position;

    expect(tabController.index, 0);
    expect(position.pixels, 0.0);

    pageController.jumpTo(300.0);
    await tester.pump();
    expect(tabController.animation!.value, pageController.page);

    // Touch TabBarView while ballistic scrolling is happening and
    // check if tabController's animation value properly follows page value.
    await tester.startGesture(tester.getCenter(find.byType(PageView)));
    await tester.pump();
    expect(tabController.animation!.value, pageController.page);
  });

  testWidgets('Does not instantiate intermediate tabs during animation', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/14316.
    final List<String> log = <String>[];
    await tester.pumpWidget(MaterialApp(
      home: DefaultTabController(
        length: 5,
        child: Scaffold(
          appBar: AppBar(
            bottom: const TabBar(
              tabs: <Widget>[
                Tab(text: 'car'),
                Tab(text: 'transit'),
                Tab(text: 'bike'),
                Tab(text: 'boat'),
                Tab(text: 'bus'),
              ],
            ),
            title: const Text('Tabs Test'),
          ),
          body: TabBarView(
            children: <Widget>[
              TabBody(index: 0, log: log),
              TabBody(index: 1, log: log),
              TabBody(index: 2, log: log),
              TabBody(index: 3, log: log),
              TabBody(index: 4, log: log),
            ],
          ),
        ),
      ),
    ));

    expect(find.text('0'), findsOneWidget);
    expect(find.text('3'), findsNothing);
    expect(log, <String>['init: 0']);

    await tester.tap(find.text('boat'));
    await tester.pumpAndSettle();

    expect(find.text('0'), findsNothing);
    expect(find.text('3'), findsOneWidget);

    // No other tab got instantiated during the animation.
    expect(log, <String>['init: 0', 'init: 3', 'dispose: 0']);
  });

  testWidgets("TabController's animation value should be updated when TabController's index >= tabs's length", (WidgetTester tester) async {
    // This is a regression test for the issue brought up here
    // https://github.com/flutter/flutter/issues/79226

    final List<String> tabs = <String>['A', 'B', 'C'];
    await tester.pumpWidget(
      MaterialApp(
        home: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return DefaultTabController(
              length: tabs.length,
              child: Scaffold(
                appBar: AppBar(
                  bottom: TabBar(
                    tabs: tabs.map<Widget>((String tab) => Tab(text: tab)).toList(),
                  ),
                  actions: <Widget>[
                    TextButton(
                      child: const Text('Remove Last Tab'),
                      onPressed: () {
                        setState(() {
                          tabs.removeLast();
                        });
                      },
                    ),
                  ],
                ),
                body: TabBarView(
                  children: tabs.map<Widget>((String tab) => Tab(text: 'Tab child $tab')).toList(),
                ),
              ),
            );
          },
        ),
      ),
    );

    TabController getController() => DefaultTabController.of(tester.element(find.text('B')));
    TabController controller = getController();

    controller.animateTo(2, duration: const Duration(milliseconds: 200), curve: Curves.linear);
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 300));

    controller = getController();
    expect(controller.index, 2);
    expect(controller.animation!.value, 2);

    await tester.tap(find.text('Remove Last Tab'));
    await tester.pumpAndSettle();

    controller = getController();
    expect(controller.index, 1);
    expect(controller.animation!.value, 1);
  });

  testWidgets('Tab preferredSize gives correct value', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: Material(
          child: Row(
            children: const <Tab>[
              Tab(icon: Icon(Icons.message)),
              Tab(text: 'Two'),
              Tab(text: 'Three', icon: Icon(Icons.chat)),
            ],
          ),
        ),
      ),
    );

    final Tab firstTab = tester.widget(find.widgetWithIcon(Tab, Icons.message));
    final Tab secondTab = tester.widget(find.widgetWithText(Tab, 'Two'));
    final Tab thirdTab = tester.widget(find.widgetWithText(Tab, 'Three'));

    expect(firstTab.preferredSize, const Size.fromHeight(46.0));
    expect(secondTab.preferredSize, const Size.fromHeight(46.0));
    expect(thirdTab.preferredSize, const Size.fromHeight(72.0));
  });

  testWidgets('TabBar preferredSize gives correct value when there are both icon and text in tabs', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(
      home: DefaultTabController(
        length: 5,
        child: Scaffold(
          appBar: AppBar(
            bottom: const TabBar(
              tabs: <Widget>[
                Tab(text: 'car'),
                Tab(text: 'transit'),
                Tab(text: 'bike'),
                Tab(text: 'boat', icon: Icon(Icons.message)),
                Tab(text: 'bus'),
              ],
            ),
            title: const Text('Tabs Test'),
          ),
        ),
      ),
    ));

    final TabBar tabBar = tester.widget(find.widgetWithText(TabBar, 'car'));

    expect(tabBar.preferredSize, const Size.fromHeight(74.0));
  });

  testWidgets('TabBar preferredSize gives correct value when there is only icon or text in tabs', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(
      home: DefaultTabController(
        length: 5,
        child: Scaffold(
          appBar: AppBar(
            bottom: const TabBar(
              tabs: <Widget>[
                Tab(text: 'car'),
                Tab(icon: Icon(Icons.message)),
                Tab(text: 'bike'),
                Tab(icon: Icon(Icons.chat)),
                Tab(text: 'bus'),
              ],
            ),
            title: const Text('Tabs Test'),
          ),
        ),
      ),
    ));

    final TabBar tabBar = tester.widget(find.widgetWithText(TabBar, 'car'));

    expect(tabBar.preferredSize, const Size.fromHeight(48.0));
  });

  testWidgets('Tabs are given uniform padding in case of few tabs having both text and icon', (WidgetTester tester) async {
    const EdgeInsetsGeometry expectedPaddingAdjusted = EdgeInsets.symmetric(vertical: 13.0, horizontal: 16.0);
    const EdgeInsetsGeometry expectedPaddingDefault = EdgeInsets.symmetric(horizontal: 16.0);

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            bottom: TabBar(
              controller: TabController(length: 3, vsync: const TestVSync()),
              tabs: const <Widget>[
                Tab(text: 'Tab 1', icon: Icon(Icons.plus_one)),
                Tab(text: 'Tab 2'),
                Tab(text: 'Tab 3'),
              ],
            ),
          ),
        ),
      ),
    );

    final Padding tabOne = tester.widget<Padding>(find.widgetWithText(Padding, 'Tab 1').first);
    final Padding tabTwo = tester.widget<Padding>(find.widgetWithText(Padding, 'Tab 2').first);
    final Padding tabThree = tester.widget<Padding>(find.widgetWithText(Padding, 'Tab 3').first);

    expect(tabOne.padding, expectedPaddingDefault);
    expect(tabTwo.padding, expectedPaddingAdjusted);
    expect(tabThree.padding, expectedPaddingAdjusted);
  });

  testWidgets('Tabs are given uniform padding when labelPadding is given', (WidgetTester tester) async {
    const EdgeInsetsGeometry labelPadding = EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0);
    const EdgeInsetsGeometry expectedPaddingAdjusted = EdgeInsets.symmetric(vertical: 23.0, horizontal: 20.0);
    const EdgeInsetsGeometry expectedPaddingDefault = EdgeInsets.symmetric(vertical: 10.0, horizontal: 20.0);

    await tester.pumpWidget(
      MaterialApp(
        home: Scaffold(
          appBar: AppBar(
            bottom: TabBar(
              labelPadding: labelPadding,
              controller: TabController(length: 3, vsync: const TestVSync()),
              tabs: const <Widget>[
                Tab(text: 'Tab 1', icon: Icon(Icons.plus_one)),
                Tab(text: 'Tab 2'),
                Tab(text: 'Tab 3'),
              ],
            ),
          ),
        ),
      ),
    );

    final Padding tabOne = tester.widget<Padding>(find.widgetWithText(Padding, 'Tab 1').first);
    final Padding tabTwo = tester.widget<Padding>(find.widgetWithText(Padding, 'Tab 2').first);
    final Padding tabThree = tester.widget<Padding>(find.widgetWithText(Padding, 'Tab 3').first);

    expect(tabOne.padding, expectedPaddingDefault);
    expect(tabTwo.padding, expectedPaddingAdjusted);
    expect(tabThree.padding, expectedPaddingAdjusted);
  });

  testWidgets('Tabs are given uniform padding TabBarTheme.labelPadding is given', (WidgetTester tester) async {
    const EdgeInsetsGeometry labelPadding = EdgeInsets.symmetric(vertical: 15.0, horizontal: 20);
    const EdgeInsetsGeometry expectedPaddingAdjusted = EdgeInsets.symmetric(vertical: 28.0, horizontal: 20.0);
    const EdgeInsetsGeometry expectedPaddingDefault = EdgeInsets.symmetric(vertical: 15.0, horizontal: 20.0);

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(
          tabBarTheme: const TabBarTheme(labelPadding: labelPadding),
        ),
        home: Scaffold(
          appBar: AppBar(
            bottom: TabBar(
              controller: TabController(length: 3, vsync: const TestVSync()),
              tabs: const <Widget>[
                Tab(text: 'Tab 1', icon: Icon(Icons.plus_one)),
                Tab(text: 'Tab 2'),
                Tab(text: 'Tab 3'),
              ],
            ),
          ),
        ),
      ),
    );

    final Padding tabOne = tester.widget<Padding>(find.widgetWithText(Padding, 'Tab 1').first);
    final Padding tabTwo = tester.widget<Padding>(find.widgetWithText(Padding, 'Tab 2').first);
    final Padding tabThree = tester.widget<Padding>(find.widgetWithText(Padding, 'Tab 3').first);

    expect(tabOne.padding, expectedPaddingDefault);
    expect(tabTwo.padding, expectedPaddingAdjusted);
    expect(tabThree.padding, expectedPaddingAdjusted);
  });

  testWidgets('Change tab bar height', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(
      home: DefaultTabController(
        length: 4,
        child: Scaffold(
          appBar: AppBar(
            bottom: const TabBar(
              tabs: <Widget>[
                Tab(
                  icon: Icon(Icons.check,size: 40),
                  height: 85,
                  child: Text('1 - OK',style: TextStyle(fontSize: 25),),
                ), // icon and child
                Tab(
                  height: 85,
                  child: Text('2 - OK',style: TextStyle(fontSize: 25),),
                ), // child
                Tab(
                  icon: Icon(Icons.done,size: 40),
                  height: 85,
                ), // icon
                Tab(
                  text: '4 - OK',
                  height: 85,
                ), // text
              ],
            ),
          ),
        ),
      ),
    ));
    final Tab firstTab = tester.widget(find.widgetWithIcon(Tab, Icons.check));
    final Tab secTab = tester.widget(find.widgetWithText(Tab, '2 - OK' ));
    final Tab thirdTab = tester.widget(find.widgetWithIcon(Tab, Icons.done));
    final Tab fourthTab = tester.widget(find.widgetWithText(Tab, '4 - OK' ));
    expect(firstTab.preferredSize.height, 85);
    expect(firstTab.height, 85);
    expect(secTab.height, 85);
    expect(thirdTab.height, 85);
    expect(fourthTab.height, 85);
  });

  testWidgets('Change tab bar height 2', (WidgetTester tester) async {
    await tester.pumpWidget(MaterialApp(
      home: DefaultTabController(
        length: 1,
        child: Scaffold(
          appBar: AppBar(
            bottom: const TabBar(
              tabs: <Widget>[
                Tab(
                  icon: Icon(Icons.check,size: 40),
                  text: '1 - OK',
                  height: 85,
                ), // icon and text
              ],
            ),
          ),
        ),
      ),
    ));
    final Tab firstTab = tester.widget(find.widgetWithIcon(Tab, Icons.check));
    expect(firstTab.height, 85);
  });

  testWidgets('Test semantics of TabPageSelector', (WidgetTester tester) async {
    final SemanticsTester semantics = SemanticsTester(tester);

    final TabController controller = TabController(
      vsync: const TestVSync(),
      length: 2,
    );

    await tester.pumpWidget(
      boilerplate(
        child: Column(
          children: <Widget>[
            TabBar(
              controller: controller,
              indicatorWeight: 30.0,
              tabs: const <Widget>[Tab(text: 'TAB1'), Tab(text: 'TAB2')],
            ),
            Flexible(
              child: TabBarView(
                controller: controller,
                children: const <Widget>[Text('PAGE1'), Text('PAGE2')],
              ),
            ),
            Expanded(
              child: TabPageSelector(
                controller: controller
              )
            ),
          ],
        ),
      ),
    );

    final TestSemantics expectedSemantics = TestSemantics.root(
      children: <TestSemantics>[
        TestSemantics.rootChild(
          label: 'Tab 1 of 2',
          id: 1,
          rect: TestSemantics.fullScreen,
          children: <TestSemantics>[
            TestSemantics(
              label: 'TAB1\nTab 1 of 2',
              flags: <SemanticsFlag>[SemanticsFlag.isFocusable, SemanticsFlag.isSelected],
              id: 2,
              rect: TestSemantics.fullScreen,
              actions: 1,
            ),
            TestSemantics(
              label: 'TAB2\nTab 2 of 2',
              flags: <SemanticsFlag>[SemanticsFlag.isFocusable],
              id: 3,
              rect: TestSemantics.fullScreen,
              actions: <SemanticsAction>[SemanticsAction.tap],
            ),
            TestSemantics(
              id: 4,
              rect: TestSemantics.fullScreen,
              children: <TestSemantics>[
                TestSemantics(
                  id: 6,
                  rect: TestSemantics.fullScreen,
                  actions: <SemanticsAction>[SemanticsAction.scrollLeft],
                  children: <TestSemantics>[
                    TestSemantics(
                      id: 5,
                      rect: TestSemantics.fullScreen,
                      label: 'PAGE1'
                    ),
                  ]
                ),
              ],
            ),
          ],
        ),
      ],
    );

    expect(semantics, hasSemantics(expectedSemantics, ignoreRect: true, ignoreTransform: true));

    semantics.dispose();
  });

  testWidgets('Change the TabController should make both TabBar and TabBarView return to the initial index.', (WidgetTester tester) async {
    // This is a regression test for https://github.com/flutter/flutter/issues/93237

    Widget buildFrame(TabController controller, {required bool showLast}) {
      return boilerplate(
        child: Column(
          children: <Widget>[
            TabBar(
              controller: controller,
              tabs: <Tab>[
                const Tab(text: 'one'),
                const Tab(text: 'two'),
                if (showLast) const Tab(text: 'three'),
              ],
            ),
            Flexible(
              child: TabBarView(
                controller: controller,
                children: <Widget>[
                  const Text('PAGE1'),
                  const Text('PAGE2'),
                  if (showLast) const Text('PAGE3'),
                ],
              ),
            ),
          ],
        ),
      );
    }

    final TabController controller1 = TabController(
      vsync: const TestVSync(),
      length: 3,
    );

    final TabController controller2 = TabController(
      vsync: const TestVSync(),
      length: 2,
    );

    final TabController controller3 = TabController(
      vsync: const TestVSync(),
      length: 3,
    );

    await tester.pumpWidget(buildFrame(controller1, showLast: true));
    final PageView pageView = tester.widget(find.byType(PageView));
    final PageController pageController = pageView.controller;
    await tester.tap(find.text('three'));
    await tester.pumpAndSettle();
    expect(controller1.index, 2);
    expect(pageController.page, 2);

    // Change TabController from 3 items to 2.
    await tester.pumpWidget(buildFrame(controller2, showLast: false));
    await tester.pumpAndSettle();
    expect(controller2.index, 0);
    expect(pageController.page, 0);

    // Change TabController from 2 items to 3.
    await tester.pumpWidget(buildFrame(controller3, showLast: true));
    await tester.pumpAndSettle();
    expect(controller3.index, 0);
    expect(pageController.page, 0);

    await tester.tap(find.text('three'));
    await tester.pumpAndSettle();

    expect(controller3.index, 2);
    expect(pageController.page, 2);
  });

  testWidgets('Do not crash when the new TabController.index is longer than the old length.', (WidgetTester tester) async {
    // This is a regression test for https://github.com/flutter/flutter/issues/97441

    Widget buildFrame(TabController controller, {required bool showLast}) {
      return boilerplate(
        child: Column(
          children: <Widget>[
            TabBar(
              controller: controller,
              tabs: <Tab>[
                const Tab(text: 'one'),
                const Tab(text: 'two'),
                if (showLast) const Tab(text: 'three'),
              ],
            ),
            Flexible(
              child: TabBarView(
                controller: controller,
                children: <Widget>[
                  const Text('PAGE1'),
                  const Text('PAGE2'),
                  if (showLast) const Text('PAGE3'),
                ],
              ),
            ),
          ],
        ),
      );
    }

    final TabController controller1 = TabController(
      vsync: const TestVSync(),
      length: 3,
    );

    final TabController controller2 = TabController(
      vsync: const TestVSync(),
      length: 2,
    );

    await tester.pumpWidget(buildFrame(controller1, showLast: true));
    PageView pageView = tester.widget(find.byType(PageView));
    PageController pageController = pageView.controller;
    await tester.tap(find.text('three'));
    await tester.pumpAndSettle();
    expect(controller1.index, 2);
    expect(pageController.page, 2);

    // Change TabController from controller1 to controller2.
    await tester.pumpWidget(buildFrame(controller2, showLast: false));
    await tester.pumpAndSettle();
    pageView = tester.widget(find.byType(PageView));
    pageController = pageView.controller;
    expect(controller2.index, 0);
    expect(pageController.page, 0);

    // Change TabController back to 'controller1' whose index is 2.
    await tester.pumpWidget(buildFrame(controller1, showLast: true));
    await tester.pumpAndSettle();
    pageView = tester.widget(find.byType(PageView));
    pageController = pageView.controller;
    expect(controller1.index, 2);
    expect(pageController.page, 2);
  });

  testWidgets('TabBar InkWell splashFactory and overlayColor', (WidgetTester tester) async {
    const InteractiveInkFeatureFactory splashFactory = NoSplash.splashFactory;
    final MaterialStateProperty<Color?> overlayColor = MaterialStateProperty.resolveWith<Color?>(
      (Set<MaterialState> states) => Colors.transparent,
    );

    // TabBarTheme splashFactory and overlayColor
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData.light().copyWith(
          tabBarTheme: TabBarTheme(
            splashFactory: splashFactory,
            overlayColor: overlayColor,
          )),
        home: DefaultTabController(
          length: 1,
          child: Scaffold(
            appBar: AppBar(
              bottom: TabBar(
                tabs: <Widget>[
                  Container(width: 100, height: 100, color: Colors.green),
                ],
              ),
            ),
          ),
        ),
      ),
    );

    expect(tester.widget<InkWell>(find.byType(InkWell)).splashFactory, splashFactory);
    expect(tester.widget<InkWell>(find.byType(InkWell)).overlayColor, overlayColor);

    // TabBar splashFactory and overlayColor
    await tester.pumpWidget(
      MaterialApp(
        home: DefaultTabController(
          length: 1,
          child: Scaffold(
            appBar: AppBar(
              bottom: TabBar(
                splashFactory: splashFactory,
                overlayColor: overlayColor,
                tabs: <Widget>[
                  Container(width: 100, height: 100, color: Colors.green),
                ],
              ),
            ),
          ),
        ),
      ),
    );
    await tester.pumpAndSettle(); // theme animation
    expect(tester.widget<InkWell>(find.byType(InkWell)).splashFactory, splashFactory);
    expect(tester.widget<InkWell>(find.byType(InkWell)).overlayColor, overlayColor);
  });

  testWidgets('splashBorderRadius is passed to InkWell.borderRadius', (WidgetTester tester) async {
    const Color hoverColor = Color(0xfff44336);
    const double radius = 20;
    await tester.pumpWidget(
      boilerplate(
        child: DefaultTabController(
          length: 1,
          child: TabBar(
            overlayColor: MaterialStateProperty.resolveWith<Color>(
              (Set<MaterialState> states) {
                if (states.contains(MaterialState.hovered)) {
                  return hoverColor;
                }
                return Colors.black54;
              },
            ),
            splashBorderRadius: BorderRadius.circular(radius),
            tabs: const <Widget>[
              Tab(
                child: Text(''),
              ),
            ],
          ),
        ),
      ),
    );
    await tester.pumpAndSettle();
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1);
    await gesture.moveTo(tester.getCenter(find.byType(Tab)));
    await tester.pumpAndSettle();
    final RenderObject object = tester.allRenderObjects.firstWhere((RenderObject element) => element.runtimeType.toString() == '_RenderInkFeatures');
    expect(
      object,
      paints..rrect(
        color: hoverColor,
        rrect: RRect.fromRectAndRadius(
          tester.getRect(find.byType(InkWell)),
          const Radius.circular(radius)
        ),
      ),
    );
    gesture.removePointer();
  });

  testWidgets('Do not crash if the controller and TabBarView are updated at different phases(build and layout) of the same frame', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/104994.
    List<String> tabTextContent = <String>[];

    await tester.pumpWidget(
      MaterialApp(
        home: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return DefaultTabController(
              length: tabTextContent.length,
              child: Scaffold(
                appBar: AppBar(
                  title: const Text('Default TabBar Preview'),
                  bottom: tabTextContent.isNotEmpty
                      ? TabBar(
                    isScrollable: true,
                    tabs: tabTextContent.map((String textContent) => Tab(text: textContent)).toList(),
                  )
                      : null,
                ),
                body: LayoutBuilder(
                  builder: (_, __) {
                    return tabTextContent.isNotEmpty
                      ? TabBarView(
                        children: tabTextContent.map((String textContent) => Tab(text: "$textContent's view")).toList(),
                      )
                      : const Center(child: Text('No tabs'));
                  },
                ),
                bottomNavigationBar: BottomAppBar(
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: <Widget>[
                      IconButton(
                        key: const Key('Add tab'),
                        icon: const Icon(Icons.add),
                        onPressed: () {
                          setState(() {
                            tabTextContent = List<String>.from(tabTextContent)
                              ..add('Tab ${tabTextContent.length + 1}');
                          });
                        },
                      ),
                      IconButton(
                        key: const Key('Delete tab'),
                        icon: const Icon(Icons.delete),
                        onPressed: () {
                          setState(() {
                            tabTextContent = List<String>.from(tabTextContent)
                              ..removeLast();
                          });
                        },
                      ),
                    ],
                  ),
                ),
              ),
            );
          },
        ),
      ),
    );

    // Initializes with zero tabs properly
    expect(find.text('No tabs'), findsOneWidget);
    await tester.tap(find.byKey(const Key('Add tab')));
    await tester.pumpAndSettle();
    expect(find.text('Tab 1'), findsOneWidget);
    expect(find.text("Tab 1's view"), findsOneWidget);

    // Dynamically updates to zero tabs properly
    await tester.tap(find.byKey(const Key('Delete tab')));
    await tester.pumpAndSettle();
    expect(find.text('No tabs'), findsOneWidget);
  });

  testWidgets("Throw if the controller's length mismatch the tabs count", (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: DefaultTabController(
          length: 2,
          child: Scaffold(
            appBar: AppBar(
              bottom: TabBar(
                tabs: <Widget>[
                  Container(width: 100, height: 100, color: Colors.green),
                ],
              ),
            ),
          ),
        ),
      ),
    );

    expect(tester.takeException(), isAssertionError);
  });

  testWidgets("Throw if the controller's length mismatch the TabBarView‘s children count", (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: DefaultTabController(
          length: 1,
          child: Scaffold(
            appBar: AppBar(
              bottom: TabBar(
                tabs: <Widget>[
                  Container(width: 100, height: 100, color: Colors.green),
                ],
              ),
            ),
            body: const TabBarView(
              children: <Widget>[
                Icon(Icons.directions_car),
                Icon(Icons.directions_transit),
                Icon(Icons.directions_bike),
              ],
            ),
          ),
        ),
      ),
    );

    expect(tester.takeException(), isAssertionError);
  });

  testWidgets('Tab has correct selected/unselected hover color', (WidgetTester tester) async {
    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
    final ThemeData theme = ThemeData(useMaterial3: true);
    final List<String> tabs = <String>['A', 'B', 'C'];

    await tester.pumpWidget(Theme(
      data: theme,
      child: buildFrame(tabs: tabs, value: 'C')),
    );

    await tester.pumpAndSettle();
    final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
    expect(
      inkFeatures,
      isNot(paints
        ..rect(
          color: theme.colorScheme.onSurface.withOpacity(0.08),
        ))
    );
    expect(
      inkFeatures,
      isNot(paints
        ..rect(
          color: theme.colorScheme.primary.withOpacity(0.08),
        ))
    );

    // Start hovering unselected tab.
    final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse);
    await gesture.addPointer();
    await gesture.moveTo(tester.getCenter(find.byType(Tab).first));
    await tester.pumpAndSettle();
    expect(
      inkFeatures,
      paints
        ..rect(
          color: theme.colorScheme.onSurface.withOpacity(0.08),
        )
    );

    // Start hovering selected tab.
    await gesture.moveTo(tester.getCenter(find.byType(Tab).last));
    await tester.pumpAndSettle();
    expect(
      inkFeatures,
      paints
        ..rect(
          color: theme.colorScheme.primary.withOpacity(0.08),
        ),
    );
  });

  testWidgets('Tab has correct selected/unselected focus color', (WidgetTester tester) async {
    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
    final ThemeData theme = ThemeData(useMaterial3: true);
    final List<String> tabs = <String>['A', 'B', 'C'];

    await tester.pumpWidget(MaterialApp(
        theme: theme,
        home: buildFrame(tabs: tabs, value: 'B'),
      ),
    );

    await tester.pumpAndSettle();
    final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
    expect(
      inkFeatures,
      isNot(paints
        ..rect(
          color: theme.colorScheme.onSurface.withOpacity(0.12),
        ))
    );
    expect(
      inkFeatures,
      isNot(paints
        ..rect(
          color: theme.colorScheme.primary.withOpacity(0.12),
        ))
    );

    await tester.sendKeyEvent(LogicalKeyboardKey.tab);
    await tester.pumpAndSettle();
    expect(tester.binding.focusManager.primaryFocus?.hasPrimaryFocus, isTrue);
    expect(
      inkFeatures,
      paints
        ..rect(
          color: theme.colorScheme.onSurface.withOpacity(0.12),
        ),
    );

    await tester.sendKeyEvent(LogicalKeyboardKey.tab);
    await tester.pumpAndSettle();
    expect(tester.binding.focusManager.primaryFocus?.hasPrimaryFocus, isTrue);
    expect(
      inkFeatures,
      paints
        ..rect(
          color: theme.colorScheme.primary.withOpacity(0.12),
        ),
    );
  });

  testWidgets('Tab has correct selected/unselected pressed color', (WidgetTester tester) async {
    final ThemeData theme = ThemeData(useMaterial3: true);
    final List<String> tabs = <String>['A', 'B', 'C'];

    await tester.pumpWidget(MaterialApp(
        theme: theme,
        home: buildFrame(tabs: tabs, value: 'B'),
      ),
    );

    await tester.pumpAndSettle();
    final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
    expect(
      inkFeatures,
      isNot(paints
        ..rect(
          color: theme.colorScheme.primary.withOpacity(0.12),
        ))
    );

    // Press unselected tab.
    TestGesture gesture = await tester.startGesture(tester.getCenter(find.text('A')));
    await tester.pumpAndSettle(); // Let the press highlight animation finish.
    expect(
      inkFeatures,
      paints
        ..rect(
          color: theme.colorScheme.primary.withOpacity(0.12),
        ),
    );

    // Release pressed gesture.
    await gesture.up();
    await tester.pumpAndSettle();

    // Press selected tab.
    gesture = await tester.startGesture(tester.getCenter(find.text('B')));
    await tester.pumpAndSettle(); // Let the press highlight animation finish.
    expect(
      inkFeatures,
      paints
        ..rect(
          color: theme.colorScheme.primary.withOpacity(0.12),
        ),
    );
  });

  group('Material 2', () {
    // Tests that are only relevant for Material 2. Once ThemeData.useMaterial3
    // is turned on by default, these tests can be removed.

    testWidgets('TabBar default selected/unselected text style', (WidgetTester tester) async {
      final ThemeData theme = ThemeData();
      final List<String> tabs = <String>['A', 'B', 'C'];

      const String selectedValue = 'A';
      const String unSelectedValue = 'C';
      await tester.pumpWidget(buildFrame(tabs: tabs, value: selectedValue));
      expect(find.text('A'), findsOneWidget);
      expect(find.text('B'), findsOneWidget);
      expect(find.text('C'), findsOneWidget);

      // Test selected label text style.
      expect(tester.renderObject<RenderParagraph>(find.text(selectedValue)).text.style!.fontFamily, 'Roboto');
      expect(tester.renderObject<RenderParagraph>(find.text(selectedValue)).text.style!.fontSize, 14.0);
      expect(tester.renderObject<RenderParagraph>(
        find.text(selectedValue)).text.style!.color,
        theme.primaryTextTheme.bodyLarge!.color,
      );

      // Test unselected label text style.
      expect(tester.renderObject<RenderParagraph>(find.text(unSelectedValue)).text.style!.fontFamily, 'Roboto');
      expect(tester.renderObject<RenderParagraph>(find.text(unSelectedValue)).text.style!.fontSize, 14.0);
      expect(tester.renderObject<RenderParagraph>(
        find.text(unSelectedValue)).text.style!.color,
        theme.primaryTextTheme.bodyLarge!.color!.withAlpha(0xB2) // 70% alpha,
      );
    });

    testWidgets('TabBar default unselectedLabelColor inherits labelColor with 70% opacity', (WidgetTester tester) async {
      // This is a regression test for https://github.com/flutter/flutter/pull/116273
      final List<String> tabs = <String>['A', 'B', 'C'];

      const String selectedValue = 'A';
      const String unSelectedValue = 'C';
      const Color labelColor = Color(0xff0000ff);
      await tester.pumpWidget(
        Theme(
          data: ThemeData(tabBarTheme: const TabBarTheme(labelColor: labelColor)),
          child: buildFrame(tabs: tabs, value: selectedValue),
        ),
      );
      expect(find.text('A'), findsOneWidget);
      expect(find.text('B'), findsOneWidget);
      expect(find.text('C'), findsOneWidget);

      // Test selected label color.
      expect(tester.renderObject<RenderParagraph>(
        find.text(selectedValue)).text.style!.color,
        labelColor,
      );

      // Test unselected label color.
      expect(tester.renderObject<RenderParagraph>(
        find.text(unSelectedValue)).text.style!.color,
        labelColor.withAlpha(0xB2) // 70% alpha,
      );
    });
  });
}

class KeepAliveInk extends StatefulWidget {
  const KeepAliveInk(this.title, {super.key});
  final String title;
  @override
  State<StatefulWidget> createState() {
    return _KeepAliveInkState();
  }
}

class _KeepAliveInkState extends State<KeepAliveInk> with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Ink(
      child: Text(widget.title),
    );
  }

  @override
  bool get wantKeepAlive => true;
}

class TabBarDemo extends StatelessWidget {
  const TabBarDemo({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: DefaultTabController(
        length: 3,
        child: Scaffold(
          appBar: AppBar(
            bottom: const TabBar(
              tabs: <Widget>[
                Tab(icon: Icon(Icons.directions_car)),
                Tab(icon: Icon(Icons.directions_transit)),
                Tab(icon: Icon(Icons.directions_bike)),
              ],
            ),
            title: const Text('Tabs Demo'),
          ),
          body: const TabBarView(
            children: <Widget>[
              Icon(Icons.directions_car),
              Icon(Icons.directions_transit),
              Icon(Icons.directions_bike),
            ],
          ),
        ),
      ),
    );
  }
}

class MockScrollMetrics extends Fake implements ScrollMetrics { }

class TabBody extends StatefulWidget {
  const TabBody({ super.key, required this.index, required this.log, this.marker = '' });

  final int index;
  final List<String> log;
  final String marker;

  @override
  State<TabBody> createState() => TabBodyState();
}

class TabBodyState extends State<TabBody> {
  @override
  void initState() {
    widget.log.add('init: ${widget.index}');
    super.initState();
  }

  @override
  void didUpdateWidget(TabBody oldWidget) {
    super.didUpdateWidget(oldWidget);
    // To keep the logging straight, widgets must not change their index.
    assert(oldWidget.index == widget.index);
  }

  @override
  void dispose() {
    widget.log.add('dispose: ${widget.index}');
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: widget.marker.isEmpty
        ? Text('${widget.index}')
        : Text('${widget.index}-${widget.marker}'),
    );
  }
}
