// 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 CurvedAnimation animation = CurvedAnimation(
          parent: controller,
          curve: Curves.easeOut,
        );
        addTearDown(animation.dispose);
        final Animation<Decoration> curvedDecorationAnimation =
          decorationTween.animate(animation);

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