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

class SimpleExpansionPanelListTestWidget extends StatefulWidget {
  const SimpleExpansionPanelListTestWidget({
    super.key,
    this.firstPanelKey,
    this.secondPanelKey,
    this.canTapOnHeader = false,
    this.expandedHeaderPadding,
    this.dividerColor,
    this.elevation = 2,
  });

  final Key? firstPanelKey;
  final Key? secondPanelKey;
  final bool canTapOnHeader;
  final Color? dividerColor;
  final double elevation;

  /// If null, the default [ExpansionPanelList]'s expanded header padding value is applied via [defaultExpandedHeaderPadding]
  final EdgeInsets? expandedHeaderPadding;

  /// Mirrors the default expanded header padding as its source constants are private.
  static EdgeInsets defaultExpandedHeaderPadding()
  {
    return const ExpansionPanelList().expandedHeaderPadding;
  }

  @override
  State<SimpleExpansionPanelListTestWidget> createState() => _SimpleExpansionPanelListTestWidgetState();
}

class _SimpleExpansionPanelListTestWidgetState extends State<SimpleExpansionPanelListTestWidget> {
  List<bool> extendedState = <bool>[false, false];

  @override
  Widget build(BuildContext context) {
    return ExpansionPanelList(
      expandedHeaderPadding: widget.expandedHeaderPadding ?? SimpleExpansionPanelListTestWidget.defaultExpandedHeaderPadding(),
      expansionCallback: (int index, bool isExpanded) {
        setState(() {
          extendedState[index] = !extendedState[index];
        });
      },
      dividerColor: widget.dividerColor,
      elevation: widget.elevation,
      children: <ExpansionPanel>[
        ExpansionPanel(
          headerBuilder: (BuildContext context, bool isExpanded) {
            return Text(isExpanded ? 'B' : 'A', key: widget.firstPanelKey);
          },
          body: const SizedBox(height: 100.0),
          canTapOnHeader: widget.canTapOnHeader,
          isExpanded: extendedState[0],
        ),
        ExpansionPanel(
          headerBuilder: (BuildContext context, bool isExpanded) {
            return Text(isExpanded ? 'D' : 'C', key: widget.secondPanelKey);
          },
          body: const SizedBox(height: 100.0),
          canTapOnHeader: widget.canTapOnHeader,
          isExpanded: extendedState[1],
        ),
      ],
    );
  }
}

class ExpansionPanelListSemanticsTest extends StatefulWidget {
  const ExpansionPanelListSemanticsTest({ super.key, required this.headerKey });

