// Copyright 2013 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.

// @dart = 2.6
import 'dart:typed_data';

import 'package:test/test.dart';

import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart' as ui;

import 'common.dart';

void main() {
  group('CanvasKit API', () {
    setUpAll(() async {
      await ui.webOnlyInitializePlatform();
    });

    test('Using CanvasKit', () {
      expect(experimentalUseSkia, true);
    });

    _blendModeTests();
    _paintStyleTests();
    _strokeCapTests();
    _strokeJoinTests();
    _filterQualityTests();
    _blurStyleTests();
    _tileModeTests();
    _fillTypeTests();
    _pathOpTests();
    _clipOpTests();
    _pointModeTests();
    _vertexModeTests();
    _imageTests();
    _shaderTests();
    _paintTests();
    _maskFilterTests();
    _colorFilterTests();
    _imageFilterTests();
    _mallocTests();
    _sharedColorTests();
    _toSkPointTests();
    _toSkColorStopsTests();
    _toSkMatrixFromFloat32Tests();
    _skSkRectTests();
    _skVerticesTests();
    group('SkPath', () {
      _pathTests();
    });
    group('SkCanvas', () {
      _canvasTests();
    });
  // TODO: https://github.com/flutter/flutter/issues/60040
  }, skip: isIosSafari);
}

void _blendModeTests() {
  test('blend mode mapping is correct', () {
    expect(canvasKitJs.BlendMode.Clear.value, ui.BlendMode.clear.index);
    expect(canvasKitJs.BlendMode.Src.value, ui.BlendMode.src.index);
    expect(canvasKitJs.BlendMode.Dst.value, ui.BlendMode.dst.index);
    expect(canvasKitJs.BlendMode.SrcOver.value, ui.BlendMode.srcOver.index);
    expect(canvasKitJs.BlendMode.DstOver.value, ui.BlendMode.dstOver.index);
    expect(canvasKitJs.BlendMode.SrcIn.value, ui.BlendMode.srcIn.index);
    expect(canvasKitJs.BlendMode.DstIn.value, ui.BlendMode.dstIn.index);
    expect(canvasKitJs.BlendMode.SrcOut.value, ui.BlendMode.srcOut.index);
    expect(canvasKitJs.BlendMode.DstOut.value, ui.BlendMode.dstOut.index);
    expect(canvasKitJs.BlendMode.SrcATop.value, ui.BlendMode.srcATop.index);
    expect(canvasKitJs.BlendMode.DstATop.value, ui.BlendMode.dstATop.index);
    expect(canvasKitJs.BlendMode.Xor.value, ui.BlendMode.xor.index);
    expect(canvasKitJs.BlendMode.Plus.value, ui.BlendMode.plus.index);
    expect(canvasKitJs.BlendMode.Modulate.value, ui.BlendMode.modulate.index);
    expect(canvasKitJs.BlendMode.Screen.value, ui.BlendMode.screen.index);
    expect(canvasKitJs.BlendMode.Overlay.value, ui.BlendMode.overlay.index);
    expect(canvasKitJs.BlendMode.Darken.value, ui.BlendMode.darken.index);
    expect(canvasKitJs.BlendMode.Lighten.value, ui.BlendMode.lighten.index);
    expect(canvasKitJs.BlendMode.ColorDodge.value, ui.BlendMode.colorDodge.index);
    expect(canvasKitJs.BlendMode.ColorBurn.value, ui.BlendMode.colorBurn.index);
    expect(canvasKitJs.BlendMode.HardLight.value, ui.BlendMode.hardLight.index);
    expect(canvasKitJs.BlendMode.SoftLight.value, ui.BlendMode.softLight.index);
    expect(canvasKitJs.BlendMode.Difference.value, ui.BlendMode.difference.index);
    expect(canvasKitJs.BlendMode.Exclusion.value, ui.BlendMode.exclusion.index);
    expect(canvasKitJs.BlendMode.Multiply.value, ui.BlendMode.multiply.index);
    expect(canvasKitJs.BlendMode.Hue.value, ui.BlendMode.hue.index);
    expect(canvasKitJs.BlendMode.Saturation.value, ui.BlendMode.saturation.index);
    expect(canvasKitJs.BlendMode.Color.value, ui.BlendMode.color.index);
    expect(canvasKitJs.BlendMode.Luminosity.value, ui.BlendMode.luminosity.index);
  });

  test('ui.BlendMode converts to SkBlendMode', () {
    for (ui.BlendMode blendMode in ui.BlendMode.values) {
      expect(toSkBlendMode(blendMode).value, blendMode.index);
    }
  });
}

void _paintStyleTests() {
  test('paint style mapping is correct', () {
    expect(canvasKitJs.PaintStyle.Fill.value, ui.PaintingStyle.fill.index);
    expect(canvasKitJs.PaintStyle.Stroke.value, ui.PaintingStyle.stroke.index);
  });

  test('ui.PaintingStyle converts to SkPaintStyle', () {
    for (ui.PaintingStyle style in ui.PaintingStyle.values) {
      expect(toSkPaintStyle(style).value, style.index);
    }
  });
}

