// Copyright 2019 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/animation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.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,
            child: const _StatefulTestWidget(name: 'Foo'),
            animation: animation,
            secondaryAnimation: secondaryAnimation,
          ),
        ),
      ));
      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,
            child: const _StatefulTestWidget(name: 'Foo'),
            animation: animation,
            secondaryAnimation: secondaryAnimation,
          ),
        ),
      ));
      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,
            child: const _StatefulTestWidget(name: 'Foo'),
            animation: animation,
            secondaryAnimation: secondaryAnimation,
          ),
        ),
      ));
      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:
      // SharedAxisTransitionType.scaled should not return a translation
      // offset.
      return null;
  }
}

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)
                : Container(
                    child: 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);
