// 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/foundation.dart' show DiagnosticLevel, FlutterError;
import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart';

import '../rendering/mock_canvas.dart';

class SillyBorder extends BoxBorder {
  @override
  dynamic noSuchMethod(Invocation invocation) => null;
}

void main() {
  test('BoxBorder.lerp', () {
    // names of the form fooAtX are foo, lerped X% of the way to null
    const BoxBorder directionalWithMagentaTop5 = BorderDirectional(top: BorderSide(color: Color(0xFFFF00FF), width: 5.0));
    const BoxBorder directionalWithMagentaTop5At25 = BorderDirectional(top: BorderSide(color: Color(0x3F3F003F), width: 1.25));
    const BoxBorder directionalWithMagentaTop5At75 = BorderDirectional(top: BorderSide(color: Color(0xBFBF00BF), width: 3.75));
    const BoxBorder directionalWithSides10 = BorderDirectional(start: BorderSide(width: 10.0), end: BorderSide(width: 20.0));
    const BoxBorder directionalWithSides10At25 = BorderDirectional(start: BorderSide(width: 2.5, color: Color(0x3F000000)), end: BorderSide(width: 5.0, color: Color(0x3F000000)));
    const BoxBorder directionalWithSides10At50 = BorderDirectional(start: BorderSide(width: 5.0, color: Color(0x7F000000)), end: BorderSide(width: 10.0, color: Color(0x7F000000)));
    const BoxBorder directionalWithSides10At75 = BorderDirectional(start: BorderSide(width: 7.5, color: Color(0xBF000000)), end: BorderSide(width: 15.0, color: Color(0xBF000000)));
    const BoxBorder directionalWithSides20 = BorderDirectional(start: BorderSide(width: 20.0), end: BorderSide(width: 40.0));
    const BoxBorder directionalWithSides30 = BorderDirectional(start: BorderSide(width: 30.0), end: BorderSide(width: 60.0));
    const BoxBorder directionalWithTop10 = BorderDirectional(top: BorderSide(width: 10.0));
    const BoxBorder directionalWithYellowTop10 = BorderDirectional(top: BorderSide(color: Color(0xFFFFFF00), width: 10.0));
    const BoxBorder directionalWithYellowTop5 = BorderDirectional(top: BorderSide(color: Color(0xFFFFFF00), width: 5.0));
    const BoxBorder visualWithMagentaTop10 = Border(top: BorderSide(color: Color(0xFFFF00FF), width: 10.0));
    const BoxBorder visualWithMagentaTop5 = Border(top: BorderSide(color: Color(0xFFFF00FF), width: 5.0));
    const BoxBorder visualWithSides10 = Border(left: BorderSide(width: 10.0), right: BorderSide(width: 20.0));
    const BoxBorder visualWithSides10At25 = Border(left: BorderSide(width: 2.5, color: Color(0x3F000000)), right: BorderSide(width: 5.0, color: Color(0x3F000000)));
    const BoxBorder visualWithSides10At50 = Border(left: BorderSide(width: 5.0, color: Color(0x7F000000)), right: BorderSide(width: 10.0, color: Color(0x7F000000)));
    const BoxBorder visualWithSides10At75 = Border(left: BorderSide(width: 7.5, color: Color(0xBF000000)), right: BorderSide(width: 15.0, color: Color(0xBF000000)));
    const BoxBorder visualWithSides20 = Border(left: BorderSide(width: 20.0), right: BorderSide(width: 40.0));
    const BoxBorder visualWithSides30 = Border(left: BorderSide(width: 30.0), right: BorderSide(width: 60.0));
    const BoxBorder visualWithTop10 = Border(top: BorderSide(width: 10.0));
    const BoxBorder visualWithTop100 = Border(top: BorderSide(width: 100.0));
    const BoxBorder visualWithTop190 = Border(top: BorderSide(width: 190.0));
    const BoxBorder visualWithYellowTop5 = Border(top: BorderSide(color: Color(0xFFFFFF00), width: 5.0));
    const BoxBorder visualWithYellowTop5At25 = Border(top: BorderSide(color: Color(0x3F3F3F00), width: 1.25));
    const BoxBorder visualWithYellowTop5At75 = Border(top: BorderSide(color: Color(0xBFBFBF00), width: 3.75));

    expect(BoxBorder.lerp(null, null, -1.0), null);
    expect(BoxBorder.lerp(Border.all(width: 10.0), null, -1.0), Border.all(width: 20.0));
    expect(BoxBorder.lerp(null, Border.all(width: 10.0), -1.0), Border.all(width: 0.0, style: BorderStyle.none));
    expect(BoxBorder.lerp(directionalWithTop10, null, -1.0), const BorderDirectional(top: BorderSide(width: 20.0)));
    expect(BoxBorder.lerp(null, directionalWithTop10, -1.0), const BorderDirectional());
    expect(BoxBorder.lerp(directionalWithTop10, visualWithTop100, -1.0), const Border());
    expect(BoxBorder.lerp(visualWithSides10, directionalWithMagentaTop5, -1.0), visualWithSides20);
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithMagentaTop5, -1.0), const Border(top: BorderSide(color: Color(0xFFFFFF00), width: 5.0)));
    expect(BoxBorder.lerp(visualWithSides10, directionalWithSides10, -1.0), visualWithSides30);
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithSides10, -1.0), directionalWithYellowTop10);
    expect(() => BoxBorder.lerp(SillyBorder(), const Border(), -1.0), throwsFlutterError);

    expect(BoxBorder.lerp(null, null, 0.0), null);
    expect(BoxBorder.lerp(Border.all(width: 10.0), null, 0.0), Border.all(width: 10.0));
    expect(BoxBorder.lerp(null, Border.all(width: 10.0), 0.0), const Border());
    expect(BoxBorder.lerp(directionalWithTop10, null, 0.0), const BorderDirectional(top: BorderSide(width: 10.0)));
    expect(BoxBorder.lerp(null, directionalWithTop10, 0.0), const BorderDirectional());
    expect(BoxBorder.lerp(directionalWithTop10, visualWithTop100, 0.0), visualWithTop10);
    expect(BoxBorder.lerp(visualWithSides10, directionalWithMagentaTop5, 0.0), visualWithSides10);
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithMagentaTop5, 0.0), const Border(top: BorderSide(color: Color(0xFFFFFF00), width: 5.0)));
    expect(BoxBorder.lerp(visualWithSides10, directionalWithSides10, 0.0), visualWithSides10);
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithSides10, 0.0), directionalWithYellowTop5);
    expect(() => BoxBorder.lerp(SillyBorder(), const Border(), 0.0), throwsFlutterError);

    expect(BoxBorder.lerp(null, null, 0.25), null);
    expect(BoxBorder.lerp(Border.all(width: 10.0), null, 0.25), Border.all(width: 7.5));
    expect(BoxBorder.lerp(null, Border.all(width: 10.0), 0.25), Border.all(width: 2.5));
    expect(BoxBorder.lerp(directionalWithTop10, null, 0.25), const BorderDirectional(top: BorderSide(width: 7.5)));
    expect(BoxBorder.lerp(null, directionalWithTop10, 0.25), const BorderDirectional(top: BorderSide(width: 2.5)));
    expect(BoxBorder.lerp(directionalWithTop10, visualWithTop100, 0.25), const Border(top: BorderSide(width: 32.5)));
    expect(BoxBorder.lerp(visualWithSides10, directionalWithMagentaTop5, 0.25), visualWithSides10At75 + directionalWithMagentaTop5At25);
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithMagentaTop5, 0.25), Border(top: BorderSide(width: 5.0, color: Color.lerp(const Color(0xFFFFFF00), const Color(0xFFFF00FF), 0.25)!)));
    expect(BoxBorder.lerp(visualWithSides10, directionalWithSides10, 0.25), visualWithSides10At50);
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithSides10, 0.25), visualWithYellowTop5At75 + directionalWithSides10At25);
    expect(() => BoxBorder.lerp(SillyBorder(), const Border(), 0.25), throwsFlutterError);

    expect(BoxBorder.lerp(null, null, 0.75), null);
    expect(BoxBorder.lerp(Border.all(width: 10.0), null, 0.75), Border.all(width: 2.5));
    expect(BoxBorder.lerp(null, Border.all(width: 10.0), 0.75), Border.all(width: 7.5));
    expect(BoxBorder.lerp(directionalWithTop10, null, 0.75), const BorderDirectional(top: BorderSide(width: 2.5)));
    expect(BoxBorder.lerp(null, directionalWithTop10, 0.75), const BorderDirectional(top: BorderSide(width: 7.5)));
    expect(BoxBorder.lerp(directionalWithTop10, visualWithTop100, 0.75), const Border(top: BorderSide(width: 77.5)));
    expect(BoxBorder.lerp(visualWithSides10, directionalWithMagentaTop5, 0.75), visualWithSides10At25 + directionalWithMagentaTop5At75);
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithMagentaTop5, 0.75), Border(top: BorderSide(width: 5.0, color: Color.lerp(const Color(0xFFFFFF00), const Color(0xFFFF00FF), 0.75)!)));
    expect(BoxBorder.lerp(visualWithSides10, directionalWithSides10, 0.75), directionalWithSides10At50);
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithSides10, 0.75), visualWithYellowTop5At25 + directionalWithSides10At75);
    expect(() => BoxBorder.lerp(SillyBorder(), const Border(), 0.75), throwsFlutterError);

    expect(BoxBorder.lerp(null, null, 1.0), null);
    expect(BoxBorder.lerp(Border.all(width: 10.0), null, 1.0), Border.all(width: 0.0, style: BorderStyle.none));
    expect(BoxBorder.lerp(null, Border.all(width: 10.0), 1.0), Border.all(width: 10.0));
    expect(BoxBorder.lerp(directionalWithTop10, null, 1.0), const BorderDirectional());
    expect(BoxBorder.lerp(null, directionalWithTop10, 1.0), const BorderDirectional(top: BorderSide(width: 10.0)));
    expect(BoxBorder.lerp(directionalWithTop10, visualWithTop100, 1.0), visualWithTop100);
    expect(BoxBorder.lerp(visualWithSides10, directionalWithMagentaTop5, 1.0), visualWithMagentaTop5);
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithMagentaTop5, 1.0), visualWithMagentaTop5);
    expect(BoxBorder.lerp(visualWithSides10, directionalWithSides10, 1.0), directionalWithSides10);
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithSides10, 1.0), directionalWithSides10);
    expect(() => BoxBorder.lerp(SillyBorder(), const Border(), 1.0), throwsFlutterError);

    expect(BoxBorder.lerp(null, null, 2.0), null);
    expect(BoxBorder.lerp(Border.all(width: 10.0), null, 2.0), Border.all(width: 0.0, style: BorderStyle.none));
    expect(BoxBorder.lerp(null, Border.all(width: 10.0), 2.0), Border.all(width: 20.0));
    expect(BoxBorder.lerp(directionalWithTop10, null, 2.0), const BorderDirectional());
    expect(BoxBorder.lerp(null, directionalWithTop10, 2.0), const BorderDirectional(top: BorderSide(width: 20.0)));
    expect(BoxBorder.lerp(directionalWithTop10, visualWithTop100, 2.0), visualWithTop190);
    expect(BoxBorder.lerp(visualWithSides10, directionalWithMagentaTop5, 2.0), visualWithMagentaTop10);
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithMagentaTop5, 2.0), visualWithMagentaTop5);
    expect(BoxBorder.lerp(visualWithSides10, directionalWithSides10, 2.0), directionalWithSides30);
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithSides10, 2.0), directionalWithSides20);
    expect(() => BoxBorder.lerp(SillyBorder(), const Border(), 2.0), throwsFlutterError);
  });

  test('BoxBorder.lerp throws correct FlutterError message', () {
    late FlutterError error;
    try {
      BoxBorder.lerp(SillyBorder(), const Border(), 2.0);
    } on FlutterError catch (e) {
      error = e;
    }
    expect(error, isNotNull);
    expect(error.diagnostics.length, 3);
    expect(error.diagnostics[2].level, DiagnosticLevel.hint);
    expect(
      error.diagnostics[2].toStringDeep(),
      equalsIgnoringHashCodes(
        'For a more general interpolation method, consider using\n'
        'ShapeBorder.lerp instead.\n',
      ),
    );
    expect(error.toStringDeep(), equalsIgnoringHashCodes(
      'FlutterError\n'
      '   BoxBorder.lerp can only interpolate Border and BorderDirectional\n'
      '   classes.\n'
      '   BoxBorder.lerp() was called with two objects of type SillyBorder\n'
      '   and Border:\n'
      '     SillyBorder()\n'
      '     Border.all(BorderSide(Color(0xff000000), 0.0,\n'
      '   BorderStyle.none))\n'
      '   However, only Border and BorderDirectional classes are supported\n'
      '   by this method.\n'
      '   For a more general interpolation method, consider using\n'
      '   ShapeBorder.lerp instead.\n',
    ));
  });

  test('BoxBorder.getInnerPath / BoxBorder.getOuterPath', () {
    // for Border, BorderDirectional
    const Border border = Border(top: BorderSide(width: 10.0), right: BorderSide(width: 20.0));
    const BorderDirectional borderDirectional = BorderDirectional(top: BorderSide(width: 10.0), end: BorderSide(width: 20.0));
    expect(
      border.getOuterPath(const Rect.fromLTRB(50.0, 60.0, 110.0, 190.0), textDirection: TextDirection.rtl),
      isPathThat(
        includes: <Offset>[
          const Offset(50.0, 60.0),
          const Offset(60.0, 60.0),
          const Offset(60.0, 70.0),
          const Offset(80.0, 190.0),
          const Offset(109.0, 189.0),
          const Offset(110.0, 80.0),
          const Offset(110.0, 190.0),
        ],
        excludes: <Offset>[
          const Offset(40.0, 60.0),
          const Offset(50.0, 50.0),
          const Offset(111.0, 190.0),
          const Offset(110.0, 191.0),
          const Offset(111.0, 191.0),
          Offset.zero,
          const Offset(-10.0, -10.0),
          const Offset(0.0, -10.0),
          const Offset(-10.0, 0.0),
          const Offset(1000.0, 1000.0),
        ],
      ),
    );
    expect(
      border.getInnerPath(const Rect.fromLTRB(50.0, 60.0, 110.0, 190.0), textDirection: TextDirection.rtl),
      // inner path is a rect from 50.0,70.0 to 90.0,190.0
      isPathThat(
        includes: <Offset>[
          const Offset(50.0, 70.0),
          const Offset(55.0, 70.0),
          const Offset(50.0, 75.0),
          const Offset(70.0, 70.0),
          const Offset(70.0, 71.0),
          const Offset(71.0, 70.0),
          const Offset(71.0, 71.0),
          const Offset(80.0, 180.0),
          const Offset(80.0, 190.0),
          const Offset(89.0, 189.0),
          const Offset(90.0, 190.0),
        ],
        excludes: <Offset>[
          const Offset(40.0, 60.0),
          const Offset(50.0, 50.0),
          const Offset(50.0, 60.0),
          const Offset(60.0, 60.0),
          Offset.zero,
          const Offset(-10.0, -10.0),
          const Offset(0.0, -10.0),
          const Offset(-10.0, 0.0),
          const Offset(110.0, 80.0),
          const Offset(89.0, 191.0),
          const Offset(90.0, 191.0),
          const Offset(91.0, 189.0),
          const Offset(91.0, 190.0),
          const Offset(91.0, 191.0),
          const Offset(109.0, 189.0),
          const Offset(110.0, 190.0),
          const Offset(1000.0, 1000.0),
        ],
      ),
    );
    expect(
      borderDirectional.getOuterPath(const Rect.fromLTRB(50.0, 60.0, 110.0, 190.0), textDirection: TextDirection.rtl),
      isPathThat(
        includes: <Offset>[
          const Offset(50.0, 60.0),
          const Offset(60.0, 60.0),
          const Offset(60.0, 70.0),
          const Offset(80.0, 190.0),
          const Offset(109.0, 189.0),
          const Offset(110.0, 80.0),
          const Offset(110.0, 190.0),
        ],
        excludes: <Offset>[
          const Offset(40.0, 60.0),
          const Offset(50.0, 50.0),
          const Offset(111.0, 190.0),
          const Offset(110.0, 191.0),
          const Offset(111.0, 191.0),
          Offset.zero,
          const Offset(-10.0, -10.0),
          const Offset(0.0, -10.0),
          const Offset(-10.0, 0.0),
          const Offset(1000.0, 1000.0),
        ],
      ),
    );
    expect(
      borderDirectional.getInnerPath(const Rect.fromLTRB(50.0, 60.0, 110.0, 190.0), textDirection: TextDirection.rtl),
      // inner path is a rect from 70.0,70.0 to 110.0,190.0
      isPathThat(
        includes: <Offset>[
          const Offset(70.0, 70.0),
          const Offset(70.0, 71.0),
          const Offset(71.0, 70.0),
          const Offset(71.0, 71.0),
          const Offset(80.0, 180.0),
          const Offset(80.0, 190.0),
          const Offset(89.0, 189.0),
          const Offset(90.0, 190.0),
          const Offset(91.0, 189.0),
          const Offset(91.0, 190.0),
          const Offset(109.0, 189.0),
          const Offset(110.0, 80.0),
          const Offset(110.0, 190.0),
        ],
        excludes: <Offset>[
          const Offset(40.0, 60.0),
          const Offset(50.0, 50.0),
          const Offset(50.0, 60.0),
          const Offset(50.0, 70.0),
          const Offset(50.0, 75.0),
          const Offset(55.0, 70.0),
          const Offset(60.0, 60.0),
          Offset.zero,
          const Offset(-10.0, -10.0),
          const Offset(0.0, -10.0),
          const Offset(-10.0, 0.0),
          const Offset(89.0, 191.0),
          const Offset(90.0, 191.0),
          const Offset(91.0, 191.0),
          const Offset(110.0, 191.0),
          const Offset(111.0, 190.0),
          const Offset(111.0, 191.0),
          const Offset(1000.0, 1000.0),
        ],
      ),
    );
    expect(
      borderDirectional.getOuterPath(const Rect.fromLTRB(50.0, 60.0, 110.0, 190.0), textDirection: TextDirection.ltr),
      isPathThat(
        includes: <Offset>[
          const Offset(50.0, 60.0),
          const Offset(60.0, 60.0),
          const Offset(60.0, 70.0),
          const Offset(80.0, 190.0),
          const Offset(109.0, 189.0),
          const Offset(110.0, 80.0),
          const Offset(110.0, 190.0),
        ],
        excludes: <Offset>[
          const Offset(40.0, 60.0),
          const Offset(50.0, 50.0),
          const Offset(111.0, 190.0),
          const Offset(110.0, 191.0),
          const Offset(111.0, 191.0),
          Offset.zero,
          const Offset(-10.0, -10.0),
          const Offset(0.0, -10.0),
          const Offset(-10.0, 0.0),
          const Offset(1000.0, 1000.0),
        ],
      ),
    );
    expect(
      borderDirectional.getInnerPath(const Rect.fromLTRB(50.0, 60.0, 110.0, 190.0), textDirection: TextDirection.ltr),
      // inner path is a rect from 50.0,70.0 to 90.0,190.0
      isPathThat(
        includes: <Offset>[
          const Offset(50.0, 70.0),
          const Offset(50.0, 75.0),
          const Offset(55.0, 70.0),
          const Offset(70.0, 70.0),
          const Offset(70.0, 71.0),
          const Offset(71.0, 70.0),
          const Offset(71.0, 71.0),
          const Offset(80.0, 180.0),
          const Offset(80.0, 190.0),
          const Offset(89.0, 189.0),
          const Offset(90.0, 190.0),
        ],
        excludes: <Offset>[
          const Offset(50.0, 50.0),
          const Offset(40.0, 60.0),
          const Offset(50.0, 60.0),
          const Offset(60.0, 60.0),
          Offset.zero,
          const Offset(-10.0, -10.0),
          const Offset(0.0, -10.0),
          const Offset(-10.0, 0.0),
          const Offset(110.0, 80.0),
          const Offset(89.0, 191.0),
          const Offset(90.0, 191.0),
          const Offset(91.0, 189.0),
          const Offset(91.0, 190.0),
          const Offset(91.0, 191.0),
          const Offset(109.0, 189.0),
          const Offset(110.0, 190.0),
          const Offset(1000.0, 1000.0),
        ],
      ),
    );
  });

  test('BorderDirectional.merge', () {
    const BorderSide magenta3 = BorderSide(color: Color(0xFFFF00FF), width: 3.0);
    const BorderSide magenta6 = BorderSide(color: Color(0xFFFF00FF), width: 6.0);
    const BorderSide yellow2 = BorderSide(color: Color(0xFFFFFF00), width: 2.0);
    const BorderSide yellowNone0 = BorderSide(color: Color(0xFFFFFF00), width: 0.0, style: BorderStyle.none);
    expect(
      BorderDirectional.merge(
        const BorderDirectional(top: yellow2),
        const BorderDirectional(end: magenta3),
      ),
      const BorderDirectional(top: yellow2, end: magenta3),
    );
    expect(
      BorderDirectional.merge(
        const BorderDirectional(bottom: magenta3),
        const BorderDirectional(bottom: magenta3),
      ),
      const BorderDirectional(bottom: magenta6),
    );
    expect(
      BorderDirectional.merge(
        const BorderDirectional(start: magenta3, end: yellowNone0),
        const BorderDirectional(end: yellow2),
      ),
      const BorderDirectional(start: magenta3, end: yellow2),
    );
    expect(
      BorderDirectional.merge(const BorderDirectional(), const BorderDirectional()),
      const BorderDirectional(),
    );
    expect(
      () => BorderDirectional.merge(
        const BorderDirectional(start: magenta3),
        const BorderDirectional(start: yellow2),
      ),
      throwsAssertionError,
    );
  });

  test('BorderDirectional.dimensions', () {
    expect(
      const BorderDirectional(
        top: BorderSide(width: 3.0),
        start: BorderSide(width: 2.0),
        end: BorderSide(width: 7.0),
        bottom: BorderSide(width: 5.0),
      ).dimensions,
      const EdgeInsetsDirectional.fromSTEB(2.0, 3.0, 7.0, 5.0),
    );
  });

  test('BorderDirectional.isUniform', () {
    expect(
      const BorderDirectional(
        top: BorderSide(width: 3.0),
        start: BorderSide(width: 3.0),
        end: BorderSide(width: 3.0),
        bottom: BorderSide(width: 3.1),
      ).isUniform,
      false,
    );
    expect(
      const BorderDirectional(
        top: BorderSide(width: 3.0),
        start: BorderSide(width: 3.0),
        end: BorderSide(width: 3.0),
        bottom: BorderSide(width: 3.0),
      ).isUniform,
      true,
    );
    expect(
      const BorderDirectional(
        top: BorderSide(color: Color(0xFFFFFFFF)),
        start: BorderSide(color: Color(0xFFFFFFFE)),
        end: BorderSide(color: Color(0xFFFFFFFF)),
        bottom: BorderSide(color: Color(0xFFFFFFFF)),
      ).isUniform,
      false,
    );
    expect(
      const BorderDirectional(
        top: BorderSide(color: Color(0xFFFFFFFF)),
        start: BorderSide(color: Color(0xFFFFFFFF)),
        end: BorderSide(color: Color(0xFFFFFFFF)),
        bottom: BorderSide(color: Color(0xFFFFFFFF)),
      ).isUniform,
      true,
    );
    expect(
      const BorderDirectional(
        top: BorderSide(style: BorderStyle.none),
        start: BorderSide(style: BorderStyle.none),
        end: BorderSide(style: BorderStyle.none),
        bottom: BorderSide(style: BorderStyle.solid, width: 0.0),
      ).isUniform,
      false,
    );
    expect(
      const BorderDirectional(
        top: BorderSide(style: BorderStyle.none),
        start: BorderSide(style: BorderStyle.none),
        end: BorderSide(style: BorderStyle.none),
        bottom: BorderSide.none,
      ).isUniform,
      false,
    );
    expect(
      const BorderDirectional(
        top: BorderSide.none,
        start: BorderSide.none,
        end: BorderSide.none,
        bottom: BorderSide.none,
      ).isUniform,
      true,
    );
    expect(
      const BorderDirectional().isUniform,
      true,
    );
  });

  test('BorderDirectional.add - all directional', () {
    const BorderSide magenta3 = BorderSide(color: Color(0xFFFF00FF), width: 3.0);
    const BorderSide magenta6 = BorderSide(color: Color(0xFFFF00FF), width: 6.0);
    const BorderSide yellow2 = BorderSide(color: Color(0xFFFFFF00), width: 2.0);
    const BorderSide yellowNone0 = BorderSide(color: Color(0xFFFFFF00), width: 0.0, style: BorderStyle.none);
    expect(
      const BorderDirectional(top: yellow2) + const BorderDirectional(end: magenta3),
      const BorderDirectional(top: yellow2, end: magenta3),
    );
    expect(
      const BorderDirectional(bottom: magenta3) + const BorderDirectional(bottom: magenta3),
      const BorderDirectional(bottom: magenta6),
    );
    expect(
      const BorderDirectional(start: magenta3, end: yellowNone0) + const BorderDirectional(end: yellow2),
      const BorderDirectional(start: magenta3, end: yellow2),
    );
    expect(
      const BorderDirectional() + const BorderDirectional(),
      const BorderDirectional(),
    );
    expect(
      const BorderDirectional(start: magenta3) + const BorderDirectional(start: yellow2),
      isNot(isA<BorderDirectional>()), // see shape_border_test.dart for better tests of this case
    );
    const BorderDirectional b3 = BorderDirectional(top: magenta3);
    const BorderDirectional b6 = BorderDirectional(top: magenta6);
    expect(b3 + b3, b6);
    const BorderDirectional b0 = BorderDirectional(top: yellowNone0);
    const BorderDirectional bZ = BorderDirectional();
    expect(b0 + b0, bZ);
    expect(bZ + bZ, bZ);
    expect(b0 + bZ, bZ);
    expect(bZ + b0, bZ);
  });

  test('BorderDirectional.add', () {
    const BorderSide side1 = BorderSide(color: Color(0x11111111));
    const BorderSide doubleSide1 = BorderSide(color: Color(0x11111111), width: 2.0);
    const BorderSide side2 = BorderSide(color: Color(0x22222222));
    const BorderSide doubleSide2 = BorderSide(color: Color(0x22222222), width: 2.0);

    // adding tops and sides
    expect(const Border(left: side1) + const BorderDirectional(top: side2), const Border(left: side1, top: side2));
    expect(const BorderDirectional(start: side1) + const Border(top: side2), const BorderDirectional(start: side1, top: side2));
    expect(const Border(top: side2) + const BorderDirectional(start: side1), const BorderDirectional(start: side1, top: side2));
    expect(const BorderDirectional(top: side2) + const Border(left: side1), const Border(left: side1, top: side2));

    // adding incompatible tops and bottoms
    expect((const Border(top: side1) + const BorderDirectional(top: side2)).toString(), contains(' + '));
    expect((const BorderDirectional(top: side2) + const Border(top: side1)).toString(), contains(' + '));
    expect((const Border(bottom: side1) + const BorderDirectional(bottom: side2)).toString(), contains(' + '));
    expect((const BorderDirectional(bottom: side2) + const Border(bottom: side1)).toString(), contains(' + '));

    // adding compatible tops and bottoms
    expect(const BorderDirectional(top: side1) + const Border(top: side1), const Border(top: doubleSide1));
    expect(const Border(top: side1) + const BorderDirectional(top: side1), const Border(top: doubleSide1));
    expect(const BorderDirectional(bottom: side1) + const Border(bottom: side1), const Border(bottom: doubleSide1));
    expect(const Border(bottom: side1) + const BorderDirectional(bottom: side1), const Border(bottom: doubleSide1));

    const Border borderWithLeft = Border(left: side1, top: side2, bottom: side2);
    const Border borderWithRight = Border(right: side1, top: side2, bottom: side2);
    const Border borderWithoutSides = Border(top: side2, bottom: side2);
    const BorderDirectional borderDirectionalWithStart = BorderDirectional(start: side1, top: side2, bottom: side2);
    const BorderDirectional borderDirectionalWithEnd = BorderDirectional(end: side1, top: side2, bottom: side2);
    const BorderDirectional borderDirectionalWithoutSides = BorderDirectional(top: side2, bottom: side2);

    expect((borderWithLeft + borderDirectionalWithStart).toString(), '$borderWithLeft + $borderDirectionalWithStart');
    expect((borderWithLeft + borderDirectionalWithEnd).toString(), '$borderWithLeft + $borderDirectionalWithEnd');
    expect((borderWithLeft + borderDirectionalWithoutSides).toString(), '${const Border(left: side1, top: doubleSide2, bottom: doubleSide2)}');
    expect((borderWithRight + borderDirectionalWithStart).toString(), '$borderWithRight + $borderDirectionalWithStart');
    expect((borderWithRight + borderDirectionalWithEnd).toString(), '$borderWithRight + $borderDirectionalWithEnd');
    expect((borderWithRight + borderDirectionalWithoutSides).toString(), '${const Border(right: side1, top: doubleSide2, bottom: doubleSide2)}');
    expect((borderWithoutSides + borderDirectionalWithStart).toString(), '${const BorderDirectional(start: side1, top: doubleSide2, bottom: doubleSide2)}');
    expect((borderWithoutSides + borderDirectionalWithEnd).toString(), '${const BorderDirectional(end: side1, top: doubleSide2, bottom: doubleSide2)}');
    expect((borderWithoutSides + borderDirectionalWithoutSides).toString(), '${const Border(top: doubleSide2, bottom: doubleSide2)}');

    expect((borderDirectionalWithStart + borderWithLeft).toString(), '$borderDirectionalWithStart + $borderWithLeft');
    expect((borderDirectionalWithEnd + borderWithLeft).toString(), '$borderDirectionalWithEnd + $borderWithLeft');
    expect((borderDirectionalWithoutSides + borderWithLeft).toString(), '${const Border(left: side1, top: doubleSide2, bottom: doubleSide2)}');
    expect((borderDirectionalWithStart + borderWithRight).toString(), '$borderDirectionalWithStart + $borderWithRight');
    expect((borderDirectionalWithEnd + borderWithRight).toString(), '$borderDirectionalWithEnd + $borderWithRight');
    expect((borderDirectionalWithoutSides + borderWithRight).toString(), '${const Border(right: side1, top: doubleSide2, bottom: doubleSide2)}');
    expect((borderDirectionalWithStart + borderWithoutSides).toString(), '${const BorderDirectional(start: side1, top: doubleSide2, bottom: doubleSide2)}');
    expect((borderDirectionalWithEnd + borderWithoutSides).toString(), '${const BorderDirectional(end: side1, top: doubleSide2, bottom: doubleSide2)}');
    expect((borderDirectionalWithoutSides + borderWithoutSides).toString(), '${const Border(top: doubleSide2, bottom: doubleSide2)}');
  });

  test('BorderDirectional.scale', () {
    const BorderSide magenta3 = BorderSide(color: Color(0xFFFF00FF), width: 3.0);
    const BorderSide magenta6 = BorderSide(color: Color(0xFFFF00FF), width: 6.0);
    const BorderSide yellow2 = BorderSide(color: Color(0xFFFFFF00), width: 2.0);
    const BorderSide yellowNone0 = BorderSide(color: Color(0xFFFFFF00), width: 0.0, style: BorderStyle.none);
    const BorderDirectional b3 = BorderDirectional(start: magenta3);
    const BorderDirectional b6 = BorderDirectional(start: magenta6);
    expect(b3.scale(2.0), b6);
    const BorderDirectional bY0 = BorderDirectional(top: yellowNone0);
    expect(bY0.scale(3.0), bY0);
    const BorderDirectional bY2 = BorderDirectional(top: yellow2);
    expect(bY2.scale(0.0), bY0);
  });

  test('BorderDirectional.lerp', () {
    const BorderDirectional directionalWithTop10 = BorderDirectional(top: BorderSide(width: 10.0));
    const BorderDirectional atMinus100 = BorderDirectional(start: BorderSide(width: 0.0), end: BorderSide(width: 300.0));
    const BorderDirectional at0 = BorderDirectional(start: BorderSide(width: 100.0), end: BorderSide(width: 200.0));
    const BorderDirectional at25 = BorderDirectional(start: BorderSide(width: 125.0), end: BorderSide(width: 175.0));
    const BorderDirectional at75 = BorderDirectional(start: BorderSide(width: 175.0), end: BorderSide(width: 125.0));
    const BorderDirectional at100 = BorderDirectional(start: BorderSide(width: 200.0), end: BorderSide(width: 100.0));
    const BorderDirectional at200 = BorderDirectional(start: BorderSide(width: 300.0), end: BorderSide(width: 0.0));

    expect(BorderDirectional.lerp(null, null, -1.0), null);
    expect(BorderDirectional.lerp(directionalWithTop10, null, -1.0), const BorderDirectional(top: BorderSide(width: 20.0)));
    expect(BorderDirectional.lerp(null, directionalWithTop10, -1.0), const BorderDirectional());
    expect(BorderDirectional.lerp(at0, at100, -1.0), atMinus100);

    expect(BorderDirectional.lerp(null, null, 0.0), null);
    expect(BorderDirectional.lerp(directionalWithTop10, null, 0.0), const BorderDirectional(top: BorderSide(width: 10.0)));
    expect(BorderDirectional.lerp(null, directionalWithTop10, 0.0), const BorderDirectional());
    expect(BorderDirectional.lerp(at0, at100, 0.0), at0);

    expect(BorderDirectional.lerp(null, null, 0.25), null);
    expect(BorderDirectional.lerp(directionalWithTop10, null, 0.25), const BorderDirectional(top: BorderSide(width: 7.5)));
    expect(BorderDirectional.lerp(null, directionalWithTop10, 0.25), const BorderDirectional(top: BorderSide(width: 2.5)));
    expect(BorderDirectional.lerp(at0, at100, 0.25), at25);

    expect(BorderDirectional.lerp(null, null, 0.75), null);
    expect(BorderDirectional.lerp(directionalWithTop10, null, 0.75), const BorderDirectional(top: BorderSide(width: 2.5)));
    expect(BorderDirectional.lerp(null, directionalWithTop10, 0.75), const BorderDirectional(top: BorderSide(width: 7.5)));
    expect(BorderDirectional.lerp(at0, at100, 0.75), at75);

    expect(BorderDirectional.lerp(null, null, 1.0), null);
    expect(BorderDirectional.lerp(directionalWithTop10, null, 1.0), const BorderDirectional());
    expect(BorderDirectional.lerp(null, directionalWithTop10, 1.0), const BorderDirectional(top: BorderSide(width: 10.0)));
    expect(BorderDirectional.lerp(at0, at100, 1.0), at100);

    expect(BorderDirectional.lerp(null, null, 2.0), null);
    expect(BorderDirectional.lerp(directionalWithTop10, null, 2.0), const BorderDirectional());
    expect(BorderDirectional.lerp(null, directionalWithTop10, 2.0), const BorderDirectional(top: BorderSide(width: 20.0)));
    expect(BorderDirectional.lerp(at0, at100, 2.0), at200);
  });

  test('BorderDirectional.paint', () {
    expect(
      (Canvas canvas) {
        const BorderDirectional(end: BorderSide(width: 10.0, color: Color(0xFF00FF00)))
          .paint(canvas, const Rect.fromLTRB(10.0, 20.0, 30.0, 40.0), textDirection: TextDirection.rtl);
      },
      paints
        ..path(
          includes: <Offset>[const Offset(15.0, 30.0)],
          excludes: <Offset>[const Offset(25.0, 30.0)],
          color: const Color(0xFF00FF00),
        ),
    );
    expect(
      (Canvas canvas) {
        const BorderDirectional(end: BorderSide(width: 10.0, color: Color(0xFF00FF00)))
          .paint(canvas, const Rect.fromLTRB(10.0, 20.0, 30.0, 40.0), textDirection: TextDirection.ltr);
      },
      paints
        ..path(
          includes: <Offset>[const Offset(25.0, 30.0)],
          excludes: <Offset>[const Offset(15.0, 30.0)],
          color: const Color(0xFF00FF00),
        ),
    );
    expect(
      (Canvas canvas) {
        const BorderDirectional(end: BorderSide(width: 10.0, color: Color(0xFF00FF00)))
          .paint(canvas, const Rect.fromLTRB(10.0, 20.0, 30.0, 40.0));
      },
      paintsAssertion, // no TextDirection
    );
  });

  test('BorderDirectional hashCode', () {
    final BorderSide side = BorderSide(width: nonconst(2.0));
    expect(BorderDirectional(top: side).hashCode, BorderDirectional(top: side).hashCode);
    expect(BorderDirectional(top: side).hashCode, isNot(BorderDirectional(bottom: side).hashCode));
  });

  test('BoxDecoration.border takes a BorderDirectional', () {
    const BoxDecoration decoration2 = BoxDecoration(
      border: BorderDirectional(start: BorderSide(width: 2.0)),
    );
    const BoxDecoration decoration4 = BoxDecoration(
      border: BorderDirectional(start: BorderSide(width: 4.0)),
    );
    const BoxDecoration decoration6 = BoxDecoration(
      border: BorderDirectional(start: BorderSide(width: 6.0)),
    );
    final BoxPainter painter = decoration2.createBoxPainter();
    expect(
      (Canvas canvas) {
        painter.paint(
          canvas,
          const Offset(30.0, 0.0),
          const ImageConfiguration(size: Size(20.0, 20.0), textDirection: TextDirection.rtl),
        );
      },
      paints
        ..path(
          includes: <Offset>[const Offset(49.0, 10.0)],
          excludes: <Offset>[const Offset(31.0, 10.0)],
        ),
    );
    expect(
      (Canvas canvas) {
        painter.paint(
          canvas,
          const Offset(30.0, 0.0),
          const ImageConfiguration(size: Size(20.0, 20.0), textDirection: TextDirection.ltr),
        );
      },
      paints
        ..path(
          includes: <Offset>[const Offset(31.0, 10.0)],
          excludes: <Offset>[const Offset(49.0, 10.0)],
        ),
    );
    expect(decoration2.padding, const EdgeInsetsDirectional.fromSTEB(2.0, 0.0, 0.0, 0.0));
    expect(decoration2.scale(2.0), decoration4);
    expect(BoxDecoration.lerp(decoration2, decoration6, 0.5), decoration4);
  });
}