void _strokeCapTests() {
  test('stroke cap mapping is correct', () {
    expect(canvasKitJs.StrokeCap.Butt.value, ui.StrokeCap.butt.index);
    expect(canvasKitJs.StrokeCap.Round.value, ui.StrokeCap.round.index);
    expect(canvasKitJs.StrokeCap.Square.value, ui.StrokeCap.square.index);
  });

  test('ui.StrokeCap converts to SkStrokeCap', () {
    for (ui.StrokeCap cap in ui.StrokeCap.values) {
      expect(toSkStrokeCap(cap).value, cap.index);
    }
  });
}

void _strokeJoinTests() {
  test('stroke cap mapping is correct', () {
    expect(canvasKitJs.StrokeJoin.Miter.value, ui.StrokeJoin.miter.index);
    expect(canvasKitJs.StrokeJoin.Round.value, ui.StrokeJoin.round.index);
    expect(canvasKitJs.StrokeJoin.Bevel.value, ui.StrokeJoin.bevel.index);
  });

  test('ui.StrokeJoin converts to SkStrokeJoin', () {
    for (ui.StrokeJoin join in ui.StrokeJoin.values) {
      expect(toSkStrokeJoin(join).value, join.index);
    }
  });
}

void _filterQualityTests() {
  test('filter quality mapping is correct', () {
    expect(canvasKitJs.FilterQuality.None.value, ui.FilterQuality.none.index);
    expect(canvasKitJs.FilterQuality.Low.value, ui.FilterQuality.low.index);
    expect(canvasKitJs.FilterQuality.Medium.value, ui.FilterQuality.medium.index);
    expect(canvasKitJs.FilterQuality.High.value, ui.FilterQuality.high.index);
  });

  test('ui.FilterQuality converts to SkFilterQuality', () {
    for (ui.FilterQuality cap in ui.FilterQuality.values) {
      expect(toSkFilterQuality(cap).value, cap.index);
    }
  });
}

void _blurStyleTests() {
  test('blur style mapping is correct', () {
    expect(canvasKitJs.BlurStyle.Normal.value, ui.BlurStyle.normal.index);
    expect(canvasKitJs.BlurStyle.Solid.value, ui.BlurStyle.solid.index);
    expect(canvasKitJs.BlurStyle.Outer.value, ui.BlurStyle.outer.index);
    expect(canvasKitJs.BlurStyle.Inner.value, ui.BlurStyle.inner.index);
  });

  test('ui.BlurStyle converts to SkBlurStyle', () {
    for (ui.BlurStyle style in ui.BlurStyle.values) {
      expect(toSkBlurStyle(style).value, style.index);
    }
  });
}

void _tileModeTests() {
  test('tile mode mapping is correct', () {
    expect(canvasKitJs.TileMode.Clamp.value, ui.TileMode.clamp.index);
    expect(canvasKitJs.TileMode.Repeat.value, ui.TileMode.repeated.index);
    expect(canvasKitJs.TileMode.Mirror.value, ui.TileMode.mirror.index);
  });

  test('ui.TileMode converts to SkTileMode', () {
    for (ui.TileMode mode in ui.TileMode.values) {
      expect(toSkTileMode(mode).value, mode.index);
    }
  });
}

void _fillTypeTests() {
  test('fill type mapping is correct', () {
    expect(canvasKitJs.FillType.Winding.value, ui.PathFillType.nonZero.index);
    expect(canvasKitJs.FillType.EvenOdd.value, ui.PathFillType.evenOdd.index);
  });

  test('ui.PathFillType converts to SkFillType', () {
    for (ui.PathFillType type in ui.PathFillType.values) {
      expect(toSkFillType(type).value, type.index);
    }
  });
}

void _pathOpTests() {
  // TODO(yjbanov): https://github.com/flutter/flutter/issues/61403
  // test('path op mapping is correct', () {
  //   expect(canvasKitJs.PathOp.Difference.value, ui.PathOperation.difference.index);
  //   expect(canvasKitJs.PathOp.Intersect.value, ui.PathOperation.intersect.index);
  //   expect(canvasKitJs.PathOp.Union.value, ui.PathOperation.union.index);
  //   expect(canvasKitJs.PathOp.XOR.value, ui.PathOperation.xor.index);
  //   expect(canvasKitJs.PathOp.ReverseDifference, ui.PathOperation.reverseDifference.index);
  // });

  // test('ui.PathOperation converts to SkPathOp', () {
  //   for (ui.PathOperation op in ui.PathOperation.values) {
  //     expect(toSkPathOp(op).value, op.index);
  //   }
  // });
}

