// 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/shared_axis_transition.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:vector_math/vector_math_64.dart' hide Colors;

void main() {
  group('SharedAxisTransitionType.horizontal', () {
    testWidgets(
      'SharedAxisPageTransitionsBuilder builds a SharedAxisTransition',
      (WidgetTester tester) async {
        final AnimationController animation = AnimationController(
          vsync: const TestVSync(),
        );
        final AnimationController secondaryAnimation = AnimationController(
          vsync: const TestVSync(),
        );

        await tester.pumpWidget(
          const SharedAxisPageTransitionsBuilder(
            transitionType: SharedAxisTransitionType.horizontal,
          ).buildTransitions<void>(
            null,
            null,
            animation,
            secondaryAnimation,
            const Placeholder(),
          ),
        );

        expect(find.byType(SharedAxisTransition), findsOneWidget);
      },
    );

    testWidgets(
      'SharedAxisTransition runs forward',
      (WidgetTester tester) async {
        final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
        const String bottomRoute = '/';
        const String topRoute = '/a';

        await tester.pumpWidget(
          _TestWidget(
            navigatorKey: navigator,
            transitionType: SharedAxisTransitionType.horizontal,
          ),
        );

        expect(find.text(bottomRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.horizontal,
          ),
          0.0,
        );
        expect(_getOpacity(bottomRoute, tester), 1.0);
        expect(find.text(topRoute), findsNothing);

        navigator.currentState!.pushNamed(topRoute);
        await tester.pump();
        await tester.pump();

        // Bottom route is not offset and fully visible.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.horizontal,
          ),
          0.0,
        );
        expect(_getOpacity(bottomRoute, tester), 1.0);
        // Top route is offset to the right by 30.0 pixels
        // and not visible yet.
        expect(find.text(topRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            topRoute,
            tester,
            SharedAxisTransitionType.horizontal,
          ),
          30.0,
        );
        expect(_getOpacity(topRoute, tester), 0.0);

        // Jump 3/10ths of the way through the transition, bottom route
        // should be be completely faded out while the top route
        // is also completely faded out.
        // Transition time: 300ms, 3/10 * 300ms = 90ms
        await tester.pump(const Duration(milliseconds: 90));

        // Bottom route is now invisible
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getOpacity(bottomRoute, tester), 0.0);
        // Top route is still invisible, but moving towards the left.
        expect(find.text(topRoute), findsOneWidget);
        expect(_getOpacity(topRoute, tester), 0.0);
        double? topOffset = _getTranslationOffset(
          topRoute,
          tester,
          SharedAxisTransitionType.horizontal,
        );
        expect(topOffset, lessThan(30.0));
        expect(topOffset, greaterThan(0.0));

        // Jump to the middle of fading in
        await tester.pump(const Duration(milliseconds: 90));
        // Bottom route is still invisible
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getOpacity(bottomRoute, tester), 0.0);
        // Top route is fading in
        expect(find.text(topRoute), findsOneWidget);
        expect(_getOpacity(topRoute, tester), greaterThan(0));
        expect(_getOpacity(topRoute, tester), lessThan(1.0));
        topOffset = _getTranslationOffset(
          topRoute,
          tester,
          SharedAxisTransitionType.horizontal,
        );
        expect(topOffset, greaterThan(0.0));
        expect(topOffset, lessThan(30.0));

        // Jump to the end of the transition
        await tester.pump(const Duration(milliseconds: 120));
        // Bottom route is not visible.
        expect(find.text(bottomRoute), findsOneWidget);

        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.horizontal,
          ),
          -30.0,
        );
        expect(_getOpacity(bottomRoute, tester), 0.0);
        // Top route has no offset and is visible.
        expect(find.text(topRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            topRoute,
            tester,
            SharedAxisTransitionType.horizontal,
          ),
          0.0,
        );
        expect(_getOpacity(topRoute, tester), 1.0);

        await tester.pump(const Duration(milliseconds: 1));
        expect(find.text(bottomRoute), findsNothing);
        expect(find.text(topRoute), findsOneWidget);
      },
    );

    testWidgets(
      'SharedAxisTransition runs in reverse',
      (WidgetTester tester) async {
        final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
        const String bottomRoute = '/';
        const String topRoute = '/a';

        await tester.pumpWidget(
          _TestWidget(
            navigatorKey: navigator,
            transitionType: SharedAxisTransitionType.horizontal,
          ),
        );

        navigator.currentState!.pushNamed('/a');
        await tester.pumpAndSettle();

        expect(find.text(topRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            topRoute,
            tester,
            SharedAxisTransitionType.horizontal,
          ),
          0.0,
        );
        expect(_getOpacity(topRoute, tester), 1.0);
        expect(find.text(bottomRoute), findsNothing);

        navigator.currentState!.pop();
        await tester.pump();

        // Top route is is not offset and fully visible.
        expect(find.text(topRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            topRoute,
            tester,
            SharedAxisTransitionType.horizontal,
          ),
          0.0,
        );
        expect(_getOpacity(topRoute, tester), 1.0);
        // Bottom route is offset to the left and is not visible yet.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.horizontal,
          ),
          -30.0,
        );
        expect(_getOpacity(bottomRoute, tester), 0.0);

        // Jump 3/10ths of the way through the transition, bottom route
        // should be be completely faded out while the top route
        // is also completely faded out.
        // Transition time: 300ms, 3/10 * 300ms = 90ms
        await tester.pump(const Duration(milliseconds: 90));

        // Top route is now invisible
        expect(find.text(topRoute), findsOneWidget);
        expect(_getOpacity(topRoute, tester), 0.0);
        // Bottom route is still invisible, but moving towards the right.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getOpacity(bottomRoute, tester),
            moreOrLessEquals(0, epsilon: 0.005));
        double? bottomOffset = _getTranslationOffset(
          bottomRoute,
          tester,
          SharedAxisTransitionType.horizontal,
        );
        expect(bottomOffset, lessThan(0.0));
        expect(bottomOffset, greaterThan(-30.0));

        // Jump to the middle of fading in
        await tester.pump(const Duration(milliseconds: 90));
        // Top route is still invisible
        expect(find.text(topRoute), findsOneWidget);
        expect(_getOpacity(topRoute, tester), 0.0);
        // Bottom route is fading in
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getOpacity(bottomRoute, tester), greaterThan(0));
        expect(_getOpacity(bottomRoute, tester), lessThan(1.0));
        bottomOffset = _getTranslationOffset(
          bottomRoute,
          tester,
          SharedAxisTransitionType.horizontal,
        );
        expect(bottomOffset, lessThan(0.0));
        expect(bottomOffset, greaterThan(-30.0));

        // Jump to the end of the transition
        await tester.pump(const Duration(milliseconds: 120));
        // Top route is not visible and is offset to the right.
        expect(find.text(topRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            topRoute,
            tester,
            SharedAxisTransitionType.horizontal,
          ),
          30.0,
        );
        expect(_getOpacity(topRoute, tester), 0.0);
        // Bottom route is not offset and is visible.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.horizontal,
          ),
          0.0,
        );
        expect(_getOpacity(bottomRoute, tester), 1.0);

        await tester.pump(const Duration(milliseconds: 1));
        expect(find.text(topRoute), findsNothing);
        expect(find.text(bottomRoute), findsOneWidget);
      },
    );

    testWidgets(
      'SharedAxisTransition does not jump when interrupted',
      (WidgetTester tester) async {
        final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
        const String bottomRoute = '/';
        const String topRoute = '/a';

        await tester.pumpWidget(
          _TestWidget(
            navigatorKey: navigator,
            transitionType: SharedAxisTransitionType.horizontal,
          ),
        );
        expect(find.text(bottomRoute), findsOneWidget);
        expect(find.text(topRoute), findsNothing);

        navigator.currentState!.pushNamed(topRoute);
        await tester.pump();

        // Jump to halfway point of transition.
        await tester.pump(const Duration(milliseconds: 150));
        // Bottom route is fully faded out.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getOpacity(bottomRoute, tester), 0.0);
        final double halfwayBottomOffset = _getTranslationOffset(
          bottomRoute,
          tester,
          SharedAxisTransitionType.horizontal,
        );
        expect(halfwayBottomOffset, lessThan(0.0));
        expect(halfwayBottomOffset, greaterThan(-30.0));

        // Top route is fading/coming in.
        expect(find.text(topRoute), findsOneWidget);
        final double halfwayTopOffset = _getTranslationOffset(
          topRoute,
          tester,
          SharedAxisTransitionType.horizontal,
        );
        final double halfwayTopOpacity = _getOpacity(topRoute, tester);
        expect(halfwayTopOffset, greaterThan(0.0));
        expect(halfwayTopOffset, lessThan(30.0));
        expect(halfwayTopOpacity, greaterThan(0.0));
        expect(halfwayTopOpacity, lessThan(1.0));

        // Interrupt the transition with a pop.
        navigator.currentState!.pop();
        await tester.pump();

        // Nothing should change.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.horizontal,
          ),
          halfwayBottomOffset,
        );
        expect(_getOpacity(bottomRoute, tester), 0.0);
        expect(find.text(topRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            topRoute,
            tester,
            SharedAxisTransitionType.horizontal,
          ),
          halfwayTopOffset,
        );
        expect(_getOpacity(topRoute, tester), halfwayTopOpacity);

        // Jump to the 1/4 (75 ms) point of transition
        await tester.pump(const Duration(milliseconds: 75));
        expect(find.text(bottomRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.horizontal,
          ),
          lessThan(0.0),
        );
        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.horizontal,
          ),
          greaterThan(-30.0),
        );
        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.horizontal,
          ),
          greaterThan(halfwayBottomOffset),
        );
        expect(_getOpacity(bottomRoute, tester), greaterThan(0.0));
        expect(_getOpacity(bottomRoute, tester), lessThan(1.0));

        // Jump to the end.
        await tester.pump(const Duration(milliseconds: 75));
        expect(find.text(bottomRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.horizontal,
          ),
          0.0,
        );
        expect(_getOpacity(bottomRoute, tester), 1.0);
        expect(find.text(topRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            topRoute,
            tester,
            SharedAxisTransitionType.horizontal,
          ),
          30.0,
        );
        expect(_getOpacity(topRoute, tester), 0.0);

        await tester.pump(const Duration(milliseconds: 1));
        expect(find.text(topRoute), findsNothing);
        expect(find.text(bottomRoute), findsOneWidget);
      },
    );

    testWidgets(
      'State is not lost when transitioning',
      (WidgetTester tester) async {
        final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
        const String bottomRoute = '/';
        const String topRoute = '/a';

        await tester.pumpWidget(
          _TestWidget(
            navigatorKey: navigator,
            contentBuilder: (RouteSettings settings) {
              return _StatefulTestWidget(
                key: ValueKey<String?>(settings.name),
                name: settings.name!,
              );
            },
            transitionType: SharedAxisTransitionType.horizontal,
          ),
        );

        final _StatefulTestWidgetState bottomState = tester.state(
          find.byKey(const ValueKey<String?>(bottomRoute)),
        );
        expect(bottomState.widget.name, bottomRoute);

        navigator.currentState!.pushNamed(topRoute);
        await tester.pump();
        await tester.pump();

        expect(
          tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
          bottomState,
        );
        final _StatefulTestWidgetState topState = tester.state(
          find.byKey(const ValueKey<String?>(topRoute)),
        );
        expect(topState.widget.name, topRoute);

        await tester.pump(const Duration(milliseconds: 150));
        expect(
          tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
          bottomState,
        );
        expect(
          tester.state(find.byKey(const ValueKey<String?>(topRoute))),
          topState,
        );

        await tester.pumpAndSettle();
        expect(
          tester.state(find.byKey(
            const ValueKey<String?>(bottomRoute),
            skipOffstage: false,
          )),
          bottomState,
        );
        expect(
          tester.state(find.byKey(const ValueKey<String?>(topRoute))),
          topState,
        );

        navigator.currentState!.pop();
        await tester.pump();

        expect(
          tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
          bottomState,
        );
        expect(
          tester.state(find.byKey(const ValueKey<String?>(topRoute))),
          topState,
        );

        await tester.pump(const Duration(milliseconds: 150));
        expect(
          tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
          bottomState,
        );
        expect(
          tester.state(find.byKey(const ValueKey<String?>(topRoute))),
          topState,
        );

        await tester.pumpAndSettle();
        expect(
          tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
          bottomState,
        );
        expect(find.byKey(const ValueKey<String?>(topRoute)), findsNothing);
      },
    );

    testWidgets('default fill color', (WidgetTester tester) async {
      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
      const String bottomRoute = '/';
      const String topRoute = '/a';

      // The default fill color should be derived from ThemeData.canvasColor.
      final Color defaultFillColor = ThemeData().canvasColor;

      await tester.pumpWidget(
        _TestWidget(
          navigatorKey: navigator,
          transitionType: SharedAxisTransitionType.horizontal,
        ),
      );

      expect(find.text(bottomRoute), findsOneWidget);
      Finder fillContainerFinder = find
          .ancestor(
            matching: find.byType(Container),
            of: find.byKey(const ValueKey<String?>('/')),
          )
          .last;
      expect(fillContainerFinder, findsOneWidget);
      expect(tester.widget<Container>(fillContainerFinder).color,
          defaultFillColor);

      navigator.currentState!.pushNamed(topRoute);
      await tester.pump();
      await tester.pumpAndSettle();

      fillContainerFinder = find
          .ancestor(
            matching: find.byType(Container),
            of: find.byKey(const ValueKey<String?>('/a')),
          )
          .last;
      expect(fillContainerFinder, findsOneWidget);
      expect(tester.widget<Container>(fillContainerFinder).color,
          defaultFillColor);
    });

    testWidgets('custom fill color', (WidgetTester tester) async {
      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
      const String bottomRoute = '/';
      const String topRoute = '/a';

      await tester.pumpWidget(
        _TestWidget(
          navigatorKey: navigator,
          fillColor: Colors.green,
          transitionType: SharedAxisTransitionType.horizontal,
        ),
      );

      expect(find.text(bottomRoute), findsOneWidget);
      Finder fillContainerFinder = find
          .ancestor(
            matching: find.byType(Container),
            of: find.byKey(const ValueKey<String?>('/')),
          )
          .last;
      expect(fillContainerFinder, findsOneWidget);
      expect(tester.widget<Container>(fillContainerFinder).color, Colors.green);

      navigator.currentState!.pushNamed(topRoute);
      await tester.pump();
      await tester.pumpAndSettle();

      fillContainerFinder = find
          .ancestor(
            matching: find.byType(Container),
            of: find.byKey(const ValueKey<String?>('/a')),
          )
          .last;
      expect(fillContainerFinder, findsOneWidget);
      expect(tester.widget<Container>(fillContainerFinder).color, Colors.green);
    });

    testWidgets('should keep state', (WidgetTester tester) async {
      final AnimationController animation = AnimationController(
        vsync: const TestVSync(),
        duration: const Duration(milliseconds: 300),
      );
      final AnimationController secondaryAnimation = AnimationController(
        vsync: const TestVSync(),
        duration: const Duration(milliseconds: 300),
      );
      await tester.pumpWidget(Directionality(
        textDirection: TextDirection.ltr,
        child: Center(
          child: SharedAxisTransition(
            transitionType: SharedAxisTransitionType.horizontal,
            animation: animation,
            secondaryAnimation: secondaryAnimation,
            child: const _StatefulTestWidget(name: 'Foo'),
          ),
        ),
      ));
      final State<StatefulWidget> state = tester.state(
        find.byType(_StatefulTestWidget),
      );
      expect(state, isNotNull);

      animation.forward();
      await tester.pump();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pumpAndSettle();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));

      secondaryAnimation.forward();
      await tester.pump();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pumpAndSettle();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));

      secondaryAnimation.reverse();
      await tester.pump();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pumpAndSettle();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));

      animation.reverse();
      await tester.pump();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pumpAndSettle();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
    });
  });

  group('SharedAxisTransitionType.vertical', () {
    testWidgets(
      'SharedAxisPageTransitionsBuilder builds a SharedAxisTransition',
      (WidgetTester tester) async {
        final AnimationController animation = AnimationController(
          vsync: const TestVSync(),
        );
        final AnimationController secondaryAnimation = AnimationController(
          vsync: const TestVSync(),
        );

        await tester.pumpWidget(
          const SharedAxisPageTransitionsBuilder(
            transitionType: SharedAxisTransitionType.vertical,
          ).buildTransitions<void>(
            null,
            null,
            animation,
            secondaryAnimation,
            const Placeholder(),
          ),
        );

        expect(find.byType(SharedAxisTransition), findsOneWidget);
      },
    );

    testWidgets(
      'SharedAxisTransition runs forward',
      (WidgetTester tester) async {
        final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
        const String bottomRoute = '/';
        const String topRoute = '/a';

        await tester.pumpWidget(
          _TestWidget(
            navigatorKey: navigator,
            transitionType: SharedAxisTransitionType.vertical,
          ),
        );

        expect(find.text(bottomRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.vertical,
          ),
          0.0,
        );
        expect(_getOpacity(bottomRoute, tester), 1.0);
        expect(find.text(topRoute), findsNothing);

        navigator.currentState!.pushNamed(topRoute);
        await tester.pump();
        await tester.pump();

        // Bottom route is not offset and fully visible.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.vertical,
          ),
          0.0,
        );
        expect(_getOpacity(bottomRoute, tester), 1.0);
        // Top route is offset down by 30.0 pixels
        // and not visible yet.
        expect(find.text(topRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            topRoute,
            tester,
            SharedAxisTransitionType.vertical,
          ),
          30.0,
        );
        expect(_getOpacity(topRoute, tester), 0.0);

        // Jump 3/10ths of the way through the transition, bottom route
        // should be be completely faded out while the top route
        // is also completely faded out.
        // Transition time: 300ms, 3/10 * 300ms = 90ms
        await tester.pump(const Duration(milliseconds: 90));

        // Bottom route is now invisible
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getOpacity(bottomRoute, tester), 0.0);
        // Top route is still invisible, but moving up.
        expect(find.text(topRoute), findsOneWidget);
        expect(_getOpacity(topRoute, tester), 0.0);
        double? topOffset = _getTranslationOffset(
          topRoute,
          tester,
          SharedAxisTransitionType.vertical,
        );
        expect(topOffset, lessThan(30.0));
        expect(topOffset, greaterThan(0.0));

        // Jump to the middle of fading in
        await tester.pump(const Duration(milliseconds: 90));
        // Bottom route is still invisible
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getOpacity(bottomRoute, tester), 0.0);
        // Top route is fading in
        expect(find.text(topRoute), findsOneWidget);
        expect(_getOpacity(topRoute, tester), greaterThan(0));
        expect(_getOpacity(topRoute, tester), lessThan(1.0));
        topOffset = _getTranslationOffset(
          topRoute,
          tester,
          SharedAxisTransitionType.vertical,
        );
        expect(topOffset, greaterThan(0.0));
        expect(topOffset, lessThan(30.0));

        // Jump to the end of the transition
        await tester.pump(const Duration(milliseconds: 120));
        // Bottom route is not visible.
        expect(find.text(bottomRoute), findsOneWidget);

        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.vertical,
          ),
          -30.0,
        );
        expect(_getOpacity(bottomRoute, tester), 0.0);
        // Top route has no offset and is visible.
        expect(find.text(topRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            topRoute,
            tester,
            SharedAxisTransitionType.vertical,
          ),
          0.0,
        );
        expect(_getOpacity(topRoute, tester), 1.0);

        await tester.pump(const Duration(milliseconds: 1));
        expect(find.text(bottomRoute), findsNothing);
        expect(find.text(topRoute), findsOneWidget);
      },
    );

    testWidgets(
      'SharedAxisTransition runs in reverse',
      (WidgetTester tester) async {
        final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
        const String bottomRoute = '/';
        const String topRoute = '/a';

        await tester.pumpWidget(
          _TestWidget(
            navigatorKey: navigator,
            transitionType: SharedAxisTransitionType.vertical,
          ),
        );

        navigator.currentState!.pushNamed('/a');
        await tester.pumpAndSettle();

        expect(find.text(topRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            topRoute,
            tester,
            SharedAxisTransitionType.vertical,
          ),
          0.0,
        );
        expect(_getOpacity(topRoute, tester), 1.0);
        expect(find.text(bottomRoute), findsNothing);

        navigator.currentState!.pop();
        await tester.pump();

        // Top route is is not offset and fully visible.
        expect(find.text(topRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            topRoute,
            tester,
            SharedAxisTransitionType.vertical,
          ),
          0.0,
        );
        expect(_getOpacity(topRoute, tester), 1.0);
        // Bottom route is offset up and is not visible yet.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.vertical,
          ),
          -30.0,
        );
        expect(_getOpacity(bottomRoute, tester), 0.0);

        // Jump 3/10ths of the way through the transition, bottom route
        // should be be completely faded out while the top route
        // is also completely faded out.
        // Transition time: 300ms, 3/10 * 300ms = 90ms
        await tester.pump(const Duration(milliseconds: 90));

        // Top route is now invisible
        expect(find.text(topRoute), findsOneWidget);
        expect(_getOpacity(topRoute, tester), 0.0);
        // Bottom route is still invisible, but moving down.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(
          _getOpacity(bottomRoute, tester),
          moreOrLessEquals(0, epsilon: 0.005),
        );
        double? bottomOffset = _getTranslationOffset(
          bottomRoute,
          tester,
          SharedAxisTransitionType.vertical,
        );
        expect(bottomOffset, lessThan(0.0));
        expect(bottomOffset, greaterThan(-30.0));

        // Jump to the middle of fading in
        await tester.pump(const Duration(milliseconds: 90));
        // Top route is still invisible
        expect(find.text(topRoute), findsOneWidget);
        expect(_getOpacity(topRoute, tester), 0.0);
        // Bottom route is fading in
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getOpacity(bottomRoute, tester), greaterThan(0));
        expect(_getOpacity(bottomRoute, tester), lessThan(1.0));
        bottomOffset = _getTranslationOffset(
          bottomRoute,
          tester,
          SharedAxisTransitionType.vertical,
        );
        expect(bottomOffset, lessThan(0.0));
        expect(bottomOffset, greaterThan(-30.0));

        // Jump to the end of the transition
        await tester.pump(const Duration(milliseconds: 120));
        // Top route is not visible and is offset down.
        expect(find.text(topRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            topRoute,
            tester,
            SharedAxisTransitionType.vertical,
          ),
          30.0,
        );
        expect(_getOpacity(topRoute, tester), 0.0);
        // Bottom route is not offset and is visible.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.vertical,
          ),
          0.0,
        );
        expect(_getOpacity(bottomRoute, tester), 1.0);

        await tester.pump(const Duration(milliseconds: 1));
        expect(find.text(topRoute), findsNothing);
        expect(find.text(bottomRoute), findsOneWidget);
      },
    );

    testWidgets(
      'SharedAxisTransition does not jump when interrupted',
      (WidgetTester tester) async {
        final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
        const String bottomRoute = '/';
        const String topRoute = '/a';

        await tester.pumpWidget(
          _TestWidget(
            navigatorKey: navigator,
            transitionType: SharedAxisTransitionType.vertical,
          ),
        );
        expect(find.text(bottomRoute), findsOneWidget);
        expect(find.text(topRoute), findsNothing);

        navigator.currentState!.pushNamed(topRoute);
        await tester.pump();

        // Jump to halfway point of transition.
        await tester.pump(const Duration(milliseconds: 150));
        // Bottom route is fully faded out.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getOpacity(bottomRoute, tester), 0.0);
        final double halfwayBottomOffset = _getTranslationOffset(
          bottomRoute,
          tester,
          SharedAxisTransitionType.vertical,
        );
        expect(halfwayBottomOffset, lessThan(0.0));
        expect(halfwayBottomOffset, greaterThan(-30.0));

        // Top route is fading/coming in.
        expect(find.text(topRoute), findsOneWidget);
        final double halfwayTopOffset = _getTranslationOffset(
          topRoute,
          tester,
          SharedAxisTransitionType.vertical,
        );
        final double halfwayTopOpacity = _getOpacity(topRoute, tester);
        expect(halfwayTopOffset, greaterThan(0.0));
        expect(halfwayTopOffset, lessThan(30.0));
        expect(halfwayTopOpacity, greaterThan(0.0));
        expect(halfwayTopOpacity, lessThan(1.0));

        // Interrupt the transition with a pop.
        navigator.currentState!.pop();
        await tester.pump();

        // Nothing should change.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.vertical,
          ),
          halfwayBottomOffset,
        );
        expect(_getOpacity(bottomRoute, tester), 0.0);
        expect(find.text(topRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            topRoute,
            tester,
            SharedAxisTransitionType.vertical,
          ),
          halfwayTopOffset,
        );
        expect(_getOpacity(topRoute, tester), halfwayTopOpacity);

        // Jump to the 1/4 (75 ms) point of transition
        await tester.pump(const Duration(milliseconds: 75));
        expect(find.text(bottomRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.vertical,
          ),
          lessThan(0.0),
        );
        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.vertical,
          ),
          greaterThan(-30.0),
        );
        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.vertical,
          ),
          greaterThan(halfwayBottomOffset),
        );
        expect(_getOpacity(bottomRoute, tester), greaterThan(0.0));
        expect(_getOpacity(bottomRoute, tester), lessThan(1.0));

        // Jump to the end.
        await tester.pump(const Duration(milliseconds: 75));
        expect(find.text(bottomRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            bottomRoute,
            tester,
            SharedAxisTransitionType.vertical,
          ),
          0.0,
        );
        expect(_getOpacity(bottomRoute, tester), 1.0);
        expect(find.text(topRoute), findsOneWidget);
        expect(
          _getTranslationOffset(
            topRoute,
            tester,
            SharedAxisTransitionType.vertical,
          ),
          30.0,
        );
        expect(_getOpacity(topRoute, tester), 0.0);

        await tester.pump(const Duration(milliseconds: 1));
        expect(find.text(topRoute), findsNothing);
        expect(find.text(bottomRoute), findsOneWidget);
      },
    );

    testWidgets(
      'State is not lost when transitioning',
      (WidgetTester tester) async {
        final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
        const String bottomRoute = '/';
        const String topRoute = '/a';

        await tester.pumpWidget(
          _TestWidget(
            navigatorKey: navigator,
            contentBuilder: (RouteSettings settings) {
              return _StatefulTestWidget(
                key: ValueKey<String?>(settings.name),
                name: settings.name!,
              );
            },
            transitionType: SharedAxisTransitionType.vertical,
          ),
        );

        final _StatefulTestWidgetState bottomState = tester.state(
          find.byKey(const ValueKey<String?>(bottomRoute)),
        );
        expect(bottomState.widget.name, bottomRoute);

        navigator.currentState!.pushNamed(topRoute);
        await tester.pump();
        await tester.pump();

        expect(
          tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
          bottomState,
        );
        final _StatefulTestWidgetState topState = tester.state(
          find.byKey(const ValueKey<String?>(topRoute)),
        );
        expect(topState.widget.name, topRoute);

        await tester.pump(const Duration(milliseconds: 150));
        expect(
          tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
          bottomState,
        );
        expect(
          tester.state(find.byKey(const ValueKey<String?>(topRoute))),
          topState,
        );

        await tester.pumpAndSettle();
        expect(
          tester.state(find.byKey(
            const ValueKey<String?>(bottomRoute),
            skipOffstage: false,
          )),
          bottomState,
        );
        expect(
          tester.state(find.byKey(const ValueKey<String?>(topRoute))),
          topState,
        );

        navigator.currentState!.pop();
        await tester.pump();

        expect(
          tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
          bottomState,
        );
        expect(
          tester.state(find.byKey(const ValueKey<String?>(topRoute))),
          topState,
        );

        await tester.pump(const Duration(milliseconds: 150));
        expect(
          tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
          bottomState,
        );
        expect(
          tester.state(find.byKey(const ValueKey<String?>(topRoute))),
          topState,
        );

        await tester.pumpAndSettle();
        expect(
          tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
          bottomState,
        );
        expect(find.byKey(const ValueKey<String?>(topRoute)), findsNothing);
      },
    );

    testWidgets('default fill color', (WidgetTester tester) async {
      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
      const String bottomRoute = '/';
      const String topRoute = '/a';

      // The default fill color should be derived from ThemeData.canvasColor.
      final Color defaultFillColor = ThemeData().canvasColor;

      await tester.pumpWidget(
        _TestWidget(
          navigatorKey: navigator,
          transitionType: SharedAxisTransitionType.vertical,
        ),
      );

      expect(find.text(bottomRoute), findsOneWidget);
      Finder fillContainerFinder = find
          .ancestor(
            matching: find.byType(Container),
            of: find.byKey(const ValueKey<String?>('/')),
          )
          .last;
      expect(fillContainerFinder, findsOneWidget);
      expect(tester.widget<Container>(fillContainerFinder).color,
          defaultFillColor);

      navigator.currentState!.pushNamed(topRoute);
      await tester.pump();
      await tester.pumpAndSettle();

      fillContainerFinder = find
          .ancestor(
            matching: find.byType(Container),
            of: find.byKey(const ValueKey<String?>('/a')),
          )
          .last;
      expect(fillContainerFinder, findsOneWidget);
      expect(tester.widget<Container>(fillContainerFinder).color,
          defaultFillColor);
    });

    testWidgets('custom fill color', (WidgetTester tester) async {
      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
      const String bottomRoute = '/';
      const String topRoute = '/a';

      await tester.pumpWidget(
        _TestWidget(
          navigatorKey: navigator,
          fillColor: Colors.green,
          transitionType: SharedAxisTransitionType.vertical,
        ),
      );

      expect(find.text(bottomRoute), findsOneWidget);
      Finder fillContainerFinder = find
          .ancestor(
            matching: find.byType(Container),
            of: find.byKey(const ValueKey<String?>('/')),
          )
          .last;
      expect(fillContainerFinder, findsOneWidget);
      expect(tester.widget<Container>(fillContainerFinder).color, Colors.green);

      navigator.currentState!.pushNamed(topRoute);
      await tester.pump();
      await tester.pumpAndSettle();

      fillContainerFinder = find
          .ancestor(
            matching: find.byType(Container),
            of: find.byKey(const ValueKey<String?>('/a')),
          )
          .last;
      expect(fillContainerFinder, findsOneWidget);
      expect(tester.widget<Container>(fillContainerFinder).color, Colors.green);
    });

    testWidgets('should keep state', (WidgetTester tester) async {
      final AnimationController animation = AnimationController(
        vsync: const TestVSync(),
        duration: const Duration(milliseconds: 300),
      );
      final AnimationController secondaryAnimation = AnimationController(
        vsync: const TestVSync(),
        duration: const Duration(milliseconds: 300),
      );
      await tester.pumpWidget(Directionality(
        textDirection: TextDirection.ltr,
        child: Center(
          child: SharedAxisTransition(
            transitionType: SharedAxisTransitionType.vertical,
            animation: animation,
            secondaryAnimation: secondaryAnimation,
            child: const _StatefulTestWidget(name: 'Foo'),
          ),
        ),
      ));
      final State<StatefulWidget> state = tester.state(
        find.byType(_StatefulTestWidget),
      );
      expect(state, isNotNull);

      animation.forward();
      await tester.pump();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pumpAndSettle();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));

      secondaryAnimation.forward();
      await tester.pump();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pumpAndSettle();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));

      secondaryAnimation.reverse();
      await tester.pump();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pumpAndSettle();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));

      animation.reverse();
      await tester.pump();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pumpAndSettle();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
    });
  });

  group('SharedAxisTransitionType.scaled', () {
    testWidgets(
      'SharedAxisPageTransitionsBuilder builds a SharedAxisTransition',
      (WidgetTester tester) async {
        final AnimationController animation = AnimationController(
          vsync: const TestVSync(),
        );
        final AnimationController secondaryAnimation = AnimationController(
          vsync: const TestVSync(),
        );

        await tester.pumpWidget(
          const SharedAxisPageTransitionsBuilder(
            transitionType: SharedAxisTransitionType.scaled,
          ).buildTransitions<void>(
            null,
            null,
            animation,
            secondaryAnimation,
            const Placeholder(),
          ),
        );

        expect(find.byType(SharedAxisTransition), findsOneWidget);
      },
    );

    testWidgets(
      'SharedAxisTransition runs forward',
      (WidgetTester tester) async {
        final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
        const String bottomRoute = '/';
        const String topRoute = '/a';

        await tester.pumpWidget(
          _TestWidget(
            navigatorKey: navigator,
            transitionType: SharedAxisTransitionType.scaled,
          ),
        );

        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getScale(bottomRoute, tester), 1.0);
        expect(_getOpacity(bottomRoute, tester), 1.0);
        expect(find.text(topRoute), findsNothing);

        navigator.currentState!.pushNamed(topRoute);
        await tester.pump();
        await tester.pump();

        // Bottom route is full size and fully visible.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getScale(bottomRoute, tester), 1.0);
        expect(_getOpacity(bottomRoute, tester), 1.0);
        // Top route is at 80% of full size and not visible yet.
        expect(find.text(topRoute), findsOneWidget);
        expect(_getScale(topRoute, tester), 0.8);
        expect(_getOpacity(topRoute, tester), 0.0);

        // Jump 3/10ths of the way through the transition, bottom route
        // should be be completely faded out while the top route
        // is also completely faded out.
        // Transition time: 300ms, 3/10 * 300ms = 90ms
        await tester.pump(const Duration(milliseconds: 90));

        // Bottom route is now invisible
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getOpacity(bottomRoute, tester), 0.0);
        // Top route is still invisible, but scaling up.
        expect(find.text(topRoute), findsOneWidget);
        expect(_getOpacity(topRoute, tester), 0.0);
        double topScale = _getScale(topRoute, tester);
        expect(topScale, greaterThan(0.8));
        expect(topScale, lessThan(1.0));

        // Jump to the middle of fading in
        await tester.pump(const Duration(milliseconds: 90));
        // Bottom route is still invisible
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getOpacity(bottomRoute, tester), 0.0);
        // Top route is fading in
        expect(find.text(topRoute), findsOneWidget);
        expect(_getOpacity(topRoute, tester), greaterThan(0));
        expect(_getOpacity(topRoute, tester), lessThan(1.0));
        topScale = _getScale(topRoute, tester);
        expect(topScale, greaterThan(0.8));
        expect(topScale, lessThan(1.0));

        // Jump to the end of the transition
        await tester.pump(const Duration(milliseconds: 120));
        // Bottom route is not visible.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getScale(bottomRoute, tester), 1.1);
        expect(_getOpacity(bottomRoute, tester), 0.0);
        // Top route fully scaled in and visible.
        expect(find.text(topRoute), findsOneWidget);
        expect(_getScale(topRoute, tester), 1.0);
        expect(_getOpacity(topRoute, tester), 1.0);

        await tester.pump(const Duration(milliseconds: 1));
        expect(find.text(bottomRoute), findsNothing);
        expect(find.text(topRoute), findsOneWidget);
      },
    );

    testWidgets(
      'SharedAxisTransition runs in reverse',
      (WidgetTester tester) async {
        final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
        const String bottomRoute = '/';
        const String topRoute = '/a';

        await tester.pumpWidget(
          _TestWidget(
            navigatorKey: navigator,
            transitionType: SharedAxisTransitionType.scaled,
          ),
        );

        navigator.currentState!.pushNamed(topRoute);
        await tester.pumpAndSettle();

        expect(find.text(topRoute), findsOneWidget);
        expect(_getScale(topRoute, tester), 1.0);
        expect(_getOpacity(topRoute, tester), 1.0);
        expect(find.text(bottomRoute), findsNothing);

        navigator.currentState!.pop();
        await tester.pump();

        // Top route is full size and fully visible.
        expect(find.text(topRoute), findsOneWidget);
        expect(_getScale(topRoute, tester), 1.0);
        expect(_getOpacity(topRoute, tester), 1.0);
        // Bottom route is at 110% of full size and not visible yet.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getScale(bottomRoute, tester), 1.1);
        expect(_getOpacity(bottomRoute, tester), 0.0);

        // Jump 3/10ths of the way through the transition, bottom route
        // should be be completely faded out while the top route
        // is also completely faded out.
        // Transition time: 300ms, 3/10 * 300ms = 90ms
        await tester.pump(const Duration(milliseconds: 90));

        // Bottom route is now invisible
        expect(find.text(topRoute), findsOneWidget);
        expect(_getOpacity(topRoute, tester), 0.0);
        // Top route is still invisible, but scaling down.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(
          _getOpacity(bottomRoute, tester),
          moreOrLessEquals(0, epsilon: 0.005),
        );
        double bottomScale = _getScale(bottomRoute, tester);
        expect(bottomScale, greaterThan(1.0));
        expect(bottomScale, lessThan(1.1));

        // Jump to the middle of fading in
        await tester.pump(const Duration(milliseconds: 90));
        // Top route is still invisible
        expect(find.text(topRoute), findsOneWidget);
        expect(_getOpacity(topRoute, tester), 0.0);
        // Bottom route is fading in
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getOpacity(bottomRoute, tester), greaterThan(0));
        expect(_getOpacity(bottomRoute, tester), lessThan(1.0));
        bottomScale = _getScale(bottomRoute, tester);
        expect(bottomScale, greaterThan(1.0));
        expect(bottomScale, lessThan(1.1));

        // Jump to the end of the transition
        await tester.pump(const Duration(milliseconds: 120));
        // Top route is not visible.
        expect(find.text(topRoute), findsOneWidget);
        expect(_getScale(topRoute, tester), 0.8);
        expect(_getOpacity(topRoute, tester), 0.0);
        // Bottom route fully scaled in and visible.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getScale(bottomRoute, tester), 1.0);
        expect(_getOpacity(bottomRoute, tester), 1.0);

        await tester.pump(const Duration(milliseconds: 1));
        expect(find.text(topRoute), findsNothing);
        expect(find.text(bottomRoute), findsOneWidget);
      },
    );

    testWidgets(
      'SharedAxisTransition does not jump when interrupted',
      (WidgetTester tester) async {
        final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
        const String bottomRoute = '/';
        const String topRoute = '/a';

        await tester.pumpWidget(
          _TestWidget(
            navigatorKey: navigator,
            transitionType: SharedAxisTransitionType.scaled,
          ),
        );
        expect(find.text(bottomRoute), findsOneWidget);
        expect(find.text(topRoute), findsNothing);

        navigator.currentState!.pushNamed(topRoute);
        await tester.pump();

        // Jump to halfway point of transition.
        await tester.pump(const Duration(milliseconds: 150));
        // Bottom route is fully faded out.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getOpacity(bottomRoute, tester), 0.0);
        final double halfwayBottomScale = _getScale(bottomRoute, tester);
        expect(halfwayBottomScale, greaterThan(1.0));
        expect(halfwayBottomScale, lessThan(1.1));

        // Top route is fading/scaling in.
        expect(find.text(topRoute), findsOneWidget);
        final double halfwayTopScale = _getScale(topRoute, tester);
        final double halfwayTopOpacity = _getOpacity(topRoute, tester);
        expect(halfwayTopScale, greaterThan(0.8));
        expect(halfwayTopScale, lessThan(1.0));
        expect(halfwayTopOpacity, greaterThan(0.0));
        expect(halfwayTopOpacity, lessThan(1.0));

        // Interrupt the transition with a pop.
        navigator.currentState!.pop();
        await tester.pump();

        // Nothing should change.
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getScale(bottomRoute, tester), halfwayBottomScale);
        expect(_getOpacity(bottomRoute, tester), 0.0);
        expect(find.text(topRoute), findsOneWidget);
        expect(_getScale(topRoute, tester), halfwayTopScale);
        expect(_getOpacity(topRoute, tester), halfwayTopOpacity);

        // Jump to the 1/4 (75 ms) point of transition
        await tester.pump(const Duration(milliseconds: 75));
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getScale(bottomRoute, tester), greaterThan(1.0));
        expect(_getScale(bottomRoute, tester), lessThan(1.1));
        expect(_getScale(bottomRoute, tester), lessThan(halfwayBottomScale));
        expect(_getOpacity(bottomRoute, tester), greaterThan(0.0));
        expect(_getOpacity(bottomRoute, tester), lessThan(1.0));

        // Jump to the end.
        await tester.pump(const Duration(milliseconds: 75));
        expect(find.text(bottomRoute), findsOneWidget);
        expect(_getScale(bottomRoute, tester), 1.0);
        expect(_getOpacity(bottomRoute, tester), 1.0);
        expect(find.text(topRoute), findsOneWidget);
        expect(_getScale(topRoute, tester), 0.80);
        expect(_getOpacity(topRoute, tester), 0.0);

        await tester.pump(const Duration(milliseconds: 1));
        expect(find.text(topRoute), findsNothing);
        expect(find.text(bottomRoute), findsOneWidget);
      },
    );

    testWidgets(
      'SharedAxisTransition properly disposes animation',
      (WidgetTester tester) async {
        final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
        const String bottomRoute = '/';
        const String topRoute = '/a';

        await tester.pumpWidget(
          _TestWidget(
            navigatorKey: navigator,
            transitionType: SharedAxisTransitionType.scaled,
          ),
        );
        expect(find.text(bottomRoute), findsOneWidget);
        expect(find.text(topRoute), findsNothing);

        navigator.currentState!.pushNamed(topRoute);
        await tester.pump();

        // Jump to halfway point of transition.
        await tester.pump(const Duration(milliseconds: 150));
        expect(find.byType(SharedAxisTransition), findsNWidgets(2));

        // Rebuild the app without the transition.
        await tester.pumpWidget(
          MaterialApp(
            navigatorKey: navigator,
            home: const Material(
              child: Text('abc'),
            ),
          ),
        );
        await tester.pump();
        // Transitions should have been disposed of.
        expect(find.byType(SharedAxisTransition), findsNothing);
      },
    );

    testWidgets(
      'State is not lost when transitioning',
      (WidgetTester tester) async {
        final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
        const String bottomRoute = '/';
        const String topRoute = '/a';

        await tester.pumpWidget(
          _TestWidget(
            navigatorKey: navigator,
            transitionType: SharedAxisTransitionType.scaled,
            contentBuilder: (RouteSettings settings) {
              return _StatefulTestWidget(
                key: ValueKey<String?>(settings.name),
                name: settings.name!,
              );
            },
          ),
        );

        final _StatefulTestWidgetState bottomState = tester.state(
          find.byKey(const ValueKey<String?>(bottomRoute)),
        );
        expect(bottomState.widget.name, bottomRoute);

        navigator.currentState!.pushNamed(topRoute);
        await tester.pump();
        await tester.pump();

        expect(
          tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
          bottomState,
        );
        final _StatefulTestWidgetState topState = tester.state(
          find.byKey(const ValueKey<String?>(topRoute)),
        );
        expect(topState.widget.name, topRoute);

        await tester.pump(const Duration(milliseconds: 150));
        expect(
          tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
          bottomState,
        );
        expect(
          tester.state(find.byKey(const ValueKey<String?>(topRoute))),
          topState,
        );

        await tester.pumpAndSettle();
        expect(
          tester.state(find.byKey(
            const ValueKey<String?>(bottomRoute),
            skipOffstage: false,
          )),
          bottomState,
        );
        expect(
          tester.state(find.byKey(const ValueKey<String?>(topRoute))),
          topState,
        );

        navigator.currentState!.pop();
        await tester.pump();

        expect(
          tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
          bottomState,
        );
        expect(
          tester.state(find.byKey(const ValueKey<String?>(topRoute))),
          topState,
        );

        await tester.pump(const Duration(milliseconds: 150));
        expect(
          tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
          bottomState,
        );
        expect(
          tester.state(find.byKey(const ValueKey<String?>(topRoute))),
          topState,
        );

        await tester.pumpAndSettle();
        expect(
          tester.state(find.byKey(const ValueKey<String?>(bottomRoute))),
          bottomState,
        );
        expect(find.byKey(const ValueKey<String?>(topRoute)), findsNothing);
      },
    );

    testWidgets('default fill color', (WidgetTester tester) async {
      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
      const String bottomRoute = '/';
      const String topRoute = '/a';

      // The default fill color should be derived from ThemeData.canvasColor.
      final Color defaultFillColor = ThemeData().canvasColor;

      await tester.pumpWidget(
        _TestWidget(
          navigatorKey: navigator,
          transitionType: SharedAxisTransitionType.scaled,
        ),
      );

      expect(find.text(bottomRoute), findsOneWidget);
      Finder fillContainerFinder = find
          .ancestor(
            matching: find.byType(Container),
            of: find.byKey(const ValueKey<String?>('/')),
          )
          .last;
      expect(fillContainerFinder, findsOneWidget);
      expect(tester.widget<Container>(fillContainerFinder).color,
          defaultFillColor);

      navigator.currentState!.pushNamed(topRoute);
      await tester.pump();
      await tester.pumpAndSettle();

      fillContainerFinder = find
          .ancestor(
            matching: find.byType(Container),
            of: find.byKey(const ValueKey<String?>('/a')),
          )
          .last;
      expect(fillContainerFinder, findsOneWidget);
      expect(tester.widget<Container>(fillContainerFinder).color,
          defaultFillColor);
    });

    testWidgets('custom fill color', (WidgetTester tester) async {
      final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
      const String bottomRoute = '/';
      const String topRoute = '/a';

      await tester.pumpWidget(
        _TestWidget(
          navigatorKey: navigator,
          fillColor: Colors.green,
          transitionType: SharedAxisTransitionType.scaled,
        ),
      );

      expect(find.text(bottomRoute), findsOneWidget);
      Finder fillContainerFinder = find
          .ancestor(
            matching: find.byType(Container),
            of: find.byKey(const ValueKey<String?>('/')),
          )
          .last;
      expect(fillContainerFinder, findsOneWidget);
      expect(tester.widget<Container>(fillContainerFinder).color, Colors.green);

      navigator.currentState!.pushNamed(topRoute);
      await tester.pump();
      await tester.pumpAndSettle();

      fillContainerFinder = find
          .ancestor(
            matching: find.byType(Container),
            of: find.byKey(const ValueKey<String?>('/a')),
          )
          .last;
      expect(fillContainerFinder, findsOneWidget);
      expect(tester.widget<Container>(fillContainerFinder).color, Colors.green);
    });

    testWidgets('should keep state', (WidgetTester tester) async {
      final AnimationController animation = AnimationController(
        vsync: const TestVSync(),
        duration: const Duration(milliseconds: 300),
      );
      final AnimationController secondaryAnimation = AnimationController(
        vsync: const TestVSync(),
        duration: const Duration(milliseconds: 300),
      );
      await tester.pumpWidget(Directionality(
        textDirection: TextDirection.ltr,
        child: Center(
          child: SharedAxisTransition(
            transitionType: SharedAxisTransitionType.scaled,
            animation: animation,
            secondaryAnimation: secondaryAnimation,
            child: const _StatefulTestWidget(name: 'Foo'),
          ),
        ),
      ));
      final State<StatefulWidget> state = tester.state(
        find.byType(_StatefulTestWidget),
      );
      expect(state, isNotNull);

      animation.forward();
      await tester.pump();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pumpAndSettle();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));

      secondaryAnimation.forward();
      await tester.pump();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pumpAndSettle();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));

      secondaryAnimation.reverse();
      await tester.pump();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pumpAndSettle();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));

      animation.reverse();
      await tester.pump();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pump(const Duration(milliseconds: 150));
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
      await tester.pumpAndSettle();
      expect(state, same(tester.state(find.byType(_StatefulTestWidget))));
    });
  });
}

