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

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

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

class TestIcon extends StatefulWidget {
  const TestIcon({super.key});

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

class TestIconState extends State<TestIcon> {
  late IconThemeData iconTheme;

  @override
  Widget build(BuildContext context) {
    iconTheme = IconTheme.of(context);
    return const Icon(Icons.expand_more);
  }
}

class TestText extends StatefulWidget {
  const TestText(this.text, {super.key});

  final String text;

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

class TestTextState extends State<TestText> {
  late TextStyle textStyle;

  @override
  Widget build(BuildContext context) {
    textStyle = DefaultTextStyle.of(context).style;
    return Text(widget.text);
  }
}

void main() {
  const Color dividerColor = Color(0x1f333333);
  const Color foregroundColor = Colors.blueAccent;
  const Color unselectedWidgetColor = Colors.black54;
  const Color headerColor = Colors.black45;

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

  testWidgets('ExpansionTile initial state', (WidgetTester tester) async {
    final Key topKey = UniqueKey();
    final Key tileKey = UniqueKey();
    const Key expandedKey = PageStorageKey<String>('expanded');
    const Key collapsedKey = PageStorageKey<String>('collapsed');
    const Key defaultKey = PageStorageKey<String>('default');

    await tester.pumpWidget(MaterialApp(
      theme: ThemeData(dividerColor: dividerColor),
      home: Material(
        child: SingleChildScrollView(
          child: Column(
            children: <Widget>[
              ListTile(title: const Text('Top'), key: topKey),
              ExpansionTile(
                key: expandedKey,
                initiallyExpanded: true,
                title: const Text('Expanded'),
                backgroundColor: Colors.red,
                children: <Widget>[
                  ListTile(
                    key: tileKey,
                    title: const Text('0'),
                  ),
                ],
              ),
              ExpansionTile(
                key: collapsedKey,
                title: const Text('Collapsed'),
                children: <Widget>[
                  ListTile(
                    key: tileKey,
                    title: const Text('0'),
                  ),
                ],
              ),
              const ExpansionTile(
                key: defaultKey,
                title: Text('Default'),
                children: <Widget>[
                  ListTile(title: Text('0')),
                ],
              ),
            ],
          ),
        ),
      ),
    ));

    double getHeight(Key key) => tester.getSize(find.byKey(key)).height;
    DecoratedBox getDecoratedBox(Key key) => tester.firstWidget(find.descendant(
      of: find.byKey(key),
      matching: find.byType(DecoratedBox),
    ));

    expect(getHeight(topKey), getHeight(expandedKey) - getHeight(tileKey) - 2.0);
    expect(getHeight(topKey), getHeight(collapsedKey) - 2.0);
    expect(getHeight(topKey), getHeight(defaultKey) - 2.0);

    ShapeDecoration expandedContainerDecoration = getDecoratedBox(expandedKey).decoration as ShapeDecoration;
    expect(expandedContainerDecoration.color, Colors.red);
    expect((expandedContainerDecoration.shape as Border).top.color, dividerColor);
    expect((expandedContainerDecoration.shape as Border).bottom.color, dividerColor);

    ShapeDecoration collapsedContainerDecoration = getDecoratedBox(collapsedKey).decoration as ShapeDecoration;
    expect(collapsedContainerDecoration.color, Colors.transparent);
    expect((collapsedContainerDecoration.shape as Border).top.color, Colors.transparent);
    expect((collapsedContainerDecoration.shape as Border).bottom.color, Colors.transparent);

    await tester.tap(find.text('Expanded'));
    await tester.tap(find.text('Collapsed'));
    await tester.tap(find.text('Default'));

    await tester.pump();

    // Pump to the middle of the animation for expansion.
    await tester.pump(const Duration(milliseconds: 100));
    final ShapeDecoration collapsingContainerDecoration = getDecoratedBox(collapsedKey).decoration as ShapeDecoration;
    expect(collapsingContainerDecoration.color, Colors.transparent);
    expect((collapsingContainerDecoration.shape as Border).top.color, const Color(0x15222222));
    expect((collapsingContainerDecoration.shape as Border).bottom.color, const Color(0x15222222));

    // Pump all the way to the end now.
    await tester.pump(const Duration(seconds: 1));

    expect(getHeight(topKey), getHeight(expandedKey) - 2.0);
    expect(getHeight(topKey), getHeight(collapsedKey) - getHeight(tileKey) - 2.0);
    expect(getHeight(topKey), getHeight(defaultKey) - getHeight(tileKey) - 2.0);

    // Expanded should be collapsed now.
    expandedContainerDecoration = getDecoratedBox(expandedKey).decoration as ShapeDecoration;
    expect(expandedContainerDecoration.color, Colors.transparent);
    expect((expandedContainerDecoration.shape as Border).top.color, Colors.transparent);
    expect((expandedContainerDecoration.shape as Border).bottom.color, Colors.transparent);

    // Collapsed should be expanded now.
    collapsedContainerDecoration = getDecoratedBox(collapsedKey).decoration as ShapeDecoration;
    expect(collapsedContainerDecoration.color, Colors.transparent);
    expect((collapsedContainerDecoration.shape as Border).top.color, dividerColor);
    expect((collapsedContainerDecoration.shape as Border).bottom.color, dividerColor);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));

  testWidgets('ExpansionTile Theme dependencies', (WidgetTester tester) async {
    final Key expandedTitleKey = UniqueKey();
    final Key collapsedTitleKey = UniqueKey();
    final Key expandedIconKey = UniqueKey();
    final Key collapsedIconKey = UniqueKey();

    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(
          useMaterial3: false,
          colorScheme: ColorScheme.fromSwatch().copyWith(primary: foregroundColor),
          unselectedWidgetColor: unselectedWidgetColor,
          textTheme: const TextTheme(titleMedium: TextStyle(color: headerColor)),
        ),
        home: Material(
          child: SingleChildScrollView(
            child: Column(
              children: <Widget>[
                const ListTile(title: Text('Top')),
                ExpansionTile(
                  initiallyExpanded: true,
                  title: TestText('Expanded', key: expandedTitleKey),
                  backgroundColor: Colors.red,
                  trailing: TestIcon(key: expandedIconKey),
                  children: const <Widget>[ListTile(title: Text('0'))],
                ),
                ExpansionTile(
                  title: TestText('Collapsed', key: collapsedTitleKey),
                  trailing: TestIcon(key: collapsedIconKey),
                  children: const <Widget>[ListTile(title: Text('0'))],
                ),
              ],
            ),
          ),
        ),
      ),
    );

    Color iconColor(Key key) => tester.state<TestIconState>(find.byKey(key)).iconTheme.color!;
    Color textColor(Key key) => tester.state<TestTextState>(find.byKey(key)).textStyle.color!;

    expect(textColor(expandedTitleKey), foregroundColor);
    expect(textColor(collapsedTitleKey), headerColor);
    expect(iconColor(expandedIconKey), foregroundColor);
    expect(iconColor(collapsedIconKey), unselectedWidgetColor);

    // Tap both tiles to change their state: collapse and extend respectively
    await tester.tap(find.text('Expanded'));
    await tester.tap(find.text('Collapsed'));
    await tester.pump();
    await tester.pump(const Duration(seconds: 1));
    await tester.pump(const Duration(seconds: 1));

    expect(textColor(expandedTitleKey), headerColor);
    expect(textColor(collapsedTitleKey), foregroundColor);
    expect(iconColor(expandedIconKey), unselectedWidgetColor);
    expect(iconColor(collapsedIconKey), foregroundColor);
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS,  TargetPlatform.macOS }));

  testWidgets('ExpansionTile subtitle',
  // TODO(polina-c): remove when fixed https://github.com/flutter/flutter/issues/145600 [leak-tracking-opt-in]
  experimentalLeakTesting: LeakTesting.settings.withTracked(classes: const <String>['CurvedAnimation']),
  (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Scaffold(
          body: ExpansionTile(
            title: Text('Title'),
            subtitle: Text('Subtitle'),
            children: <Widget>[ListTile(title: Text('0'))],
          ),
        ),
      ),
    );

    expect(find.text('Subtitle'), findsOneWidget);
  });

  testWidgets('ExpansionTile maintainState', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        theme: ThemeData(
          platform: TargetPlatform.iOS,
          dividerColor: dividerColor,
        ),
        home: const Material(
          child: SingleChildScrollView(
            child: Column(
              children: <Widget>[
                ExpansionTile(
                  title: Text('Tile 1'),
                  maintainState: true,
                  children: <Widget>[
                    Text('Maintaining State'),
                  ],
                ),
                ExpansionTile(
                  title: Text('Title 2'),
                  children: <Widget>[
                    Text('Discarding State'),
                  ],
                ),
              ],
            ),
          ),
        ),
      ),
    );

     // This text should be offstage while ExpansionTile collapsed
     expect(find.text('Maintaining State', skipOffstage: false), findsOneWidget);
     expect(find.text('Maintaining State'), findsNothing);
     // This text shouldn't be there while ExpansionTile collapsed
     expect(find.text('Discarding State'), findsNothing);
   });

  testWidgets('ExpansionTile padding test', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(
      home: Material(
        child: Center(
          child: ExpansionTile(
            title: Text('Hello'),
            tilePadding: EdgeInsets.fromLTRB(8, 12, 4, 10),
          ),
        ),
      ),
    ));

    final Rect titleRect = tester.getRect(find.text('Hello'));
    final Rect trailingRect = tester.getRect(find.byIcon(Icons.expand_more));
    final Rect listTileRect = tester.getRect(find.byType(ListTile));
    final Rect tallerWidget = titleRect.height > trailingRect.height ? titleRect : trailingRect;

    // Check the positions of title and trailing Widgets, after padding is applied.
    expect(listTileRect.left, titleRect.left - 8);
    expect(listTileRect.right, trailingRect.right + 4);

    // Calculate the remaining height of ListTile from the default height.
    final double remainingHeight = 56 - tallerWidget.height;
    expect(listTileRect.top, tallerWidget.top - remainingHeight / 2 - 12);
    expect(listTileRect.bottom, tallerWidget.bottom + remainingHeight / 2 + 10);
  });

  testWidgets('ExpansionTile expandedAlignment test', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(
      home: Material(
        child: Center(
          child: ExpansionTile(
            title: Text('title'),
            expandedAlignment: Alignment.centerLeft,
            children: <Widget>[
              SizedBox(height: 100, width: 100),
              SizedBox(height: 100, width: 80),
            ],
          ),
        ),
      ),
    ));

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

    final Rect columnRect = tester.getRect(find.byType(Column).last);

    // The expandedAlignment is used to define the alignment of the Column widget in
    // expanded tile, not the alignment of the children inside the Column.
    expect(columnRect.left, 0.0);
    // The width of the Column is the width of the largest child. The largest width
    // being 100.0, the offset of the right edge of Column from X-axis should be 100.0.
    expect(columnRect.right, 100.0);
  });

  testWidgets('ExpansionTile expandedCrossAxisAlignment test', (WidgetTester tester) async {
    const Key child0Key = Key('child0');
    const Key child1Key = Key('child1');

    await tester.pumpWidget(const MaterialApp(
      home: Material(
        child: Center(
          child: ExpansionTile(
            title: Text('title'),
            // Set the column's alignment to Alignment.centerRight to test CrossAxisAlignment
            // of children widgets. This helps distinguish the effect of expandedAlignment
            // and expandedCrossAxisAlignment later in the test.
            expandedAlignment: Alignment.centerRight,
            expandedCrossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              SizedBox(height: 100, width: 100, key: child0Key),
              SizedBox(height: 100, width: 80, key: child1Key),
            ],
          ),
        ),
      ),
    ));

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

    final Rect columnRect = tester.getRect(find.byType(Column).last);
    final Rect child0Rect = tester.getRect(find.byKey(child0Key));
    final Rect child1Rect = tester.getRect(find.byKey(child1Key));

    // Since expandedAlignment is set to Alignment.centerRight, the column of children
    // should be aligned to the center right of the expanded tile. This provides confirmation
    // that the expandedCrossAxisAlignment.start is 700.0, where columnRect.left is.
    expect(columnRect.right, 800.0);
    // The width of the Column is the width of the largest child. The largest width
    // being 100.0, the offset of the left edge of Column from X-axis should be 700.0.
    expect(columnRect.left, 700.0);

    // Considering the value of expandedCrossAxisAlignment is CrossAxisAlignment.start,
    // the offset of the left edge of both the children from X-axis should be 700.0.
    expect(child0Rect.left, 700.0);
    expect(child1Rect.left, 700.0);
  });

  testWidgets('CrossAxisAlignment.baseline is not allowed', (WidgetTester tester) async {
    expect(
      () {
        MaterialApp(
          home: Material(
            child: ExpansionTile(
              initiallyExpanded: true,
              title: const Text('title'),
              expandedCrossAxisAlignment: CrossAxisAlignment.baseline,
            ),
          ),
        );
      },
      throwsA(isA<AssertionError>().having((AssertionError error) => error.toString(), '.toString()', contains(
        'CrossAxisAlignment.baseline is not supported since the expanded'
        ' children are aligned in a column, not a row. Try to use another constant.',
      ))),
    );
  });

  testWidgets('expandedCrossAxisAlignment and expandedAlignment default values', (WidgetTester tester) async {
    const Key child1Key = Key('child1');

    await tester.pumpWidget(const MaterialApp(
      home: Material(
        child: Center(
          child: ExpansionTile(
            title: Text('title'),
            children: <Widget>[
              SizedBox(height: 100, width: 100),
              SizedBox(height: 100, width: 80, key: child1Key),
            ],
          ),
        ),
      ),
    ));


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

    final Rect columnRect = tester.getRect(find.byType(Column).last);
    final Rect child1Rect = tester.getRect(find.byKey(child1Key));

    // The default viewport size is Size(800, 600).
    // By default the value of extendedAlignment is Alignment.center, hence the offset
    // of left and right edges from x axis should be equal.
    expect(columnRect.left, 800 - columnRect.right);

    // By default the value of extendedCrossAxisAlignment is CrossAxisAlignment.center, hence
    // the offset of left and right edges from Column should be equal.
    expect(child1Rect.left - columnRect.left, columnRect.right - child1Rect.right);

  });

  testWidgets('childrenPadding default value', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: Center(
            child: ExpansionTile(
              title: Text('title'),
              children: <Widget>[
                SizedBox(height: 100, width: 100),
              ],
            ),
          ),
        ),
      ),
    );

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

    final Rect columnRect = tester.getRect(find.byType(Column).last);
    final Rect paddingRect = tester.getRect(find.byType(Padding).last);

    // By default, the value of childrenPadding is EdgeInsets.zero, hence offset
    // of all the edges from x-axis and y-axis should be equal for Padding and Column.
    expect(columnRect.top, paddingRect.top);
    expect(columnRect.left, paddingRect.left);
    expect(columnRect.right, paddingRect.right);
    expect(columnRect.bottom, paddingRect.bottom);
  });

  testWidgets('ExpansionTile childrenPadding test', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: Center(
            child: ExpansionTile(
              title: Text('title'),
              childrenPadding: EdgeInsets.fromLTRB(10, 8, 12, 4),
              children: <Widget>[
                SizedBox(height: 100, width: 100),
              ],
            ),
          ),
        ),
      ),
    );

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

    final Rect columnRect = tester.getRect(find.byType(Column).last);
    final Rect paddingRect = tester.getRect(find.byType(Padding).last);

    // Check the offset of all the edges from x-axis and y-axis after childrenPadding
    // is applied.
    expect(columnRect.left, paddingRect.left + 10);
    expect(columnRect.top, paddingRect.top + 8);
    expect(columnRect.right, paddingRect.right - 12);
    expect(columnRect.bottom, paddingRect.bottom - 4);
  });

  testWidgets('ExpansionTile.collapsedBackgroundColor', (WidgetTester tester) async {
    const Key expansionTileKey = Key('expansionTileKey');
    const Color backgroundColor = Colors.red;
    const Color collapsedBackgroundColor = Colors.brown;

    await tester.pumpWidget(const MaterialApp(
      home: Material(
        child: ExpansionTile(
          key: expansionTileKey,
          title: Text('Title'),
          backgroundColor: backgroundColor,
          collapsedBackgroundColor: collapsedBackgroundColor,
          children: <Widget>[
            SizedBox(height: 100, width: 100),
          ],
        ),
      ),
    ));

    ShapeDecoration shapeDecoration =  tester.firstWidget<DecoratedBox>(find.descendant(
      of: find.byKey(expansionTileKey),
      matching: find.byType(DecoratedBox),
    )).decoration as ShapeDecoration;

    expect(shapeDecoration.color, collapsedBackgroundColor);

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

    shapeDecoration =  tester.firstWidget<DecoratedBox>(find.descendant(
      of: find.byKey(expansionTileKey),
      matching: find.byType(DecoratedBox),
    )).decoration as ShapeDecoration;

    expect(shapeDecoration.color, backgroundColor);
  });

  testWidgets('ExpansionTile default iconColor, textColor', (WidgetTester tester) async {
    final ThemeData theme = ThemeData(useMaterial3: true);

    await tester.pumpWidget(MaterialApp(
      theme: theme,
      home: const Material(
        child: ExpansionTile(
          title: TestText('title'),
          trailing: TestIcon(),
          children: <Widget>[
            SizedBox(height: 100, width: 100),
          ],
        ),
      ),
    ));

    Color getIconColor() => tester.state<TestIconState>(find.byType(TestIcon)).iconTheme.color!;
    Color getTextColor() => tester.state<TestTextState>(find.byType(TestText)).textStyle.color!;

    expect(getIconColor(), theme.colorScheme.onSurfaceVariant);
    expect(getTextColor(), theme.colorScheme.onSurface);

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

    expect(getIconColor(), theme.colorScheme.primary);
    expect(getTextColor(), theme.colorScheme.onSurface);
  });

  testWidgets('ExpansionTile iconColor, textColor', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/pull/78281

    const Color iconColor = Color(0xff00ff00);
    const Color collapsedIconColor = Color(0xff0000ff);
    const Color textColor = Color(0xff00ffff);
    const Color collapsedTextColor = Color(0xffff00ff);

    await tester.pumpWidget(const MaterialApp(
      home: Material(
        child: ExpansionTile(
          iconColor: iconColor,
          collapsedIconColor: collapsedIconColor,
          textColor: textColor,
          collapsedTextColor: collapsedTextColor,
          title: TestText('title'),
          trailing: TestIcon(),
          children: <Widget>[
            SizedBox(height: 100, width: 100),
          ],
        ),
      ),
    ));

    Color getIconColor() => tester.state<TestIconState>(find.byType(TestIcon)).iconTheme.color!;
    Color getTextColor() => tester.state<TestTextState>(find.byType(TestText)).textStyle.color!;

    expect(getIconColor(), collapsedIconColor);
    expect(getTextColor(), collapsedTextColor);

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

    expect(getIconColor(), iconColor);
    expect(getTextColor(), textColor);
  });

  testWidgets('ExpansionTile Border', (WidgetTester tester) async {
    const Key expansionTileKey = PageStorageKey<String>('expansionTile');

    const Border collapsedShape = Border(
      top: BorderSide(color: Colors.blue),
      bottom: BorderSide(color: Colors.green)
    );
    final Border shape = Border.all(color: Colors.red);

    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: ExpansionTile(
          key: expansionTileKey,
          title: const Text('ExpansionTile'),
          collapsedShape: collapsedShape,
          shape: shape,
          children: const <Widget>[
            ListTile(
              title: Text('0'),
            ),
          ],
        ),
      ),
    ));

    // When a custom shape is provided, ExpansionTile will use the
    // Material widget to draw the shape and background color
    // instead of a Container.
    Material material = getMaterial(tester);
    // ExpansionTile should be collapsed initially.
    expect(material.shape, collapsedShape);
    expect(material.clipBehavior, Clip.antiAlias);

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

    // ExpansionTile should be Expanded now.
    material = getMaterial(tester);
    expect(material.shape, shape);
    expect(material.clipBehavior, Clip.antiAlias);
  });

  testWidgets('ExpansionTile platform controlAffinity test', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(
      home: Material(
        child: ExpansionTile(
          title: Text('Title'),
        ),
      ),
    ));

    final ListTile listTile = tester.widget(find.byType(ListTile));
    expect(listTile.leading, isNull);
    expect(listTile.trailing.runtimeType, RotationTransition);
  });

  testWidgets('ExpansionTile trailing controlAffinity test', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(
      home: Material(
        child: ExpansionTile(
          title: Text('Title'),
          controlAffinity: ListTileControlAffinity.trailing,
        ),
      ),
    ));

    final ListTile listTile = tester.widget(find.byType(ListTile));
    expect(listTile.leading, isNull);
    expect(listTile.trailing.runtimeType, RotationTransition);
  });

  testWidgets('ExpansionTile leading controlAffinity test', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(
      home: Material(
        child: ExpansionTile(
          title: Text('Title'),
          controlAffinity: ListTileControlAffinity.leading,
        ),
      ),
    ));

    final ListTile listTile = tester.widget(find.byType(ListTile));
    expect(listTile.leading.runtimeType, RotationTransition);
    expect(listTile.trailing, isNull);
  });

  testWidgets('ExpansionTile override rotating icon test', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(
      home: Material(
        child: ExpansionTile(
          title: Text('Title'),
          leading: Icon(Icons.info),
          controlAffinity: ListTileControlAffinity.leading,
        ),
      ),
    ));

    final ListTile listTile = tester.widget(find.byType(ListTile));
    expect(listTile.leading.runtimeType, Icon);
    expect(listTile.trailing, isNull);
  });

  testWidgets('Nested ListTile Semantics', (WidgetTester tester) async {
    tester.binding.focusManager.highlightStrategy = FocusHighlightStrategy.alwaysTraditional;
    final SemanticsHandle handle = tester.ensureSemantics();

    await tester.pumpWidget(const MaterialApp(
      home: Material(
        child: Column(
          children: <Widget>[
            ExpansionTile(
              title: Text('First Expansion Tile'),
            ),
            ExpansionTile(
              initiallyExpanded: true,
              title: Text('Second Expansion Tile'),
            ),
          ],
        ),
      ),
    ));

    await tester.pumpAndSettle();

    // Focus the first ExpansionTile.
    tester.binding.focusManager.primaryFocus?.nextFocus();
    await tester.pumpAndSettle();

    // The first list tile is focused.
    expect(
      tester.getSemantics(find.byType(ListTile).first),
      matchesSemantics(
        hasTapAction: true,
        hasEnabledState: true,
        isEnabled: true,
        isFocused: true,
        isFocusable: true,
        label: 'First Expansion Tile',
        textDirection: TextDirection.ltr,
      ),
    );

    // The first list tile is not focused.
    expect(
      tester.getSemantics(find.byType(ListTile).last),
      matchesSemantics(
        hasTapAction: true,
        hasEnabledState: true,
        isEnabled: true,
        isFocusable: true,
        label: 'Second Expansion Tile',
        textDirection: TextDirection.ltr,
      ),
    );
    handle.dispose();
  });

  testWidgets('ExpansionTile Semantics announcement', (WidgetTester tester) async {
    final SemanticsHandle handle = tester.ensureSemantics();
    const DefaultMaterialLocalizations localizations = DefaultMaterialLocalizations();
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: ExpansionTile(
            title: Text('Title'),
            children: <Widget>[
              SizedBox(height: 100, width: 100),
            ],
          ),
        ),
      ),
    );

    // There is no semantics announcement without tap action.
    expect(tester.takeAnnouncements(), isEmpty);

    // Tap the title to expand ExpansionTile.
    await tester.tap(find.text('Title'));
    await tester.pumpAndSettle();

    // The announcement should be the opposite of the current state.
    // The ExpansionTile is expanded, so the announcement should be
    // "Expanded".
    expect(tester.takeAnnouncements().first.message, localizations.collapsedHint);

    // Tap the title to collapse ExpansionTile.
    await tester.tap(find.text('Title'));
    await tester.pumpAndSettle();

    // The announcement should be the opposite of the current state.
    // The ExpansionTile is collapsed, so the announcement should be
    // "Collapsed".
    expect(tester.takeAnnouncements().first.message, localizations.expandedHint);
    handle.dispose();
  }, skip: defaultTargetPlatform == TargetPlatform.iOS); // [intended] https://github.com/flutter/flutter/issues/122101.

  // This is a regression test for https://github.com/flutter/flutter/issues/132264.
  testWidgets('ExpansionTile Semantics announcement is delayed on iOS', (WidgetTester tester) async {
    final SemanticsHandle handle = tester.ensureSemantics();
    const DefaultMaterialLocalizations localizations = DefaultMaterialLocalizations();
    await tester.pumpWidget(
      const MaterialApp(
        home: Material(
          child: ExpansionTile(
            title: Text('Title'),
            children: <Widget>[
              SizedBox(height: 100, width: 100),
            ],
          ),
        ),
      ),
    );

    // There is no semantics announcement without tap action.
    expect(tester.takeAnnouncements(), isEmpty);

    // Tap the title to expand ExpansionTile.
    await tester.tap(find.text('Title'));
    await tester.pump(const Duration(seconds: 1)); // Wait for the announcement to be made.

    expect(tester.takeAnnouncements().first.message, localizations.collapsedHint);

    // Tap the title to collapse ExpansionTile.
    await tester.tap(find.text('Title'));
    await tester.pump(const Duration(seconds: 1)); // Wait for the announcement to be made.

    expect(tester.takeAnnouncements().first.message, localizations.expandedHint);
    handle.dispose();
  }, variant: TargetPlatformVariant.only(TargetPlatform.iOS));

  testWidgets('Semantics with the onTapHint is an ancestor of ListTile', (WidgetTester tester) async {
    // This is a regression test for https://github.com/flutter/flutter/pull/121624
    final SemanticsHandle handle = tester.ensureSemantics();
    const DefaultMaterialLocalizations localizations = DefaultMaterialLocalizations();

    await tester.pumpWidget(const MaterialApp(
      home: Material(
        child: Column(
          children: <Widget>[
            ExpansionTile(
              title: Text('First Expansion Tile'),
            ),
            ExpansionTile(
              initiallyExpanded: true,
              title: Text('Second Expansion Tile'),
            ),
          ],
        ),
      ),
    ));

    SemanticsNode semantics = tester.getSemantics(
      find.ancestor(
        of: find.byType(ListTile).first,
        matching: find.byType(Semantics),
      ).first,
    );
    expect(semantics, isNotNull);
    // The onTapHint is passed to semantics properties's hintOverrides.
    expect(semantics.hintOverrides, isNotNull);
    // The hint should be the opposite of the current state.
    // The first ExpansionTile is collapsed, so the hint should be
    // "double tap to expand".
    expect(semantics.hintOverrides!.onTapHint, localizations.expansionTileCollapsedTapHint);

    semantics = tester.getSemantics(
      find.ancestor(
        of: find.byType(ListTile).last,
        matching: find.byType(Semantics),
      ).first,
    );

    expect(semantics, isNotNull);
    // The onTapHint is passed to semantics properties's hintOverrides.
    expect(semantics.hintOverrides, isNotNull);
    // The hint should be the opposite of the current state.
    // The second ExpansionTile is expanded, so the hint should be
    // "double tap to collapse".
    expect(semantics.hintOverrides!.onTapHint, localizations.expansionTileExpandedTapHint);
    handle.dispose();
  });

  testWidgets('Semantics hint for iOS and macOS', (WidgetTester tester) async {
    final SemanticsHandle handle = tester.ensureSemantics();
    const DefaultMaterialLocalizations localizations = DefaultMaterialLocalizations();

    await tester.pumpWidget(const MaterialApp(
      home: Material(
        child: Column(
          children: <Widget>[
            ExpansionTile(
              title: Text('First Expansion Tile'),
            ),
            ExpansionTile(
              initiallyExpanded: true,
              title: Text('Second Expansion Tile'),
            ),
          ],
        ),
      ),
    ));

    SemanticsNode semantics = tester.getSemantics(
      find.ancestor(
        of: find.byType(ListTile).first,
        matching: find.byType(Semantics),
      ).first,
    );

    expect(semantics, isNotNull);
    expect(
      semantics.hint,
      '${localizations.expandedHint}\n ${localizations.expansionTileCollapsedHint}',
    );

    semantics = tester.getSemantics(
      find.ancestor(
        of: find.byType(ListTile).last,
        matching: find.byType(Semantics),
      ).first,
    );

    expect(semantics, isNotNull);
    expect(
      semantics.hint,
      '${localizations.collapsedHint}\n ${localizations.expansionTileExpandedHint}',
    );
    handle.dispose();
  }, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));

  testWidgets('Collapsed ExpansionTile properties can be updated with setState', (WidgetTester tester) async {
    const Key expansionTileKey = Key('expansionTileKey');
    ShapeBorder collapsedShape = const RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(4)),
    );
    Color collapsedTextColor = const Color(0xffffffff);
    Color collapsedBackgroundColor = const Color(0xffff0000);
    Color collapsedIconColor = const Color(0xffffffff);

    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return Column(
              children: <Widget>[
                ExpansionTile(
                  key: expansionTileKey,
                  collapsedShape: collapsedShape,
                  collapsedTextColor: collapsedTextColor,
                  collapsedBackgroundColor: collapsedBackgroundColor,
                  collapsedIconColor: collapsedIconColor,
                  title: const TestText('title'),
                  trailing: const TestIcon(),
                  children: const <Widget>[
                    SizedBox(height: 100, width: 100),
                  ],
                ),
                // This button is used to update the ExpansionTile properties.
                FilledButton(
                  onPressed: () {
                    setState(() {
                      collapsedShape = const RoundedRectangleBorder(
                        borderRadius: BorderRadius.all(Radius.circular(16)),
                      );
                      collapsedTextColor = const Color(0xff000000);
                      collapsedBackgroundColor = const Color(0xffffff00);
                      collapsedIconColor = const Color(0xff000000);
                    });
                  },
                  child: const Text('Update collapsed properties'),
                ),
              ],
            );
          }
        ),
      ),
    ));

    // When a custom shape is provided, ExpansionTile will use the
    // Material widget to draw the shape and background color
    // instead of a Container.
    Material material = getMaterial(tester);

    // Test initial ExpansionTile properties.
    expect(material.shape, const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4))));
    expect(material.color, const Color(0xffff0000));
    expect(material.clipBehavior, Clip.antiAlias);
    expect(tester.state<TestIconState>(find.byType(TestIcon)).iconTheme.color, const Color(0xffffffff));
    expect(tester.state<TestTextState>(find.byType(TestText)).textStyle.color, const Color(0xffffffff));

    // Tap the button to update the ExpansionTile properties.
    await tester.tap(find.text('Update collapsed properties'));
    await tester.pumpAndSettle();

    material = getMaterial(tester);

    // Test updated ExpansionTile properties.
    expect(material.shape, const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(16))));
    expect(material.color, const Color(0xffffff00));
    expect(material.clipBehavior, Clip.antiAlias);
    expect(tester.state<TestIconState>(find.byType(TestIcon)).iconTheme.color, const Color(0xff000000));
    expect(tester.state<TestTextState>(find.byType(TestText)).textStyle.color, const Color(0xff000000));
  });

  testWidgets('Expanded ExpansionTile properties can be updated with setState', (WidgetTester tester) async {
    const Key expansionTileKey = Key('expansionTileKey');
    ShapeBorder shape = const RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(12)),
    );
    Color textColor = const Color(0xff00ffff);
    Color backgroundColor = const Color(0xff0000ff);
    Color iconColor = const Color(0xff00ffff);

    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return Column(
              children: <Widget>[
                ExpansionTile(
                  key: expansionTileKey,
                  shape: shape,
                  textColor: textColor,
                  backgroundColor: backgroundColor,
                  iconColor: iconColor,
                  title: const TestText('title'),
                  trailing: const TestIcon(),
                  children: const <Widget>[
                    SizedBox(height: 100, width: 100),
                  ],
                ),
                // This button is used to update the ExpansionTile properties.
                FilledButton(
                  onPressed: () {
                    setState(() {
                      shape = const RoundedRectangleBorder(
                        borderRadius: BorderRadius.all(Radius.circular(6)),
                      );
                      textColor = const Color(0xffffffff);
                      backgroundColor = const Color(0xff123456);
                      iconColor = const Color(0xffffffff);
                    });
                  },
                  child: const Text('Update collapsed properties'),
                ),
              ],
            );
          }
        ),
      ),
    ));

    // Tap to expand the ExpansionTile.
    await tester.tap(find.text('title'));
    await tester.pumpAndSettle();

    // When a custom shape is provided, ExpansionTile will use the
    // Material widget to draw the shape and background color
    // instead of a Container.
    Material material = getMaterial(tester);

    // Test initial ExpansionTile properties.
    expect(material.shape, const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12))));
    expect(material.color, const Color(0xff0000ff));
    expect(material.clipBehavior, Clip.antiAlias);
    expect(tester.state<TestIconState>(find.byType(TestIcon)).iconTheme.color, const Color(0xff00ffff));
    expect(tester.state<TestTextState>(find.byType(TestText)).textStyle.color, const Color(0xff00ffff));

    // Tap the button to update the ExpansionTile properties.
    await tester.tap(find.text('Update collapsed properties'));
    await tester.pumpAndSettle();

    material = getMaterial(tester);
    iconColor = tester.state<TestIconState>(find.byType(TestIcon)).iconTheme.color!;
    textColor = tester.state<TestTextState>(find.byType(TestText)).textStyle.color!;

    // Test updated ExpansionTile properties.
    expect(material.shape, const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(6))));
    expect(material.color, const Color(0xff123456));
    expect(material.clipBehavior, Clip.antiAlias);
    expect(tester.state<TestIconState>(find.byType(TestIcon)).iconTheme.color, const Color(0xffffffff));
    expect(tester.state<TestTextState>(find.byType(TestText)).textStyle.color, const Color(0xffffffff));
  });

  testWidgets('Override ExpansionTile animation using AnimationStyle', (WidgetTester tester) async {
    const Key expansionTileKey = Key('expansionTileKey');

    Widget buildExpansionTile({ AnimationStyle? animationStyle }) {
      return MaterialApp(
        home: Material(
          child: Center(
            child: ExpansionTile(
              key: expansionTileKey,
              expansionAnimationStyle: animationStyle,
              title: const TestText('title'),
              children: const <Widget>[
                SizedBox(height: 100, width: 100),
              ],
            ),
          ),
        ),
      );
    }

    await tester.pumpWidget(buildExpansionTile());

    double getHeight(Key key) => tester.getSize(find.byKey(key)).height;

    // Test initial ExpansionTile height.
    expect(getHeight(expansionTileKey), 58.0);

    // Test the default expansion animation.
    await tester.tap(find.text('title'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 50)); // Advance the animation by 1/4 of its duration.

    expect(getHeight(expansionTileKey), closeTo(67.4, 0.1));

    await tester.pump(const Duration(milliseconds: 50)); // Advance the animation by 2/4 of its duration.

    expect(getHeight(expansionTileKey), closeTo(89.6, 0.1));

    await tester.pumpAndSettle(); // Advance the animation to the end.

    expect(getHeight(expansionTileKey), 158.0);

    // Tap to collapse the ExpansionTile.
    await tester.tap(find.text('title'));
    await tester.pumpAndSettle();

    // Override the animation duration.
    await tester.pumpWidget(buildExpansionTile(animationStyle: AnimationStyle(duration: const Duration(milliseconds: 800))));
    await tester.pumpAndSettle();

    // Test the overridden animation duration.
    await tester.tap(find.text('title'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 200)); // Advance the animation by 1/4 of its duration.

    expect(getHeight(expansionTileKey), closeTo(67.4, 0.1));

    await tester.pump(const Duration(milliseconds: 200)); // Advance the animation by 2/4 of its duration.

    expect(getHeight(expansionTileKey), closeTo(89.6, 0.1));

    await tester.pumpAndSettle(); // Advance the animation to the end.

    expect(getHeight(expansionTileKey), 158.0);

    // Tap to collapse the ExpansionTile.
    await tester.tap(find.text('title'));
    await tester.pumpAndSettle();

    // Override the animation curve.
    await tester.pumpWidget(buildExpansionTile(animationStyle: AnimationStyle(
      curve: Easing.emphasizedDecelerate,
      reverseCurve: Easing.emphasizedAccelerate,
    )));
    await tester.pumpAndSettle();

    // Test the overridden animation curve.
    await tester.tap(find.text('title'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 50)); // Advance the animation by 1/4 of its duration.

    expect(getHeight(expansionTileKey), closeTo(141.2, 0.1));

    await tester.pump(const Duration(milliseconds: 50)); // Advance the animation by 2/4 of its duration.

    expect(getHeight(expansionTileKey), closeTo(153, 0.1));

    await tester.pumpAndSettle(); // Advance the animation to the end.

    expect(getHeight(expansionTileKey), 158.0);

    // Test the overridden reverse (collapse) animation curve.
    await tester.tap(find.text('title'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 50)); // Advance the animation by 1/4 of its duration.

    expect(getHeight(expansionTileKey), closeTo(98.6, 0.1));

    await tester.pump(const Duration(milliseconds: 50)); // Advance the animation by 2/4 of its duration.

    expect(getHeight(expansionTileKey), closeTo(73.4, 0.1));

    await tester.pumpAndSettle(); // Advance the animation to the end.

    expect(getHeight(expansionTileKey), 58.0);

    // Test no animation.
    await tester.pumpWidget(buildExpansionTile(animationStyle: AnimationStyle.noAnimation));

    // Tap to expand the ExpansionTile.
    await tester.tap(find.text('title'));
    await tester.pump();

    expect(getHeight(expansionTileKey), 158.0);
  });

  testWidgets('Material3 - ExpansionTile draws Inkwell splash on top of background color', (WidgetTester tester) async {
    const Key expansionTileKey = Key('expansionTileKey');
    const ShapeBorder shape = RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(16)),
    );
    const ShapeBorder collapsedShape = RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(16)),
    );
    const Color collapsedBackgroundColor = Color(0xff00ff00);
    const Color backgroundColor = Color(0xffff0000);

    await tester.pumpWidget(const MaterialApp(
      home: Material(
        child: Center(
          child: Padding(
            padding: EdgeInsets.symmetric(horizontal: 24.0),
            child: ExpansionTile(
              key: expansionTileKey,
              shape: shape,
              collapsedBackgroundColor: collapsedBackgroundColor,
              backgroundColor: backgroundColor,
              collapsedShape: collapsedShape,
              title: TestText('title'),
              trailing: TestIcon(),
              children: <Widget>[
                SizedBox(height: 100, width: 100),
              ],
            ),
          ),
        ),
      ),
    ));

    // Tap and hold the ExpansionTile to trigger ink splash.
    final Offset center = tester.getCenter(find.byKey(expansionTileKey));
    final TestGesture gesture = await tester.startGesture(center);
    await tester.pump(); // Start the splash animation.
    await tester.pump(const Duration(milliseconds: 100)); // Splash is underway.

    // Material 3 uses the InkSparkle which uses a shader, so we can't capture
    // the effect with paint methods. Use a golden test instead.
    // Check if the ink sparkle is drawn on top of the background color.
    await expectLater(
      find.byKey(expansionTileKey),
      matchesGoldenFile('expansion_tile.ink_splash.drawn_on_top_of_background_color.png'),
    );

    // Finish gesture to release resources.
    await gesture.up();
    await tester.pumpAndSettle();
  });

 testWidgets('Default clipBehavior when a shape is provided', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Scaffold(
          body: ExpansionTile(
            title: Text('Title'),
            subtitle: Text('Subtitle'),
            shape: StadiumBorder(),
            children: <Widget>[ListTile(title: Text('0'))],
          ),
        ),
      ),
    );

    expect(getMaterial(tester).clipBehavior, Clip.antiAlias);
  });

 testWidgets('Can override clipBehavior when a shape is provided', (WidgetTester tester) async {
    await tester.pumpWidget(
      const MaterialApp(
        home: Scaffold(
          body: ExpansionTile(
            title: Text('Title'),
            subtitle: Text('Subtitle'),
            shape: StadiumBorder(),
            clipBehavior: Clip.none,
            children: <Widget>[ListTile(title: Text('0'))],
          ),
        ),
      ),
    );

    expect(getMaterial(tester).clipBehavior, Clip.none);
  });

  group('Material 2', () {
    // These tests are only relevant for Material 2. Once Material 2
    // support is deprecated and the APIs are removed, these tests
    // can be deleted.

    testWidgets('ExpansionTile default iconColor, textColor', (WidgetTester tester) async {
      final ThemeData theme = ThemeData(useMaterial3: false);

      await tester.pumpWidget(MaterialApp(
        theme: theme,
        home: const Material(
          child: ExpansionTile(
            title: TestText('title'),
            trailing: TestIcon(),
            children: <Widget>[
              SizedBox(height: 100, width: 100),
            ],
          ),
        ),
      ));

      Color getIconColor() => tester.state<TestIconState>(find.byType(TestIcon)).iconTheme.color!;
      Color getTextColor() => tester.state<TestTextState>(find.byType(TestText)).textStyle.color!;

      expect(getIconColor(), theme.unselectedWidgetColor);
      expect(getTextColor(), theme.textTheme.titleMedium!.color);

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

      expect(getIconColor(), theme.colorScheme.primary);
      expect(getTextColor(), theme.colorScheme.primary);
    });

    testWidgets('Material2 - ExpansionTile draws inkwell splash on top of background color', (WidgetTester tester) async {
      const Key expansionTileKey = Key('expansionTileKey');
      final ThemeData theme = ThemeData(useMaterial3: false);
      const ShapeBorder shape = RoundedRectangleBorder(
        borderRadius: BorderRadius.all(Radius.circular(16)),
      );
      const ShapeBorder collapsedShape = RoundedRectangleBorder(
        borderRadius: BorderRadius.all(Radius.circular(16)),
      );
      const Color collapsedBackgroundColor = Color(0xff00ff00);
      const Color backgroundColor = Color(0xffff0000);

      await tester.pumpWidget(MaterialApp(
        theme: theme,
        home: const Material(
          child: Center(
            child: Padding(
              padding: EdgeInsets.symmetric(horizontal: 24.0),
              child: ExpansionTile(
                key: expansionTileKey,
                shape: shape,
                collapsedBackgroundColor: collapsedBackgroundColor,
                backgroundColor: backgroundColor,
                collapsedShape: collapsedShape,
                title: TestText('title'),
                trailing: TestIcon(),
                children: <Widget>[
                  SizedBox(height: 100, width: 100),
                ],
              ),
            ),
          ),
        ),
      ));

      // Tap and hold the ExpansionTile to trigger ink splash.
      final Offset center = tester.getCenter(find.byKey(expansionTileKey));
      final TestGesture gesture = await tester.startGesture(center);
      await tester.pump(); // Start the splash animation.
      await tester.pump(const Duration(milliseconds: 100)); // Splash is underway.

      final RenderObject inkFeatures = tester.allRenderObjects.firstWhere((RenderObject object) => object.runtimeType.toString() == '_RenderInkFeatures');
      // Check if the ink splash is drawn on top of the background color.
      expect(inkFeatures, paints..path(color: collapsedBackgroundColor)..circle(color: theme.splashColor));

      // Finish gesture to release resources.
      await gesture.up();
      await tester.pumpAndSettle();
    });
  });

  testWidgets('ExpansionTileController isExpanded, expand() and collapse()', (WidgetTester tester) async {
    final ExpansionTileController controller = ExpansionTileController();

    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: ExpansionTile(
          controller: controller,
          title: const Text('Title'),
          children: const <Widget>[
            Text('Child 0'),
          ],
        ),
      ),
    ));

    expect(find.text('Child 0'), findsNothing);
    expect(controller.isExpanded, isFalse);
    controller.expand();
    expect(controller.isExpanded, isTrue);
    await tester.pumpAndSettle();
    expect(find.text('Child 0'), findsOneWidget);
    expect(controller.isExpanded, isTrue);
    controller.collapse();
    expect(controller.isExpanded, isFalse);
    await tester.pumpAndSettle();
    expect(find.text('Child 0'), findsNothing);
  });

  testWidgets('Calling ExpansionTileController.expand/collapsed has no effect if it is already expanded/collapsed', (WidgetTester tester) async {
    final ExpansionTileController controller = ExpansionTileController();

    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: ExpansionTile(
          controller: controller,
          title: const Text('Title'),
          initiallyExpanded: true,
          children: const <Widget>[
            Text('Child 0'),
          ],
        ),
      ),
    ));

    expect(find.text('Child 0'), findsOneWidget);
    expect(controller.isExpanded, isTrue);
    controller.expand();
    expect(controller.isExpanded, isTrue);
    await tester.pump();
    expect(tester.hasRunningAnimations, isFalse);
    expect(find.text('Child 0'), findsOneWidget);
    controller.collapse();
    expect(controller.isExpanded, isFalse);
    await tester.pump();
    expect(tester.hasRunningAnimations, isTrue);
    await tester.pumpAndSettle();
    expect(controller.isExpanded, isFalse);
    expect(find.text('Child 0'), findsNothing);
    controller.collapse();
    expect(controller.isExpanded, isFalse);
    await tester.pump();
    expect(tester.hasRunningAnimations, isFalse);
  });

  testWidgets('Call to ExpansionTileController.of()', (WidgetTester tester) async {
    final GlobalKey titleKey = GlobalKey();
    final GlobalKey childKey = GlobalKey();
    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: ExpansionTile(
          initiallyExpanded: true,
          title: Text('Title', key: titleKey),
          children: <Widget>[
            Text('Child 0', key: childKey),
          ],
        ),
      ),
    ));

    final ExpansionTileController controller1 = ExpansionTileController.of(childKey.currentContext!);
    expect(controller1.isExpanded, isTrue);

    final ExpansionTileController controller2 = ExpansionTileController.of(titleKey.currentContext!);
    expect(controller2.isExpanded, isTrue);

    expect(controller1, controller2);
  });

  testWidgets('Call to ExpansionTile.maybeOf()', (WidgetTester tester) async {
    final GlobalKey titleKey = GlobalKey();
    final GlobalKey nonDescendantKey = GlobalKey();
    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: Column(
          children: <Widget>[
            ExpansionTile(
              title: Text('Title', key: titleKey),
              children: const <Widget>[
                Text('Child 0'),
              ],
            ),
            Text('Non descendant', key: nonDescendantKey),
          ],
        ),
      ),
    ));

    final ExpansionTileController? controller1 = ExpansionTileController.maybeOf(titleKey.currentContext!);
    expect(controller1, isNotNull);
    expect(controller1?.isExpanded, isFalse);

    final ExpansionTileController? controller2 = ExpansionTileController.maybeOf(nonDescendantKey.currentContext!);
    expect(controller2, isNull);
  });

  testWidgets('Check if dense, enableFeedback, visualDensity parameter is working', (WidgetTester tester) async {
    final GlobalKey titleKey = GlobalKey();
    final GlobalKey nonDescendantKey = GlobalKey();

    const bool dense = true;
    const bool enableFeedback = false;
    const VisualDensity visualDensity = VisualDensity.compact;

    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: Column(
          children: <Widget>[
            ExpansionTile(
              dense: dense,
              enableFeedback: enableFeedback,
              visualDensity: visualDensity,
              title: Text('Title', key: titleKey),
              children: const <Widget>[
                Text('Child 0'),
              ],
            ),
            Text('Non descendant', key: nonDescendantKey),
          ],
        ),
      ),
    ));

    final Finder tileFinder = find.byType(ListTile);
    final ListTile tileWidget = tester.widget<ListTile>(tileFinder);
    expect(tileWidget.dense, dense);
    expect(tileWidget.enableFeedback, enableFeedback);
    expect(tileWidget.visualDensity, visualDensity);
  });

  testWidgets('ExpansionTileController should not toggle if disabled', (WidgetTester tester) async {
    final ExpansionTileController controller = ExpansionTileController();

    await tester.pumpWidget(MaterialApp(
      home: Material(
        child: ExpansionTile(
          enabled: false,
          controller: controller,
          title: const Text('Title'),
          children: const <Widget>[
            Text('Child 0'),
          ],
        ),
      ),
    ));

    expect(find.text('Child 0'), findsNothing);
    expect(controller.isExpanded, isFalse);
    await tester.tap(find.widgetWithText(ExpansionTile, 'Title'));
    await tester.pumpAndSettle();
    expect(find.text('Child 0'), findsNothing);
    expect(controller.isExpanded, isFalse);
    controller.expand();
    await tester.pumpAndSettle();
    expect(find.text('Child 0'), findsOneWidget);
    expect(controller.isExpanded, isTrue);
    await tester.tap(find.widgetWithText(ExpansionTile, 'Title'));
    await tester.pumpAndSettle();
    expect(find.text('Child 0'), findsOneWidget);
    expect(controller.isExpanded, isTrue);
  });

  testWidgets('ExpansionTile does not include the default trailing icon when showTrailingIcon: false (#145268)', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(
      home: Material(
        child: ExpansionTile(
          enabled: false,
          tilePadding: EdgeInsets.zero,
          title: ColoredBox(color: Colors.red, child: Text('Title')),
          showTrailingIcon: false,
        ),
      ),
    ));

    final Size materialAppSize = tester.getSize(find.byType(MaterialApp));
    final Size titleSize = tester.getSize(find.byType(ColoredBox));

    expect(titleSize.width, materialAppSize.width);
  });

  testWidgets('ExpansionTile with smaller trailing widget allocates at least 32.0 units of space (preserves original behavior) (#145268)', (WidgetTester tester) async {
    await tester.pumpWidget(const MaterialApp(
      home: Material(
        child: ExpansionTile(
          enabled: false,
          tilePadding: EdgeInsets.zero,
          title: ColoredBox(color: Colors.red, child: Text('Title')),
          trailing: SizedBox.shrink(),
        ),
      ),
    ));

    final Size materialAppSize = tester.getSize(find.byType(MaterialApp));
    final Size titleSize = tester.getSize(find.byType(ColoredBox));

    expect(titleSize.width, materialAppSize.width - 32.0);
  });
}
