// 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 'dart:ui' as ui show Gradient, Image, ImageFilter;

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

import 'mock_canvas.dart';
import 'rendering_tester.dart';

void main() {
  TestRenderingFlutterBinding.ensureInitialized();
  test('RenderFittedBox handles applying paint transform and hit-testing with empty size', () {
    final RenderFittedBox fittedBox = RenderFittedBox(
      child: RenderCustomPaint(
        painter: TestCallbackPainter(onPaint: () {}),
      ),
    );

    layout(fittedBox, phase: EnginePhase.flushSemantics);
    final Matrix4 transform = Matrix4.identity();
    fittedBox.applyPaintTransform(fittedBox.child!, transform);
    expect(transform, Matrix4.zero());

    final BoxHitTestResult hitTestResult = BoxHitTestResult();
    expect(fittedBox.hitTestChildren(hitTestResult, position: Offset.zero), isFalse);
  });

  test('RenderFittedBox does not paint with empty sizes', () {
    bool painted;
    RenderFittedBox makeFittedBox(Size size) {
      return RenderFittedBox(
        child: RenderCustomPaint(
          preferredSize: size,
          painter: TestCallbackPainter(onPaint: () {
            painted = true;
          }),
        ),
      );
    }

    // The RenderFittedBox paints if both its size and its child's size are nonempty.
    painted = false;
    layout(makeFittedBox(const Size(1, 1)), phase: EnginePhase.paint);
    expect(painted, equals(true));

    // The RenderFittedBox should not paint if its child is empty-sized.
    painted = false;
    layout(makeFittedBox(Size.zero), phase: EnginePhase.paint);
    expect(painted, equals(false));

    // The RenderFittedBox should not paint if it is empty.
    painted = false;
    layout(makeFittedBox(const Size(1, 1)), constraints: BoxConstraints.tight(Size.zero), phase: EnginePhase.paint);
    expect(painted, equals(false));
  });

  test('RenderPhysicalModel compositing', () {
    final RenderPhysicalModel root = RenderPhysicalModel(color: const Color(0xffff00ff));
    layout(root, phase: EnginePhase.composite);
    expect(root.needsCompositing, isFalse);

    // On Fuchsia, the system compositor is responsible for drawing shadows
    // for physical model layers with non-zero elevation.
    root.elevation = 1.0;
    pumpFrame(phase: EnginePhase.composite);
    expect(root.needsCompositing, isFalse);

    root.elevation = 0.0;
    pumpFrame(phase: EnginePhase.composite);
    expect(root.needsCompositing, isFalse);
  });

  test('RenderSemanticsGestureHandler adds/removes correct semantic actions', () {
    final RenderSemanticsGestureHandler renderObj = RenderSemanticsGestureHandler(
      onTap: () { },
      onHorizontalDragUpdate: (DragUpdateDetails details) { },
    );

    SemanticsConfiguration config = SemanticsConfiguration();
    renderObj.describeSemanticsConfiguration(config);
    expect(config.getActionHandler(SemanticsAction.tap), isNotNull);
    expect(config.getActionHandler(SemanticsAction.scrollLeft), isNotNull);
    expect(config.getActionHandler(SemanticsAction.scrollRight), isNotNull);

    config = SemanticsConfiguration();
    renderObj.validActions = <SemanticsAction>{SemanticsAction.tap, SemanticsAction.scrollLeft};

    renderObj.describeSemanticsConfiguration(config);
    expect(config.getActionHandler(SemanticsAction.tap), isNotNull);
    expect(config.getActionHandler(SemanticsAction.scrollLeft), isNotNull);
    expect(config.getActionHandler(SemanticsAction.scrollRight), isNull);
  });

  group('RenderPhysicalShape', () {
    test('shape change triggers repaint', () {
      for (final TargetPlatform platform in TargetPlatform.values) {
        debugDefaultTargetPlatformOverride = platform;

        final RenderPhysicalShape root = RenderPhysicalShape(
          color: const Color(0xffff00ff),
          clipper: const ShapeBorderClipper(shape: CircleBorder()),
        );
        layout(root, phase: EnginePhase.composite);
        expect(root.debugNeedsPaint, isFalse);

        // Same shape, no repaint.
        root.clipper = const ShapeBorderClipper(shape: CircleBorder());
        expect(root.debugNeedsPaint, isFalse);

        // Different shape triggers repaint.
        root.clipper = const ShapeBorderClipper(shape: StadiumBorder());
        expect(root.debugNeedsPaint, isTrue);
      }
      debugDefaultTargetPlatformOverride = null;
    });

    test('compositing', () {
      for (final TargetPlatform platform in TargetPlatform.values) {
        debugDefaultTargetPlatformOverride = platform;
        final RenderPhysicalShape root = RenderPhysicalShape(
          color: const Color(0xffff00ff),
          clipper: const ShapeBorderClipper(shape: CircleBorder()),
        );
        layout(root, phase: EnginePhase.composite);
        expect(root.needsCompositing, isFalse);

        // On non-Fuchsia platforms, we composite physical shape layers
        root.elevation = 1.0;
        pumpFrame(phase: EnginePhase.composite);
        expect(root.needsCompositing, isFalse);

        root.elevation = 0.0;
        pumpFrame(phase: EnginePhase.composite);
        expect(root.needsCompositing, isFalse);
      }
      debugDefaultTargetPlatformOverride = null;
    });
  });

  test('RenderRepaintBoundary can capture images of itself', () async {
    RenderRepaintBoundary boundary = RenderRepaintBoundary();
    layout(boundary, constraints: BoxConstraints.tight(const Size(100.0, 200.0)));
    pumpFrame(phase: EnginePhase.composite);
    ui.Image image = await boundary.toImage();
    expect(image.width, equals(100));
    expect(image.height, equals(200));

    // Now with pixel ratio set to something other than 1.0.
    boundary = RenderRepaintBoundary();
    layout(boundary, constraints: BoxConstraints.tight(const Size(100.0, 200.0)));
    pumpFrame(phase: EnginePhase.composite);
    image = await boundary.toImage(pixelRatio: 2.0);
    expect(image.width, equals(200));
    expect(image.height, equals(400));

    // Try building one with two child layers and make sure it renders them both.
    boundary = RenderRepaintBoundary();
    final RenderStack stack = RenderStack()..alignment = Alignment.topLeft;
    final RenderDecoratedBox blackBox = RenderDecoratedBox(
      decoration: const BoxDecoration(color: Color(0xff000000)),
      child: RenderConstrainedBox(
        additionalConstraints: BoxConstraints.tight(const Size.square(20.0)),
      ),
    );
    stack.add(
      RenderOpacity()
        ..opacity = 0.5
        ..child = blackBox,
    );
    final RenderDecoratedBox whiteBox = RenderDecoratedBox(
      decoration: const BoxDecoration(color: Color(0xffffffff)),
      child: RenderConstrainedBox(
        additionalConstraints: BoxConstraints.tight(const Size.square(10.0)),
      ),
    );
    final RenderPositionedBox positioned = RenderPositionedBox(
      widthFactor: 2.0,
      heightFactor: 2.0,
      alignment: Alignment.topRight,
      child: whiteBox,
    );
    stack.add(positioned);
    boundary.child = stack;
    layout(boundary, constraints: BoxConstraints.tight(const Size(20.0, 20.0)));
    pumpFrame(phase: EnginePhase.composite);
    image = await boundary.toImage();
    expect(image.width, equals(20));
    expect(image.height, equals(20));
    ByteData data = (await image.toByteData())!;

    int getPixel(int x, int y) => data.getUint32((x + y * image.width) * 4);

    expect(data.lengthInBytes, equals(20 * 20 * 4));
    expect(data.elementSizeInBytes, equals(1));
    expect(getPixel(0, 0), equals(0x00000080));
    expect(getPixel(image.width - 1, 0 ), equals(0xffffffff));

    final OffsetLayer layer = boundary.debugLayer! as OffsetLayer;

    image = await layer.toImage(Offset.zero & const Size(20.0, 20.0));
    expect(image.width, equals(20));
    expect(image.height, equals(20));
    data = (await image.toByteData())!;
    expect(getPixel(0, 0), equals(0x00000080));
    expect(getPixel(image.width - 1, 0 ), equals(0xffffffff));

    // non-zero offsets.
    image = await layer.toImage(const Offset(-10.0, -10.0) & const Size(30.0, 30.0));
    expect(image.width, equals(30));
    expect(image.height, equals(30));
    data = (await image.toByteData())!;
    expect(getPixel(0, 0), equals(0x00000000));
    expect(getPixel(10, 10), equals(0x00000080));
    expect(getPixel(image.width - 1, 0), equals(0x00000000));
    expect(getPixel(image.width - 1, 10), equals(0xffffffff));

    // offset combined with a custom pixel ratio.
    image = await layer.toImage(const Offset(-10.0, -10.0) & const Size(30.0, 30.0), pixelRatio: 2.0);
    expect(image.width, equals(60));
    expect(image.height, equals(60));
    data = (await image.toByteData())!;
    expect(getPixel(0, 0), equals(0x00000000));
    expect(getPixel(20, 20), equals(0x00000080));
    expect(getPixel(image.width - 1, 0), equals(0x00000000));
    expect(getPixel(image.width - 1, 20), equals(0xffffffff));
  }, skip: isBrowser); // https://github.com/flutter/flutter/issues/49857

  test('RenderOpacity does not composite if it is transparent', () {
    final RenderOpacity renderOpacity = RenderOpacity(
      opacity: 0.0,
      child: RenderSizedBox(const Size(1.0, 1.0)), // size doesn't matter
    );

    layout(renderOpacity, phase: EnginePhase.composite);
    expect(renderOpacity.needsCompositing, false);
  });

  test('RenderOpacity does composite if it is opaque', () {
    final RenderOpacity renderOpacity = RenderOpacity(
      child: RenderSizedBox(const Size(1.0, 1.0)), // size doesn't matter
    );

    layout(renderOpacity, phase: EnginePhase.composite);
    expect(renderOpacity.needsCompositing, true);
  });

  test('RenderOpacity reuses its layer', () {
    _testLayerReuse<OpacityLayer>(RenderOpacity(
      opacity: 0.5,  // must not be 0 or 1.0. Otherwise, it won't create a layer
      child: RenderRepaintBoundary(
        child: RenderSizedBox(const Size(1.0, 1.0)),
      ), // size doesn't matter
    ));
  });

  test('RenderAnimatedOpacity does not composite if it is transparent', () async {
    final Animation<double> opacityAnimation = AnimationController(
      vsync: FakeTickerProvider(),
    )..value = 0.0;

    final RenderAnimatedOpacity renderAnimatedOpacity = RenderAnimatedOpacity(
      opacity: opacityAnimation,
      child: RenderSizedBox(const Size(1.0, 1.0)), // size doesn't matter
    );

    layout(renderAnimatedOpacity, phase: EnginePhase.composite);
    expect(renderAnimatedOpacity.needsCompositing, false);
  });

  test('RenderAnimatedOpacity does not composite if it is opaque', () {
    final Animation<double> opacityAnimation = AnimationController(
      vsync: FakeTickerProvider(),
    )..value = 1.0;

    final RenderAnimatedOpacity renderAnimatedOpacity = RenderAnimatedOpacity(
      opacity: opacityAnimation,
      child: RenderSizedBox(const Size(1.0, 1.0)), // size doesn't matter
    );

    layout(renderAnimatedOpacity, phase: EnginePhase.composite);
    expect(renderAnimatedOpacity.needsCompositing, false);
  });

  test('RenderAnimatedOpacity does composite if it is partially opaque', () {
    final Animation<double> opacityAnimation = AnimationController(
      vsync: FakeTickerProvider(),
    )..value = 0.5;

    final RenderAnimatedOpacity renderAnimatedOpacity = RenderAnimatedOpacity(
      opacity: opacityAnimation,
      child: RenderSizedBox(const Size(1.0, 1.0)), // size doesn't matter
    );

    layout(renderAnimatedOpacity, phase: EnginePhase.composite);
    expect(renderAnimatedOpacity.needsCompositing, true);
  });

  test('RenderAnimatedOpacity reuses its layer', () {
    final Animation<double> opacityAnimation = AnimationController(
      vsync: FakeTickerProvider(),
    )..value = 0.5;  // must not be 0 or 1.0. Otherwise, it won't create a layer

    _testLayerReuse<OpacityLayer>(RenderAnimatedOpacity(
      opacity: opacityAnimation,
      child: RenderSizedBox(const Size(1.0, 1.0)), // size doesn't matter
    ));
  });

  test('RenderShaderMask reuses its layer', () {
    _testLayerReuse<ShaderMaskLayer>(RenderShaderMask(
      shaderCallback: (Rect rect) {
        return ui.Gradient.radial(
          rect.center,
          rect.shortestSide / 2.0,
          const <Color>[Color.fromRGBO(0, 0, 0, 1.0), Color.fromRGBO(255, 255, 255, 1.0)],
        );
      },
      child: RenderSizedBox(const Size(1.0, 1.0)), // size doesn't matter
    ));
  });

  test('RenderBackdropFilter reuses its layer', () {
    _testLayerReuse<BackdropFilterLayer>(RenderBackdropFilter(
      filter: ui.ImageFilter.blur(),
      child: RenderSizedBox(const Size(1.0, 1.0)), // size doesn't matter
    ));
  });

  test('RenderClipRect reuses its layer', () {
    _testLayerReuse<ClipRectLayer>(RenderClipRect(
      clipper: _TestRectClipper(),
      child: RenderRepaintBoundary(
        child: RenderSizedBox(const Size(1.0, 1.0)),
      ), // size doesn't matter
    ));
  });

  test('RenderClipRRect reuses its layer', () {
    _testLayerReuse<ClipRRectLayer>(RenderClipRRect(
      clipper: _TestRRectClipper(),
      child: RenderRepaintBoundary(
        child: RenderSizedBox(const Size(1.0, 1.0)),
      ), // size doesn't matter
    ));
  });

  test('RenderClipOval reuses its layer', () {
    _testLayerReuse<ClipPathLayer>(RenderClipOval(
      clipper: _TestRectClipper(),
      child: RenderRepaintBoundary(
        child: RenderSizedBox(const Size(1.0, 1.0)),
      ), // size doesn't matter
    ));
  });

  test('RenderClipPath reuses its layer', () {
    _testLayerReuse<ClipPathLayer>(RenderClipPath(
      clipper: _TestPathClipper(),
      child: RenderRepaintBoundary(
        child: RenderSizedBox(const Size(1.0, 1.0)),
      ), // size doesn't matter
    ));
  });

  test('RenderPhysicalModel reuses its layer', () {
    _testLayerReuse<ClipRRectLayer>(RenderPhysicalModel(
      clipBehavior: Clip.hardEdge,
      color: const Color.fromRGBO(0, 0, 0, 1.0),
      child: RenderRepaintBoundary(
        child: RenderSizedBox(const Size(1.0, 1.0)),
      ), // size doesn't matter
    ));
  });

  test('RenderPhysicalShape reuses its layer', () {
    _testLayerReuse<ClipPathLayer>(RenderPhysicalShape(
      clipper: _TestPathClipper(),
      clipBehavior: Clip.hardEdge,
      color: const Color.fromRGBO(0, 0, 0, 1.0),
      child: RenderRepaintBoundary(
        child: RenderSizedBox(const Size(1.0, 1.0)),
      ), // size doesn't matter
    ));
  });

  test('RenderTransform reuses its layer', () {
    _testLayerReuse<TransformLayer>(RenderTransform(
      // Use a 3D transform to force compositing.
      transform: Matrix4.rotationX(0.1),
      child: RenderRepaintBoundary(
        child: RenderSizedBox(const Size(1.0, 1.0)),
      ), // size doesn't matter
    ));
  });

  void testFittedBoxWithClipRectLayer() {
    _testLayerReuse<ClipRectLayer>(RenderFittedBox(
      fit: BoxFit.cover,
      clipBehavior: Clip.hardEdge,
      // Inject opacity under the clip to force compositing.
      child: RenderRepaintBoundary(
        child: RenderSizedBox(const Size(100.0, 200.0)),
      ), // size doesn't matter
    ));
  }

  void testFittedBoxWithTransformLayer() {
    _testLayerReuse<TransformLayer>(RenderFittedBox(
      fit: BoxFit.fill,
      // Inject opacity under the clip to force compositing.
      child: RenderRepaintBoundary(
        child: RenderSizedBox(const Size(1, 1)),
      ), // size doesn't matter
    ));
  }

  test('RenderFittedBox reuses ClipRectLayer', () {
    testFittedBoxWithClipRectLayer();
  });

  test('RenderFittedBox reuses TransformLayer', () {
    testFittedBoxWithTransformLayer();
  });

  test('RenderFittedBox switches between ClipRectLayer and TransformLayer, and reuses them', () {
    testFittedBoxWithClipRectLayer();

    // clip -> transform
    testFittedBoxWithTransformLayer();
    // transform -> clip
    testFittedBoxWithClipRectLayer();
  });

  test('RenderFittedBox respects clipBehavior', () {
    const BoxConstraints viewport = BoxConstraints(maxHeight: 100.0, maxWidth: 100.0);
    final TestClipPaintingContext context = TestClipPaintingContext();

    // By default, clipBehavior should be Clip.none
    final RenderFittedBox defaultBox = RenderFittedBox(child: box200x200, fit: BoxFit.none);
    layout(defaultBox, constraints: viewport, phase: EnginePhase.composite, onErrors: expectOverflowedErrors);
    defaultBox.paint(context, Offset.zero);
    expect(context.clipBehavior, equals(Clip.none));

    for (final Clip clip in Clip.values) {
      final RenderFittedBox box = RenderFittedBox(child: box200x200, fit: BoxFit.none, clipBehavior: clip);
      layout(box, constraints: viewport, phase: EnginePhase.composite, onErrors: expectOverflowedErrors);
      box.paint(context, Offset.zero);
      expect(context.clipBehavior, equals(clip));
    }
  });

  test('RenderMouseRegion can change properties when detached', () {
    final RenderMouseRegion object = RenderMouseRegion();
    object
      ..opaque = false
      ..onEnter = (_) {}
      ..onExit = (_) {}
      ..onHover = (_) {};
    // Passes if no error is thrown
  });

  test('RenderFractionalTranslation updates its semantics after its translation value is set', () {
    final _TestSemanticsUpdateRenderFractionalTranslation box = _TestSemanticsUpdateRenderFractionalTranslation(
      translation: const Offset(0.5, 0.5),
    );
    layout(box, constraints: BoxConstraints.tight(const Size(200.0, 200.0)));
    expect(box.markNeedsSemanticsUpdateCallCount, 1);
    box.translation = const Offset(0.4, 0.4);
    expect(box.markNeedsSemanticsUpdateCallCount, 2);
    box.translation = const Offset(0.3, 0.3);
    expect(box.markNeedsSemanticsUpdateCallCount, 3);
  });

  test('RenderFollowerLayer hit test without a leader layer and the showWhenUnlinked is true', () {
    final RenderFollowerLayer follower = RenderFollowerLayer(
      link: LayerLink(),
      child: RenderSizedBox(const Size(1.0, 1.0)),
    );
    layout(follower, constraints: BoxConstraints.tight(const Size(200.0, 200.0)));
    final BoxHitTestResult hitTestResult = BoxHitTestResult();
    expect(follower.hitTest(hitTestResult, position: Offset.zero), isTrue);
  });

  test('RenderFollowerLayer hit test without a leader layer and the showWhenUnlinked is false', () {
    final RenderFollowerLayer follower = RenderFollowerLayer(
      link: LayerLink(),
      showWhenUnlinked: false,
      child: RenderSizedBox(const Size(1.0, 1.0)),
    );
    layout(follower, constraints: BoxConstraints.tight(const Size(200.0, 200.0)));
    final BoxHitTestResult hitTestResult = BoxHitTestResult();
    expect(follower.hitTest(hitTestResult, position: Offset.zero), isFalse);
  });

  test('RenderFollowerLayer hit test with a leader layer and the showWhenUnlinked is true', () {
    // Creates a layer link with a leader.
    final LayerLink link = LayerLink();
    final LeaderLayer leader = LeaderLayer(link: link);
    leader.attach(Object());

    final RenderFollowerLayer follower = RenderFollowerLayer(
      link: link,
      child: RenderSizedBox(const Size(1.0, 1.0)),
    );
    layout(follower, constraints: BoxConstraints.tight(const Size(200.0, 200.0)));
    final BoxHitTestResult hitTestResult = BoxHitTestResult();
    expect(follower.hitTest(hitTestResult, position: Offset.zero), isTrue);
  });

  test('RenderFollowerLayer hit test with a leader layer and the showWhenUnlinked is false', () {
    // Creates a layer link with a leader.
    final LayerLink link = LayerLink();
    final LeaderLayer leader = LeaderLayer(link: link);
    leader.attach(Object());

    final RenderFollowerLayer follower = RenderFollowerLayer(
      link: link,
      showWhenUnlinked: false,
      child: RenderSizedBox(const Size(1.0, 1.0)),
    );
    layout(follower, constraints: BoxConstraints.tight(const Size(200.0, 200.0)));
    final BoxHitTestResult hitTestResult = BoxHitTestResult();
    // The follower is still hit testable because there is a leader layer.
    expect(follower.hitTest(hitTestResult, position: Offset.zero), isTrue);
  });

  test('RenderObject can become a repaint boundary', () {
    final ConditionalRepaintBoundary childBox = ConditionalRepaintBoundary();
    final ConditionalRepaintBoundary renderBox = ConditionalRepaintBoundary(child: childBox);

    layout(renderBox, phase: EnginePhase.composite);

    expect(childBox.paintCount, 1);
    expect(renderBox.paintCount, 1);

    renderBox.isRepaintBoundary = true;
    renderBox.markNeedsCompositingBitsUpdate();
    renderBox.markNeedsCompositedLayerUpdate();

    pumpFrame(phase: EnginePhase.composite);

    // The first time the render object becomes a repaint boundary
    // we must repaint from the parent to allow the layer to be
    // created.
    expect(childBox.paintCount, 2);
    expect(renderBox.paintCount, 2);
    expect(renderBox.debugLayer, isA<OffsetLayer>());

    renderBox.markNeedsCompositedLayerUpdate();
    expect(renderBox.debugNeedsPaint, false);
    expect(renderBox.debugNeedsCompositedLayerUpdate, true);

    pumpFrame(phase: EnginePhase.composite);

    // The second time the layer exists and we can skip paint.
    expect(childBox.paintCount, 2);
    expect(renderBox.paintCount, 2);
    expect(renderBox.debugLayer, isA<OffsetLayer>());

    renderBox.isRepaintBoundary = false;
    renderBox.markNeedsCompositingBitsUpdate();

    pumpFrame(phase: EnginePhase.composite);

    // Once it stops being a repaint boundary we must repaint to
    // remove the layer. its required that the render object
    // perform this action in paint.
    expect(childBox.paintCount, 3);
    expect(renderBox.paintCount, 3);
    expect(renderBox.debugLayer, null);

    // When the render object is not a repaint boundary, calling
    // markNeedsLayerPropertyUpdate is the same as calling
    // markNeedsPaint.

    renderBox.markNeedsCompositedLayerUpdate();
    expect(renderBox.debugNeedsPaint, true);
    expect(renderBox.debugNeedsCompositedLayerUpdate, true);
  });

  test('RenderObject with repaint boundary asserts when a composited layer is replaced during layer property update', () {
    final ConditionalRepaintBoundary childBox = ConditionalRepaintBoundary(isRepaintBoundary: true);
    final ConditionalRepaintBoundary renderBox = ConditionalRepaintBoundary(child: childBox);

    // Ignore old layer.
    childBox.offsetLayerFactory = (OffsetLayer? oldLayer) {
      return TestOffsetLayerA();
    };

    layout(renderBox, phase: EnginePhase.composite);

    expect(childBox.paintCount, 1);
    expect(renderBox.paintCount, 1);

    renderBox.markNeedsCompositedLayerUpdate();

    pumpFrame(phase: EnginePhase.composite, onErrors: expectAssertionError);
  }, skip: kIsWeb); // https://github.com/flutter/flutter/issues/102086

  test('RenderObject with repaint boundary asserts when a composited layer is replaced during painting', () {
    final ConditionalRepaintBoundary childBox = ConditionalRepaintBoundary(isRepaintBoundary: true);
    final ConditionalRepaintBoundary renderBox = ConditionalRepaintBoundary(child: childBox);

    // Ignore old layer.
    childBox.offsetLayerFactory = (OffsetLayer? oldLayer) {
      return TestOffsetLayerA();
    };

    layout(renderBox, phase: EnginePhase.composite);

    expect(childBox.paintCount, 1);
    expect(renderBox.paintCount, 1);
    renderBox.markNeedsPaint();

    pumpFrame(phase: EnginePhase.composite, onErrors: expectAssertionError);
  }, skip: kIsWeb); // https://github.com/flutter/flutter/issues/102086

  test('RenderObject with repaint boundary asserts when a composited layer tries to update its own offset', () {
    final ConditionalRepaintBoundary childBox = ConditionalRepaintBoundary(isRepaintBoundary: true);
    final ConditionalRepaintBoundary renderBox = ConditionalRepaintBoundary(child: childBox);

    // Ignore old layer.
    childBox.offsetLayerFactory = (OffsetLayer? oldLayer) {
      return (oldLayer ?? TestOffsetLayerA())..offset = const Offset(2133, 4422);
    };

    layout(renderBox, phase: EnginePhase.composite);

    expect(childBox.paintCount, 1);
    expect(renderBox.paintCount, 1);
    renderBox.markNeedsPaint();

    pumpFrame(phase: EnginePhase.composite, onErrors: expectAssertionError);
  }, skip: kIsWeb); // https://github.com/flutter/flutter/issues/102086

  test('RenderObject markNeedsPaint while repaint boundary, and then updated to no longer be a repaint boundary with '
    'calling markNeedsCompositingBitsUpdate 1', () {
    final ConditionalRepaintBoundary childBox = ConditionalRepaintBoundary(isRepaintBoundary: true);
    final ConditionalRepaintBoundary renderBox = ConditionalRepaintBoundary(child: childBox);
    // Ignore old layer.
    childBox.offsetLayerFactory = (OffsetLayer? oldLayer) {
      return oldLayer ?? TestOffsetLayerA();
    };

    layout(renderBox, phase: EnginePhase.composite);

    expect(childBox.paintCount, 1);
    expect(renderBox.paintCount, 1);

    childBox.markNeedsPaint();
    childBox.isRepaintBoundary = false;
    childBox.markNeedsCompositingBitsUpdate();

    expect(() => pumpFrame(phase: EnginePhase.composite), returnsNormally);
  });

  test('RenderObject markNeedsPaint while repaint boundary, and then updated to no longer be a repaint boundary with '
    'calling markNeedsCompositingBitsUpdate 2', () {
    final ConditionalRepaintBoundary childBox = ConditionalRepaintBoundary(isRepaintBoundary: true);
    final ConditionalRepaintBoundary renderBox = ConditionalRepaintBoundary(child: childBox);
    // Ignore old layer.
    childBox.offsetLayerFactory = (OffsetLayer? oldLayer) {
      return oldLayer ?? TestOffsetLayerA();
    };

    layout(renderBox, phase: EnginePhase.composite);

    expect(childBox.paintCount, 1);
    expect(renderBox.paintCount, 1);

    childBox.isRepaintBoundary = false;
    childBox.markNeedsCompositingBitsUpdate();
    childBox.markNeedsPaint();

    expect(() => pumpFrame(phase: EnginePhase.composite), returnsNormally);
  });

  test('RenderObject markNeedsPaint while repaint boundary, and then updated to no longer be a repaint boundary with '
    'calling markNeedsCompositingBitsUpdate 3', () {
    final ConditionalRepaintBoundary childBox = ConditionalRepaintBoundary(isRepaintBoundary: true);
    final ConditionalRepaintBoundary renderBox = ConditionalRepaintBoundary(child: childBox);
    // Ignore old layer.
    childBox.offsetLayerFactory = (OffsetLayer? oldLayer) {
      return oldLayer ?? TestOffsetLayerA();
    };

    layout(renderBox, phase: EnginePhase.composite);

    expect(childBox.paintCount, 1);
    expect(renderBox.paintCount, 1);

    childBox.isRepaintBoundary = false;
    childBox.markNeedsCompositedLayerUpdate();
    childBox.markNeedsCompositingBitsUpdate();

    expect(() => pumpFrame(phase: EnginePhase.composite), returnsNormally);
  });

  test('Offstage implements paintsChild correctly', () {
    final RenderBox box = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
    final RenderBox parent = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
    final RenderOffstage offstage = RenderOffstage(offstage: false, child: box);
    parent.adoptChild(offstage);

    expect(offstage.paintsChild(box), true);

    offstage.offstage = true;

    expect(offstage.paintsChild(box), false);
  });

  test('Opacity implements paintsChild correctly', () {
    final RenderBox box = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
    final RenderBox parent = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
    final RenderOpacity opacity = RenderOpacity(child: box);
    parent.adoptChild(opacity);

    expect(opacity.paintsChild(box), true);

    opacity.opacity = 0;

    expect(opacity.paintsChild(box), false);
  });

  test('AnimatedOpacity sets paint matrix to zero when alpha == 0', () {
    final RenderBox box = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
    final RenderBox parent = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
    final AnimationController opacityAnimation = AnimationController(value: 1, vsync: FakeTickerProvider());
    final RenderAnimatedOpacity opacity = RenderAnimatedOpacity(opacity: opacityAnimation, child: box);
    parent.adoptChild(opacity);

    // Make it listen to the animation.
    opacity.attach(PipelineOwner());

    expect(opacity.paintsChild(box), true);

    opacityAnimation.value = 0;

    expect(opacity.paintsChild(box), false);
  });

  test('AnimatedOpacity sets paint matrix to zero when alpha == 0 (sliver)', () {
    final RenderSliver sliver = RenderSliverToBoxAdapter(child: RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20)));
    final RenderBox parent = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 20));
    final AnimationController opacityAnimation = AnimationController(value: 1, vsync: FakeTickerProvider());
    final RenderSliverAnimatedOpacity opacity = RenderSliverAnimatedOpacity(opacity: opacityAnimation, sliver: sliver);
    parent.adoptChild(opacity);

    // Make it listen to the animation.
    opacity.attach(PipelineOwner());

    expect(opacity.paintsChild(sliver), true);

    opacityAnimation.value = 0;

    expect(opacity.paintsChild(sliver), false);
  });

  test('RenderCustomClip extenders respect clipBehavior when asked to describeApproximateClip', () {
    final RenderBox child = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 200, height: 200));
    final RenderClipRect renderClipRect = RenderClipRect(clipBehavior: Clip.none, child: child);
    layout(renderClipRect);
    expect(
      renderClipRect.describeApproximatePaintClip(child),
      null,
    );
    renderClipRect.clipBehavior = Clip.hardEdge;
    expect(
      renderClipRect.describeApproximatePaintClip(child),
      Offset.zero & renderClipRect.size,
    );
    renderClipRect.clipBehavior = Clip.antiAlias;
    expect(
      renderClipRect.describeApproximatePaintClip(child),
      Offset.zero & renderClipRect.size,
    );
    renderClipRect.clipBehavior = Clip.antiAliasWithSaveLayer;
    expect(
      renderClipRect.describeApproximatePaintClip(child),
      Offset.zero & renderClipRect.size,
    );
  });

  // Simulate painting a RenderBox as if 'debugPaintSizeEnabled == true'
  Function(PaintingContext, Offset) debugPaint(RenderBox renderBox) {
    layout(renderBox);
    pumpFrame(phase: EnginePhase.compositingBits);
    return (PaintingContext context, Offset offset) {
      renderBox.paint(context, offset);
      renderBox.debugPaintSize(context, offset);
    };
  }

  test('RenderClipPath.debugPaintSize draws a path and a debug text when clipBehavior is not Clip.none', () {
    Function(PaintingContext, Offset) debugPaintClipRect(Clip clip) {
      final RenderBox child = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 200, height: 200));
      final RenderClipPath renderClipPath = RenderClipPath(clipBehavior: clip, child: child);
      return debugPaint(renderClipPath);
    }

    // RenderClipPath.debugPaintSize draws when clipBehavior is not Clip.none
    expect(debugPaintClipRect(Clip.hardEdge), paintsExactlyCountTimes(#drawPath, 1));
    expect(debugPaintClipRect(Clip.hardEdge), paintsExactlyCountTimes(#drawParagraph, 1));

    // RenderClipPath.debugPaintSize does not draw when clipBehavior is Clip.none
    // Regression test for https://github.com/flutter/flutter/issues/105969
    expect(debugPaintClipRect(Clip.none), paintsExactlyCountTimes(#drawPath, 0));
    expect(debugPaintClipRect(Clip.none), paintsExactlyCountTimes(#drawParagraph, 0));
  });

  test('RenderClipRect.debugPaintSize draws a rect and a debug text when clipBehavior is not Clip.none', () {
    Function(PaintingContext, Offset) debugPaintClipRect(Clip clip) {
      final RenderBox child = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 200, height: 200));
      final RenderClipRect renderClipRect = RenderClipRect(clipBehavior: clip, child: child);
      return debugPaint(renderClipRect);
    }

    // RenderClipRect.debugPaintSize draws when clipBehavior is not Clip.none
    expect(debugPaintClipRect(Clip.hardEdge), paintsExactlyCountTimes(#drawRect, 1));
    expect(debugPaintClipRect(Clip.hardEdge), paintsExactlyCountTimes(#drawParagraph, 1));

    // RenderClipRect.debugPaintSize does not draw when clipBehavior is Clip.none
    expect(debugPaintClipRect(Clip.none), paintsExactlyCountTimes(#drawRect, 0));
    expect(debugPaintClipRect(Clip.none), paintsExactlyCountTimes(#drawParagraph, 0));
  });

  test('RenderClipRRect.debugPaintSize draws a rounded rect and a debug text when clipBehavior is not Clip.none', () {
    Function(PaintingContext, Offset) debugPaintClipRRect(Clip clip) {
      final RenderBox child = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 200, height: 200));
      final RenderClipRRect renderClipRRect = RenderClipRRect(clipBehavior: clip, child: child);
      return debugPaint(renderClipRRect);
    }

    // RenderClipRRect.debugPaintSize draws when clipBehavior is not Clip.none
    expect(debugPaintClipRRect(Clip.hardEdge), paintsExactlyCountTimes(#drawRRect, 1));
    expect(debugPaintClipRRect(Clip.hardEdge), paintsExactlyCountTimes(#drawParagraph, 1));

    // RenderClipRRect.debugPaintSize does not draw when clipBehavior is Clip.none
    expect(debugPaintClipRRect(Clip.none), paintsExactlyCountTimes(#drawRRect, 0));
    expect(debugPaintClipRRect(Clip.none), paintsExactlyCountTimes(#drawParagraph, 0));
  });

  test('RenderClipOval.debugPaintSize draws a path and a debug text when clipBehavior is not Clip.none', () {
    Function(PaintingContext, Offset) debugPaintClipOval(Clip clip) {
      final RenderBox child = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 200, height: 200));
      final RenderClipOval renderClipOval = RenderClipOval(clipBehavior: clip, child: child);
      return debugPaint(renderClipOval);
    }

    // RenderClipOval.debugPaintSize draws when clipBehavior is not Clip.none
    expect(debugPaintClipOval(Clip.hardEdge), paintsExactlyCountTimes(#drawPath, 1));
    expect(debugPaintClipOval(Clip.hardEdge), paintsExactlyCountTimes(#drawParagraph, 1));

    // RenderClipOval.debugPaintSize does not draw when clipBehavior is Clip.none
    expect(debugPaintClipOval(Clip.none), paintsExactlyCountTimes(#drawPath, 0));
    expect(debugPaintClipOval(Clip.none), paintsExactlyCountTimes(#drawParagraph, 0));
  });
}

class _TestRectClipper extends CustomClipper<Rect> {
  @override
  Rect getClip(Size size) {
    return Rect.zero;
  }

  @override
  Rect getApproximateClipRect(Size size) => getClip(size);

  @override
  bool shouldReclip(_TestRectClipper oldClipper) => true;
}

class _TestRRectClipper extends CustomClipper<RRect> {
  @override
  RRect getClip(Size size) {
    return RRect.zero;
  }

  @override
  Rect getApproximateClipRect(Size size) => getClip(size).outerRect;

  @override
  bool shouldReclip(_TestRRectClipper oldClipper) => true;
}

// Forces two frames and checks that:
// - a layer is created on the first frame
// - the layer is reused on the second frame
void _testLayerReuse<L extends Layer>(RenderBox renderObject) {
  expect(L, isNot(Layer));
  expect(renderObject.debugLayer, null);
  layout(renderObject, phase: EnginePhase.paint, constraints: BoxConstraints.tight(const Size(10, 10)));
  final Layer? layer = renderObject.debugLayer;
  expect(layer, isA<L>());
  expect(layer, isNotNull);

  // Mark for repaint otherwise pumpFrame is a noop.
  renderObject.markNeedsPaint();
  expect(renderObject.debugNeedsPaint, true);
  pumpFrame(phase: EnginePhase.paint);
  expect(renderObject.debugNeedsPaint, false);
  expect(renderObject.debugLayer, same(layer));
}

class _TestPathClipper extends CustomClipper<Path> {
  @override
  Path getClip(Size size) {
    return Path()
      ..addRect(const Rect.fromLTWH(50.0, 50.0, 100.0, 100.0));
  }
  @override
  bool shouldReclip(_TestPathClipper oldClipper) => false;
}

class _TestSemanticsUpdateRenderFractionalTranslation extends RenderFractionalTranslation {
  _TestSemanticsUpdateRenderFractionalTranslation({
    required super.translation,
  });

  int markNeedsSemanticsUpdateCallCount = 0;

  @override
  void markNeedsSemanticsUpdate() {
    markNeedsSemanticsUpdateCallCount++;
    super.markNeedsSemanticsUpdate();
  }
}

class ConditionalRepaintBoundary extends RenderProxyBox {
  ConditionalRepaintBoundary({this.isRepaintBoundary = false, RenderBox? child}) : super(child);

  @override
  bool isRepaintBoundary = false;

  OffsetLayer Function(OffsetLayer?)? offsetLayerFactory;

  int paintCount = 0;

  @override
  OffsetLayer updateCompositedLayer({required covariant OffsetLayer? oldLayer}) {
    if (offsetLayerFactory != null) {
      return offsetLayerFactory!.call(oldLayer);
    }
    return super.updateCompositedLayer(oldLayer: oldLayer);
  }

  @override
  void paint(PaintingContext context, Offset offset) {
    paintCount += 1;
    super.paint(context, offset);
  }
}

class TestOffsetLayerA extends OffsetLayer {}

void expectAssertionError() {
  final FlutterErrorDetails errorDetails = TestRenderingFlutterBinding.instance.takeFlutterErrorDetails()!;
  final bool asserted = errorDetails.toString().contains('Failed assertion');
  if (!asserted) {
    FlutterError.reportError(errorDetails);
  }
}
