// 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 not 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, false);
  });

  test('RenderOpacity does composite if it is partially opaque', () {
    final RenderOpacity renderOpacity = RenderOpacity(
      opacity: 0.1,
      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);
  }
}