void _clipOpTests() {
  test('clip op mapping is correct', () {
    expect(canvasKitJs.ClipOp.Difference.value, ui.ClipOp.difference.index);
    expect(canvasKitJs.ClipOp.Intersect.value, ui.ClipOp.intersect.index);
  });

  test('ui.ClipOp converts to SkClipOp', () {
    for (ui.ClipOp op in ui.ClipOp.values) {
      expect(toSkClipOp(op).value, op.index);
    }
  });
}

void _pointModeTests() {
  test('point mode mapping is correct', () {
    expect(canvasKitJs.PointMode.Points.value, ui.PointMode.points.index);
    expect(canvasKitJs.PointMode.Lines.value, ui.PointMode.lines.index);
    expect(canvasKitJs.PointMode.Polygon.value, ui.PointMode.polygon.index);
  });

  test('ui.PointMode converts to SkPointMode', () {
    for (ui.PointMode op in ui.PointMode.values) {
      expect(toSkPointMode(op).value, op.index);
    }
  });
}

void _vertexModeTests() {
  test('vertex mode mapping is correct', () {
    expect(canvasKitJs.VertexMode.Triangles.value, ui.VertexMode.triangles.index);
    expect(canvasKitJs.VertexMode.TrianglesStrip.value, ui.VertexMode.triangleStrip.index);
    expect(canvasKitJs.VertexMode.TriangleFan.value, ui.VertexMode.triangleFan.index);
  });

  test('ui.VertexMode converts to SkVertexMode', () {
    for (ui.VertexMode op in ui.VertexMode.values) {
      expect(toSkVertexMode(op).value, op.index);
    }
  });
}

void _imageTests() {
  test('MakeAnimatedImageFromEncoded makes a non-animated image', () {
    final SkAnimatedImage nonAnimated = canvasKitJs.MakeAnimatedImageFromEncoded(kTransparentImage);
    expect(nonAnimated.getFrameCount(), 1);
    expect(nonAnimated.getRepetitionCount(), 0);
    expect(nonAnimated.width(), 1);
    expect(nonAnimated.height(), 1);

    final SkImage frame = nonAnimated.getCurrentFrame();
    expect(frame.width(), 1);
    expect(frame.height(), 1);

    expect(nonAnimated.decodeNextFrame(), -1);
    expect(frame.makeShader(canvasKitJs.TileMode.Repeat, canvasKitJs.TileMode.Mirror), isNotNull);
  });

  test('MakeAnimatedImageFromEncoded makes an animated image', () {
    final SkAnimatedImage animated = canvasKitJs.MakeAnimatedImageFromEncoded(kAnimatedGif);
    expect(animated.getFrameCount(), 3);
    expect(animated.getRepetitionCount(), -1);  // animates forever
    expect(animated.width(), 1);
    expect(animated.height(), 1);
    for (int i = 0; i < 100; i++) {
      final SkImage frame = animated.getCurrentFrame();
      expect(frame.width(), 1);
      expect(frame.height(), 1);
      expect(animated.decodeNextFrame(), 100);
    }
  });
}

void _shaderTests() {
  test('MakeLinearGradient', () {
    expect(_makeTestShader(), isNotNull);
  });

  test('MakeRadialGradient', () {
    expect(canvasKitJs.SkShader.MakeRadialGradient(
      Float32List.fromList([1, 1]),
      10.0,
      <Float32List>[
        Float32List.fromList([0, 0, 0, 1]),
        Float32List.fromList([1, 1, 1, 1]),
      ],
      Float32List.fromList([0, 1]),
      canvasKitJs.TileMode.Repeat,
      toSkMatrixFromFloat32(Matrix4.identity().storage),
      0,
    ), isNotNull);
  });

  test('MakeTwoPointConicalGradient', () {
    expect(canvasKitJs.SkShader.MakeTwoPointConicalGradient(
      Float32List.fromList([1, 1]),
      10.0,
      Float32List.fromList([1, 1]),
      10.0,
      <Float32List>[
        Float32List.fromList([0, 0, 0, 1]),
        Float32List.fromList([1, 1, 1, 1]),
      ],
      Float32List.fromList([0, 1]),
      canvasKitJs.TileMode.Repeat,
      toSkMatrixFromFloat32(Matrix4.identity().storage),
      0,
    ), isNotNull);
  });
}

SkShader _makeTestShader() {
  return canvasKitJs.SkShader.MakeLinearGradient(
    Float32List.fromList([0, 0]),
    Float32List.fromList([1, 1]),
    [
      Float32List.fromList([255, 0, 0, 255]),
    ],
    Float32List.fromList([0, 1]),
    canvasKitJs.TileMode.Repeat,
  );
}

