// Copyright 2013 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:animations/src/open_container.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  testWidgets(
    'Container opens - Fade (by default)',
    (WidgetTester tester) async {
      const ShapeBorder shape = RoundedRectangleBorder(
        borderRadius: BorderRadius.all(Radius.circular(8.0)),
      );
      bool closedBuilderCalled = false;
      bool openBuilderCalled = false;

      await tester.pumpWidget(_boilerplate(
        child: Center(
          child: OpenContainer(
            closedColor: Colors.green,
            openColor: Colors.blue,
            closedElevation: 4.0,
            openElevation: 8.0,
            closedShape: shape,
            closedBuilder: (BuildContext context, VoidCallback _) {
              closedBuilderCalled = true;
              return const Text('Closed');
            },
            openBuilder: (BuildContext context, VoidCallback _) {
              openBuilderCalled = true;
              return const Text('Open');
            },
          ),
        ),
      ));

      // Closed container has the expected properties.
      final StatefulElement srcMaterialElement = tester.firstElement(
        find.ancestor(
          of: find.text('Closed'),
          matching: find.byType(Material),
        ),
      );
      final Material srcMaterial = srcMaterialElement.widget as Material;
      expect(srcMaterial.color, Colors.green);
      expect(srcMaterial.elevation, 4.0);
      expect(srcMaterial.shape, shape);
      expect(find.text('Closed'), findsOneWidget);
      expect(find.text('Open'), findsNothing);
      expect(closedBuilderCalled, isTrue);
      expect(openBuilderCalled, isFalse);
      final Rect srcMaterialRect = tester.getRect(
        find.byElementPredicate((Element e) => e == srcMaterialElement),
      );

      // Open the container.
      await tester.tap(find.text('Closed'));
      expect(find.text('Closed'), findsOneWidget);
      expect(find.text('Open'), findsNothing);
      await tester.pump();

      // On the first frame of the animation everything still looks like before.
      final StatefulElement destMaterialElement = tester.firstElement(
        find.ancestor(
          of: find.text('Closed'),
          matching: find.byType(Material),
        ),
      );
      final Material closedMaterial = destMaterialElement.widget as Material;
      expect(closedMaterial.color, Colors.green);
      expect(closedMaterial.elevation, 4.0);
      expect(closedMaterial.shape, shape);
      expect(find.text('Closed'), findsOneWidget);
      expect(find.text('Open'), findsOneWidget);
      final Rect closedMaterialRect = tester.getRect(
        find.byElementPredicate((Element e) => e == destMaterialElement),
      );
      expect(closedMaterialRect, srcMaterialRect);
      expect(_getOpacity(tester, 'Open'), 0.0);
      expect(_getOpacity(tester, 'Closed'), 1.0);

      final _TrackedData dataClosed = _TrackedData(
        closedMaterial,
        closedMaterialRect,
      );

      // Jump to the start of the fade in.
      await tester.pump(const Duration(milliseconds: 60)); // 300ms * 1/5 = 60ms
      final _TrackedData dataPreFade = _TrackedData(
        destMaterialElement.widget as Material,
        tester.getRect(
          find.byElementPredicate((Element e) => e == destMaterialElement),
        ),
      );
      _expectMaterialPropertiesHaveAdvanced(
        smallerMaterial: dataClosed,
        biggerMaterial: dataPreFade,
        tester: tester,
      );
      expect(_getOpacity(tester, 'Open'), moreOrLessEquals(0.0));
      expect(_getOpacity(tester, 'Closed'), 1.0);

      // Jump to the middle of the fade in.
      await tester
          .pump(const Duration(milliseconds: 30)); // 300ms * 3/10 = 90ms
      final _TrackedData dataMidFadeIn = _TrackedData(
        destMaterialElement.widget as Material,
        tester.getRect(
          find.byElementPredicate((Element e) => e == destMaterialElement),
        ),
      );
      _expectMaterialPropertiesHaveAdvanced(
        smallerMaterial: dataPreFade,
        biggerMaterial: dataMidFadeIn,
        tester: tester,
      );
      expect(dataMidFadeIn.material.color, isNot(dataPreFade.material.color));
      expect(_getOpacity(tester, 'Open'), lessThan(1.0));
      expect(_getOpacity(tester, 'Open'), greaterThan(0.0));
      expect(_getOpacity(tester, 'Closed'), 1.0);

      // Jump to the end of the fade in at 2/5 of 300ms.
      await tester.pump(
        const Duration(milliseconds: 30),
      ); // 300ms * 2/5 = 120ms

      final _TrackedData dataPostFadeIn = _TrackedData(
        destMaterialElement.widget as Material,
        tester.getRect(
          find.byElementPredicate((Element e) => e == destMaterialElement),
        ),
      );
      _expectMaterialPropertiesHaveAdvanced(
        smallerMaterial: dataMidFadeIn,
        biggerMaterial: dataPostFadeIn,
        tester: tester,
      );
      expect(_getOpacity(tester, 'Open'), moreOrLessEquals(1.0));
      expect(_getOpacity(tester, 'Closed'), 1.0);

      // Jump almost to the end of the transition.
      await tester.pump(const Duration(milliseconds: 180));
      final _TrackedData dataTransitionDone = _TrackedData(
        destMaterialElement.widget as Material,
        tester.getRect(
          find.byElementPredicate((Element e) => e == destMaterialElement),
        ),
      );
      _expectMaterialPropertiesHaveAdvanced(
        smallerMaterial: dataMidFadeIn,
        biggerMaterial: dataTransitionDone,
        tester: tester,
      );
      expect(_getOpacity(tester, 'Open'), 1.0);
      expect(dataTransitionDone.material.color, Colors.blue);
      expect(dataTransitionDone.material.elevation, 8.0);
      expect(dataTransitionDone.radius, 0.0);
      expect(dataTransitionDone.rect, const Rect.fromLTRB(0, 0, 800, 600));

      await tester.pump(const Duration(milliseconds: 1));
      expect(find.text('Closed'), findsNothing); // No longer in the tree.
      expect(find.text('Open'), findsOneWidget);
      final StatefulElement finalMaterialElement = tester.firstElement(
        find.ancestor(
          of: find.text('Open'),
          matching: find.byType(Material),
        ),
      );
      final _TrackedData dataOpen = _TrackedData(
        finalMaterialElement.widget as Material,
        tester.getRect(
          find.byElementPredicate((Element e) => e == finalMaterialElement),
        ),
      );
      expect(dataOpen.material.color, dataTransitionDone.material.color);
      expect(
          dataOpen.material.elevation, dataTransitionDone.material.elevation);
      expect(dataOpen.radius, dataTransitionDone.radius);
      expect(dataOpen.rect, dataTransitionDone.rect);
    },
  );

  testWidgets(
    'Container closes - Fade (by default)',
    (WidgetTester tester) async {
      const ShapeBorder shape = RoundedRectangleBorder(
        borderRadius: BorderRadius.all(Radius.circular(8.0)),
      );

      await tester.pumpWidget(_boilerplate(
        child: Center(
          child: OpenContainer(
            closedColor: Colors.green,
            openColor: Colors.blue,
            closedElevation: 4.0,
            openElevation: 8.0,
            closedShape: shape,
            closedBuilder: (BuildContext context, VoidCallback _) {
              return const Text('Closed');
            },
            openBuilder: (BuildContext context, VoidCallback _) {
              return const Text('Open');
            },
          ),
        ),
      ));

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

      // Open container has the expected properties.
      expect(find.text('Closed'), findsNothing);
      expect(find.text('Open'), findsOneWidget);
      final StatefulElement initialMaterialElement = tester.firstElement(
        find.ancestor(
          of: find.text('Open'),
          matching: find.byType(Material),
        ),
      );
      final _TrackedData dataOpen = _TrackedData(
        initialMaterialElement.widget as Material,
        tester.getRect(
          find.byElementPredicate((Element e) => e == initialMaterialElement),
        ),
      );
      expect(dataOpen.material.color, Colors.blue);
      expect(dataOpen.material.elevation, 8.0);
      expect(dataOpen.radius, 0.0);
      expect(dataOpen.rect, const Rect.fromLTRB(0, 0, 800, 600));

      // Close the container.
      final NavigatorState navigator = tester.state(find.byType(Navigator));
      navigator.pop();
      await tester.pump();

      expect(find.text('Closed'), findsOneWidget);
      expect(find.text('Open'), findsOneWidget);
      final StatefulElement materialElement = tester.firstElement(
        find.ancestor(
          of: find.text('Open'),
          matching: find.byType(Material),
        ),
      );
      final _TrackedData dataTransitionStart = _TrackedData(
        materialElement.widget as Material,
        tester.getRect(
          find.byElementPredicate((Element e) => e == materialElement),
        ),
      );
      expect(dataTransitionStart.material.color, dataOpen.material.color);
      expect(
          dataTransitionStart.material.elevation, dataOpen.material.elevation);
      expect(dataTransitionStart.radius, dataOpen.radius);
      expect(dataTransitionStart.rect, dataOpen.rect);
      expect(_getOpacity(tester, 'Open'), 1.0);
      await tester.pump(const Duration(microseconds: 1)); // 300 * 1/5 = 60

      // Jump to start of fade out: 1/5 of 300.
      await tester.pump(const Duration(milliseconds: 60)); // 300 * 1/5 = 60
      final _TrackedData dataPreFadeOut = _TrackedData(
        materialElement.widget as Material,
        tester.getRect(
          find.byElementPredicate((Element e) => e == materialElement),
        ),
      );
      _expectMaterialPropertiesHaveAdvanced(
        smallerMaterial: dataPreFadeOut,
        biggerMaterial: dataTransitionStart,
        tester: tester,
      );
      expect(_getOpacity(tester, 'Open'), moreOrLessEquals(1.0));
      expect(_getOpacity(tester, 'Closed'), 1.0);

      // Jump to the middle of the fade out.
      await tester.pump(const Duration(milliseconds: 30)); // 300 * 3/10 = 90
      final _TrackedData dataMidpoint = _TrackedData(
        materialElement.widget as Material,
        tester.getRect(
          find.byElementPredicate((Element e) => e == materialElement),
        ),
      );
      _expectMaterialPropertiesHaveAdvanced(
        smallerMaterial: dataMidpoint,
        biggerMaterial: dataPreFadeOut,
        tester: tester,
      );
      expect(dataMidpoint.material.color, isNot(dataPreFadeOut.material.color));
      expect(_getOpacity(tester, 'Open'), lessThan(1.0));
      expect(_getOpacity(tester, 'Open'), greaterThan(0.0));
      expect(_getOpacity(tester, 'Closed'), 1.0);

      // Jump to the end of the fade out.
      await tester.pump(const Duration(milliseconds: 30)); // 300 * 2/5 = 120
      final _TrackedData dataPostFadeOut = _TrackedData(
        materialElement.widget as Material,
        tester.getRect(
          find.byElementPredicate((Element e) => e == materialElement),
        ),
      );
      _expectMaterialPropertiesHaveAdvanced(
        smallerMaterial: dataPostFadeOut,
        biggerMaterial: dataMidpoint,
        tester: tester,
      );
      expect(_getOpacity(tester, 'Open'), moreOrLessEquals(0.0));
      expect(_getOpacity(tester, 'Closed'), 1.0);

      // Jump almost to the end of the transition.
      await tester.pump(const Duration(milliseconds: 180));
      final _TrackedData dataTransitionDone = _TrackedData(
        materialElement.widget as Material,
        tester.getRect(
          find.byElementPredicate((Element e) => e == materialElement),
        ),
      );
      _expectMaterialPropertiesHaveAdvanced(
        smallerMaterial: dataTransitionDone,
        biggerMaterial: dataPostFadeOut,
        tester: tester,
      );
      expect(_getOpacity(tester, 'Closed'), 1.0);
      expect(_getOpacity(tester, 'Open'), 0.0);
      expect(dataTransitionDone.material.color, Colors.green);
      expect(dataTransitionDone.material.elevation, 4.0);
      expect(dataTransitionDone.radius, 8.0);

      await tester.pump(const Duration(milliseconds: 1));
      expect(find.text('Open'), findsNothing); // No longer in the tree.
      expect(find.text('Closed'), findsOneWidget);
      final StatefulElement finalMaterialElement = tester.firstElement(
        find.ancestor(
          of: find.text('Closed'),
          matching: find.byType(Material),
        ),
      );
      final _TrackedData dataClosed = _TrackedData(
        finalMaterialElement.widget as Material,
        tester.getRect(
          find.byElementPredicate((Element e) => e == finalMaterialElement),
        ),
      );
      expect(dataClosed.material.color, dataTransitionDone.material.color);
      expect(
        dataClosed.material.elevation,
        dataTransitionDone.material.elevation,
      );
      expect(dataClosed.radius, dataTransitionDone.radius);
      expect(dataClosed.rect, dataTransitionDone.rect);
    },
  );

  testWidgets('Container opens - Fade through', (WidgetTester tester) async {
    const ShapeBorder shape = RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(8.0)),
    );
    bool closedBuilderCalled = false;
    bool openBuilderCalled = false;

    await tester.pumpWidget(_boilerplate(
      child: Center(
        child: OpenContainer(
          closedColor: Colors.green,
          openColor: Colors.blue,
          middleColor: Colors.red,
          closedElevation: 4.0,
          openElevation: 8.0,
          closedShape: shape,
          closedBuilder: (BuildContext context, VoidCallback _) {
            closedBuilderCalled = true;
            return const Text('Closed');
          },
          openBuilder: (BuildContext context, VoidCallback _) {
            openBuilderCalled = true;
            return const Text('Open');
          },
          transitionType: ContainerTransitionType.fadeThrough,
        ),
      ),
    ));

    // Closed container has the expected properties.
    final StatefulElement srcMaterialElement = tester.firstElement(
      find.ancestor(
        of: find.text('Closed'),
        matching: find.byType(Material),
      ),
    );
    final Material srcMaterial = srcMaterialElement.widget as Material;
    expect(srcMaterial.color, Colors.green);
    expect(srcMaterial.elevation, 4.0);
    expect(srcMaterial.shape, shape);
    expect(find.text('Closed'), findsOneWidget);
    expect(find.text('Open'), findsNothing);
    expect(closedBuilderCalled, isTrue);
    expect(openBuilderCalled, isFalse);
    final Rect srcMaterialRect = tester.getRect(
      find.byElementPredicate((Element e) => e == srcMaterialElement),
    );

    // Open the container.
    await tester.tap(find.text('Closed'));
    expect(find.text('Closed'), findsOneWidget);
    expect(find.text('Open'), findsNothing);
    await tester.pump();

    // On the first frame of the animation everything still looks like before.
    final StatefulElement destMaterialElement = tester.firstElement(
      find.ancestor(
        of: find.text('Closed'),
        matching: find.byType(Material),
      ),
    );
    final Material closedMaterial = destMaterialElement.widget as Material;
    expect(closedMaterial.color, Colors.green);
    expect(closedMaterial.elevation, 4.0);
    expect(closedMaterial.shape, shape);
    expect(find.text('Closed'), findsOneWidget);
    expect(find.text('Open'), findsOneWidget);
    final Rect closedMaterialRect = tester.getRect(
      find.byElementPredicate((Element e) => e == destMaterialElement),
    );
    expect(closedMaterialRect, srcMaterialRect);
    expect(_getOpacity(tester, 'Open'), 0.0);
    expect(_getOpacity(tester, 'Closed'), 1.0);

    final _TrackedData dataClosed = _TrackedData(
      closedMaterial,
      closedMaterialRect,
    );

    // The fade-out takes 1/5 of 300ms. Let's jump to the midpoint of that.
    await tester.pump(const Duration(milliseconds: 30)); // 300ms * 1/10 = 30ms
    final _TrackedData dataMidFadeOut = _TrackedData(
      destMaterialElement.widget as Material,
      tester.getRect(
        find.byElementPredicate((Element e) => e == destMaterialElement),
      ),
    );
    _expectMaterialPropertiesHaveAdvanced(
      smallerMaterial: dataClosed,
      biggerMaterial: dataMidFadeOut,
      tester: tester,
    );
    expect(dataMidFadeOut.material.color, isNot(dataClosed.material.color));
    expect(_getOpacity(tester, 'Open'), 0.0);
    expect(_getOpacity(tester, 'Closed'), lessThan(1.0));
    expect(_getOpacity(tester, 'Closed'), greaterThan(0.0));

    // Let's jump to the crossover point at 1/5 of 300ms.
    await tester.pump(const Duration(milliseconds: 30)); // 300ms * 1/5 = 60ms
    final _TrackedData dataMidpoint = _TrackedData(
      destMaterialElement.widget as Material,
      tester.getRect(
        find.byElementPredicate((Element e) => e == destMaterialElement),
      ),
    );
    _expectMaterialPropertiesHaveAdvanced(
      smallerMaterial: dataMidFadeOut,
      biggerMaterial: dataMidpoint,
      tester: tester,
    );
    expect(dataMidpoint.material.color, Colors.red);
    expect(_getOpacity(tester, 'Open'), moreOrLessEquals(0.0));
    expect(_getOpacity(tester, 'Closed'), moreOrLessEquals(0.0));

    // Let's jump to the middle of the fade-in at 3/5 of 300ms
    await tester.pump(const Duration(milliseconds: 120)); // 300ms * 3/5 = 180ms
    final _TrackedData dataMidFadeIn = _TrackedData(
      destMaterialElement.widget as Material,
      tester.getRect(
        find.byElementPredicate((Element e) => e == destMaterialElement),
      ),
    );
    _expectMaterialPropertiesHaveAdvanced(
      smallerMaterial: dataMidpoint,
      biggerMaterial: dataMidFadeIn,
      tester: tester,
    );
    expect(dataMidFadeIn.material.color, isNot(dataMidpoint.material.color));
    expect(_getOpacity(tester, 'Open'), lessThan(1.0));
    expect(_getOpacity(tester, 'Open'), greaterThan(0.0));
    expect(_getOpacity(tester, 'Closed'), 0.0);

    // Let's jump almost to the end of the transition.
    await tester.pump(const Duration(milliseconds: 120));
    final _TrackedData dataTransitionDone = _TrackedData(
      destMaterialElement.widget as Material,
      tester.getRect(
        find.byElementPredicate((Element e) => e == destMaterialElement),
      ),
    );
    _expectMaterialPropertiesHaveAdvanced(
      smallerMaterial: dataMidFadeIn,
      biggerMaterial: dataTransitionDone,
      tester: tester,
    );
    expect(
      dataTransitionDone.material.color,
      isNot(dataMidFadeIn.material.color),
    );
    expect(_getOpacity(tester, 'Open'), 1.0);
    expect(_getOpacity(tester, 'Closed'), 0.0);
    expect(dataTransitionDone.material.color, Colors.blue);
    expect(dataTransitionDone.material.elevation, 8.0);
    expect(dataTransitionDone.radius, 0.0);
    expect(dataTransitionDone.rect, const Rect.fromLTRB(0, 0, 800, 600));

    await tester.pump(const Duration(milliseconds: 1));
    expect(find.text('Closed'), findsNothing); // No longer in the tree.
    expect(find.text('Open'), findsOneWidget);
    final StatefulElement finalMaterialElement = tester.firstElement(
      find.ancestor(
        of: find.text('Open'),
        matching: find.byType(Material),
      ),
    );
    final _TrackedData dataOpen = _TrackedData(
      finalMaterialElement.widget as Material,
      tester.getRect(
        find.byElementPredicate((Element e) => e == finalMaterialElement),
      ),
    );
    expect(dataOpen.material.color, dataTransitionDone.material.color);
    expect(dataOpen.material.elevation, dataTransitionDone.material.elevation);
    expect(dataOpen.radius, dataTransitionDone.radius);
    expect(dataOpen.rect, dataTransitionDone.rect);
  });

  testWidgets('Container closes - Fade through', (WidgetTester tester) async {
    const ShapeBorder shape = RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(8.0)),
    );

    await tester.pumpWidget(_boilerplate(
      child: Center(
        child: OpenContainer(
          closedColor: Colors.green,
          openColor: Colors.blue,
          middleColor: Colors.red,
          closedElevation: 4.0,
          openElevation: 8.0,
          closedShape: shape,
          closedBuilder: (BuildContext context, VoidCallback _) {
            return const Text('Closed');
          },
          openBuilder: (BuildContext context, VoidCallback _) {
            return const Text('Open');
          },
          transitionType: ContainerTransitionType.fadeThrough,
        ),
      ),
    ));

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

    // Open container has the expected properties.
    expect(find.text('Closed'), findsNothing);
    expect(find.text('Open'), findsOneWidget);
    final StatefulElement initialMaterialElement = tester.firstElement(
      find.ancestor(
        of: find.text('Open'),
        matching: find.byType(Material),
      ),
    );
    final _TrackedData dataOpen = _TrackedData(
      initialMaterialElement.widget as Material,
      tester.getRect(
        find.byElementPredicate((Element e) => e == initialMaterialElement),
      ),
    );
    expect(dataOpen.material.color, Colors.blue);
    expect(dataOpen.material.elevation, 8.0);
    expect(dataOpen.radius, 0.0);
    expect(dataOpen.rect, const Rect.fromLTRB(0, 0, 800, 600));

    // Close the container.
    final NavigatorState navigator = tester.state(find.byType(Navigator));
    navigator.pop();
    await tester.pump();
    await tester.pump();

    expect(find.text('Closed'), findsOneWidget);
    expect(find.text('Open'), findsOneWidget);
    final StatefulElement materialElement = tester.firstElement(
      find.ancestor(
        of: find.text('Open'),
        matching: find.byType(Material),
      ),
    );
    final _TrackedData dataTransitionStart = _TrackedData(
      materialElement.widget as Material,
      tester.getRect(
        find.byElementPredicate((Element e) => e == materialElement),
      ),
    );
    expect(dataTransitionStart.material.color, dataOpen.material.color);
    expect(dataTransitionStart.material.elevation, dataOpen.material.elevation);
    expect(dataTransitionStart.radius, dataOpen.radius);
    expect(dataTransitionStart.rect, dataOpen.rect);
    expect(_getOpacity(tester, 'Open'), 1.0);
    expect(_getOpacity(tester, 'Closed'), 0.0);

    // Jump to mid-point of fade-out: 1/10 of 300ms.
    await tester.pump(const Duration(milliseconds: 30)); // 300ms * 1/10 = 30ms
    final _TrackedData dataMidFadeOut = _TrackedData(
      materialElement.widget as Material,
      tester.getRect(
        find.byElementPredicate((Element e) => e == materialElement),
      ),
    );
    _expectMaterialPropertiesHaveAdvanced(
      smallerMaterial: dataMidFadeOut,
      biggerMaterial: dataTransitionStart,
      tester: tester,
    );
    expect(
      dataMidFadeOut.material.color,
      isNot(dataTransitionStart.material.color),
    );
    expect(_getOpacity(tester, 'Closed'), 0.0);
    expect(_getOpacity(tester, 'Open'), lessThan(1.0));
    expect(_getOpacity(tester, 'Open'), greaterThan(0.0));

    // Let's jump to the crossover point at 1/5 of 300ms.
    await tester.pump(const Duration(milliseconds: 30)); // 300ms * 1/5 = 60ms
    final _TrackedData dataMidpoint = _TrackedData(
      materialElement.widget as Material,
      tester.getRect(
        find.byElementPredicate((Element e) => e == materialElement),
      ),
    );
    _expectMaterialPropertiesHaveAdvanced(
      smallerMaterial: dataMidpoint,
      biggerMaterial: dataMidFadeOut,
      tester: tester,
    );
    expect(dataMidpoint.material.color, Colors.red);
    expect(_getOpacity(tester, 'Open'), moreOrLessEquals(0.0));
    expect(_getOpacity(tester, 'Closed'), moreOrLessEquals(0.0));

    // Let's jump to the middle of the fade-in at 3/5 of 300ms
    await tester.pump(const Duration(milliseconds: 120)); // 300ms * 3/5 = 180ms
    final _TrackedData dataMidFadeIn = _TrackedData(
      materialElement.widget as Material,
      tester.getRect(
        find.byElementPredicate((Element e) => e == materialElement),
      ),
    );
    _expectMaterialPropertiesHaveAdvanced(
      smallerMaterial: dataMidFadeIn,
      biggerMaterial: dataMidpoint,
      tester: tester,
    );
    expect(dataMidFadeIn.material.color, isNot(dataMidpoint.material.color));
    expect(_getOpacity(tester, 'Closed'), lessThan(1.0));
    expect(_getOpacity(tester, 'Closed'), greaterThan(0.0));
    expect(_getOpacity(tester, 'Open'), 0.0);

    // Let's jump almost to the end of the transition.
    await tester.pump(const Duration(milliseconds: 120));
    final _TrackedData dataTransitionDone = _TrackedData(
      materialElement.widget as Material,
      tester.getRect(
        find.byElementPredicate((Element e) => e == materialElement),
      ),
    );
    _expectMaterialPropertiesHaveAdvanced(
      smallerMaterial: dataTransitionDone,
      biggerMaterial: dataMidFadeIn,
      tester: tester,
    );
    expect(
      dataTransitionDone.material.color,
      isNot(dataMidFadeIn.material.color),
    );
    expect(_getOpacity(tester, 'Closed'), 1.0);
    expect(_getOpacity(tester, 'Open'), 0.0);
    expect(dataTransitionDone.material.color, Colors.green);
    expect(dataTransitionDone.material.elevation, 4.0);
    expect(dataTransitionDone.radius, 8.0);

    await tester.pump(const Duration(milliseconds: 1));
    expect(find.text('Open'), findsNothing); // No longer in the tree.
    expect(find.text('Closed'), findsOneWidget);
    final StatefulElement finalMaterialElement = tester.firstElement(
      find.ancestor(
        of: find.text('Closed'),
        matching: find.byType(Material),
      ),
    );
    final _TrackedData dataClosed = _TrackedData(
      finalMaterialElement.widget as Material,
      tester.getRect(
        find.byElementPredicate((Element e) => e == finalMaterialElement),
      ),
    );
    expect(dataClosed.material.color, dataTransitionDone.material.color);
    expect(
      dataClosed.material.elevation,
      dataTransitionDone.material.elevation,
    );
    expect(dataClosed.radius, dataTransitionDone.radius);
    expect(dataClosed.rect, dataTransitionDone.rect);
  });

  testWidgets('Cannot tap container if tappable=false',
      (WidgetTester tester) async {
    await tester.pumpWidget(_boilerplate(
      child: Center(
        child: OpenContainer(
          tappable: false,
          closedBuilder: (BuildContext context, VoidCallback _) {
            return const Text('Closed');
          },
          openBuilder: (BuildContext context, VoidCallback _) {
            return const Text('Open');
          },
        ),
      ),
    ));

    expect(find.text('Open'), findsNothing);
    expect(find.text('Closed'), findsOneWidget);
    await tester.tap(find.text('Closed'));
    await tester.pumpAndSettle();
    expect(find.text('Open'), findsNothing);
    expect(find.text('Closed'), findsOneWidget);
  });

  testWidgets('Action callbacks work', (WidgetTester tester) async {
    late VoidCallback open, close;
    await tester.pumpWidget(_boilerplate(
      child: Center(
        child: OpenContainer(
          tappable: false,
          closedBuilder: (BuildContext context, VoidCallback action) {
            open = action;
            return const Text('Closed');
          },
          openBuilder: (BuildContext context, VoidCallback action) {
            close = action;
            return const Text('Open');
          },
        ),
      ),
    ));

    expect(find.text('Open'), findsNothing);
    expect(find.text('Closed'), findsOneWidget);

    expect(open, isNotNull);
    open();
    await tester.pumpAndSettle();

    expect(find.text('Open'), findsOneWidget);
    expect(find.text('Closed'), findsNothing);

    expect(close, isNotNull);
    close();
    await tester.pumpAndSettle();

    expect(find.text('Open'), findsNothing);
    expect(find.text('Closed'), findsOneWidget);
  });

  testWidgets('open widget keeps state', (WidgetTester tester) async {
    await tester.pumpWidget(_boilerplate(
      child: Center(
        child: OpenContainer(
          closedBuilder: (BuildContext context, VoidCallback action) {
            return const Text('Closed');
          },
          openBuilder: (BuildContext context, VoidCallback action) {
            return const DummyStatefulWidget();
          },
        ),
      ),
    ));

    await tester.tap(find.text('Closed'));
    await tester.pump(const Duration(milliseconds: 200));

    final State stateOpening = tester.state(find.byType(DummyStatefulWidget));
    expect(stateOpening, isNotNull);

    await tester.pumpAndSettle();
    expect(find.text('Closed'), findsNothing);
    final State stateOpen = tester.state(find.byType(DummyStatefulWidget));
    expect(stateOpen, isNotNull);
    expect(stateOpen, same(stateOpening));

    final NavigatorState navigator = tester.state(find.byType(Navigator));
    navigator.pop();
    await tester.pump(const Duration(milliseconds: 200));
    expect(find.text('Closed'), findsOneWidget);
    final State stateClosing = tester.state(find.byType(DummyStatefulWidget));
    expect(stateClosing, isNotNull);
    expect(stateClosing, same(stateOpen));
  });

  testWidgets('closed widget keeps state', (WidgetTester tester) async {
    late VoidCallback open;
    await tester.pumpWidget(_boilerplate(
      child: Center(
        child: OpenContainer(
          closedBuilder: (BuildContext context, VoidCallback action) {
            open = action;
            return const DummyStatefulWidget();
          },
          openBuilder: (BuildContext context, VoidCallback action) {
            return const Text('Open');
          },
        ),
      ),
    ));

    final State stateClosed = tester.state(find.byType(DummyStatefulWidget));
    expect(stateClosed, isNotNull);

    open();
    await tester.pump(const Duration(milliseconds: 200));
    expect(find.text('Open'), findsOneWidget);

    final State stateOpening = tester.state(find.byType(DummyStatefulWidget));
    expect(stateOpening, same(stateClosed));

    await tester.pumpAndSettle();
    expect(find.byType(DummyStatefulWidget), findsNothing);
    expect(find.text('Open'), findsOneWidget);
    final State stateOpen = tester.state(find.byType(
      DummyStatefulWidget,
      skipOffstage: false,
    ));
    expect(stateOpen, same(stateOpening));

    final NavigatorState navigator = tester.state(find.byType(Navigator));
    navigator.pop();
    await tester.pump(const Duration(milliseconds: 200));
    expect(find.text('Open'), findsOneWidget);
    final State stateClosing = tester.state(find.byType(DummyStatefulWidget));
    expect(stateClosing, same(stateOpen));

    await tester.pumpAndSettle();
    expect(find.text('Open'), findsNothing);
    final State stateClosedAgain =
        tester.state(find.byType(DummyStatefulWidget));
    expect(stateClosedAgain, same(stateClosing));
  });

  testWidgets('closes to the right location when src position has changed',
      (WidgetTester tester) async {
    final Widget openContainer = OpenContainer(
      closedBuilder: (BuildContext context, VoidCallback action) {
        return const SizedBox(
          height: 100,
          width: 100,
          child: Text('Closed'),
        );
      },
      openBuilder: (BuildContext context, VoidCallback action) {
        return GestureDetector(
          onTap: action,
          child: const Text('Open'),
        );
      },
    );

    await tester.pumpWidget(_boilerplate(
      child: Align(
        alignment: Alignment.topLeft,
        child: openContainer,
      ),
    ));

    final Rect originTextRect = tester.getRect(find.text('Closed'));
    expect(originTextRect.topLeft, Offset.zero);

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

    expect(find.text('Open'), findsOneWidget);
    expect(find.text('Closed'), findsNothing);

    await tester.pumpWidget(_boilerplate(
      child: Align(
        alignment: Alignment.bottomLeft,
        child: openContainer,
      ),
    ));

    expect(find.text('Open'), findsOneWidget);
    expect(find.text('Closed'), findsNothing);

    await tester.tap(find.text('Open'));
    await tester.pump(); // Need one frame to measure things in the old route.
    await tester.pump(const Duration(milliseconds: 300));
    expect(find.text('Open'), findsOneWidget);
    expect(find.text('Closed'), findsOneWidget);

    final Rect transitionEndTextRect = tester.getRect(find.text('Open'));
    expect(transitionEndTextRect.topLeft, const Offset(0.0, 600.0 - 100.0));

    await tester.pump(const Duration(milliseconds: 1));
    expect(find.text('Open'), findsNothing);
    expect(find.text('Closed'), findsOneWidget);

    final Rect finalTextRect = tester.getRect(find.text('Closed'));
    expect(finalTextRect.topLeft, transitionEndTextRect.topLeft);
  });

  testWidgets('src changes size while open', (WidgetTester tester) async {
    final Widget openContainer = _boilerplate(
      child: Center(
        child: OpenContainer(
          closedBuilder: (BuildContext context, VoidCallback action) {
            return const _SizableContainer(
              initialSize: 100,
              child: Text('Closed'),
            );
          },
          openBuilder: (BuildContext context, VoidCallback action) {
            return GestureDetector(
              onTap: action,
              child: const Text('Open'),
            );
          },
        ),
      ),
    );

    await tester.pumpWidget(openContainer);

    final Size orignalClosedRect = tester.getSize(find
        .ancestor(
          of: find.text('Closed'),
          matching: find.byType(Material),
        )
        .first);
    expect(orignalClosedRect, const Size(100, 100));

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

    expect(find.text('Open'), findsOneWidget);
    expect(find.text('Closed'), findsNothing);

    final _SizableContainerState containerState = tester.state(find.byType(
      _SizableContainer,
      skipOffstage: false,
    ));
    containerState.size = 200;

    expect(find.text('Open'), findsOneWidget);
    expect(find.text('Closed'), findsNothing);
    await tester.tap(find.text('Open'));
    await tester.pump(); // Need one frame to measure things in the old route.
    await tester.pump(const Duration(milliseconds: 300));
    expect(find.text('Open'), findsOneWidget);
    expect(find.text('Closed'), findsOneWidget);

    final Size transitionEndSize = tester.getSize(find
        .ancestor(
          of: find.text('Open'),
          matching: find.byType(Material),
        )
        .first);
    expect(transitionEndSize, const Size(200, 200));

    await tester.pump(const Duration(milliseconds: 1));
    expect(find.text('Open'), findsNothing);
    expect(find.text('Closed'), findsOneWidget);

    final Size finalSize = tester.getSize(find
        .ancestor(
          of: find.text('Closed'),
          matching: find.byType(Material),
        )
        .first);
    expect(finalSize, const Size(200, 200));
  });

  testWidgets('transition is interrupted and should not jump',
      (WidgetTester tester) async {
    await tester.pumpWidget(_boilerplate(
      child: Center(
        child: OpenContainer(
          closedBuilder: (BuildContext context, VoidCallback action) {
            return const Text('Closed');
          },
          openBuilder: (BuildContext context, VoidCallback action) {
            return const Text('Open');
          },
        ),
      ),
    ));

    await tester.tap(find.text('Closed'));
    await tester.pump();
    await tester.pump(const Duration(milliseconds: 150));
    expect(find.text('Open'), findsOneWidget);
    expect(find.text('Closed'), findsOneWidget);

    final Material openingMaterial = tester.firstWidget(find.ancestor(
      of: find.text('Closed'),
      matching: find.byType(Material),
    ));
    final Rect openingRect = tester.getRect(
      find.byWidgetPredicate((Widget w) => w == openingMaterial),
    );

    // Close the container while it is half way to open.
    final NavigatorState navigator = tester.state(find.byType(Navigator));
    navigator.pop();
    await tester.pump();

    final Material closingMaterial = tester.firstWidget(find.ancestor(
      of: find.text('Open'),
      matching: find.byType(Material),
    ));
    final Rect closingRect = tester.getRect(
      find.byWidgetPredicate((Widget w) => w == closingMaterial),
    );

    expect(closingMaterial.elevation, openingMaterial.elevation);
    expect(closingMaterial.color, openingMaterial.color);
    expect(closingMaterial.shape, openingMaterial.shape);
    expect(closingRect, openingRect);
  });

  testWidgets('navigator is not full size', (WidgetTester tester) async {
    await tester.pumpWidget(Center(
      child: SizedBox(
        width: 300,
        height: 400,
        child: _boilerplate(
          child: Center(
            child: OpenContainer(
              closedBuilder: (BuildContext context, VoidCallback action) {
                return const Text('Closed');
              },
              openBuilder: (BuildContext context, VoidCallback action) {
                return const Text('Open');
              },
            ),
          ),
        ),
      ),
    ));
    const Rect fullNavigator = Rect.fromLTWH(250, 100, 300, 400);

    expect(tester.getRect(find.byType(Navigator)), fullNavigator);
    final Rect materialRectClosed = tester.getRect(find
        .ancestor(
          of: find.text('Closed'),
          matching: find.byType(Material),
        )
        .first);

    await tester.tap(find.text('Closed'));
    await tester.pump();
    expect(find.text('Open'), findsOneWidget);
    expect(find.text('Closed'), findsOneWidget);
    final Rect materialRectTransitionStart = tester.getRect(find.ancestor(
      of: find.text('Closed'),
      matching: find.byType(Material),
    ));
    expect(materialRectTransitionStart, materialRectClosed);

    await tester.pump(const Duration(milliseconds: 300));
    expect(find.text('Open'), findsOneWidget);
    expect(find.text('Closed'), findsOneWidget);
    final Rect materialRectTransitionEnd = tester.getRect(find.ancestor(
      of: find.text('Open'),
      matching: find.byType(Material),
    ));
    expect(materialRectTransitionEnd, fullNavigator);
    await tester.pumpAndSettle();
    expect(find.text('Open'), findsOneWidget);
    expect(find.text('Closed'), findsNothing);
    final Rect materialRectOpen = tester.getRect(find.ancestor(
      of: find.text('Open'),
      matching: find.byType(Material),
    ));
    expect(materialRectOpen, fullNavigator);
  });

  testWidgets('does not crash when disposed right after pop',
      (WidgetTester tester) async {
    await tester.pumpWidget(Center(
      child: SizedBox(
        width: 300,
        height: 400,
        child: _boilerplate(
          child: Center(
            child: OpenContainer(
              closedBuilder: (BuildContext context, VoidCallback action) {
                return const Text('Closed');
              },
              openBuilder: (BuildContext context, VoidCallback action) {
                return const Text('Open');
              },
            ),
          ),
        ),
      ),
    ));

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

    final NavigatorState navigator = tester.state(find.byType(Navigator));
    navigator.pop();

    await tester.pumpWidget(const Placeholder());
    expect(tester.takeException(), isNull);
    await tester.pumpAndSettle();
    expect(tester.takeException(), isNull);
  });

  testWidgets('can specify a duration', (WidgetTester tester) async {
    await tester.pumpWidget(Center(
      child: SizedBox(
        width: 300,
        height: 400,
        child: _boilerplate(
          child: Center(
            child: OpenContainer(
              transitionDuration: const Duration(seconds: 2),
              closedBuilder: (BuildContext context, VoidCallback action) {
                return const Text('Closed');
              },
              openBuilder: (BuildContext context, VoidCallback action) {
                return const Text('Open');
              },
            ),
          ),
        ),
      ),
    ));

    expect(find.text('Open'), findsNothing);
    expect(find.text('Closed'), findsOneWidget);

    await tester.tap(find.text('Closed'));
    await tester.pump();

    // Jump to the end of the transition.
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Open'), findsOneWidget); // faded in
    expect(find.text('Closed'), findsOneWidget); // faded out
    await tester.pump(const Duration(milliseconds: 1));
    expect(find.text('Open'), findsOneWidget);
    expect(find.text('Closed'), findsNothing);

    final NavigatorState navigator = tester.state(find.byType(Navigator));
    navigator.pop();
    await tester.pump();

    // Jump to the end of the transition.
    await tester.pump(const Duration(seconds: 2));
    expect(find.text('Open'), findsOneWidget); // faded out
    expect(find.text('Closed'), findsOneWidget); // faded in
    await tester.pump(const Duration(milliseconds: 1));
    expect(find.text('Open'), findsNothing);
    expect(find.text('Closed'), findsOneWidget);
  });

  testWidgets('can specify an open shape', (WidgetTester tester) async {
    await tester.pumpWidget(Center(
      child: SizedBox(
        width: 300,
        height: 400,
        child: _boilerplate(
          child: Center(
            child: OpenContainer(
              closedShape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(10),
              ),
              openShape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(40),
              ),
              closedBuilder: (BuildContext context, VoidCallback action) {
                return const Text('Closed');
              },
              openBuilder: (BuildContext context, VoidCallback action) {
                return const Text('Open');
              },
            ),
          ),
        ),
      ),
    ));

    expect(find.text('Open'), findsNothing);
    expect(find.text('Closed'), findsOneWidget);
    final double closedRadius = _getRadius(tester.firstWidget(find.ancestor(
      of: find.text('Closed'),
      matching: find.byType(Material),
    )));
    expect(closedRadius, 10.0);

    await tester.tap(find.text('Closed'));
    await tester.pump();
    expect(find.text('Open'), findsOneWidget);
    expect(find.text('Closed'), findsOneWidget);
    final double openingRadius = _getRadius(tester.firstWidget(find.ancestor(
      of: find.text('Open'),
      matching: find.byType(Material),
    )));
    expect(openingRadius, 10.0);

    await tester.pump(const Duration(milliseconds: 150));
    expect(find.text('Open'), findsOneWidget);
    expect(find.text('Closed'), findsOneWidget);
    final double halfwayRadius = _getRadius(tester.firstWidget(find.ancestor(
      of: find.text('Open'),
      matching: find.byType(Material),
    )));
    expect(halfwayRadius, greaterThan(10.0));
    expect(halfwayRadius, lessThan(40.0));

    await tester.pump(const Duration(milliseconds: 150));
    expect(find.text('Open'), findsOneWidget);
    expect(find.text('Closed'), findsOneWidget);
    final double openRadius = _getRadius(tester.firstWidget(find.ancestor(
      of: find.text('Open'),
      matching: find.byType(Material),
    )));
    expect(openRadius, 40.0);

    await tester.pump(const Duration(milliseconds: 1));
    expect(find.text('Closed'), findsNothing);
    expect(find.text('Open'), findsOneWidget);
    final double finalRadius = _getRadius(tester.firstWidget(find.ancestor(
      of: find.text('Open'),
      matching: find.byType(Material),
    )));
    expect(finalRadius, 40.0);
  });

  testWidgets('Scrim', (WidgetTester tester) async {
    const ShapeBorder shape = RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(8.0)),
    );

    await tester.pumpWidget(_boilerplate(
      child: Center(
        child: OpenContainer(
          closedColor: Colors.green,
          openColor: Colors.blue,
          closedElevation: 4.0,
          openElevation: 8.0,
          closedShape: shape,
          closedBuilder: (BuildContext context, VoidCallback _) {
            return const Text('Closed');
          },
          openBuilder: (BuildContext context, VoidCallback _) {
            return const Text('Open');
          },
        ),
      ),
    ));

    expect(find.text('Closed'), findsOneWidget);
    expect(find.text('Open'), findsNothing);
    await tester.tap(find.text('Closed'));
    await tester.pump();

    expect(_getScrimColor(tester), Colors.transparent);

    await tester.pump(const Duration(milliseconds: 50));
    final Color halfwayFadeInColor = _getScrimColor(tester);
    expect(halfwayFadeInColor, isNot(Colors.transparent));
    expect(halfwayFadeInColor, isNot(Colors.black54));

    // Scrim is done fading in early.
    await tester.pump(const Duration(milliseconds: 50));
    expect(_getScrimColor(tester), Colors.black54);

    await tester.pump(const Duration(milliseconds: 200));
    expect(_getScrimColor(tester), Colors.black54);

    await tester.pumpAndSettle();

    // Close the container
    final NavigatorState navigator = tester.state(find.byType(Navigator));
    navigator.pop();
    await tester.pump();

    expect(_getScrimColor(tester), Colors.black54);

    // Scrim takes longer to fade out (vs. fade in).
    await tester.pump(const Duration(milliseconds: 200));
    final Color halfwayFadeOutColor = _getScrimColor(tester);
    expect(halfwayFadeOutColor, isNot(Colors.transparent));
    expect(halfwayFadeOutColor, isNot(Colors.black54));

    await tester.pump(const Duration(milliseconds: 100));
    expect(_getScrimColor(tester), Colors.transparent);
  });

  testWidgets(
      'Container partly offscreen can be opened without crash - vertical',
      (WidgetTester tester) async {
    final ScrollController controller =
        ScrollController(initialScrollOffset: 50);
    await tester.pumpWidget(Center(
      child: SizedBox(
        height: 200,
        width: 200,
        child: _boilerplate(
          child: ListView.builder(
            cacheExtent: 0,
            controller: controller,
            itemBuilder: (BuildContext context, int index) {
              return OpenContainer(
                closedBuilder: (BuildContext context, VoidCallback _) {
                  return SizedBox(
                    height: 100,
                    width: 100,
                    child: Text('Closed $index'),
                  );
                },
                openBuilder: (BuildContext context, VoidCallback _) {
                  return Text('Open $index');
                },
              );
            },
          ),
        ),
      ),
    ));

    void expectClosedState() {
      expect(find.text('Closed 0'), findsOneWidget);
      expect(find.text('Closed 1'), findsOneWidget);
      expect(find.text('Closed 2'), findsOneWidget);
      expect(find.text('Closed 3'), findsNothing);

      expect(find.text('Open 0'), findsNothing);
      expect(find.text('Open 1'), findsNothing);
      expect(find.text('Open 2'), findsNothing);
      expect(find.text('Open 3'), findsNothing);
    }

    expectClosedState();

    // Open container that's partly visible at top.
    await tester.tapAt(
      tester.getBottomRight(find.text('Closed 0')) - const Offset(20, 20),
    );
    await tester.pump();
    await tester.pumpAndSettle();
    expect(find.text('Closed 0'), findsNothing);
    expect(find.text('Open 0'), findsOneWidget);

    final NavigatorState navigator = tester.state(find.byType(Navigator));
    navigator.pop();
    await tester.pump();
    await tester.pumpAndSettle();
    expectClosedState();

    // Open container that's partly visible at bottom.
    await tester.tapAt(
      tester.getTopLeft(find.text('Closed 2')) + const Offset(20, 20),
    );
    await tester.pump();
    await tester.pumpAndSettle();

    expect(find.text('Closed 2'), findsNothing);
    expect(find.text('Open 2'), findsOneWidget);
  });

  testWidgets(
      'Container partly offscreen can be opened without crash - horizontal',
      (WidgetTester tester) async {
    final ScrollController controller =
        ScrollController(initialScrollOffset: 50);
    await tester.pumpWidget(Center(
      child: SizedBox(
        height: 200,
        width: 200,
        child: _boilerplate(
          child: ListView.builder(
            scrollDirection: Axis.horizontal,
            cacheExtent: 0,
            controller: controller,
            itemBuilder: (BuildContext context, int index) {
              return OpenContainer(
                closedBuilder: (BuildContext context, VoidCallback _) {
                  return SizedBox(
                    height: 100,
                    width: 100,
                    child: Text('Closed $index'),
                  );
                },
                openBuilder: (BuildContext context, VoidCallback _) {
                  return Text('Open $index');
                },
              );
            },
          ),
        ),
      ),
    ));

    void expectClosedState() {
      expect(find.text('Closed 0'), findsOneWidget);
      expect(find.text('Closed 1'), findsOneWidget);
      expect(find.text('Closed 2'), findsOneWidget);
      expect(find.text('Closed 3'), findsNothing);

      expect(find.text('Open 0'), findsNothing);
      expect(find.text('Open 1'), findsNothing);
      expect(find.text('Open 2'), findsNothing);
      expect(find.text('Open 3'), findsNothing);
    }

    expectClosedState();

    // Open container that's partly visible at left edge.
    await tester.tapAt(
      tester.getBottomRight(find.text('Closed 0')) - const Offset(20, 20),
    );
    await tester.pump();
    await tester.pumpAndSettle();
    expect(find.text('Closed 0'), findsNothing);
    expect(find.text('Open 0'), findsOneWidget);

    final NavigatorState navigator = tester.state(find.byType(Navigator));
    navigator.pop();
    await tester.pump();
    await tester.pumpAndSettle();
    expectClosedState();

    // Open container that's partly visible at right edge.
    await tester.tapAt(
      tester.getTopLeft(find.text('Closed 2')) + const Offset(20, 20),
    );
    await tester.pump();
    await tester.pumpAndSettle();

    expect(find.text('Closed 2'), findsNothing);
    expect(find.text('Open 2'), findsOneWidget);
  });

  testWidgets(
      'Container can be dismissed after container widget itself is removed without crash',
      (WidgetTester tester) async {
    await tester.pumpWidget(_boilerplate(child: _RemoveOpenContainerExample()));

    expect(find.text('Closed'), findsOneWidget);
    expect(find.text('Closed', skipOffstage: false), findsOneWidget);
    expect(find.text('Open'), findsNothing);

    await tester.tap(find.text('Open the container'));
    await tester.pumpAndSettle();

    expect(find.text('Closed'), findsNothing);
    expect(find.text('Closed', skipOffstage: false), findsOneWidget);
    expect(find.text('Open'), findsOneWidget);

    await tester.tap(find.text('Remove the container'));
    await tester.pump();

    expect(find.text('Closed'), findsNothing);
    expect(find.text('Closed', skipOffstage: false), findsNothing);
    expect(find.text('Open'), findsOneWidget);

    await tester.tap(find.text('Close the container'));
    await tester.pumpAndSettle();

    expect(find.text('Closed'), findsNothing);
    expect(find.text('Closed', skipOffstage: false), findsNothing);
    expect(find.text('Open'), findsNothing);
    expect(find.text('Container has been removed'), findsOneWidget);
  });

  testWidgets('onClosed callback is called when container has closed',
      (WidgetTester tester) async {
    bool hasClosed = false;
    final Widget openContainer = OpenContainer(
      onClosed: (dynamic _) {
        hasClosed = true;
      },
      closedBuilder: (BuildContext context, VoidCallback action) {
        return GestureDetector(
          onTap: action,
          child: const Text('Closed'),
        );
      },
      openBuilder: (BuildContext context, VoidCallback action) {
        return GestureDetector(
          onTap: action,
          child: const Text('Open'),
        );
      },
    );

    await tester.pumpWidget(
      _boilerplate(child: openContainer),
    );

    expect(find.text('Open'), findsNothing);
    expect(find.text('Closed'), findsOneWidget);
    expect(hasClosed, isFalse);

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

    expect(find.text('Open'), findsOneWidget);
    expect(find.text('Closed'), findsNothing);

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

    expect(find.text('Open'), findsNothing);
    expect(find.text('Closed'), findsOneWidget);
    expect(hasClosed, isTrue);
  });

  testWidgets(
      'onClosed callback receives popped value when container has closed',
      (WidgetTester tester) async {
    bool? value = false;
    final Widget openContainer = OpenContainer<bool>(
      onClosed: (bool? poppedValue) {
        value = poppedValue;
      },
      closedBuilder: (BuildContext context, VoidCallback action) {
        return GestureDetector(
          onTap: action,
          child: const Text('Closed'),
        );
      },
      openBuilder:
          (BuildContext context, CloseContainerActionCallback<bool> action) {
        return GestureDetector(
          onTap: () => action(returnValue: true),
          child: const Text('Open'),
        );
      },
    );

    await tester.pumpWidget(
      _boilerplate(child: openContainer),
    );

    expect(find.text('Open'), findsNothing);
    expect(find.text('Closed'), findsOneWidget);
    expect(value, isFalse);

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

    expect(find.text('Open'), findsOneWidget);
    expect(find.text('Closed'), findsNothing);

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

    expect(find.text('Open'), findsNothing);
    expect(find.text('Closed'), findsOneWidget);
    expect(value, isTrue);
  });

  testWidgets('closedBuilder has anti-alias clip by default',
      (WidgetTester tester) async {
    final GlobalKey closedBuilderKey = GlobalKey();
    final Widget openContainer = OpenContainer(
      closedBuilder: (BuildContext context, VoidCallback action) {
        return Text('Close', key: closedBuilderKey);
      },
      openBuilder:
          (BuildContext context, CloseContainerActionCallback<bool> action) {
        return const Text('Open');
      },
    );

    await tester.pumpWidget(
      _boilerplate(child: openContainer),
    );

    final Finder closedBuilderMaterial = find
        .ancestor(
          of: find.byKey(closedBuilderKey),
          matching: find.byType(Material),
        )
        .first;

    final Material material = tester.widget<Material>(closedBuilderMaterial);
    expect(material.clipBehavior, Clip.antiAlias);
  });

  testWidgets('closedBuilder has no clip', (WidgetTester tester) async {
    final GlobalKey closedBuilderKey = GlobalKey();
    final Widget openContainer = OpenContainer(
      closedBuilder: (BuildContext context, VoidCallback action) {
        return Text('Close', key: closedBuilderKey);
      },
      openBuilder:
          (BuildContext context, CloseContainerActionCallback<bool> action) {
        return const Text('Open');
      },
      clipBehavior: Clip.none,
    );

    await tester.pumpWidget(
      _boilerplate(child: openContainer),
    );

    final Finder closedBuilderMaterial = find
        .ancestor(
          of: find.byKey(closedBuilderKey),
          matching: find.byType(Material),
        )
        .first;

    final Material material = tester.widget<Material>(closedBuilderMaterial);
    expect(material.clipBehavior, Clip.none);
  });

  Widget createRootNavigatorTest({
    required Key appKey,
    required Key nestedNavigatorKey,
    required bool useRootNavigator,
  }) {
    return Center(
      child: SizedBox(
        width: 100,
        height: 100,
        child: MaterialApp(
          key: appKey,
          // a nested navigator
          home: Center(
            child: SizedBox(
              width: 50,
              height: 50,
              child: Navigator(
                key: nestedNavigatorKey,
                onGenerateRoute: (RouteSettings route) {
                  return MaterialPageRoute<dynamic>(
                    settings: route,
                    builder: (BuildContext context) {
                      return OpenContainer(
                        useRootNavigator: useRootNavigator,
                        closedBuilder: (BuildContext context, _) {
                          return const Text('Closed');
                        },
                        openBuilder: (BuildContext context, _) {
                          return const Text('Opened');
                        },
                      );
                    },
                  );
                },
              ),
            ),
          ),
        ),
      ),
    );
  }

  testWidgets(
      'Verify that "useRootNavigator: false" uses the correct navigator',
      (WidgetTester tester) async {
    const Key appKey = Key('App');
    const Key nestedNavigatorKey = Key('Nested Navigator');

    await tester.pumpWidget(createRootNavigatorTest(
        appKey: appKey,
        nestedNavigatorKey: nestedNavigatorKey,
        useRootNavigator: false));

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

    expect(
        find.descendant(of: find.byKey(appKey), matching: find.text('Opened')),
        findsOneWidget);

    expect(
        find.descendant(
            of: find.byKey(nestedNavigatorKey), matching: find.text('Opened')),
        findsOneWidget);
  });

  testWidgets('Verify that "useRootNavigator: true" uses the correct navigator',
      (WidgetTester tester) async {
    const Key appKey = Key('App');
    const Key nestedNavigatorKey = Key('Nested Navigator');

    await tester.pumpWidget(createRootNavigatorTest(
        appKey: appKey,
        nestedNavigatorKey: nestedNavigatorKey,
        useRootNavigator: true));

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

    expect(
        find.descendant(of: find.byKey(appKey), matching: find.text('Opened')),
        findsOneWidget);

    expect(
        find.descendant(
            of: find.byKey(nestedNavigatorKey), matching: find.text('Opened')),
        findsNothing);
  });

  testWidgets('Verify correct opened size  when "useRootNavigator: false"',
      (WidgetTester tester) async {
    const Key appKey = Key('App');
    const Key nestedNavigatorKey = Key('Nested Navigator');

    await tester.pumpWidget(createRootNavigatorTest(
        appKey: appKey,
        nestedNavigatorKey: nestedNavigatorKey,
        useRootNavigator: false));

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

    expect(tester.getSize(find.text('Opened')),
        equals(tester.getSize(find.byKey(nestedNavigatorKey))));
  });

  testWidgets('Verify correct opened size  when "useRootNavigator: true"',
      (WidgetTester tester) async {
    const Key appKey = Key('App');
    const Key nestedNavigatorKey = Key('Nested Navigator');

    await tester.pumpWidget(createRootNavigatorTest(
        appKey: appKey,
        nestedNavigatorKey: nestedNavigatorKey,
        useRootNavigator: true));

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

    expect(tester.getSize(find.text('Opened')),
        equals(tester.getSize(find.byKey(appKey))));
  });

  testWidgets(
    'Verify routeSettings passed to Navigator',
    (WidgetTester tester) async {
      const RouteSettings routeSettings = RouteSettings(
        name: 'route-name',
        arguments: 'arguments',
      );

      final Widget openContainer = OpenContainer(
        routeSettings: routeSettings,
        closedBuilder: (BuildContext context, VoidCallback action) {
          return GestureDetector(
            onTap: action,
            child: const Text('Closed'),
          );
        },
        openBuilder: (BuildContext context, VoidCallback action) {
          return GestureDetector(
            onTap: action,
            child: const Text('Open'),
          );
        },
      );

      await tester.pumpWidget(_boilerplate(child: openContainer));

      // Open the container
      await tester.tap(find.text('Closed'));
      await tester.pumpAndSettle();

      // Expect the last route pushed to the navigator to contain RouteSettings
      // equal to the RouteSettings passed to the OpenContainer
      final ModalRoute<dynamic> modalRoute = ModalRoute.of(
        tester.element(find.text('Open')),
      )!;
      expect(modalRoute.settings, routeSettings);
    },
  );
}

