// 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);

      // 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();
}
