// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker_flutter_testing/leak_tracker_flutter_testing.dart';

void main() {
  testWidgets('toString control test', (WidgetTester tester) async {
    const Widget widget = FadeTransition(
      opacity: kAlwaysCompleteAnimation,
      child: Text('Ready', textDirection: TextDirection.ltr),
    );
    expect(widget.toString, isNot(throwsException));
  });

  group('DecoratedBoxTransition test', () {
    final DecorationTween decorationTween = DecorationTween(
      begin: BoxDecoration(
        color: const Color(0xFFFFFFFF),
        border: Border.all(
          width: 4.0,
        ),
        borderRadius: BorderRadius.zero,
        boxShadow: const <BoxShadow>[
          BoxShadow(
            color: Color(0x66000000),
            blurRadius: 10.0,
            spreadRadius: 4.0,
          ),
        ],
      ),
      end: BoxDecoration(
        color: const Color(0xFF000000),
        border: Border.all(
          color: const Color(0xFF202020),
        ),
        borderRadius: const BorderRadius.all(Radius.circular(10.0)),
        // No shadow.
      ),
    );

    late AnimationController controller;

    setUp(() {
      controller = AnimationController(vsync: const TestVSync());
    });

    testWidgets('decoration test', (WidgetTester tester) async {
      final DecoratedBoxTransition transitionUnderTest =
      DecoratedBoxTransition(
        decoration: decorationTween.animate(controller),
        child: const Text(
          "Doesn't matter",
          textDirection: TextDirection.ltr,
        ),
      );

      await tester.pumpWidget(transitionUnderTest);
      RenderDecoratedBox actualBox = tester.renderObject(find.byType(DecoratedBox));
      BoxDecoration actualDecoration = actualBox.decoration as BoxDecoration;

      expect(actualDecoration.color, const Color(0xFFFFFFFF));
      expect(actualDecoration.boxShadow![0].blurRadius, 10.0);
      expect(actualDecoration.boxShadow![0].spreadRadius, 4.0);
      expect(actualDecoration.boxShadow![0].color, const Color(0x66000000));

      controller.value = 0.5;

      await tester.pump();
      actualBox = tester.renderObject(find.byType(DecoratedBox));
      actualDecoration = actualBox.decoration as BoxDecoration;

      expect(actualDecoration.color, const Color(0xFF7F7F7F));
      expect(actualDecoration.border, isA<Border>());
      final Border border = actualDecoration.border! as Border;
      expect(border.left.width, 2.5);
      expect(border.left.style, BorderStyle.solid);
      expect(border.left.color, const Color(0xFF101010));
      expect(actualDecoration.borderRadius, const BorderRadius.all(Radius.circular(5.0)));
      expect(actualDecoration.shape, BoxShape.rectangle);
      expect(actualDecoration.boxShadow![0].blurRadius, 5.0);
      expect(actualDecoration.boxShadow![0].spreadRadius, 2.0);
      // Scaling a shadow doesn't change the color.
      expect(actualDecoration.boxShadow![0].color, const Color(0x66000000));

      controller.value = 1.0;

      await tester.pump();
      actualBox = tester.renderObject(find.byType(DecoratedBox));
      actualDecoration = actualBox.decoration as BoxDecoration;

      expect(actualDecoration.color, const Color(0xFF000000));
      expect(actualDecoration.boxShadow, null);
    });

    testWidgets('animations work with curves test',
    // TODO(polina-c): remove when fixed https://github.com/flutter/flutter/issues/145600 [leak-tracking-opt-in]
    experimentalLeakTesting: LeakTesting.settings.withTracked(classes: const <String>['CurvedAnimation']),
    (WidgetTester tester) async {
      final Animation<Decoration> curvedDecorationAnimation =
        decorationTween.animate(CurvedAnimation(
        parent: controller,
        curve: Curves.easeOut,
      ));

      final DecoratedBoxTransition transitionUnderTest = DecoratedBoxTransition(
        decoration: curvedDecorationAnimation,
        position: DecorationPosition.foreground,
        child: const Text(
          "Doesn't matter",
          textDirection: TextDirection.ltr,
        ),
      );

      await tester.pumpWidget(transitionUnderTest);

      RenderDecoratedBox actualBox = tester.renderObject(find.byType(DecoratedBox));
      BoxDecoration actualDecoration = actualBox.decoration as BoxDecoration;

      expect(actualDecoration.color, const Color(0xFFFFFFFF));
      expect(actualDecoration.boxShadow![0].blurRadius, 10.0);
      expect(actualDecoration.boxShadow![0].spreadRadius, 4.0);
      expect(actualDecoration.boxShadow![0].color, const Color(0x66000000));

      controller.value = 0.5;

      await tester.pump();
      actualBox = tester.renderObject(find.byType(DecoratedBox));
      actualDecoration = actualBox.decoration as BoxDecoration;

      // Same as the test above but the values should be much closer to the
      // tween's end values given the easeOut curve.
      expect(actualDecoration.color, const Color(0xFF505050));
      expect(actualDecoration.border, isA<Border>());
      final Border border = actualDecoration.border! as Border;
      expect(border.left.width, moreOrLessEquals(1.9, epsilon: 0.1));
      expect(border.left.style, BorderStyle.solid);
      expect(border.left.color, const Color(0xFF151515));
      expect(actualDecoration.borderRadius!.resolve(TextDirection.ltr).topLeft.x, moreOrLessEquals(6.8, epsilon: 0.1));
      expect(actualDecoration.shape, BoxShape.rectangle);
      expect(actualDecoration.boxShadow![0].blurRadius, moreOrLessEquals(3.1, epsilon: 0.1));
      expect(actualDecoration.boxShadow![0].spreadRadius, moreOrLessEquals(1.2, epsilon: 0.1));
      // Scaling a shadow doesn't change the color.
      expect(actualDecoration.boxShadow![0].color, const Color(0x66000000));
    });
  });

  testWidgets('AlignTransition animates', (WidgetTester tester) async {
    final AnimationController controller = AnimationController(vsync: const TestVSync());
    addTearDown(controller.dispose);
    final Animation<Alignment> alignmentTween = AlignmentTween(
      begin: Alignment.centerLeft,
      end: Alignment.bottomRight,
    ).animate(controller);
    final Widget widget = AlignTransition(
      alignment: alignmentTween,
      child: const Text('Ready', textDirection: TextDirection.ltr),
    );

    await tester.pumpWidget(widget);

    final RenderPositionedBox actualPositionedBox = tester.renderObject(find.byType(Align));

    Alignment actualAlignment = actualPositionedBox.alignment as Alignment;
    expect(actualAlignment, Alignment.centerLeft);

    controller.value = 0.5;
    await tester.pump();
    actualAlignment = actualPositionedBox.alignment as Alignment;
    expect(actualAlignment, const Alignment(0.0, 0.5));
  });

  testWidgets('RelativePositionedTransition animates', (WidgetTester tester) async {
    final AnimationController controller = AnimationController(vsync: const TestVSync());
    addTearDown(controller.dispose);
    final Animation<Rect?> rectTween = RectTween(
      begin: const Rect.fromLTWH(0, 0, 30, 40),
      end: const Rect.fromLTWH(100, 200, 100, 200),
    ).animate(controller);
    final Widget widget = Directionality(
      textDirection: TextDirection.rtl,
      child: Stack(
        alignment: Alignment.centerLeft,
        children: <Widget>[
          RelativePositionedTransition(
            size: const Size(200, 300),
            rect: rectTween,
            child: const Placeholder(),
          ),
        ],
      ),
    );

    await tester.pumpWidget(widget);

    final Positioned actualPositioned = tester.widget(find.byType(Positioned));
    final RenderBox renderBox = tester.renderObject(find.byType(Placeholder));

    Rect actualRect = Rect.fromLTRB(
      actualPositioned.left!,
      actualPositioned.top!,
      actualPositioned.right ?? 0.0,
      actualPositioned.bottom ?? 0.0,
    );
    expect(actualRect, equals(const Rect.fromLTRB(0, 0, 170, 260)));
    expect(renderBox.size, equals(const Size(630, 340)));

    controller.value = 0.5;
    await tester.pump();
    actualRect = Rect.fromLTRB(
      actualPositioned.left!,
      actualPositioned.top!,
      actualPositioned.right ?? 0.0,
      actualPositioned.bottom ?? 0.0,
    );
    expect(actualRect, equals(const Rect.fromLTWH(0, 0, 170, 260)));
    expect(renderBox.size, equals(const Size(665, 420)));
  });

  testWidgets('AlignTransition keeps width and height factors', (WidgetTester tester) async {
    final AnimationController controller = AnimationController(vsync: const TestVSync());
    addTearDown(controller.dispose);
    final Animation<Alignment> alignmentTween = AlignmentTween(
      begin: Alignment.centerLeft,
      end: Alignment.bottomRight,
    ).animate(controller);
    final Widget widget = AlignTransition(
      alignment: alignmentTween,
      widthFactor: 0.3,
      heightFactor: 0.4,
      child: const Text('Ready', textDirection: TextDirection.ltr),
    );

    await tester.pumpWidget(widget);

    final Align actualAlign = tester.widget(find.byType(Align));

    expect(actualAlign.widthFactor, 0.3);
    expect(actualAlign.heightFactor, 0.4);
  });

  testWidgets('SizeTransition clamps negative size factors - vertical axis', (WidgetTester tester) async {
    final AnimationController controller = AnimationController(vsync: const TestVSync());
    addTearDown(controller.dispose);
    final Animation<double> animation = Tween<double>(begin: -1.0, end: 1.0).animate(controller);

    final Widget widget =  Directionality(
      textDirection: TextDirection.ltr,
      child: SizeTransition(
        sizeFactor: animation,
        fixedCrossAxisSizeFactor: 2.0,
        child: const Text('Ready'),
      ),
    );

    await tester.pumpWidget(widget);

    final RenderPositionedBox actualPositionedBox = tester.renderObject(find.byType(Align));
    expect(actualPositionedBox.heightFactor, 0.0);
    expect(actualPositionedBox.widthFactor, 2.0);

    controller.value = 0.0;
    await tester.pump();
    expect(actualPositionedBox.heightFactor, 0.0);
    expect(actualPositionedBox.widthFactor, 2.0);

    controller.value = 0.75;
    await tester.pump();
    expect(actualPositionedBox.heightFactor, 0.5);
    expect(actualPositionedBox.widthFactor, 2.0);

    controller.value = 1.0;
    await tester.pump();
    expect(actualPositionedBox.heightFactor, 1.0);
    expect(actualPositionedBox.widthFactor, 2.0);
  });

  testWidgets('SizeTransition clamps negative size factors - horizontal axis', (WidgetTester tester) async {
    final AnimationController controller = AnimationController(vsync: const TestVSync());
    addTearDown(controller.dispose);
    final Animation<double> animation = Tween<double>(begin: -1.0, end: 1.0).animate(controller);

    final Widget widget =  Directionality(
      textDirection: TextDirection.ltr,
      child: SizeTransition(
        axis: Axis.horizontal,
        sizeFactor: animation,
        fixedCrossAxisSizeFactor: 1.0,
        child: const Text('Ready'),
      ),
    );

    await tester.pumpWidget(widget);

    final RenderPositionedBox actualPositionedBox = tester.renderObject(find.byType(Align));
    expect(actualPositionedBox.widthFactor, 0.0);
    expect(actualPositionedBox.heightFactor, 1.0);

    controller.value = 0.0;
    await tester.pump();
    expect(actualPositionedBox.widthFactor, 0.0);
    expect(actualPositionedBox.heightFactor, 1.0);

    controller.value = 0.75;
    await tester.pump();
    expect(actualPositionedBox.widthFactor, 0.5);
    expect(actualPositionedBox.heightFactor, 1.0);

    controller.value = 1.0;
    await tester.pump();
    expect(actualPositionedBox.widthFactor, 1.0);
    expect(actualPositionedBox.heightFactor, 1.0);
  });

  testWidgets('SizeTransition with fixedCrossAxisSizeFactor should size its cross axis from its children - vertical axis', (WidgetTester tester) async {
    final AnimationController controller = AnimationController(vsync: const TestVSync());
    addTearDown(controller.dispose);
    final Animation<double> animation = Tween<double>(begin: 0, end: 1.0).animate(controller);

    const Key key = Key('key');

    final Widget widget =  Directionality(
      textDirection: TextDirection.ltr,
      child: Center(
        child: SizedBox(
          key: key,
          child: SizeTransition(
            sizeFactor: animation,
            fixedCrossAxisSizeFactor: 1.0,
            child: const SizedBox.square(dimension: 100),
          ),
        ),
      ),
    );

    await tester.pumpWidget(widget);

    final RenderPositionedBox actualPositionedBox = tester.renderObject(find.byType(Align));
    expect(actualPositionedBox.heightFactor, 0.0);
    expect(actualPositionedBox.widthFactor, 1.0);
    expect(tester.getSize(find.byKey(key)), const Size(100, 0));

    controller.value = 0.0;
    await tester.pump();
    expect(actualPositionedBox.heightFactor, 0.0);
    expect(actualPositionedBox.widthFactor, 1.0);
    expect(tester.getSize(find.byKey(key)), const Size(100, 0));

    controller.value = 0.5;
    await tester.pump();
    expect(actualPositionedBox.heightFactor, 0.5);
    expect(actualPositionedBox.widthFactor, 1.0);
    expect(tester.getSize(find.byKey(key)), const Size(100, 50));

    controller.value = 1.0;
    await tester.pump();
    expect(actualPositionedBox.heightFactor, 1.0);
    expect(actualPositionedBox.widthFactor, 1.0);
    expect(tester.getSize(find.byKey(key)), const Size.square(100));

    controller.value = 0.5;
    await tester.pump();
    expect(actualPositionedBox.heightFactor, 0.5);
    expect(actualPositionedBox.widthFactor, 1.0);
    expect(tester.getSize(find.byKey(key)), const Size(100, 50));

    controller.value = 0.0;
    await tester.pump();
    expect(actualPositionedBox.heightFactor, 0.0);
    expect(actualPositionedBox.widthFactor, 1.0);
    expect(tester.getSize(find.byKey(key)), const Size(100, 0));
  });

  testWidgets('SizeTransition with fixedCrossAxisSizeFactor should size its cross axis from its children - horizontal axis', (WidgetTester tester) async {
    final AnimationController controller = AnimationController(vsync: const TestVSync());
    addTearDown(controller.dispose);
    final Animation<double> animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller);

    const Key key = Key('key');

    final Widget widget =  Directionality(
      textDirection: TextDirection.ltr,
      child: Center(
        child: SizedBox(
          key: key,
          child: SizeTransition(
            axis: Axis.horizontal,
            sizeFactor: animation,
            fixedCrossAxisSizeFactor: 1.0,
            child: const SizedBox.square(dimension: 100),
          ),
        ),
      ),
    );

    await tester.pumpWidget(widget);

    final RenderPositionedBox actualPositionedBox = tester.renderObject(find.byType(Align));
    expect(actualPositionedBox.heightFactor, 1.0);
    expect(actualPositionedBox.widthFactor, 0.0);
    expect(tester.getSize(find.byKey(key)), const Size(0, 100));

    controller.value = 0.0;
    await tester.pump();
    expect(actualPositionedBox.heightFactor, 1.0);
    expect(actualPositionedBox.widthFactor, 0.0);
    expect(tester.getSize(find.byKey(key)), const Size(0, 100));

    controller.value = 0.5;
    await tester.pump();
    expect(actualPositionedBox.heightFactor, 1.0);
    expect(actualPositionedBox.widthFactor, 0.5);
    expect(tester.getSize(find.byKey(key)), const Size(50, 100));

    controller.value = 1.0;
    await tester.pump();
    expect(actualPositionedBox.heightFactor, 1.0);
    expect(actualPositionedBox.widthFactor, 1.0);
    expect(tester.getSize(find.byKey(key)), const Size.square(100));

    controller.value = 0.5;
    await tester.pump();
    expect(actualPositionedBox.heightFactor, 1.0);
    expect(actualPositionedBox.widthFactor, 0.5);
    expect(tester.getSize(find.byKey(key)), const Size(50, 100));

    controller.value = 0.0;
    await tester.pump();
    expect(actualPositionedBox.heightFactor, 1.0);
    expect(actualPositionedBox.widthFactor, 0.0);
    expect(tester.getSize(find.byKey(key)), const Size(0, 100));
  });

  testWidgets('MatrixTransition animates', (WidgetTester tester) async {
    final AnimationController controller = AnimationController(vsync: const TestVSync());
    addTearDown(controller.dispose);
    final Widget widget = MatrixTransition(
      alignment: Alignment.topRight,
      onTransform: (double value) => Matrix4.translationValues(value, value, value),
      animation: controller,
      child: const Text(
        'Matrix',
        textDirection: TextDirection.ltr,
      ),
    );

    await tester.pumpWidget(widget);
    Transform actualTransformedBox = tester.widget(find.byType(Transform));
    Matrix4 actualTransform = actualTransformedBox.transform;
    expect(actualTransform, equals(Matrix4.rotationZ(0.0)));

    controller.value = 0.5;
    await tester.pump();
    actualTransformedBox = tester.widget(find.byType(Transform));
    actualTransform = actualTransformedBox.transform;
    expect(actualTransform, Matrix4.fromList(<double>[
      1.0,  0.0, 0.0, 0.5,
      0.0,  1.0, 0.0, 0.5,
      0.0,  0.0, 1.0, 0.5,
      0.0,  0.0, 0.0, 1.0,
    ])..transpose());

    controller.value = 0.75;
    await tester.pump();
    actualTransformedBox = tester.widget(find.byType(Transform));
    actualTransform = actualTransformedBox.transform;
    expect(actualTransform, Matrix4.fromList(<double>[
      1.0, 0.0, 0.0, 0.75,
      0.0, 1.0, 0.0, 0.75,
      0.0, 0.0, 1.0, 0.75,
      0.0, 0.0, 0.0, 1.0,
    ])..transpose());
  });

  testWidgets('MatrixTransition maintains chosen alignment during animation', (WidgetTester tester) async {
    final AnimationController controller = AnimationController(vsync: const TestVSync());
    addTearDown(controller.dispose);
    final Widget widget = MatrixTransition(
      alignment: Alignment.topRight,
      onTransform: (double value) => Matrix4.identity(),
      animation: controller,
      child: const Text('Matrix', textDirection: TextDirection.ltr),
    );

    await tester.pumpWidget(widget);
    MatrixTransition actualTransformedBox = tester.widget(find.byType(MatrixTransition));
    Alignment actualAlignment = actualTransformedBox.alignment;
    expect(actualAlignment, Alignment.topRight);

    controller.value = 0.5;
    await tester.pump();
    actualTransformedBox = tester.widget(find.byType(MatrixTransition));
    actualAlignment = actualTransformedBox.alignment;
    expect(actualAlignment, Alignment.topRight);
  });

  testWidgets('RotationTransition animates', (WidgetTester tester) async {
    final AnimationController controller = AnimationController(vsync: const TestVSync());
    addTearDown(controller.dispose);
    final Widget widget = RotationTransition(
      alignment: Alignment.topRight,
      turns: controller,
      child: const Text(
        'Rotation',
        textDirection: TextDirection.ltr,
      ),
    );

    await tester.pumpWidget(widget);
    Transform actualRotatedBox = tester.widget(find.byType(Transform));
    Matrix4 actualTurns = actualRotatedBox.transform;
    expect(actualTurns, equals(Matrix4.rotationZ(0.0)));

    controller.value = 0.5;
    await tester.pump();
    actualRotatedBox = tester.widget(find.byType(Transform));
    actualTurns = actualRotatedBox.transform;
    expect(actualTurns, matrixMoreOrLessEquals(Matrix4.fromList(<double>[
     -1.0,  0.0, 0.0, 0.0,
      0.0, -1.0, 0.0, 0.0,
      0.0,  0.0, 1.0, 0.0,
      0.0,  0.0, 0.0, 1.0,
    ])..transpose()));

    controller.value = 0.75;
    await tester.pump();
    actualRotatedBox = tester.widget(find.byType(Transform));
    actualTurns = actualRotatedBox.transform;
    expect(actualTurns, matrixMoreOrLessEquals(Matrix4.fromList(<double>[
      0.0, 1.0, 0.0, 0.0,
     -1.0, 0.0, 0.0, 0.0,
      0.0, 0.0, 1.0, 0.0,
      0.0, 0.0, 0.0, 1.0,
    ])..transpose()));
  });

  testWidgets('RotationTransition maintains chosen alignment during animation', (WidgetTester tester) async {
    final AnimationController controller = AnimationController(vsync: const TestVSync());
    addTearDown(controller.dispose);
    final Widget widget = RotationTransition(
      alignment: Alignment.topRight,
      turns: controller,
      child: const Text('Rotation', textDirection: TextDirection.ltr),
    );

    await tester.pumpWidget(widget);
    RotationTransition actualRotatedBox = tester.widget(find.byType(RotationTransition));
    Alignment actualAlignment = actualRotatedBox.alignment;
    expect(actualAlignment, Alignment.topRight);

    controller.value = 0.5;
    await tester.pump();
    actualRotatedBox = tester.widget(find.byType(RotationTransition));
    actualAlignment = actualRotatedBox.alignment;
    expect(actualAlignment, Alignment.topRight);
  });

  group('FadeTransition', () {
    double getOpacity(WidgetTester tester, String textValue) {
      final FadeTransition opacityWidget = tester.widget<FadeTransition>(
        find.ancestor(
          of: find.text(textValue),
          matching: find.byType(FadeTransition),
        ).first,
      );
      return opacityWidget.opacity.value;
    }
    testWidgets('animates', (WidgetTester tester) async {
      final AnimationController controller = AnimationController(vsync: const TestVSync());
      addTearDown(controller.dispose);
      final Animation<double> animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller);
      final Widget widget =  Directionality(
        textDirection: TextDirection.ltr,
        child: FadeTransition(
          opacity: animation,
          child: const Text('Fade In'),
        ),
      );

      await tester.pumpWidget(widget);

      expect(getOpacity(tester, 'Fade In'), 0.0);

      controller.value = 0.25;
      await tester.pump();
      expect(getOpacity(tester, 'Fade In'), 0.25);

      controller.value = 0.5;
      await tester.pump();
      expect(getOpacity(tester, 'Fade In'), 0.5);

      controller.value = 0.75;
      await tester.pump();
      expect(getOpacity(tester, 'Fade In'), 0.75);

      controller.value = 1.0;
      await tester.pump();
      expect(getOpacity(tester, 'Fade In'), 1.0);
    });
  });

  group('SliverFadeTransition', () {
    double getOpacity(WidgetTester tester, String textValue) {
      final SliverFadeTransition opacityWidget = tester.widget<SliverFadeTransition>(
        find.ancestor(
          of: find.text(textValue),
          matching: find.byType(SliverFadeTransition),
        ).first,
      );
      return opacityWidget.opacity.value;
    }
    testWidgets('animates', (WidgetTester tester) async {
      final AnimationController controller = AnimationController(vsync: const TestVSync());
      addTearDown(controller.dispose);
      final Animation<double> animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller);
      final Widget widget = Localizations(
        locale: const Locale('en', 'us'),
        delegates: const <LocalizationsDelegate<dynamic>>[
          DefaultWidgetsLocalizations.delegate,
          DefaultMaterialLocalizations.delegate,
        ],
        child: Directionality(
          textDirection: TextDirection.ltr,
          child: MediaQuery(
            data: const MediaQueryData(),
            child: CustomScrollView(
              slivers: <Widget>[
                SliverFadeTransition(
                  opacity: animation,
                  sliver: const SliverToBoxAdapter(
                    child: Text('Fade In'),
                  ),
                ),
              ],
            ),
          ),
        ),
      );

      await tester.pumpWidget(widget);

      expect(getOpacity(tester, 'Fade In'), 0.0);

      controller.value = 0.25;
      await tester.pump();
      expect(getOpacity(tester, 'Fade In'), 0.25);

      controller.value = 0.5;
      await tester.pump();
      expect(getOpacity(tester, 'Fade In'), 0.5);

      controller.value = 0.75;
      await tester.pump();
      expect(getOpacity(tester, 'Fade In'), 0.75);

      controller.value = 1.0;
      await tester.pump();
      expect(getOpacity(tester, 'Fade In'), 1.0);
    });
  });

  group('MatrixTransition', () {
    testWidgets('uses ImageFilter when provided with FilterQuality argument', (WidgetTester tester) async {
      final AnimationController controller = AnimationController(vsync: const TestVSync());
      addTearDown(controller.dispose);
      final Animation<double> animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller);
      final Widget widget = Directionality(
        textDirection: TextDirection.ltr,
        child: MatrixTransition(
          animation: animation,
          onTransform: (double value) => Matrix4.identity(),
          filterQuality: FilterQuality.none,
          child: const Text('Matrix Transition'),
        ),
      );

      await tester.pumpWidget(widget);

      // Validate that expensive layer is not left in tree before animation has started.
      expect(tester.layers, isNot(contains(isA<ImageFilterLayer>())));

      controller.value = 0.25;
      await tester.pump();

      expect(
          tester.layers,
          contains(isA<ImageFilterLayer>().having(
            (ImageFilterLayer layer) => layer.imageFilter.toString(),
            'image filter',
            startsWith('ImageFilter.matrix('),
          )),
      );

      controller.value = 0.5;
      await tester.pump();

      expect(
          tester.layers,
          contains(isA<ImageFilterLayer>().having(
            (ImageFilterLayer layer) => layer.imageFilter.toString(),
            'image filter',
            startsWith('ImageFilter.matrix('),
          )),
      );

      controller.value = 0.75;
      await tester.pump();

      expect(
          tester.layers,
          contains(isA<ImageFilterLayer>().having(
            (ImageFilterLayer layer) => layer.imageFilter.toString(),
            'image filter',
            startsWith('ImageFilter.matrix('),
          )),
      );

      controller.value = 1;
      await tester.pump();

      // Validate that expensive layer is not left in tree after animation has finished.
      expect(tester.layers, isNot(contains(isA<ImageFilterLayer>())));
    });
  });

  group('ScaleTransition', () {
    testWidgets('uses ImageFilter when provided with FilterQuality argument', (WidgetTester tester) async {
      final AnimationController controller = AnimationController(vsync: const TestVSync());
      addTearDown(controller.dispose);
      final Animation<double> animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller);
      final Widget widget =  Directionality(
        textDirection: TextDirection.ltr,
        child: ScaleTransition(
          scale: animation,
          filterQuality: FilterQuality.none,
          child: const Text('Scale Transition'),
        ),
      );

      await tester.pumpWidget(widget);

      // Validate that expensive layer is not left in tree before animation has started.
      expect(tester.layers, isNot(contains(isA<ImageFilterLayer>())));

      controller.value = 0.25;
      await tester.pump();

      expect(tester.layers, contains(isA<ImageFilterLayer>().having(
        (ImageFilterLayer layer) => layer.imageFilter.toString(),
        'image filter',
        startsWith('ImageFilter.matrix('),
      )));

      controller.value = 0.5;
      await tester.pump();

      expect(tester.layers, contains(isA<ImageFilterLayer>().having(
        (ImageFilterLayer layer) => layer.imageFilter.toString(),
        'image filter',
        startsWith('ImageFilter.matrix('),
      )));

      controller.value = 0.75;
      await tester.pump();

      expect(tester.layers, contains(isA<ImageFilterLayer>().having(
        (ImageFilterLayer layer) => layer.imageFilter.toString(),
        'image filter',
        startsWith('ImageFilter.matrix('),
      )));

      controller.value = 1;
      await tester.pump();

      // Validate that expensive layer is not left in tree after animation has finished.
      expect(tester.layers, isNot(contains(isA<ImageFilterLayer>())));
    });
  });

  group('RotationTransition', () {
    testWidgets('uses ImageFilter when provided with FilterQuality argument', (WidgetTester tester) async {
      final AnimationController controller = AnimationController(vsync: const TestVSync());
      addTearDown(controller.dispose);
      final Animation<double> animation = Tween<double>(begin: 0.0, end: 1.0).animate(controller);
      final Widget widget =  Directionality(
        textDirection: TextDirection.ltr,
        child: RotationTransition(
          turns: animation,
          filterQuality: FilterQuality.none,
          child: const Text('Scale Transition'),
        ),
      );

      await tester.pumpWidget(widget);

      // Validate that expensive layer is not left in tree before animation has started.
      expect(tester.layers, isNot(contains(isA<ImageFilterLayer>())));

      controller.value = 0.25;
      await tester.pump();

      expect(tester.layers, contains(isA<ImageFilterLayer>().having(
        (ImageFilterLayer layer) => layer.imageFilter.toString(),
        'image filter',
        startsWith('ImageFilter.matrix('),
      )));

      controller.value = 0.5;
      await tester.pump();

      expect(tester.layers, contains(isA<ImageFilterLayer>().having(
        (ImageFilterLayer layer) => layer.imageFilter.toString(),
        'image filter',
        startsWith('ImageFilter.matrix('),
      )));

      controller.value = 0.75;
      await tester.pump();

      expect(tester.layers, contains(isA<ImageFilterLayer>().having(
        (ImageFilterLayer layer) => layer.imageFilter.toString(),
        'image filter',
        startsWith('ImageFilter.matrix('),
      )));

      controller.value = 1;
      await tester.pump();

      // Validate that expensive layer is not left in tree after animation has finished.
      expect(tester.layers, isNot(contains(isA<ImageFilterLayer>())));
    });
  });

  group('Builders', () {
    testWidgets('AnimatedBuilder rebuilds when changed', (WidgetTester tester) async {
      final GlobalKey<RedrawCounterState> redrawKey = GlobalKey<RedrawCounterState>();
      final ChangeNotifier notifier = ChangeNotifier();
      addTearDown(notifier.dispose);

      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: AnimatedBuilder(
            animation: notifier,
            builder: (BuildContext context, Widget? child) {
              return RedrawCounter(key: redrawKey, child: child);
            },
          ),
        ),
      );

      expect(redrawKey.currentState!.redraws, equals(1));
      await tester.pump();
      expect(redrawKey.currentState!.redraws, equals(1));
      notifier.notifyListeners();
      await tester.pump();
      expect(redrawKey.currentState!.redraws, equals(2));

      // Pump a few more times to make sure that we don't rebuild unnecessarily.
      await tester.pump();
      await tester.pump();
      expect(redrawKey.currentState!.redraws, equals(2));
    });

    testWidgets("AnimatedBuilder doesn't rebuild the child", (WidgetTester tester) async {
      final GlobalKey<RedrawCounterState> redrawKey = GlobalKey<RedrawCounterState>();
      final GlobalKey<RedrawCounterState> redrawKeyChild = GlobalKey<RedrawCounterState>();
      final ChangeNotifier notifier = ChangeNotifier();
      addTearDown(notifier.dispose);

      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: AnimatedBuilder(
            animation: notifier,
            builder: (BuildContext context, Widget? child) {
              return RedrawCounter(key: redrawKey, child: child);
            },
            child: RedrawCounter(key: redrawKeyChild),
          ),
        ),
      );

      expect(redrawKey.currentState!.redraws, equals(1));
      expect(redrawKeyChild.currentState!.redraws, equals(1));
      await tester.pump();
      expect(redrawKey.currentState!.redraws, equals(1));
      expect(redrawKeyChild.currentState!.redraws, equals(1));
      notifier.notifyListeners();
      await tester.pump();
      expect(redrawKey.currentState!.redraws, equals(2));
      expect(redrawKeyChild.currentState!.redraws, equals(1));

      // Pump a few more times to make sure that we don't rebuild unnecessarily.
      await tester.pump();
      await tester.pump();
      expect(redrawKey.currentState!.redraws, equals(2));
      expect(redrawKeyChild.currentState!.redraws, equals(1));
    });

    testWidgets('ListenableBuilder rebuilds when changed', (WidgetTester tester) async {
      final GlobalKey<RedrawCounterState> redrawKey = GlobalKey<RedrawCounterState>();
      final ChangeNotifier notifier = ChangeNotifier();
      addTearDown(notifier.dispose);

      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: ListenableBuilder(
            listenable: notifier,
            builder: (BuildContext context, Widget? child) {
              return RedrawCounter(key: redrawKey, child: child);
            },
          ),
        ),
      );

      expect(redrawKey.currentState!.redraws, equals(1));
      await tester.pump();
      expect(redrawKey.currentState!.redraws, equals(1));
      notifier.notifyListeners();
      await tester.pump();
      expect(redrawKey.currentState!.redraws, equals(2));

      // Pump a few more times to make sure that we don't rebuild unnecessarily.
      await tester.pump();
      await tester.pump();
      expect(redrawKey.currentState!.redraws, equals(2));
    });

    testWidgets("ListenableBuilder doesn't rebuild the child", (WidgetTester tester) async {
      final GlobalKey<RedrawCounterState> redrawKey = GlobalKey<RedrawCounterState>();
      final GlobalKey<RedrawCounterState> redrawKeyChild = GlobalKey<RedrawCounterState>();
      final ChangeNotifier notifier = ChangeNotifier();
      addTearDown(notifier.dispose);

      await tester.pumpWidget(
        Directionality(
          textDirection: TextDirection.ltr,
          child: ListenableBuilder(
            listenable: notifier,
            builder: (BuildContext context, Widget? child) {
              return RedrawCounter(key: redrawKey, child: child);
            },
            child: RedrawCounter(key: redrawKeyChild),
          ),
        ),
      );

      expect(redrawKey.currentState!.redraws, equals(1));
      expect(redrawKeyChild.currentState!.redraws, equals(1));
      await tester.pump();
      expect(redrawKey.currentState!.redraws, equals(1));
      expect(redrawKeyChild.currentState!.redraws, equals(1));
      notifier.notifyListeners();
      await tester.pump();
      expect(redrawKey.currentState!.redraws, equals(2));
      expect(redrawKeyChild.currentState!.redraws, equals(1));

      // Pump a few more times to make sure that we don't rebuild unnecessarily.
      await tester.pump();
      await tester.pump();
      expect(redrawKey.currentState!.redraws, equals(2));
      expect(redrawKeyChild.currentState!.redraws, equals(1));
    });
  });
}

class RedrawCounter extends StatefulWidget {
  const RedrawCounter({ super.key, this.child });

  final Widget? child;

  @override
  State<RedrawCounter> createState() => RedrawCounterState();
}

class RedrawCounterState extends State<RedrawCounter> {
  int redraws = 0;

  @override
  Widget build(BuildContext context) {
    redraws += 1;
    return SizedBox(child: widget.child);
  }
}