  final Key headerKey;

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

class ExpansionPanelListSemanticsTestState extends State<ExpansionPanelListSemanticsTest> {
  bool headerTapped = false;
  @override
  Widget build(BuildContext context) {
    return ListView(
      children: <Widget>[
        ExpansionPanelList(
          children: <ExpansionPanel>[
            ExpansionPanel(
              headerBuilder: (BuildContext context, bool isExpanded) {
                return MergeSemantics(
                  key: widget.headerKey,
                  child: GestureDetector(
                    onTap: () => headerTapped = true,
                    child: const Text.rich(
                      TextSpan(
                        text:'head1',
                      ),
                    ),
                  ),
                );
              },
              body: const Placeholder(),
            ),
          ],
        ),
      ],
    );
  }
}

void main() {
  testWidgets('ExpansionPanelList test', (WidgetTester tester) async {
    late int capturedIndex;
    late bool capturedIsExpanded;

    await tester.pumpWidget(
      MaterialApp(
        home: SingleChildScrollView(
          child: ExpansionPanelList(
            expansionCallback: (int index, bool isExpanded) {
              capturedIndex = index;
              capturedIsExpanded = isExpanded;
            },
            children: <ExpansionPanel>[
              ExpansionPanel(
                headerBuilder: (BuildContext context, bool isExpanded) {
                  return Text(isExpanded ? 'B' : 'A');
                },
                body: const SizedBox(height: 100.0),
              ),
            ],
          ),
        ),
      ),
    );

    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    RenderBox box = tester.renderObject(find.byType(ExpansionPanelList));
    final double oldHeight = box.size.height;
    expect(find.byType(ExpandIcon), findsOneWidget);
    await tester.tap(find.byType(ExpandIcon));
    expect(capturedIndex, 0);
    expect(capturedIsExpanded, isFalse);
    box = tester.renderObject(find.byType(ExpansionPanelList));
    expect(box.size.height, equals(oldHeight));

    // Now, expand the child panel.
    await tester.pumpWidget(
      MaterialApp(
        home: SingleChildScrollView(
          child: ExpansionPanelList(
            expansionCallback: (int index, bool isExpanded) {
              capturedIndex = index;
              capturedIsExpanded = isExpanded;
            },
            children: <ExpansionPanel>[
              ExpansionPanel(
                headerBuilder: (BuildContext context, bool isExpanded) {
                  return Text(isExpanded ? 'B' : 'A');
                },
                body: const SizedBox(height: 100.0),
                isExpanded: true, // this is the addition
              ),
            ],
          ),
        ),
      ),
    );
    await tester.pump(const Duration(milliseconds: 200));

    expect(find.text('A'), findsNothing);
    expect(find.text('B'), findsOneWidget);
    box = tester.renderObject(find.byType(ExpansionPanelList));
    expect(box.size.height - oldHeight, greaterThanOrEqualTo(100.0)); // 100 + some margin
  });

  testWidgets('ExpansionPanelList does not merge header when canTapOnHeader is false', (WidgetTester tester) async {
    final SemanticsHandle handle = tester.ensureSemantics();
    final Key headerKey = UniqueKey();
    await tester.pumpWidget(
      MaterialApp(
        home: ExpansionPanelListSemanticsTest(headerKey: headerKey),
      ),
    );

    // Make sure custom gesture detector widget is clickable.
    await tester.tap(find.text('head1'));
    await tester.pump();

    final ExpansionPanelListSemanticsTestState state =
      tester.state(find.byType(ExpansionPanelListSemanticsTest));
    expect(state.headerTapped, true);

    // Check the expansion icon semantics does not merged with header widget.
    final Finder expansionIcon = find.descendant(
      of: find.ancestor(
        of: find.byKey(headerKey),
        matching: find.byType(Row),
      ),
      matching: find.byType(ExpandIcon),
    );
    expect(tester.getSemantics(expansionIcon), matchesSemantics(
      label: 'Expand',
      isButton: true,
      hasEnabledState: true,
      isEnabled: true,
      isFocusable: true,
      hasTapAction: true,
    ));

    // Check custom header widget semantics is preserved.
    final Finder headerWidget = find.descendant(
      of: find.byKey(headerKey),
      matching: find.byType(RichText),
    );
    expect(tester.getSemantics(headerWidget), matchesSemantics(
      label: 'head1',
      hasTapAction: true,
    ));

    handle.dispose();
  });

  testWidgets('Multiple Panel List test', (WidgetTester tester) async {
    await tester.pumpWidget(
      MaterialApp(
        home: ListView(
          children: <ExpansionPanelList>[
            ExpansionPanelList(
              children: <ExpansionPanel>[
                ExpansionPanel(
                  headerBuilder: (BuildContext context, bool isExpanded) {
                    return Text(isExpanded ? 'B' : 'A');
                  },
                  body: const SizedBox(height: 100.0),
                  isExpanded: true,
                ),
              ],
            ),
            ExpansionPanelList(
              children: <ExpansionPanel>[
                ExpansionPanel(
                  headerBuilder: (BuildContext context, bool isExpanded) {
                    return Text(isExpanded ? 'D' : 'C');
                  },
                  body: const SizedBox(height: 100.0),
                  isExpanded: true,
                ),
              ],
            ),
          ],
        ),
      ),
    );
    await tester.pump(const Duration(milliseconds: 200));

    expect(find.text('A'), findsNothing);
    expect(find.text('B'), findsOneWidget);
    expect(find.text('C'), findsNothing);
    expect(find.text('D'), findsOneWidget);
  });

  testWidgets('Open/close animations', (WidgetTester tester) async {
    const Duration kSizeAnimationDuration = Duration(milliseconds: 1000);
    // The MaterialGaps animate in using kThemeAnimationDuration (hardcoded),
    // which should be less than our test size animation length. So we can assume that they
    // appear immediately. Here we just verify that our assumption is true.
    expect(kThemeAnimationDuration, lessThan(kSizeAnimationDuration ~/ 2));

    Widget build(bool a, bool b, bool c) {
      return MaterialApp(
        home: Column(
          children: <Widget>[
            ExpansionPanelList(
              animationDuration: kSizeAnimationDuration,
              children: <ExpansionPanel>[
                ExpansionPanel(
                  headerBuilder: (BuildContext context, bool isExpanded) => const Placeholder(
                    fallbackHeight: 12.0,
                  ),
                  body: const SizedBox(height: 100.0, child: Placeholder(
                    fallbackHeight: 12.0,
                  )),
                  isExpanded: a,
                ),
                ExpansionPanel(
                  headerBuilder: (BuildContext context, bool isExpanded) => const Placeholder(
                    fallbackHeight: 12.0,
                  ),
                  body: const SizedBox(height: 100.0, child: Placeholder()),
                  isExpanded: b,
                ),
                ExpansionPanel(
                  headerBuilder: (BuildContext context, bool isExpanded) => const Placeholder(
                    fallbackHeight: 12.0,
                  ),
                  body: const SizedBox(height: 100.0, child: Placeholder()),
                  isExpanded: c,
                ),
              ],
            ),
          ],
        ),
      );
    }

    await tester.pumpWidget(build(false, false, false));
    expect(tester.renderObjectList(find.byType(AnimatedSize)), hasLength(3));
    expect(tester.getRect(find.byType(AnimatedSize).at(0)), const Rect.fromLTWH(0.0, 56.0, 800.0, 0.0));
    expect(tester.getRect(find.byType(AnimatedSize).at(1)), const Rect.fromLTWH(0.0, 113.0, 800.0, 0.0));
    expect(tester.getRect(find.byType(AnimatedSize).at(2)), const Rect.fromLTWH(0.0, 170.0, 800.0, 0.0));

    await tester.pump(const Duration(milliseconds: 200));
    expect(tester.getRect(find.byType(AnimatedSize).at(0)), const Rect.fromLTWH(0.0, 56.0, 800.0, 0.0));
    expect(tester.getRect(find.byType(AnimatedSize).at(1)), const Rect.fromLTWH(0.0, 113.0, 800.0, 0.0));
    expect(tester.getRect(find.byType(AnimatedSize).at(2)), const Rect.fromLTWH(0.0, 170.0, 800.0, 0.0));

    await tester.pumpWidget(build(false, true, false));
    expect(tester.getRect(find.byType(AnimatedSize).at(0)), const Rect.fromLTWH(0.0, 56.0, 800.0, 0.0));
    expect(tester.getRect(find.byType(AnimatedSize).at(1)), const Rect.fromLTWH(0.0, 113.0, 800.0, 0.0));
    expect(tester.getRect(find.byType(AnimatedSize).at(2)), const Rect.fromLTWH(0.0, 170.0, 800.0, 0.0));

    await tester.pump(kSizeAnimationDuration ~/ 2);
    expect(tester.getRect(find.byType(AnimatedSize).at(0)), const Rect.fromLTWH(0.0, 56.0, 800.0, 0.0));
    final Rect rect1 = tester.getRect(find.byType(AnimatedSize).at(1));
    expect(rect1.left, 0.0);
    expect(rect1.top, inExclusiveRange(113.0, 113.0 + 16.0 + 32.0)); // 16.0 material gap, plus 16.0 top and bottom margins added to the header
    expect(rect1.width, 800.0);
    expect(rect1.height, inExclusiveRange(0.0, 100.0));
    final Rect rect2 = tester.getRect(find.byType(AnimatedSize).at(2));
    expect(rect2, Rect.fromLTWH(0.0, rect1.bottom + 16.0 + 56.0, 800.0, 0.0)); // the 16.0 comes from the MaterialGap being introduced, the 56.0 is the header height.

    await tester.pumpWidget(build(false, false, false));
    expect(tester.getRect(find.byType(AnimatedSize).at(0)), const Rect.fromLTWH(0.0, 56.0, 800.0, 0.0));
    expect(tester.getRect(find.byType(AnimatedSize).at(1)), rect1);
    expect(tester.getRect(find.byType(AnimatedSize).at(2)), rect2);

    await tester.pumpWidget(build(false, false, true));
    expect(tester.getRect(find.byType(AnimatedSize).at(0)), const Rect.fromLTWH(0.0, 56.0, 800.0, 0.0));
    expect(tester.getRect(find.byType(AnimatedSize).at(1)), rect1);
    expect(tester.getRect(find.byType(AnimatedSize).at(2)), rect2);

    // a few no-op pumps to make sure there's nothing fishy going on
    await tester.pump();
    await tester.pump();
    await tester.pump();
    expect(tester.getRect(find.byType(AnimatedSize).at(0)), const Rect.fromLTWH(0.0, 56.0, 800.0, 0.0));
    expect(tester.getRect(find.byType(AnimatedSize).at(1)), rect1);
    expect(tester.getRect(find.byType(AnimatedSize).at(2)), rect2);

    await tester.pumpAndSettle();
    expect(tester.getRect(find.byType(AnimatedSize).at(0)), const Rect.fromLTWH(0.0, 56.0, 800.0, 0.0));
    expect(tester.getRect(find.byType(AnimatedSize).at(1)), const Rect.fromLTWH(0.0, 56.0 + 1.0 + 56.0, 800.0, 0.0));
    expect(tester.getRect(find.byType(AnimatedSize).at(2)), const Rect.fromLTWH(0.0, 56.0 + 1.0 + 56.0 + 16.0 + 16.0 + 48.0 + 16.0, 800.0, 100.0));
  });

  testWidgets('Radio mode has max of one panel open at a time',  (WidgetTester tester) async {
    final List<ExpansionPanel> demoItemsRadio = <ExpansionPanelRadio>[
      ExpansionPanelRadio(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return Text(isExpanded ? 'B' : 'A');
        },
        body: const SizedBox(height: 100.0),
        value: 0,
      ),
      ExpansionPanelRadio(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return Text(isExpanded ? 'D' : 'C');
        },
        body: const SizedBox(height: 100.0),
        value: 1,
      ),
      ExpansionPanelRadio(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return Text(isExpanded ? 'F' : 'E');
        },
        body: const SizedBox(height: 100.0),
        value: 2,
      ),
    ];