Color _getScrimColor(WidgetTester tester) {
  return tester
      .widget<ColoredBox>(
        find.descendant(
          of: find.byType(Container),
          matching: find.byType(ColoredBox),
        ),
      )
      .color;
}

void _expectMaterialPropertiesHaveAdvanced({
  required _TrackedData biggerMaterial,
  required _TrackedData smallerMaterial,
  required WidgetTester tester,
}) {
  expect(
    biggerMaterial.material.elevation,
    greaterThan(smallerMaterial.material.elevation),
  );
  expect(biggerMaterial.radius, lessThan(smallerMaterial.radius));
  expect(biggerMaterial.rect.height, greaterThan(smallerMaterial.rect.height));
  expect(biggerMaterial.rect.width, greaterThan(smallerMaterial.rect.width));
  expect(biggerMaterial.rect.top, lessThan(smallerMaterial.rect.top));
  expect(biggerMaterial.rect.left, lessThan(smallerMaterial.rect.left));
}

double _getOpacity(WidgetTester tester, String label) {
  final FadeTransition widget = tester.firstWidget(find.ancestor(
    of: find.text(label),
    matching: find.byType(FadeTransition),
  ));
  // Verify that the correct fade transition is retrieved (i.e. not something from a page transition).
  assert(widget.child is Builder && widget.child?.key is GlobalKey, '$widget');
  return widget.opacity.value;
}