void _paintTests() {
  test('can make SkPaint', () async {
    final SkPaint paint = SkPaint();
    paint.setBlendMode(canvasKitJs.BlendMode.SrcOut);
    paint.setStyle(canvasKitJs.PaintStyle.Stroke);
    paint.setStrokeWidth(3.0);
    paint.setStrokeCap(canvasKitJs.StrokeCap.Round);
    paint.setStrokeJoin(canvasKitJs.StrokeJoin.Bevel);
    paint.setAntiAlias(true);
    paint.setColorInt(0x00FFCCAA);
    paint.setShader(_makeTestShader());
    paint.setMaskFilter(canvasKitJs.MakeBlurMaskFilter(
      canvasKitJs.BlurStyle.Outer,
      2.0,
      true,
    ));
    paint.setFilterQuality(canvasKitJs.FilterQuality.High);
    paint.setColorFilter(canvasKitJs.SkColorFilter.MakeLinearToSRGBGamma());
    paint.setStrokeMiter(1.4);
    paint.setImageFilter(canvasKitJs.SkImageFilter.MakeBlur(
      1,
      2,
      canvasKitJs.TileMode.Repeat,
      null,
    ));
  });
}

void _maskFilterTests() {
  test('MakeBlurMaskFilter', () {
    expect(canvasKitJs.MakeBlurMaskFilter(
      canvasKitJs.BlurStyle.Outer,
      5.0,
      false,
    ), isNotNull);
  });
}

void _colorFilterTests() {
  test('MakeBlend', () {
    expect(
      canvasKitJs.SkColorFilter.MakeBlend(
        Float32List.fromList([0, 0, 0, 1]),
        canvasKitJs.BlendMode.SrcATop,
      ),
      isNotNull,
    );
  });

  test('MakeMatrix', () {
    expect(
      canvasKitJs.SkColorFilter.MakeMatrix(
        Float32List(20),
      ),
      isNotNull,
    );
  });

  test('MakeSRGBToLinearGamma', () {
    expect(
      canvasKitJs.SkColorFilter.MakeSRGBToLinearGamma(),
      isNotNull,
    );
  });

  test('MakeLinearToSRGBGamma', () {
    expect(
      canvasKitJs.SkColorFilter.MakeLinearToSRGBGamma(),
      isNotNull,
    );
  });
}

void _imageFilterTests() {
  test('MakeBlur', () {
    expect(
      canvasKitJs.SkImageFilter.MakeBlur(1, 2, canvasKitJs.TileMode.Repeat, null),
      isNotNull,
    );
  });

  test('MakeMatrixTransform', () {
    expect(
      canvasKitJs.SkImageFilter.MakeMatrixTransform(
        toSkMatrixFromFloat32(Matrix4.identity().storage),
        canvasKitJs.FilterQuality.Medium,
        null,
      ),
      isNotNull,
    );
  });
}

void _mallocTests() {
  test('SkFloat32List', () {
    for (int size = 0; size < 1000; size++) {
      final SkFloat32List skList = mallocFloat32List(4);
      expect(skList, isNotNull);
      expect(skList.toTypedArray().length, 4);
    }
  });
}

void _sharedColorTests() {
  test('toSharedSkColor1', () {
    expect(
      toSharedSkColor1(const ui.Color(0xAABBCCDD)),
      Float32List(4)
        ..[0] = 0xBB / 255.0
        ..[1] = 0xCC / 255.0
        ..[2] = 0xDD / 255.0
        ..[3] = 0xAA / 255.0,
    );
  });
  test('toSharedSkColor2', () {
    expect(
      toSharedSkColor2(const ui.Color(0xAABBCCDD)),
      Float32List(4)
        ..[0] = 0xBB / 255.0
        ..[1] = 0xCC / 255.0
        ..[2] = 0xDD / 255.0
        ..[3] = 0xAA / 255.0,
    );
  });
  test('toSharedSkColor3', () {
    expect(
      toSharedSkColor3(const ui.Color(0xAABBCCDD)),
      Float32List(4)
        ..[0] = 0xBB / 255.0
        ..[1] = 0xCC / 255.0
        ..[2] = 0xDD / 255.0
        ..[3] = 0xAA / 255.0,
    );
  });
}

void _toSkPointTests() {
  test('toSkPoint', () {
    expect(
      toSkPoint(const ui.Offset(4, 5)),
      Float32List(2)
        ..[0] = 4.0
        ..[1] = 5.0,
    );
  });
}

void _toSkColorStopsTests() {
  test('toSkColorStops default', () {
    expect(
      toSkColorStops(null),
      Float32List(2)
        ..[0] = 0
        ..[1] = 1,
    );
  });

  test('toSkColorStops custom', () {
    expect(
      toSkColorStops(<double>[1, 2, 3, 4]),
      Float32List(4)
        ..[0] = 1
        ..[1] = 2
        ..[2] = 3
        ..[3] = 4,
    );
  });
}

void _toSkMatrixFromFloat32Tests() {
  test('toSkMatrixFromFloat32', () {
    final Matrix4 matrix = Matrix4.identity()
      ..translate(1, 2, 3)
      ..rotateZ(4);
    expect(
      toSkMatrixFromFloat32(matrix.storage),
      Float32List.fromList(<double>[
        -0.6536436080932617,
        0.756802499294281,
        1,
        -0.756802499294281,
        -0.6536436080932617,
        2,
        -0.0,
        0,
        1,
      ])
    );
  });
}