double _getOpacity(String key, WidgetTester tester) {
  final Finder finder = find.ancestor(
    of: find.byKey(ValueKey<String?>(key)),
    matching: find.byType(FadeTransition),
  );
  return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
    final FadeTransition transition = widget as FadeTransition;
    return a * transition.opacity.value;
  });
}

double _getTranslationOffset(
  String key,
  WidgetTester tester,
  SharedAxisTransitionType transitionType,
) {
  final Finder finder = find.ancestor(
    of: find.byKey(ValueKey<String?>(key)),
    matching: find.byType(Transform),
  );

  switch (transitionType) {
    case SharedAxisTransitionType.horizontal:
      return tester.widgetList<Transform>(finder).fold<double>(0.0,
          (double a, Widget widget) {
        final Transform transition = widget as Transform;
        final Vector3 translation = transition.transform.getTranslation();
        return a + translation.x;
      });
    case SharedAxisTransitionType.vertical:
      return tester.widgetList<Transform>(finder).fold<double>(0.0,
          (double a, Widget widget) {
        final Transform transition = widget as Transform;
        final Vector3 translation = transition.transform.getTranslation();
        return a + translation.y;
      });
    case SharedAxisTransitionType.scaled:
      assert(
        false,
        'SharedAxisTransitionType.scaled does not have a translation offset',
      );
      return 0.0;
  }
}