class _TrackedData {
  _TrackedData(this.material, this.rect);

  final Material material;
  final Rect rect;

  double get radius => _getRadius(material);
}

double _getRadius(Material material) {
  final RoundedRectangleBorder? shape =
      material.shape as RoundedRectangleBorder?;
  if (shape == null) {
    return 0.0;
  }
  final BorderRadius radius = shape.borderRadius as BorderRadius;
  return radius.topRight.x;
}

Widget _boilerplate({required Widget child}) {
  return MaterialApp(
    home: Scaffold(
      body: child,
    ),
  );
}

class _SizableContainer extends StatefulWidget {
  const _SizableContainer({required this.initialSize, required this.child});

  final double initialSize;
  final Widget child;

  @override
  State<_SizableContainer> createState() => _SizableContainerState();
}

class _SizableContainerState extends State<_SizableContainer> {
  @override
  void initState() {
    super.initState();
    _size = widget.initialSize;
  }

  double get size => _size;
  late double _size;
  set size(double value) {
    if (value == _size) {
      return;
    }
    setState(() {
      _size = value;
    });
  }

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      height: size,
      width: size,
      child: widget.child,
    );
  }
}

class _RemoveOpenContainerExample extends StatefulWidget {
  @override
  __RemoveOpenContainerExampleState createState() =>
      __RemoveOpenContainerExampleState();
}