SkPath _testClosedSkPath() {
  return SkPath()
    ..moveTo(10, 10)
    ..lineTo(20, 10)
    ..lineTo(20, 20)
    ..lineTo(10, 20)
    ..close();
}

void _pathTests() {
  SkPath path;

  setUp(() {
    path = SkPath();
  });

  test('setFillType', () {
    path.setFillType(canvasKitJs.FillType.Winding);
  });

  test('addArc', () {
    path.addArc(
      SkRect(fLeft: 10, fTop: 20, fRight: 30, fBottom: 40),
      1,
      5,
    );
  });

  test('addOval', () {
    path.addOval(
      SkRect(fLeft: 10, fTop: 20, fRight: 30, fBottom: 40),
      false,
      1,
    );
  });

  test('addPath', () {
    path.addPath(_testClosedSkPath(), 1, 0, 0, 0, 1, 0, 0, 0, 0, false);
  });

  test('addPoly', () {
    final SkFloat32List encodedPoints = toMallocedSkPoints(const <ui.Offset>[
      ui.Offset.zero,
      ui.Offset(10, 10),
    ]);
    path.addPoly(encodedPoints.toTypedArray(), true);
    freeFloat32List(encodedPoints);
  });

  test('addRoundRect', () {
    final ui.RRect rrect = ui.RRect.fromRectAndRadius(
      ui.Rect.fromLTRB(10, 10, 20, 20),
      ui.Radius.circular(3),
    );
    final SkFloat32List skRadii = mallocFloat32List(8);
    final Float32List radii = skRadii.toTypedArray();
    radii[0] = rrect.tlRadiusX;
    radii[1] = rrect.tlRadiusY;
    radii[2] = rrect.trRadiusX;
    radii[3] = rrect.trRadiusY;
    radii[4] = rrect.brRadiusX;
    radii[5] = rrect.brRadiusY;
    radii[6] = rrect.blRadiusX;
    radii[7] = rrect.blRadiusY;
    path.addRoundRect(
      toOuterSkRect(rrect),
      radii,
      false,
    );
    freeFloat32List(skRadii);
  });

  test('addRect', () {
    path.addRect(SkRect(fLeft: 1, fTop: 2, fRight: 3, fBottom: 4));
  });

  test('arcTo', () {
    path.arcTo(
      SkRect(fLeft: 1, fTop: 2, fRight: 3, fBottom: 4),
      5,
      40,
      false,
    );
  });

  test('overloaded arcTo (used for arcToPoint)', () {
    final SkPathArcToPointOverload overload = debugJsObjectWrapper.castToSkPathArcToPointOverload(path);
    overload.arcTo(
      1,
      2,
      3,
      false,
      true,
      4,
      5,
    );
  });

  test('close', () {
    _testClosedSkPath();
  });

  test('conicTo', () {
    path.conicTo(1, 2, 3, 4, 5);
  });

  test('contains', () {
    final SkPath testPath = _testClosedSkPath();
    expect(testPath.contains(15, 15), true);
    expect(testPath.contains(100, 100), false);
  });

  test('cubicTo', () {
    path.cubicTo(1, 2, 3, 4, 5, 6);
  });

  test('getBounds', () {
    final SkPath testPath = _testClosedSkPath();
    final ui.Rect bounds = testPath.getBounds().toRect();
    expect(bounds, const ui.Rect.fromLTRB(10, 10, 20, 20));
  });

  test('lineTo', () {
    path.lineTo(10, 10);
  });

  test('moveTo', () {
    path.moveTo(10, 10);
  });

  test('quadTo', () {
    path.quadTo(10, 10, 20, 20);
  });

  test('rArcTo', () {
    path.rArcTo(
      10,
      20,
      30,
      false,
      true,
      40,
      50,
    );
  });

  test('rConicTo', () {
    path.rConicTo(1, 2, 3, 4, 5);
  });

  test('rCubicTo', () {
    path.rCubicTo(1, 2, 3, 4, 5, 6);
  });

  test('rLineTo', () {
    path.rLineTo(10, 10);
  });

  test('rMoveTo', () {
    path.rMoveTo(10, 10);
  });

  test('rQuadTo', () {
    path.rQuadTo(10, 10, 20, 20);
  });

  test('reset', () {
    final SkPath testPath = _testClosedSkPath();
    expect(testPath.getBounds().toRect(), const ui.Rect.fromLTRB(10, 10, 20, 20));
    testPath.reset();
    expect(testPath.getBounds().toRect(), ui.Rect.zero);
  });

  test('toSVGString', () {
    expect(_testClosedSkPath().toSVGString(), 'M10 10L20 10L20 20L10 20L10 10Z');
  });

  test('isEmpty', () {
    expect(SkPath().isEmpty(), true);
    expect(_testClosedSkPath().isEmpty(), false);
  });

  test('copy', () {
    final SkPath original = _testClosedSkPath();
    final SkPath copy = original.copy();
    expect(original.getBounds().toRect(), copy.getBounds().toRect());
  });

  test('transform', () {
    path = _testClosedSkPath();
    path.transform(2, 0, 10, 0, 2, 10, 0, 0, 0);
    final ui.Rect transformedBounds = path.getBounds().toRect();
    expect(transformedBounds, ui.Rect.fromLTRB(30, 30, 50, 50));
  });

  test('SkContourMeasureIter/SkContourMeasure', () {
    final SkContourMeasureIter iter = SkContourMeasureIter(_testClosedSkPath(), false, 0);
    final SkContourMeasure measure1 = iter.next();
    expect(measure1.length(), 40);
    expect(measure1.getPosTan(5), Float32List.fromList(<double>[15, 10, 1, 0]));
    expect(measure1.getPosTan(15), Float32List.fromList(<double>[20, 15, 0, 1]));
    expect(measure1.isClosed(), true);

    // Starting with a box path:
    //
    //    10         20
    // 10 +-----------+
    //    |           |
    //    |           |
    //    |           |
    //    |           |
    //    |           |
    // 20 +-----------+
    //
    // Cut out the top-right quadrant:
    //
    //    10    15   20
    // 10 +-----+=====+
    //    |     ║+++++║
    //    |     ║+++++║
    //    |     +=====+ 15
    //    |           |
    //    |           |
    // 20 +-----------+
    final SkPath segment = measure1.getSegment(5, 15, true);
    expect(segment.getBounds().toRect(), ui.Rect.fromLTRB(15, 10, 20, 15));

    final SkContourMeasure measure2 = iter.next();
    expect(measure2, isNull);
  });
}