    final ExpansionPanelList expansionListRadio = ExpansionPanelList.radio(
      children: demoItemsRadio,
    );

    await tester.pumpWidget(
      MaterialApp(
        home: SingleChildScrollView(
          child: expansionListRadio,
        ),
      ),
    );

    // Initializes with all panels closed
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);
    expect(find.text('E'), findsOneWidget);
    expect(find.text('F'), findsNothing);

    RenderBox box = tester.renderObject(find.byType(ExpansionPanelList));
    double oldHeight = box.size.height;

    expect(find.byType(ExpandIcon), findsNWidgets(3));

    await tester.tap(find.byType(ExpandIcon).at(0));

    box = tester.renderObject(find.byType(ExpansionPanelList));
    expect(box.size.height, equals(oldHeight));

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

    // Now the first panel is open
    expect(find.text('A'), findsNothing);
    expect(find.text('B'), findsOneWidget);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);
    expect(find.text('E'), findsOneWidget);
    expect(find.text('F'), findsNothing);

    box = tester.renderObject(find.byType(ExpansionPanelList));
    expect(box.size.height - oldHeight, greaterThanOrEqualTo(100.0)); // 100 + some margin

    await tester.tap(find.byType(ExpandIcon).at(1));

    box = tester.renderObject(find.byType(ExpansionPanelList));
    oldHeight = box.size.height;

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

    // Now the first panel is closed and the second should be opened
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsNothing);
    expect(find.text('D'), findsOneWidget);
    expect(find.text('E'), findsOneWidget);
    expect(find.text('F'), findsNothing);

    expect(box.size.height, greaterThanOrEqualTo(oldHeight));

    demoItemsRadio.removeAt(0);

    await tester.pumpAndSettle();

    // Now the first panel should be opened
    expect(find.text('C'), findsNothing);
    expect(find.text('D'), findsOneWidget);
    expect(find.text('E'), findsOneWidget);
    expect(find.text('F'), findsNothing);


    final List<ExpansionPanel> demoItems = <ExpansionPanel>[
      ExpansionPanel(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return Text(isExpanded ? 'B' : 'A');
        },
        body: const SizedBox(height: 100.0),
      ),
      ExpansionPanel(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return Text(isExpanded ? 'D' : 'C');
        },
        body: const SizedBox(height: 100.0),
      ),
      ExpansionPanel(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return Text(isExpanded ? 'F' : 'E');
        },
        body: const SizedBox(height: 100.0),
      ),
    ];

    final ExpansionPanelList expansionList = ExpansionPanelList(
      children: demoItems,
    );

    await tester.pumpWidget(
      MaterialApp(
        home: SingleChildScrollView(
          child: expansionList,
        ),
      ),
    );

    // We've reinitialized with a regular expansion panel so they should all be closed again
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);
    expect(find.text('E'), findsOneWidget);
    expect(find.text('F'), findsNothing);
  });

  testWidgets('Radio mode calls expansionCallback once if other panels closed', (WidgetTester tester) async {
    final List<ExpansionPanel> demoItemsRadio = <ExpansionPanelRadio>[
      ExpansionPanelRadio(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return Text(isExpanded ? 'B' : 'A');
        },
        body: const SizedBox(height: 100.0),
        value: 0,
      ),
      ExpansionPanelRadio(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return Text(isExpanded ? 'D' : 'C');
        },
        body: const SizedBox(height: 100.0),
        value: 1,
      ),
      ExpansionPanelRadio(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return Text(isExpanded ? 'F' : 'E');
        },
        body: const SizedBox(height: 100.0),
        value: 2,
      ),
    ];

    final List<Map<String, dynamic>> callbackHistory = <Map<String, dynamic>>[];
    final ExpansionPanelList expansionListRadio = ExpansionPanelList.radio(
      expansionCallback: (int index, bool isExpanded) {
        callbackHistory.add(<String, dynamic>{
          'index': index,
          'isExpanded': isExpanded,
        });
      },
      children: demoItemsRadio,
    );

    await tester.pumpWidget(
      MaterialApp(
        home: SingleChildScrollView(
          child: expansionListRadio,
        ),
      ),
    );

    // Initializes with all panels closed
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);
    expect(find.text('E'), findsOneWidget);
    expect(find.text('F'), findsNothing);

    // Open one panel
    await tester.tap(find.byType(ExpandIcon).at(1));
    await tester.pumpAndSettle();

    // Callback is invoked once with appropriate arguments
    expect(callbackHistory.length, equals(1));
    expect(callbackHistory.last['index'], equals(1));
    expect(callbackHistory.last['isExpanded'], equals(false));

    // Close the same panel
    await tester.tap(find.byType(ExpandIcon).at(1));
    await tester.pumpAndSettle();

    // Callback is invoked once with appropriate arguments
    expect(callbackHistory.length, equals(2));
    expect(callbackHistory.last['index'], equals(1));
    expect(callbackHistory.last['isExpanded'], equals(true));
  });

  testWidgets('Radio mode calls expansionCallback twice if other panel open prior', (WidgetTester tester) async {
    final List<ExpansionPanel> demoItemsRadio = <ExpansionPanelRadio>[
      ExpansionPanelRadio(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return Text(isExpanded ? 'B' : 'A');
        },
        body: const SizedBox(height: 100.0),
        value: 0,
      ),
      ExpansionPanelRadio(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return Text(isExpanded ? 'D' : 'C');
        },
        body: const SizedBox(height: 100.0),
        value: 1,
      ),
      ExpansionPanelRadio(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return Text(isExpanded ? 'F' : 'E');
        },
        body: const SizedBox(height: 100.0),
        value: 2,
      ),
    ];

    final List<Map<String, dynamic>> callbackHistory = <Map<String, dynamic>>[];
    Map<String, dynamic> callbackResults;

    final ExpansionPanelList expansionListRadio = ExpansionPanelList.radio(
      expansionCallback: (int index, bool isExpanded) {
        callbackHistory.add(<String, dynamic>{
          'index': index,
          'isExpanded': isExpanded,
        });
      },
      children: demoItemsRadio,
    );

    await tester.pumpWidget(
      MaterialApp(
        home: SingleChildScrollView(
          child: expansionListRadio,
        ),
      ),
    );

    // Initializes with all panels closed
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);
    expect(find.text('E'), findsOneWidget);
    expect(find.text('F'), findsNothing);

    // Open one panel
    await tester.tap(find.byType(ExpandIcon).at(1));
    await tester.pumpAndSettle();

    // Callback is invoked once with appropriate arguments
    expect(callbackHistory.length, equals(1));
    callbackResults = callbackHistory[callbackHistory.length - 1];
    expect(callbackResults['index'], equals(1));
    expect(callbackResults['isExpanded'], equals(false));

    // Close a different panel
    await tester.tap(find.byType(ExpandIcon).at(2));
    await tester.pumpAndSettle();

    // Callback is invoked the first time with correct arguments
    expect(callbackHistory.length, equals(3));
    callbackResults = callbackHistory[callbackHistory.length - 2];
    expect(callbackResults['index'], equals(2));
    expect(callbackResults['isExpanded'], equals(false));

    // Callback is invoked the second time with correct arguments
    callbackResults = callbackHistory[callbackHistory.length - 1];
    expect(callbackResults['index'], equals(1));
    expect(callbackResults['isExpanded'], equals(false));
  });

  testWidgets(
    'didUpdateWidget accounts for toggling between ExpansionPanelList '
    'and ExpansionPaneList.radio',
    (WidgetTester tester) async {
      bool isRadioList = false;
      final List<bool> panelExpansionState = <bool>[
        false,
        false,
        false,
      ];

      ExpansionPanelList buildRadioExpansionPanelList() {
        return ExpansionPanelList.radio(
          initialOpenPanelValue: 2,
          children: <ExpansionPanelRadio>[
            ExpansionPanelRadio(
              headerBuilder: (BuildContext context, bool isExpanded) {
                return Text(isExpanded ? 'B' : 'A');
              },
              body: const SizedBox(height: 100.0),
              value: 0,
            ),
            ExpansionPanelRadio(
              headerBuilder: (BuildContext context, bool isExpanded) {
                return Text(isExpanded ? 'D' : 'C');
              },
              body: const SizedBox(height: 100.0),
              value: 1,
            ),
            ExpansionPanelRadio(
              headerBuilder: (BuildContext context, bool isExpanded) {
                return Text(isExpanded ? 'F' : 'E');
              },
              body: const SizedBox(height: 100.0),
              value: 2,
            ),
          ],
        );
      }

      ExpansionPanelList buildExpansionPanelList(StateSetter setState) {
        return ExpansionPanelList(
          expansionCallback: (int index, _) => setState(() { panelExpansionState[index] = !panelExpansionState[index]; }),
          children: <ExpansionPanel>[
            ExpansionPanel(
              isExpanded: panelExpansionState[0],
              headerBuilder: (BuildContext context, bool isExpanded) {
                return Text(isExpanded ? 'B' : 'A');
              },
              body: const SizedBox(height: 100.0),
            ),
            ExpansionPanel(
              isExpanded: panelExpansionState[1],
              headerBuilder: (BuildContext context, bool isExpanded) {
                return Text(isExpanded ? 'D' : 'C');
              },
              body: const SizedBox(height: 100.0),
            ),
            ExpansionPanel(
              isExpanded: panelExpansionState[2],
              headerBuilder: (BuildContext context, bool isExpanded) {
                return Text(isExpanded ? 'F' : 'E');
              },
              body: const SizedBox(height: 100.0),
            ),
          ],
        );
      }

      await tester.pumpWidget(
        StatefulBuilder(
          builder: (BuildContext context, StateSetter setState) {
            return MaterialApp(
              home: Scaffold(
                body: SingleChildScrollView(
                  child: isRadioList
                    ? buildRadioExpansionPanelList()
                    : buildExpansionPanelList(setState),
                ),
                floatingActionButton: FloatingActionButton(
                  onPressed: () => setState(() { isRadioList = !isRadioList; }),
                ),
              ),
            );
          },
        ),
      );

      expect(find.text('A'), findsOneWidget);
      expect(find.text('B'), findsNothing);
      expect(find.text('C'), findsOneWidget);
      expect(find.text('D'), findsNothing);
      expect(find.text('E'), findsOneWidget);
      expect(find.text('F'), findsNothing);

      await tester.tap(find.byType(ExpandIcon).at(0));
      await tester.tap(find.byType(ExpandIcon).at(1));
      await tester.pumpAndSettle();

      expect(find.text('A'), findsNothing);
      expect(find.text('B'), findsOneWidget);
      expect(find.text('C'), findsNothing);
      expect(find.text('D'), findsOneWidget);
      expect(find.text('E'), findsOneWidget);
      expect(find.text('F'), findsNothing);

      // ExpansionPanelList --> ExpansionPanelList.radio
      await tester.tap(find.byType(FloatingActionButton));
      await tester.pumpAndSettle();

      expect(find.text('A'), findsOneWidget);
      expect(find.text('B'), findsNothing);
      expect(find.text('C'), findsOneWidget);
      expect(find.text('D'), findsNothing);
      expect(find.text('E'), findsNothing);
      expect(find.text('F'), findsOneWidget);

      // ExpansionPanelList.radio --> ExpansionPanelList
      await tester.tap(find.byType(FloatingActionButton));
      await tester.pumpAndSettle();

      expect(find.text('A'), findsNothing);
      expect(find.text('B'), findsOneWidget);
      expect(find.text('C'), findsNothing);
      expect(find.text('D'), findsOneWidget);
      expect(find.text('E'), findsOneWidget);
      expect(find.text('F'), findsNothing);
    },
  );

  testWidgets('No duplicate global keys at layout/build time', (WidgetTester tester) async {
    // Regression test for https://github.com/flutter/flutter/issues/13780
    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return MaterialApp(
            // Wrapping with LayoutBuilder or other widgets that augment
            // layout/build order should not create duplicate keys
            home: LayoutBuilder(
              builder: (BuildContext context, BoxConstraints constraints) {
                return SingleChildScrollView(
                  child: ExpansionPanelList.radio(
                    expansionCallback: (int index, bool isExpanded) {
                      if (!isExpanded) {
                        // setState invocation required to trigger
                        // _ExpansionPanelListState.didUpdateWidget,
                        // which causes duplicate keys to be
                        // generated in the regression
                        setState(() {});
                      }
                    },
                    children: <ExpansionPanelRadio>[
                      ExpansionPanelRadio(
                        headerBuilder: (BuildContext context, bool isExpanded) {
                          return Text(isExpanded ? 'B' : 'A');
                        },
                        body: const SizedBox(height: 100.0),
                        value: 0,
                      ),
                      ExpansionPanelRadio(
                        headerBuilder: (BuildContext context, bool isExpanded) {
                          return Text(isExpanded ? 'D' : 'C');
                        },
                        body: const SizedBox(height: 100.0),
                        value: 1,
                      ),
                      ExpansionPanelRadio(
                        headerBuilder: (BuildContext context, bool isExpanded) {
                          return Text(isExpanded ? 'F' : 'E');
                        },
                        body: const SizedBox(height: 100.0),
                        value: 2,
                      ),
                    ],
                  ),
                );
              },
            ),
          );
        },
      ),
    );

    // Initializes with all panels closed
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);
    expect(find.text('E'), findsOneWidget);
    expect(find.text('F'), findsNothing);

    // Open a panel
    await tester.tap(find.byType(ExpandIcon).at(1));
    await tester.pumpAndSettle();

    final List<bool> panelExpansionState = <bool>[false, false];

    await tester.pumpWidget(
      StatefulBuilder(
        builder: (BuildContext context, StateSetter setState) {
          return MaterialApp(
            home: Scaffold(
              // Wrapping with LayoutBuilder or other widgets that augment
              // layout/build order should not create duplicate keys
              body: LayoutBuilder(
                builder: (BuildContext context, BoxConstraints constraints) {
                  return SingleChildScrollView(
                    child: ExpansionPanelList(
                      expansionCallback: (int index, bool isExpanded) {
                        // setState invocation required to trigger
                        // _ExpansionPanelListState.didUpdateWidget, which
                        // causes duplicate keys to be generated in the
                        // regression
                        setState(() {
                          panelExpansionState[index] = !isExpanded;
                        });
                      },
                      children: <ExpansionPanel>[
                        ExpansionPanel(
                          headerBuilder: (BuildContext context, bool isExpanded) {
                            return Text(isExpanded ? 'B' : 'A');
                          },
                          body: const SizedBox(height: 100.0),
                          isExpanded: panelExpansionState[0],
                        ),
                        ExpansionPanel(
                          headerBuilder: (BuildContext context, bool isExpanded) {
                            return Text(isExpanded ? 'D' : 'C');
                          },
                          body: const SizedBox(height: 100.0),
                          isExpanded: panelExpansionState[1],
                        ),
                      ],
                    ),
                  );
                },
              ),
            ),
          );
        },
      ),
    );

    // initializes with all panels closed
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);

    // open a panel
    await tester.tap(find.byType(ExpandIcon).at(1));
    await tester.pumpAndSettle();
  });

  testWidgets('Panel header has semantics, canTapOnHeader = false ', (WidgetTester tester) async {
    const Key expandedKey = Key('expanded');
    const Key collapsedKey = Key('collapsed');
    const DefaultMaterialLocalizations localizations = DefaultMaterialLocalizations();
    final SemanticsHandle handle = tester.ensureSemantics();
    final List<ExpansionPanel> demoItems = <ExpansionPanel>[
      ExpansionPanel(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return const Text('Expanded', key: expandedKey);
        },
        body: const SizedBox(height: 100.0),
        isExpanded: true,
      ),
      ExpansionPanel(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return const Text('Collapsed', key: collapsedKey);
        },
        body: const SizedBox(height: 100.0),
      ),
    ];

    final ExpansionPanelList expansionList = ExpansionPanelList(
      children: demoItems,
    );

    await tester.pumpWidget(
      MaterialApp(
        home: SingleChildScrollView(
          child: expansionList,
        ),
      ),
    );

    // Check the semantics of [ExpandIcon] for expanded panel.
    final Finder expandedIcon = find.descendant(
      of: find.ancestor(
        of: find.byKey(expandedKey),
        matching: find.byType(Row),
      ),
      matching: find.byType(ExpandIcon),
    );
    expect(tester.getSemantics(expandedIcon), matchesSemantics(
      label: 'Collapse',
      isButton: true,
      hasEnabledState: true,
      isEnabled: true,
      isFocusable: true,
      hasTapAction: true,
      onTapHint: localizations.expandedIconTapHint,
    ));

    // Check the semantics of the header widget for expanded panel.
    final Finder expandedHeader = find.byKey(expandedKey);
    expect(tester.getSemantics(expandedHeader), matchesSemantics(
      label: 'Expanded',
    ));

    // Check the semantics of [ExpandIcon] for collapsed panel.
    final Finder collapsedIcon = find.descendant(
      of: find.ancestor(
        of: find.byKey(collapsedKey),
        matching: find.byType(Row),
      ),
      matching: find.byType(ExpandIcon),
    );
    expect(tester.getSemantics(collapsedIcon), matchesSemantics(
      label: 'Expand',
      isButton: true,
      hasEnabledState: true,
      isEnabled: true,
      isFocusable: true,
      hasTapAction: true,
      onTapHint: localizations.collapsedIconTapHint,
    ));

    // Check the semantics of the header widget for expanded panel.
    final Finder collapsedHeader = find.byKey(collapsedKey);
    expect(tester.getSemantics(collapsedHeader), matchesSemantics(
      label: 'Collapsed',
    ));

    handle.dispose();
  });

  testWidgets('Panel header has semantics, canTapOnHeader = true', (WidgetTester tester) async {
    const Key expandedKey = Key('expanded');
    const Key collapsedKey = Key('collapsed');
    final SemanticsHandle handle = tester.ensureSemantics();
    final List<ExpansionPanel> demoItems = <ExpansionPanel>[
      ExpansionPanel(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return const Text('Expanded', key: expandedKey);
        },
        canTapOnHeader: true,
        body: const SizedBox(height: 100.0),
        isExpanded: true,
      ),
      ExpansionPanel(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return const Text('Collapsed', key: collapsedKey);
        },
        canTapOnHeader: true,
        body: const SizedBox(height: 100.0),
      ),
    ];

    final ExpansionPanelList expansionList = ExpansionPanelList(
      children: demoItems,
    );

    await tester.pumpWidget(
      MaterialApp(
        home: SingleChildScrollView(
          child: expansionList,
        ),
      ),
    );

    expect(tester.getSemantics(find.byKey(expandedKey)), matchesSemantics(
      label: 'Expanded',
      isButton: true,
      isFocusable: true,
      hasEnabledState: true,
      hasTapAction: true,
    ));

    expect(tester.getSemantics(find.byKey(collapsedKey)), matchesSemantics(
      label: 'Collapsed',
      isButton: true,
      isFocusable: true,
      hasEnabledState: true,
      hasTapAction: true,
    ));

    handle.dispose();
  });

  testWidgets('Ensure canTapOnHeader is false by default',  (WidgetTester tester) async {
    final ExpansionPanel expansionPanel = ExpansionPanel(
      headerBuilder: (BuildContext context, bool isExpanded) => const Text('Demo'),
      body: const SizedBox(height: 100.0),
    );

    expect(expansionPanel.canTapOnHeader, isFalse);
  });

  testWidgets('Toggle ExpansionPanelRadio when tapping header and canTapOnHeader is true',  (WidgetTester tester) async {
    const Key firstPanelKey = Key('firstPanelKey');
    const Key secondPanelKey = Key('secondPanelKey');

    final List<ExpansionPanel> demoItemsRadio = <ExpansionPanelRadio>[
      ExpansionPanelRadio(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return Text(isExpanded ? 'B' : 'A', key: firstPanelKey);
        },
        body: const SizedBox(height: 100.0),
        value: 0,
        canTapOnHeader: true,
      ),
      ExpansionPanelRadio(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return Text(isExpanded ? 'D' : 'C', key: secondPanelKey);
        },
        body: const SizedBox(height: 100.0),
        value: 1,
        canTapOnHeader: true,
      ),
    ];

    final ExpansionPanelList expansionListRadio = ExpansionPanelList.radio(
      children: demoItemsRadio,
    );

    await tester.pumpWidget(
      MaterialApp(
        home: SingleChildScrollView(
          child: expansionListRadio,
        ),
      ),
    );

    // Initializes with all panels closed
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);

    await tester.tap(find.byKey(firstPanelKey));
    await tester.pumpAndSettle();

    // Now the first panel is open
    expect(find.text('A'), findsNothing);
    expect(find.text('B'), findsOneWidget);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);

    await tester.tap(find.byKey(secondPanelKey));
    await tester.pumpAndSettle();

    // Now the second panel is open
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsNothing);
    expect(find.text('D'), findsOneWidget);
  });

  testWidgets('Toggle ExpansionPanel when tapping header and canTapOnHeader is true',  (WidgetTester tester) async {
    const Key firstPanelKey = Key('firstPanelKey');
    const Key secondPanelKey = Key('secondPanelKey');

    await tester.pumpWidget(
      const MaterialApp(
        home: SingleChildScrollView(
          child: SimpleExpansionPanelListTestWidget(
            firstPanelKey: firstPanelKey,
            secondPanelKey: secondPanelKey,
            canTapOnHeader: true,
          ),
        ),
      ),
    );

    // Initializes with all panels closed
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);

    await tester.tap(find.byKey(firstPanelKey));
    await tester.pumpAndSettle();

    // The first panel is open
    expect(find.text('A'), findsNothing);
    expect(find.text('B'), findsOneWidget);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);

    await tester.tap(find.byKey(firstPanelKey));
    await tester.pumpAndSettle();

    // The first panel is closed
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);

    await tester.tap(find.byKey(secondPanelKey));
    await tester.pumpAndSettle();

    // The second panel is open
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsNothing);
    expect(find.text('D'), findsOneWidget);

    await tester.tap(find.byKey(secondPanelKey));
    await tester.pumpAndSettle();

    // The second panel is closed
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);
  });

  testWidgets('Do not toggle ExpansionPanel when tapping header and canTapOnHeader is false',  (WidgetTester tester) async {
    const Key firstPanelKey = Key('firstPanelKey');
    const Key secondPanelKey = Key('secondPanelKey');

    await tester.pumpWidget(
      const MaterialApp(
        home: SingleChildScrollView(
          child: SimpleExpansionPanelListTestWidget(
            firstPanelKey: firstPanelKey,
            secondPanelKey: secondPanelKey,
          ),
        ),
      ),
    );

    // Initializes with all panels closed
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);

    await tester.tap(find.byKey(firstPanelKey));
    await tester.pumpAndSettle();

    // The first panel is closed
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);

    await tester.tap(find.byKey(secondPanelKey));
    await tester.pumpAndSettle();

    // The second panel is closed
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);
  });

  testWidgets('Do not toggle ExpansionPanelRadio when tapping header and canTapOnHeader is false',  (WidgetTester tester) async {
    const Key firstPanelKey = Key('firstPanelKey');
    const Key secondPanelKey = Key('secondPanelKey');

    final List<ExpansionPanel> demoItemsRadio = <ExpansionPanelRadio>[
      ExpansionPanelRadio(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return Text(isExpanded ? 'B' : 'A', key: firstPanelKey);
        },
        body: const SizedBox(height: 100.0),
        value: 0,
      ),
      ExpansionPanelRadio(
        headerBuilder: (BuildContext context, bool isExpanded) {
          return Text(isExpanded ? 'D' : 'C', key: secondPanelKey);
        },
        body: const SizedBox(height: 100.0),
        value: 1,
      ),
    ];

    final ExpansionPanelList expansionListRadio = ExpansionPanelList.radio(
      children: demoItemsRadio,
    );

    await tester.pumpWidget(
      MaterialApp(
        home: SingleChildScrollView(
          child: expansionListRadio,
        ),
      ),
    );

    // Initializes with all panels closed
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);

    await tester.tap(find.byKey(firstPanelKey));
    await tester.pumpAndSettle();

    // The first panel is closed
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);

    await tester.tap(find.byKey(secondPanelKey));
    await tester.pumpAndSettle();

    // The second panel is closed
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);
    expect(find.text('C'), findsOneWidget);
    expect(find.text('D'), findsNothing);
  });

  testWidgets('Correct default header padding', (WidgetTester tester) async {
    const Key firstPanelKey = Key('firstPanelKey');

    await tester.pumpWidget(
      const MaterialApp(
        home: SingleChildScrollView(
          child: SimpleExpansionPanelListTestWidget(
            firstPanelKey: firstPanelKey,
            canTapOnHeader: true,
          ),
        ),
      ),
    );

    // The panel is closed
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);

    // No padding applied to closed header
    RenderBox box = tester.renderObject(find.ancestor(of: find.byKey(firstPanelKey), matching: find.byType(AnimatedContainer)).first);
    expect(box.size.height, equals(48.0)); // _kPanelHeaderCollapsedHeight
    expect(box.size.width, equals(736.0));

    // Now, expand the child panel.
    await tester.tap(find.byKey(firstPanelKey));
    await tester.pumpAndSettle();

    // The panel is expanded
    expect(find.text('A'), findsNothing);
    expect(find.text('B'), findsOneWidget);

    // Padding is added to expanded header
    box = tester.renderObject(find.ancestor(of: find.byKey(firstPanelKey), matching: find.byType(AnimatedContainer)).first);
    expect(box.size.height, equals(80.0)); // _kPanelHeaderCollapsedHeight + 32.0 (double default padding)
    expect(box.size.width, equals(736.0));
  });

  testWidgets('Correct custom header padding', (WidgetTester tester) async {
    const Key firstPanelKey = Key('firstPanelKey');

    await tester.pumpWidget(
      const MaterialApp(
        home: SingleChildScrollView(
          child: SimpleExpansionPanelListTestWidget(
            firstPanelKey: firstPanelKey,
            canTapOnHeader: true,
            expandedHeaderPadding: EdgeInsets.symmetric(vertical: 40.0),
          ),
        ),
      ),
    );

    // The panel is closed
    expect(find.text('A'), findsOneWidget);
    expect(find.text('B'), findsNothing);

    // No padding applied to closed header
    RenderBox box = tester.renderObject(find.ancestor(of: find.byKey(firstPanelKey), matching: find.byType(AnimatedContainer)).first);
    expect(box.size.height, equals(48.0)); // _kPanelHeaderCollapsedHeight
    expect(box.size.width, equals(736.0));

    // Now, expand the child panel.
    await tester.tap(find.byKey(firstPanelKey));
    await tester.pumpAndSettle();

    // The panel is expanded
    expect(find.text('A'), findsNothing);
    expect(find.text('B'), findsOneWidget);

    // Padding is added to expanded header
    box = tester.renderObject(find.ancestor(of: find.byKey(firstPanelKey), matching: find.byType(AnimatedContainer)).first);
    expect(box.size.height, equals(128.0)); // _kPanelHeaderCollapsedHeight + 80.0 (double padding)
    expect(box.size.width, equals(736.0));
  });

  testWidgets('ExpansionPanelList respects dividerColor', (WidgetTester tester) async {
    const Color dividerColor = Colors.red;
    await tester.pumpWidget(const MaterialApp(
      home: SingleChildScrollView(
        child: SimpleExpansionPanelListTestWidget(
          dividerColor: dividerColor,
        ),
      ),
    ));

    final DecoratedBox decoratedBox = tester.widget(find.byType(DecoratedBox).last);
    final BoxDecoration decoration = decoratedBox.decoration as BoxDecoration;

    // For the last DecoratedBox, we will have a Border.top with the provided dividerColor.
    expect(decoration.border!.top.color, dividerColor);
  });

  testWidgets('ExpansionPanelList.radio respects DividerColor', (WidgetTester tester) async {
    const Color dividerColor = Colors.red;
    await tester.pumpWidget(MaterialApp(
      home: SingleChildScrollView(
        child: ExpansionPanelList.radio(
          dividerColor: dividerColor,
          children: <ExpansionPanelRadio>[
            ExpansionPanelRadio(
              headerBuilder: (BuildContext context, bool isExpanded) {
                return Text(isExpanded ? 'B' : 'A', key: const Key('firstKey'));
              },
              body: const SizedBox(height: 100.0),
              value: 0,
            ),
            ExpansionPanelRadio(
              headerBuilder: (BuildContext context, bool isExpanded) {
                return Text(isExpanded ? 'D' : 'C', key: const Key('secondKey'));
              },
              body: const SizedBox(height: 100.0),
              value: 1,
            ),
          ],
        ),
      ),
    ));

    final DecoratedBox decoratedBox = tester.widget(find.byType(DecoratedBox).last);
    final BoxDecoration boxDecoration = decoratedBox.decoration as BoxDecoration;

    // For the last DecoratedBox, we will have a Border.top with the provided dividerColor.
    expect(boxDecoration.border!.top.color, dividerColor);
  });

  testWidgets('elevation is propagated properly to MergeableMaterial', (WidgetTester tester) async {
    const double elevation = 8;

    // Test for ExpansionPanelList.
    await tester.pumpWidget(const MaterialApp(
      home: SingleChildScrollView(
        child: SimpleExpansionPanelListTestWidget(
          elevation: elevation,
        ),
      ),
    ));

    expect(tester.widget<MergeableMaterial>(find.byType(MergeableMaterial)).elevation, elevation);

    // Test for ExpansionPanelList.radio.
    await tester.pumpWidget(MaterialApp(
      home: SingleChildScrollView(
        child: ExpansionPanelList.radio(
          elevation: elevation,
          children: <ExpansionPanelRadio>[
            ExpansionPanelRadio(
              headerBuilder: (BuildContext context, bool isExpanded) {
                return Text(isExpanded ? 'B' : 'A', key: const Key('firstKey'));
              },
              body: const SizedBox(height: 100.0),
              value: 0,
            ),
            ExpansionPanelRadio(
              headerBuilder: (BuildContext context, bool isExpanded) {
                return Text(isExpanded ? 'D' : 'C', key: const Key('secondKey'));
              },
              body: const SizedBox(height: 100.0),
              value: 1,
            ),
          ],
        ),
      ),
    ));

    expect(tester.widget<MergeableMaterial>(find.byType(MergeableMaterial)).elevation, elevation);
  });

  testWidgets('Using a value non defined value throws assertion error', (WidgetTester tester) async {

    // It should throw an AssertionError since, 19 is not defined in kElevationToShadow.
    await tester.pumpWidget(const MaterialApp(
      home: SingleChildScrollView(
        child: SimpleExpansionPanelListTestWidget(
          elevation: 19,
        ),
      ),
    ));

    final dynamic exception = tester.takeException();
    expect(exception, isAssertionError);
    expect((exception as AssertionError).toString(), contains(
      'Invalid value for elevation. See the kElevationToShadow constant for'
      ' possible elevation values.',
    ));
  });

  testWidgets('ExpansionPanel.panelColor test', (WidgetTester tester) async {
    const Color firstPanelColor = Colors.red;
    const Color secondPanelColor = Colors.brown;

    await tester.pumpWidget(
      MaterialApp(
        home: SingleChildScrollView(
          child: ExpansionPanelList(
            expansionCallback: (int index, bool isExpanded) {},
            children: <ExpansionPanel>[
              ExpansionPanel(
                backgroundColor: firstPanelColor,
                headerBuilder: (BuildContext context, bool isExpanded) {
                  return const Text('A');
                },
                body: const SizedBox(height: 100.0),
              ),
              ExpansionPanel(
                backgroundColor: secondPanelColor,
                headerBuilder: (BuildContext context, bool isExpanded) {
                  return const Text('B');
                },
                body: const SizedBox(height: 100.0),
              ),
            ],
          ),
        ),
      ),
    );

    final MergeableMaterial mergeableMaterial = tester.widget(find.byType(MergeableMaterial));

    expect((mergeableMaterial.children.first as MaterialSlice).color, firstPanelColor);
    expect((mergeableMaterial.children.last as MaterialSlice).color, secondPanelColor);
  });

  testWidgets('ExpansionPanelRadio.backgroundColor test', (WidgetTester tester) async {
    const Color firstPanelColor = Colors.red;
    const Color secondPanelColor = Colors.brown;

    await tester.pumpWidget(MaterialApp(
      home: SingleChildScrollView(
        child: ExpansionPanelList.radio(
          children: <ExpansionPanelRadio>[
            ExpansionPanelRadio(
              backgroundColor: firstPanelColor,
              headerBuilder: (BuildContext context, bool isExpanded) {
                return const Text('A');
              },
              body: const SizedBox(height: 100.0),
              value: 0,
            ),
            ExpansionPanelRadio(
              backgroundColor: secondPanelColor,
              headerBuilder: (BuildContext context, bool isExpanded) {
                return const Text('B');
              },
              body: const SizedBox(height: 100.0),
              value: 1,
            ),
          ],
        ),
      ),
    ));

    final MergeableMaterial mergeableMaterial = tester.widget(find.byType(MergeableMaterial));

    expect((mergeableMaterial.children.first as MaterialSlice).color, firstPanelColor);
    expect((mergeableMaterial.children.last as MaterialSlice).color, secondPanelColor);
  });
}