double _getScale(String key, WidgetTester tester) {
  final Finder finder = find.ancestor(
    of: find.byKey(ValueKey<String?>(key)),
    matching: find.byType(ScaleTransition),
  );
  return tester.widgetList(finder).fold<double>(1.0, (double a, Widget widget) {
    final ScaleTransition transition = widget as ScaleTransition;
    return a * transition.scale.value;
  });
}

class _TestWidget extends StatelessWidget {
  const _TestWidget({
    required this.navigatorKey,
    this.contentBuilder,
    required this.transitionType,
    this.fillColor,
  });

  final Key navigatorKey;
  final _ContentBuilder? contentBuilder;
  final SharedAxisTransitionType transitionType;
  final Color? fillColor;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: navigatorKey as GlobalKey<NavigatorState>?,
      theme: ThemeData(
        platform: TargetPlatform.android,
        pageTransitionsTheme: PageTransitionsTheme(
          builders: <TargetPlatform, PageTransitionsBuilder>{
            TargetPlatform.android: SharedAxisPageTransitionsBuilder(
              fillColor: fillColor,
              transitionType: transitionType,
            ),
          },
        ),
      ),
      onGenerateRoute: (RouteSettings settings) {
        return MaterialPageRoute<void>(
          settings: settings,
          builder: (BuildContext context) {
            return contentBuilder != null
                ? contentBuilder!(settings)
                : Center(
                    key: ValueKey<String?>(settings.name),
                    child: Text(settings.name!),
                  );
          },
        );
      },
    );
  }
}

class _StatefulTestWidget extends StatefulWidget {
  const _StatefulTestWidget({Key? key, required this.name}) : super(key: key);

  final String name;

  @override
  State<_StatefulTestWidget> createState() => _StatefulTestWidgetState();
}

class _StatefulTestWidgetState extends State<_StatefulTestWidget> {
  @override
  Widget build(BuildContext context) {
    return Text(widget.name);
  }
}

typedef _ContentBuilder = Widget Function(RouteSettings settings);