void _skSkRectTests() {
  test('SkRect', () {
    final SkRect rect = SkRect(fLeft: 1, fTop: 2, fRight: 3, fBottom: 4);
    expect(rect.fLeft, 1);
    expect(rect.fTop, 2);
    expect(rect.fRight, 3);
    expect(rect.fBottom, 4);

    final ui.Rect uiRect = rect.toRect();
    expect(uiRect.left, 1);
    expect(uiRect.top, 2);
    expect(uiRect.right, 3);
    expect(uiRect.bottom, 4);
  });
}

SkVertices _testVertices() {
  return canvasKitJs.MakeSkVertices(
    canvasKitJs.VertexMode.Triangles,
    [
      Float32List.fromList([0, 0]),
      Float32List.fromList([10, 10]),
      Float32List.fromList([0, 20]),
    ],
    [
      Float32List.fromList([0, 0]),
      Float32List.fromList([10, 10]),
      Float32List.fromList([0, 20]),
    ],
    [
      Float32List.fromList([255, 0, 0, 255]),
      Float32List.fromList([0, 255, 0, 255]),
      Float32List.fromList([0, 0, 255, 255]),
    ],
    Uint16List.fromList([0, 1, 2]),
  );
}

void _skVerticesTests() {
  test('SkVertices', () {
    expect(_testVertices(), isNotNull);
  });
}