class __RemoveOpenContainerExampleState
    extends State<_RemoveOpenContainerExample> {
  bool removeOpenContainerWidget = false;

  @override
  Widget build(BuildContext context) {
    return removeOpenContainerWidget
        ? const Text('Container has been removed')
        : OpenContainer(
            closedBuilder: (BuildContext context, VoidCallback action) =>
                Column(
              children: <Widget>[
                const Text('Closed'),
                ElevatedButton(
                  onPressed: action,
                  child: const Text('Open the container'),
                ),
              ],
            ),
            openBuilder: (BuildContext context, VoidCallback action) => Column(
              children: <Widget>[
                const Text('Open'),
                ElevatedButton(
                  onPressed: action,
                  child: const Text('Close the container'),
                ),
                ElevatedButton(
                    onPressed: () {
                      setState(() {
                        removeOpenContainerWidget = true;
                      });
                    },
                    child: const Text('Remove the container')),
              ],
            ),
          );
  }
}

class DummyStatefulWidget extends StatefulWidget {
  const DummyStatefulWidget({Key? key}) : super(key: key);

  @override
  State<StatefulWidget> createState() => DummyState();
}

class DummyState extends State<DummyStatefulWidget> {
  @override
  Widget build(BuildContext context) => const SizedBox.expand();
}
