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

import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  test('BorderRadius control test', () {
    const Rect rect = Rect.fromLTRB(19.0, 23.0, 29.0, 31.0);
    BorderRadius borderRadius;

    borderRadius = const BorderRadius.all(Radius.elliptical(5.0, 7.0));
    expect(borderRadius, hasOneLineDescription);
    expect(borderRadius.topLeft, const Radius.elliptical(5.0, 7.0));
    expect(borderRadius.topRight, const Radius.elliptical(5.0, 7.0));
    expect(borderRadius.bottomLeft, const Radius.elliptical(5.0, 7.0));
    expect(borderRadius.bottomRight, const Radius.elliptical(5.0, 7.0));
    expect(borderRadius.toRRect(rect), RRect.fromRectXY(rect, 5.0, 7.0));

    borderRadius = BorderRadius.circular(3.0);
    expect(borderRadius, hasOneLineDescription);
    expect(borderRadius.topLeft, const Radius.elliptical(3.0, 3.0));
    expect(borderRadius.topRight, const Radius.elliptical(3.0, 3.0));
    expect(borderRadius.bottomLeft, const Radius.elliptical(3.0, 3.0));
    expect(borderRadius.bottomRight, const Radius.elliptical(3.0, 3.0));
    expect(borderRadius.toRRect(rect), RRect.fromRectXY(rect, 3.0, 3.0));

    const Radius radius1 = Radius.elliptical(89.0, 87.0);
    const Radius radius2 = Radius.elliptical(103.0, 107.0);

    borderRadius = const BorderRadius.vertical(top: radius1, bottom: radius2);
    expect(borderRadius, hasOneLineDescription);
    expect(borderRadius.topLeft, radius1);
    expect(borderRadius.topRight, radius1);
    expect(borderRadius.bottomLeft, radius2);
    expect(borderRadius.bottomRight, radius2);
    expect(borderRadius.toRRect(rect), RRect.fromRectAndCorners(
      rect,
      topLeft: radius1,
      topRight: radius1,
      bottomLeft: radius2,
      bottomRight: radius2,
    ));

    borderRadius = const BorderRadius.horizontal(left: radius1, right: radius2);
    expect(borderRadius, hasOneLineDescription);
    expect(borderRadius.topLeft, radius1);
    expect(borderRadius.topRight, radius2);
    expect(borderRadius.bottomLeft, radius1);
    expect(borderRadius.bottomRight, radius2);
    expect(borderRadius.toRRect(rect), RRect.fromRectAndCorners(
      rect,
      topLeft: radius1,
      topRight: radius2,
      bottomLeft: radius1,
      bottomRight: radius2,
    ));

    borderRadius = const BorderRadius.only();
    expect(borderRadius, hasOneLineDescription);
    expect(borderRadius.topLeft, Radius.zero);
    expect(borderRadius.topRight, Radius.zero);
    expect(borderRadius.bottomLeft, Radius.zero);
    expect(borderRadius.bottomRight, Radius.zero);
    expect(borderRadius.toRRect(rect), RRect.fromRectAndCorners(rect));

    borderRadius = const BorderRadius.only(topRight: radius1, bottomRight: radius2);
    expect(borderRadius, hasOneLineDescription);
    expect(borderRadius.topLeft, Radius.zero);
    expect(borderRadius.topRight, radius1);
    expect(borderRadius.bottomLeft, Radius.zero);
    expect(borderRadius.bottomRight, radius2);
    expect(borderRadius.toRRect(rect), RRect.fromRectAndCorners(
      rect,
      topLeft: Radius.zero,
      topRight: radius1,
      bottomLeft: Radius.zero,
      bottomRight: radius2,
    ));

    expect(
      const BorderRadius.only(topLeft: Radius.elliptical(1.0, 2.0)).subtract(const BorderRadius.only(topLeft: Radius.elliptical(3.0, 5.0))),
      const BorderRadius.only(topLeft: Radius.elliptical(-2.0, -3.0)),
    );
    expect(
      const BorderRadius.only(topRight: Radius.elliptical(1.0, 2.0)).add(const BorderRadius.only(topLeft: Radius.elliptical(3.0, 5.0))),
      const BorderRadius.only(topLeft: Radius.elliptical(3.0, 5.0), topRight: Radius.elliptical(1.0, 2.0)),
    );

    expect(
      const BorderRadius.only(topLeft: Radius.elliptical(1.0, 2.0)) - const BorderRadius.only(topLeft: Radius.elliptical(3.0, 5.0)),
      const BorderRadius.only(topLeft: Radius.elliptical(-2.0, -3.0)),
    );
    expect(
      const BorderRadius.only(topRight: Radius.elliptical(1.0, 2.0)) + const BorderRadius.only(topLeft: Radius.elliptical(3.0, 5.0)),
      const BorderRadius.only(topLeft: Radius.elliptical(3.0, 5.0), topRight: Radius.elliptical(1.0, 2.0)),
    );

    expect(
      -const BorderRadius.only(topLeft: Radius.elliptical(1.0, 2.0)),
      const BorderRadius.only(topLeft: Radius.elliptical(-1.0, -2.0)),
    );

    expect(
      const BorderRadius.only(
        topLeft: radius1,
        topRight: radius2,
        bottomLeft: radius2,
        bottomRight: radius1,
      ) * 0.0,
      BorderRadius.zero,
    );

    expect(
      BorderRadius.circular(15.0) / 10.0,
      BorderRadius.circular(1.5),
    );

    expect(
      BorderRadius.circular(15.0) ~/ 10.0,
      BorderRadius.circular(1.0),
    );

    expect(
      BorderRadius.circular(15.0) % 10.0,
      BorderRadius.circular(5.0),
    );
  });

  test('BorderRadius.lerp() invariants', () {
    final BorderRadius a = BorderRadius.circular(10.0);
    final BorderRadius b = BorderRadius.circular(20.0);
    expect(BorderRadius.lerp(a, b, 0.25), equals(a * 1.25));
    expect(BorderRadius.lerp(a, b, 0.25), equals(b * 0.625));
    expect(BorderRadius.lerp(a, b, 0.25), equals(a + BorderRadius.circular(2.5)));
    expect(BorderRadius.lerp(a, b, 0.25), equals(b - BorderRadius.circular(7.5)));

    expect(BorderRadius.lerp(null, null, 0.25), isNull);
    expect(BorderRadius.lerp(null, b, 0.25), equals(b * 0.25));
    expect(BorderRadius.lerp(a, null, 0.25), equals(a * 0.75));
  });

  test('BorderRadius.lerp() crazy', () {
    const BorderRadius a = BorderRadius.only(
      topLeft: Radius.elliptical(10.0, 20.0),
      topRight: Radius.elliptical(30.0, 40.0),
      bottomLeft: Radius.elliptical(50.0, 60.0),
    );
    const BorderRadius b = BorderRadius.only(
      topRight: Radius.elliptical(100.0, 110.0),
      bottomLeft: Radius.elliptical(120.0, 130.0),
      bottomRight: Radius.elliptical(140.0, 150.0),
    );
    const BorderRadius c = BorderRadius.only(
      topLeft: Radius.elliptical(5.0, 10.0), // 10,20 -> 0
      topRight: Radius.elliptical(65.0, 75.0), // 30,40 -> 100,110
      bottomLeft: Radius.elliptical(85.0, 95.0), // 50,60 -> 120,130
      bottomRight: Radius.elliptical(70.0, 75.0), // 0,0 -> 140,150
    );
    expect(BorderRadius.lerp(a, b, 0.5), c);
  });

  test('BorderRadiusDirectional control test', () {
    const Rect rect = Rect.fromLTRB(19.0, 23.0, 29.0, 31.0);
    BorderRadiusDirectional borderRadius;

    borderRadius = const BorderRadiusDirectional.all(Radius.elliptical(5.0, 7.0));
    expect(borderRadius, hasOneLineDescription);
    expect(borderRadius.topStart, const Radius.elliptical(5.0, 7.0));
    expect(borderRadius.topEnd, const Radius.elliptical(5.0, 7.0));
    expect(borderRadius.bottomStart, const Radius.elliptical(5.0, 7.0));
    expect(borderRadius.bottomEnd, const Radius.elliptical(5.0, 7.0));
    expect(borderRadius.resolve(TextDirection.ltr).toRRect(rect), RRect.fromRectXY(rect, 5.0, 7.0));
    expect(borderRadius.resolve(TextDirection.rtl).toRRect(rect), RRect.fromRectXY(rect, 5.0, 7.0));

    borderRadius = BorderRadiusDirectional.circular(3.0);
    expect(borderRadius, hasOneLineDescription);
    expect(borderRadius.topStart, const Radius.elliptical(3.0, 3.0));
    expect(borderRadius.topEnd, const Radius.elliptical(3.0, 3.0));
    expect(borderRadius.bottomStart, const Radius.elliptical(3.0, 3.0));
    expect(borderRadius.bottomEnd, const Radius.elliptical(3.0, 3.0));
    expect(borderRadius.resolve(TextDirection.ltr).toRRect(rect), RRect.fromRectXY(rect, 3.0, 3.0));
    expect(borderRadius.resolve(TextDirection.rtl).toRRect(rect), RRect.fromRectXY(rect, 3.0, 3.0));

    const Radius radius1 = Radius.elliptical(89.0, 87.0);
    const Radius radius2 = Radius.elliptical(103.0, 107.0);

    borderRadius = const BorderRadiusDirectional.vertical(top: radius1, bottom: radius2);
    expect(borderRadius, hasOneLineDescription);
    expect(borderRadius.topStart, radius1);
    expect(borderRadius.topEnd, radius1);
    expect(borderRadius.bottomStart, radius2);
    expect(borderRadius.bottomEnd, radius2);
    expect(borderRadius.resolve(TextDirection.ltr).toRRect(rect), RRect.fromRectAndCorners(
      rect,
      topLeft: radius1,
      topRight: radius1,
      bottomLeft: radius2,
      bottomRight: radius2,
    ));
    expect(borderRadius.resolve(TextDirection.rtl).toRRect(rect), RRect.fromRectAndCorners(
      rect,
      topLeft: radius1,
      topRight: radius1,
      bottomLeft: radius2,
      bottomRight: radius2,
    ));

    borderRadius = const BorderRadiusDirectional.horizontal(start: radius1, end: radius2);
    expect(borderRadius, hasOneLineDescription);
    expect(borderRadius.topStart, radius1);
    expect(borderRadius.topEnd, radius2);
    expect(borderRadius.bottomStart, radius1);
    expect(borderRadius.bottomEnd, radius2);
    expect(borderRadius.resolve(TextDirection.ltr).toRRect(rect), RRect.fromRectAndCorners(
      rect,
      topLeft: radius1,
      topRight: radius2,
      bottomLeft: radius1,
      bottomRight: radius2,
    ));
    expect(borderRadius.resolve(TextDirection.rtl).toRRect(rect), RRect.fromRectAndCorners(
      rect,
      topLeft: radius2,
      topRight: radius1,
      bottomLeft: radius2,
      bottomRight: radius1,
    ));

    borderRadius = const BorderRadiusDirectional.only();
    expect(borderRadius, hasOneLineDescription);
    expect(borderRadius.topStart, Radius.zero);
    expect(borderRadius.topEnd, Radius.zero);
    expect(borderRadius.bottomStart, Radius.zero);
    expect(borderRadius.bottomEnd, Radius.zero);
    expect(borderRadius.resolve(TextDirection.ltr).toRRect(rect), RRect.fromRectAndCorners(rect));
    expect(borderRadius.resolve(TextDirection.rtl).toRRect(rect), RRect.fromRectAndCorners(rect));

    borderRadius = const BorderRadiusDirectional.only(topEnd: radius1, bottomEnd: radius2);
    expect(borderRadius, hasOneLineDescription);
    expect(borderRadius.topStart, Radius.zero);
    expect(borderRadius.topEnd, radius1);
    expect(borderRadius.bottomStart, Radius.zero);
    expect(borderRadius.bottomEnd, radius2);
    expect(borderRadius.resolve(TextDirection.ltr).toRRect(rect), RRect.fromRectAndCorners(
      rect,
      topLeft: Radius.zero,
      topRight: radius1,
      bottomLeft: Radius.zero,
      bottomRight: radius2,
    ));
    expect(borderRadius.resolve(TextDirection.rtl).toRRect(rect), RRect.fromRectAndCorners(
      rect,
      topLeft: radius1,
      topRight: Radius.zero,
      bottomLeft: radius2,
      bottomRight: Radius.zero,
    ));

    expect(
      const BorderRadiusDirectional.only(topStart: Radius.elliptical(1.0, 2.0)).subtract(const BorderRadiusDirectional.only(topStart: Radius.elliptical(3.0, 5.0))),
      const BorderRadiusDirectional.only(topStart: Radius.elliptical(-2.0, -3.0)),
    );
    expect(
      const BorderRadiusDirectional.only(topEnd: Radius.elliptical(1.0, 2.0)).add(const BorderRadiusDirectional.only(topStart: Radius.elliptical(3.0, 5.0))),
      const BorderRadiusDirectional.only(topStart: Radius.elliptical(3.0, 5.0), topEnd: Radius.elliptical(1.0, 2.0)),
    );

    expect(
      const BorderRadiusDirectional.only(topStart: Radius.elliptical(1.0, 2.0)) - const BorderRadiusDirectional.only(topStart: Radius.elliptical(3.0, 5.0)),
      const BorderRadiusDirectional.only(topStart: Radius.elliptical(-2.0, -3.0)),
    );
    expect(
      const BorderRadiusDirectional.only(topEnd: Radius.elliptical(1.0, 2.0)) + const BorderRadiusDirectional.only(topStart: Radius.elliptical(3.0, 5.0)),
      const BorderRadiusDirectional.only(topStart: Radius.elliptical(3.0, 5.0), topEnd: Radius.elliptical(1.0, 2.0)),
    );

    expect(
      -const BorderRadiusDirectional.only(topStart: Radius.elliptical(1.0, 2.0)),
      const BorderRadiusDirectional.only(topStart: Radius.elliptical(-1.0, -2.0)),
    );

    expect(
      const BorderRadiusDirectional.only(
        topStart: radius1,
        topEnd: radius2,
        bottomStart: radius2,
        bottomEnd: radius1,
      ) * 0.0,
      BorderRadiusDirectional.zero,
    );

    expect(
      BorderRadiusDirectional.circular(15.0) / 10.0,
      BorderRadiusDirectional.circular(1.5),
    );

    expect(
      BorderRadiusDirectional.circular(15.0) ~/ 10.0,
      BorderRadiusDirectional.circular(1.0),
    );

    expect(
      BorderRadiusDirectional.circular(15.0) % 10.0,
      BorderRadiusDirectional.circular(5.0),
    );
  });

  test('BorderRadiusDirectional.lerp() invariants', () {
    final BorderRadiusDirectional a = BorderRadiusDirectional.circular(10.0);
    final BorderRadiusDirectional b = BorderRadiusDirectional.circular(20.0);
    expect(BorderRadiusDirectional.lerp(a, b, 0.25), equals(a * 1.25));
    expect(BorderRadiusDirectional.lerp(a, b, 0.25), equals(b * 0.625));
    expect(BorderRadiusDirectional.lerp(a, b, 0.25), equals(a + BorderRadiusDirectional.circular(2.5)));
    expect(BorderRadiusDirectional.lerp(a, b, 0.25), equals(b - BorderRadiusDirectional.circular(7.5)));

    expect(BorderRadiusDirectional.lerp(null, null, 0.25), isNull);
    expect(BorderRadiusDirectional.lerp(null, b, 0.25), equals(b * 0.25));
    expect(BorderRadiusDirectional.lerp(a, null, 0.25), equals(a * 0.75));
  });

  test('BorderRadiusDirectional.lerp() crazy', () {
    const BorderRadiusDirectional a = BorderRadiusDirectional.only(
      topStart: Radius.elliptical(10.0, 20.0),
      topEnd: Radius.elliptical(30.0, 40.0),
      bottomStart: Radius.elliptical(50.0, 60.0),
    );
    const BorderRadiusDirectional b = BorderRadiusDirectional.only(
      topEnd: Radius.elliptical(100.0, 110.0),
      bottomStart: Radius.elliptical(120.0, 130.0),
      bottomEnd: Radius.elliptical(140.0, 150.0),
    );
    const BorderRadiusDirectional c = BorderRadiusDirectional.only(
      topStart: Radius.elliptical(5.0, 10.0), // 10,20 -> 0
      topEnd: Radius.elliptical(65.0, 75.0), // 30,40 -> 100,110
      bottomStart: Radius.elliptical(85.0, 95.0), // 50,60 -> 120,130
      bottomEnd: Radius.elliptical(70.0, 75.0), // 0,0 -> 140,150
    );
    expect(BorderRadiusDirectional.lerp(a, b, 0.5), c);
  });

  test('BorderRadiusGeometry.lerp()', () {
    const BorderRadius a = BorderRadius.only(
      topLeft: Radius.elliptical(10.0, 20.0),
      topRight: Radius.elliptical(30.0, 40.0),
      bottomLeft: Radius.elliptical(50.0, 60.0),
    );
    const BorderRadiusDirectional b = BorderRadiusDirectional.only(
      topEnd: Radius.elliptical(100.0, 110.0),
      bottomStart: Radius.elliptical(120.0, 130.0),
      bottomEnd: Radius.elliptical(140.0, 150.0),
    );
    const BorderRadius ltr = BorderRadius.only(
      topLeft: Radius.elliptical(5.0, 10.0), // 10,20 -> 0
      topRight: Radius.elliptical(65.0, 75.0), // 30,40 -> 100,110
      bottomLeft: Radius.elliptical(85.0, 95.0), // 50,60 -> 120,130
      bottomRight: Radius.elliptical(70.0, 75.0), // 0,0 -> 140,150
    );
    const BorderRadius rtl = BorderRadius.only(
      topLeft: Radius.elliptical(55.0, 65.0), // 10,20 -> 100,110
      topRight: Radius.elliptical(15.0, 20.0), // 30,40 -> 0,0
      bottomLeft: Radius.elliptical(95.0, 105.0), // 50,60 -> 140,150
      bottomRight: Radius.elliptical(60.0, 65.0), // 0,0 -> 120,130
    );
    expect(BorderRadiusGeometry.lerp(a, b, 0.5).resolve(TextDirection.ltr), ltr);
    expect(BorderRadiusGeometry.lerp(a, b, 0.5).resolve(TextDirection.rtl), rtl);
    expect(BorderRadiusGeometry.lerp(a, b, 0.0).resolve(TextDirection.ltr), a);
    expect(BorderRadiusGeometry.lerp(a, b, 1.0).resolve(TextDirection.rtl), b.resolve(TextDirection.rtl));
  });

  test('BorderRadiusGeometry subtract', () {
    const BorderRadius a = BorderRadius.only(
      topLeft: Radius.elliptical(10.0, 20.0),
      topRight: Radius.elliptical(30.0, 40.0),
      bottomLeft: Radius.elliptical(50.0, 60.0),
    );
    const BorderRadiusDirectional b = BorderRadiusDirectional.only(
      topEnd: Radius.elliptical(100.0, 110.0),
      bottomStart: Radius.elliptical(120.0, 130.0),
      bottomEnd: Radius.elliptical(140.0, 150.0),
    );
    expect((a.subtract(b)).resolve(TextDirection.ltr), BorderRadius.only(
      topLeft: const Radius.elliptical(10.0, 20.0) - Radius.zero,
      topRight: const Radius.elliptical(30.0, 40.0) - const Radius.elliptical(100.0, 110.0),
      bottomLeft: const Radius.elliptical(50.0, 60.0) - const Radius.elliptical(120.0, 130.0),
      bottomRight: Radius.zero - const Radius.elliptical(140.0, 150.0),
    ));
    expect((a.subtract(b)).resolve(TextDirection.rtl), BorderRadius.only(
      topLeft: const Radius.elliptical(10.0, 20.0) - const Radius.elliptical(100.0, 110.0),
      topRight: const Radius.elliptical(30.0, 40.0) - Radius.zero,
      bottomLeft: const Radius.elliptical(50.0, 60.0) - const Radius.elliptical(140.0, 150.0),
      bottomRight: Radius.zero - const Radius.elliptical(120.0, 130.0),
    ));
  });

  test('BorderRadiusGeometry add', () {
    const BorderRadius a = BorderRadius.only(
      topLeft: Radius.elliptical(10.0, 20.0),
      topRight: Radius.elliptical(30.0, 40.0),
      bottomLeft: Radius.elliptical(50.0, 60.0),
    );
    const BorderRadiusDirectional b = BorderRadiusDirectional.only(
      topEnd: Radius.elliptical(100.0, 110.0),
      bottomStart: Radius.elliptical(120.0, 130.0),
      bottomEnd: Radius.elliptical(140.0, 150.0),
    );
    expect((a.add(b)).resolve(TextDirection.ltr), BorderRadius.only(
      topLeft: const Radius.elliptical(10.0, 20.0) + Radius.zero,
      topRight: const Radius.elliptical(30.0, 40.0) + const Radius.elliptical(100.0, 110.0),
      bottomLeft: const Radius.elliptical(50.0, 60.0) + const Radius.elliptical(120.0, 130.0),
      bottomRight: Radius.zero + const Radius.elliptical(140.0, 150.0),
    ));
    expect((a.add(b)).resolve(TextDirection.rtl), BorderRadius.only(
      topLeft: const Radius.elliptical(10.0, 20.0) + const Radius.elliptical(100.0, 110.0),
      topRight: const Radius.elliptical(30.0, 40.0) + Radius.zero,
      bottomLeft: const Radius.elliptical(50.0, 60.0) + const Radius.elliptical(140.0, 150.0),
      bottomRight: Radius.zero + const Radius.elliptical(120.0, 130.0),
    ));
  });

  test('BorderRadiusGeometry add and multiply', () {
    const BorderRadius a = BorderRadius.only(
      topLeft: Radius.elliptical(10.0, 20.0),
      topRight: Radius.elliptical(30.0, 40.0),
      bottomLeft: Radius.elliptical(50.0, 60.0),
    );
    const BorderRadiusDirectional b = BorderRadiusDirectional.only(
      topEnd: Radius.elliptical(100.0, 110.0),
      bottomStart: Radius.elliptical(120.0, 130.0),
      bottomEnd: Radius.elliptical(140.0, 150.0),
    );
    expect((a.add(b) * 0.5).resolve(TextDirection.ltr), BorderRadius.only(
      topLeft: (const Radius.elliptical(10.0, 20.0) + Radius.zero) / 2.0,
      topRight: (const Radius.elliptical(30.0, 40.0) + const Radius.elliptical(100.0, 110.0)) / 2.0,
      bottomLeft: (const Radius.elliptical(50.0, 60.0) + const Radius.elliptical(120.0, 130.0)) / 2.0,
      bottomRight: (Radius.zero + const Radius.elliptical(140.0, 150.0)) / 2.0,
    ));
    expect((a.add(b) * 0.5).resolve(TextDirection.rtl), BorderRadius.only(
      topLeft: (const Radius.elliptical(10.0, 20.0) + const Radius.elliptical(100.0, 110.0)) / 2.0,
      topRight: (const Radius.elliptical(30.0, 40.0) + Radius.zero) / 2.0,
      bottomLeft: (const Radius.elliptical(50.0, 60.0) + const Radius.elliptical(140.0, 150.0)) / 2.0,
      bottomRight: (Radius.zero + const Radius.elliptical(120.0, 130.0)) / 2.0,
    ));
  });

  test('BorderRadiusGeometry add and subtract', () {
    const BorderRadius a = BorderRadius.only(
      topLeft: Radius.elliptical(300.0, 500.0),
    );
    const BorderRadiusDirectional b = BorderRadiusDirectional.only(
      topEnd: Radius.elliptical(30.0, 50.0),
    );
    const BorderRadius c = BorderRadius.only(
      bottomLeft: Radius.elliptical(3.0, 5.0),
    );

    const BorderRadius ltr = BorderRadius.only(
      topLeft: Radius.elliptical(300.0, 500.0), // tL + 0 - 0
      topRight: Radius.elliptical(30.0, 50.0), // 0 + tE - 0
      bottomLeft: Radius.elliptical(-3.0, -5.0), // 0 + 0 - bL
      bottomRight: Radius.zero, // 0 + 0 - 0
    );
    const BorderRadius rtl = BorderRadius.only(
      topLeft: Radius.elliptical(330.0, 550.0), // tL + tE - 0
      topRight: Radius.zero, // 0 + 0 - 0
      bottomLeft: Radius.elliptical(-3.0, -5.0), // 0 + 0 - bL
      bottomRight: Radius.zero, // 0 + 0 - 0
    );
    expect((a.add(b.subtract(c))).resolve(TextDirection.ltr), ltr);
    expect((a.add(b.subtract(c))).resolve(TextDirection.rtl), rtl);
  });

  test('BorderRadiusGeometry add and subtract, more', () {
    const BorderRadius a = BorderRadius.only(
      topLeft: Radius.elliptical(300.0, 300.0),
      topRight: Radius.elliptical(500.0, 500.0),
      bottomLeft: Radius.elliptical(700.0, 700.0),
      bottomRight: Radius.elliptical(900.0, 900.0),
    );
    const BorderRadiusDirectional b = BorderRadiusDirectional.only(
      topStart: Radius.elliptical(30.0, 30.0),
      topEnd: Radius.elliptical(50.0, 50.0),
      bottomStart: Radius.elliptical(70.0, 70.0),
      bottomEnd: Radius.elliptical(90.0, 90.0),
    );
    const BorderRadius c = BorderRadius.only(
      topLeft: Radius.elliptical(3.0, 3.0),
      topRight: Radius.elliptical(5.0, 5.0),
      bottomLeft: Radius.elliptical(7.0, 7.0),
      bottomRight: Radius.elliptical(9.0, 9.0),
    );

    const BorderRadius ltr = BorderRadius.only(
      topLeft: Radius.elliptical(327.0, 327.0), // tL + tS - tL
      topRight: Radius.elliptical(545.0, 545.0), // tR + tE - tR
      bottomLeft: Radius.elliptical(763.0, 763.0), // bL + bS - bL
      bottomRight: Radius.elliptical(981.0, 981.0), // bR + bE - bR
    );
    const BorderRadius rtl = BorderRadius.only(
      topLeft: Radius.elliptical(347.0, 347.0), // tL + tE - tL
      topRight: Radius.elliptical(525.0, 525.0), // tR + TS - tR
      bottomLeft: Radius.elliptical(783.0, 783.0), // bL + bE + bL
      bottomRight: Radius.elliptical(961.0, 961.0), // bR + bS - bR
    );
    expect((a.add(b.subtract(c))).resolve(TextDirection.ltr), ltr);
    expect((a.add(b.subtract(c))).resolve(TextDirection.rtl), rtl);
  });

  test('BorderRadiusGeometry operators', () {
    const BorderRadius a = BorderRadius.only(
      topLeft: Radius.elliptical(10.0, 20.0),
      topRight: Radius.elliptical(30.0, 40.0),
      bottomLeft: Radius.elliptical(50.0, 60.0),
    );
    const BorderRadiusDirectional b = BorderRadiusDirectional.only(
      topEnd: Radius.elliptical(100.0, 110.0),
      bottomStart: Radius.elliptical(120.0, 130.0),
      bottomEnd: Radius.elliptical(140.0, 150.0),
    );

    const BorderRadius ltr = BorderRadius.only(
      topLeft: Radius.elliptical(5.0, 10.0), // 10,20 -> 0
      topRight: Radius.elliptical(65.0, 75.0), // 30,40 -> 100,110
      bottomLeft: Radius.elliptical(85.0, 95.0), // 50,60 -> 120,130
      bottomRight: Radius.elliptical(70.0, 75.0), // 0,0 -> 140,150
    );
    const BorderRadius rtl = BorderRadius.only(
      topLeft: Radius.elliptical(55.0, 65.0), // 10,20 -> 100,110
      topRight: Radius.elliptical(15.0, 20.0), // 30,40 -> 0,0
      bottomLeft: Radius.elliptical(95.0, 105.0), // 50,60 -> 140,150
      bottomRight: Radius.elliptical(60.0, 65.0), // 0,0 -> 120,130
    );
    expect((a.add(b.subtract(a) * 0.5)).resolve(TextDirection.ltr), ltr);
    expect((a.add(b.subtract(a) * 0.5)).resolve(TextDirection.rtl), rtl);
    expect((a.add(b.subtract(a) * 0.0)).resolve(TextDirection.ltr), a);
    expect((a.add(b.subtract(a) * 1.0)).resolve(TextDirection.rtl), b.resolve(TextDirection.rtl));
  });
}