void _canvasTests() {
  SkPictureRecorder recorder;
  SkCanvas canvas;

  setUp(() {
    recorder = SkPictureRecorder();
    canvas = recorder.beginRecording(SkRect(
      fLeft: 0,
      fTop: 0,
      fRight: 100,
      fBottom: 100,
    ));
  });

  tearDown(() {
    expect(recorder.finishRecordingAsPicture(), isNotNull);
  });

  test('save/getSaveCount/restore/restoreToCount', () {
    expect(canvas.save(), 1);
    expect(canvas.save(), 2);
    expect(canvas.save(), 3);
    expect(canvas.save(), 4);
    expect(canvas.getSaveCount(), 5);
    canvas.restoreToCount(2);
    expect(canvas.getSaveCount(), 2);
    canvas.restore();
    expect(canvas.getSaveCount(), 1);
  });

  test('saveLayer', () {
    canvas.saveLayer(
      SkRect(
        fLeft: 0,
        fTop: 0,
        fRight: 100,
        fBottom: 100,
      ),
      SkPaint(),
    );
  });

  test('SkCanvasSaveLayerWithoutBoundsOverride.saveLayer', () {
    final SkCanvasSaveLayerWithoutBoundsOverride override = debugJsObjectWrapper.castToSkCanvasSaveLayerWithoutBoundsOverride(canvas);
    override.saveLayer(SkPaint());
  });

  test('SkCanvasSaveLayerWithFilterOverride.saveLayer', () {
    final SkCanvasSaveLayerWithFilterOverride override = debugJsObjectWrapper.castToSkCanvasSaveLayerWithFilterOverride(canvas);
    override.saveLayer(
      SkPaint(),
      canvasKitJs.SkImageFilter.MakeBlur(1, 2, canvasKitJs.TileMode.Repeat, null),
      0,
      SkRect(
        fLeft: 0,
        fTop: 0,
        fRight: 100,
        fBottom: 100,
      ),
    );
  });

  test('clear', () {
    canvas.clear(Float32List.fromList([0, 0, 0, 0]));
  });

  test('clipPath', () {
    canvas.clipPath(
      _testClosedSkPath(),
      canvasKitJs.ClipOp.Intersect,
      true,
    );
  });

  test('clipRRect', () {
    canvas.clipRRect(
      SkRRect(
        rect: SkRect(
          fLeft: 0,
          fTop: 0,
          fRight: 100,
          fBottom: 100,
        ),
        rx1: 1,
        ry1: 2,
        rx2: 3,
        ry2: 4,
        rx3: 5,
        ry3: 6,
        rx4: 7,
        ry4: 8,
      ),
      canvasKitJs.ClipOp.Intersect,
      true,
    );
  });

  test('clipRect', () {
    canvas.clipRect(
      SkRect(
        fLeft: 0,
        fTop: 0,
        fRight: 100,
        fBottom: 100,
      ),
      canvasKitJs.ClipOp.Intersect,
      true,
    );
  });

  test('drawArc', () {
    canvas.drawArc(
      SkRect(
        fLeft: 0,
        fTop: 0,
        fRight: 100,
        fBottom: 50,
      ),
      0,
      100,
      true,
      SkPaint(),
    );
  });

  test('drawAtlas', () {
    final SkAnimatedImage image = canvasKitJs.MakeAnimatedImageFromEncoded(kTransparentImage);
    canvas.drawAtlas(
      image.getCurrentFrame(),
      Float32List.fromList([0, 0, 1, 1]),
      Float32List.fromList([1, 0, 2, 3]),
      SkPaint(),
      canvasKitJs.BlendMode.SrcOver,
      [
        Float32List.fromList([0, 0, 0, 1]),
        Float32List.fromList([1, 1, 1, 1]),
      ],
    );
  });

  test('drawCircle', () {
    canvas.drawCircle(1, 2, 3, SkPaint());
  });

  test('drawColorInt', () {
    canvas.drawColorInt(0xFFFFFFFF, canvasKitJs.BlendMode.SoftLight);
  });

  test('drawDRRect', () {
    canvas.drawDRRect(
      SkRRect(
        rect: SkRect(
          fLeft: 0,
          fTop: 0,
          fRight: 100,
          fBottom: 100,
        ),
        rx1: 1,
        ry1: 2,
        rx2: 3,
        ry2: 4,
        rx3: 5,
        ry3: 6,
        rx4: 7,
        ry4: 8,
      ),
      SkRRect(
        rect: SkRect(
          fLeft: 20,
          fTop: 20,
          fRight: 80,
          fBottom: 80,
        ),
        rx1: 1,
        ry1: 2,
        rx2: 3,
        ry2: 4,
        rx3: 5,
        ry3: 6,
        rx4: 7,
        ry4: 8,
      ),
      SkPaint(),
    );
  });

  test('drawImage', () {
    final SkAnimatedImage image = canvasKitJs.MakeAnimatedImageFromEncoded(kTransparentImage);
    canvas.drawImage(
      image.getCurrentFrame(),
      10,
      20,
      SkPaint(),
    );
  });

  test('drawImageRect', () {
    final SkAnimatedImage image = canvasKitJs.MakeAnimatedImageFromEncoded(kTransparentImage);
    canvas.drawImageRect(
      image.getCurrentFrame(),
      SkRect(fLeft: 0, fTop: 0, fRight: 1, fBottom: 1),
      SkRect(fLeft: 0, fTop: 0, fRight: 1, fBottom: 1),
      SkPaint(),
      false,
    );
  });

  test('drawImageNine', () {
    final SkAnimatedImage image = canvasKitJs.MakeAnimatedImageFromEncoded(kTransparentImage);
    canvas.drawImageNine(
      image.getCurrentFrame(),
      SkRect(fLeft: 0, fTop: 0, fRight: 1, fBottom: 1),
      SkRect(fLeft: 0, fTop: 0, fRight: 1, fBottom: 1),
      SkPaint(),
    );
  });

  test('drawLine', () {
    canvas.drawLine(0, 1, 2, 3, SkPaint());
  });

  test('drawOval', () {
    canvas.drawOval(SkRect(fLeft: 0, fTop: 0, fRight: 1, fBottom: 1), SkPaint());
  });

  test('drawPaint', () {
    canvas.drawPaint(SkPaint());
  });

  test('drawPath', () {
    canvas.drawPath(
      _testClosedSkPath(),
      SkPaint(),
    );
  });

  test('drawPoints', () {
    canvas.drawPoints(
      canvasKitJs.PointMode.Lines,
      Float32List.fromList([0, 0, 10, 10, 0, 10]),
      SkPaint(),
    );
  });

  test('drawRRect', () {
    canvas.drawRRect(
      SkRRect(
        rect: SkRect(
          fLeft: 0,
          fTop: 0,
          fRight: 100,
          fBottom: 100,
        ),
        rx1: 1,
        ry1: 2,
        rx2: 3,
        ry2: 4,
        rx3: 5,
        ry3: 6,
        rx4: 7,
        ry4: 8,
      ),
      SkPaint(),
    );
  });

  test('drawRect', () {
    canvas.drawRect(
      SkRect(
        fLeft: 0,
        fTop: 0,
        fRight: 100,
        fBottom: 100,
      ),
      SkPaint(),
    );
  });

  test('drawShadow', () {
    for (int flags in const <int>[0x01, 0x00]) {
      const double devicePixelRatio = 2.0;
      const double elevation = 4.0;
      const double ambientAlpha = 0.039;
      const double spotAlpha = 0.25;

      final SkPath path = _testClosedSkPath();
      final ui.Rect bounds = path.getBounds().toRect();
      final double shadowX = (bounds.left + bounds.right) / 2.0;
      final double shadowY = bounds.top - 600.0;

      const ui.Color color = ui.Color(0xAABBCCDD);
      ui.Color inAmbient = color.withAlpha((color.alpha * ambientAlpha).round());
      ui.Color inSpot = color.withAlpha((color.alpha * spotAlpha).round());

      final SkTonalColors inTonalColors = SkTonalColors(
        ambient: makeFreshSkColor(inAmbient),
        spot: makeFreshSkColor(inSpot),
      );

      final SkTonalColors tonalColors =
          canvasKitJs.computeTonalColors(inTonalColors);

      canvas.drawShadow(
        path,
        Float32List(3)
          ..[2] = devicePixelRatio * elevation,
        Float32List(3)
          ..[0] = shadowX
          ..[1] = shadowY
          ..[2] = devicePixelRatio * kLightHeight,
        devicePixelRatio * kLightRadius,
        tonalColors.ambient,
        tonalColors.spot,
        flags,
      );
    }
  });

  test('drawVertices', () {
    canvas.drawVertices(
      _testVertices(),
      canvasKitJs.BlendMode.SrcOver,
      SkPaint(),
    );
  });

  test('rotate', () {
    canvas.rotate(5, 10, 20);
  });

  test('scale', () {
    canvas.scale(2, 3);
  });

  test('skew', () {
    canvas.skew(4, 5);
  });

  test('concat', () {
    canvas.concat(toSkMatrixFromFloat32(Matrix4.identity().storage));
  });

  test('translate', () {
    canvas.translate(4, 5);
  });

  test('flush', () {
    canvas.flush();
  });

  test('drawPicture', () {
    final SkPictureRecorder otherRecorder = SkPictureRecorder();
    final SkCanvas otherCanvas = otherRecorder.beginRecording(SkRect(
      fLeft: 0,
      fTop: 0,
      fRight: 100,
      fBottom: 100,
    ));
    otherCanvas.drawLine(0, 0, 10, 10, SkPaint());
    canvas.drawPicture(otherRecorder.finishRecordingAsPicture());
  });

  test('drawParagraph', () {
    final CkParagraphBuilder builder = CkParagraphBuilder(
      CkParagraphStyle(),
    );
    builder.addText('Hello');
    final CkParagraph paragraph = builder.build();
    paragraph.layout(const ui.ParagraphConstraints(width: 100));
    canvas.drawParagraph(
      debugJsObjectWrapper.unwrapSkParagraph(paragraph.legacySkiaObject),
      10,
      20,
    );
  });
}

final Uint8List kTransparentImage = Uint8List.fromList(<int>[
  0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49,
  0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06,
  0x00, 0x00, 0x00, 0x1F, 0x15, 0xC4, 0x89, 0x00, 0x00, 0x00, 0x0A, 0x49, 0x44,
  0x41, 0x54, 0x78, 0x9C, 0x63, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x01, 0x0D,
  0x0A, 0x2D, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE,
]);

/// An animated GIF image with 3 1x1 pixel frames (a red, green, and blue
/// frames). The GIF animates forever, and each frame has a 100ms delay.
final Uint8List kAnimatedGif = Uint8List.fromList(<int> [
  0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00, 0xa1, 0x03, 0x00,
  0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0x21,
  0xff, 0x0b, 0x4e, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2e, 0x30,
  0x03, 0x01, 0x00, 0x00, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x0a, 0x00, 0xff, 0x00,
  0x2c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x4c,
  0x01, 0x00, 0x21, 0xf9, 0x04, 0x00, 0x0a, 0x00, 0xff, 0x00, 0x2c, 0x00, 0x00,
  0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x54, 0x01, 0x00, 0x21,
  0xf9, 0x04, 0x00, 0x0a, 0x00, 0xff, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x01,
  0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x44, 0x01, 0x00, 0x3b,
]);
