border_rtl_test.dart 34.6 KB
Newer Older
Ian Hickson's avatar
Ian Hickson committed
1
// Copyright 2014 The Flutter Authors. All rights reserved.
Ian Hickson's avatar
Ian Hickson committed
2 3 4
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

5
import 'package:flutter/foundation.dart' show DiagnosticLevel, FlutterError;
Ian Hickson's avatar
Ian Hickson committed
6 7 8 9
import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart';

class SillyBorder extends BoxBorder {
10 11
  const SillyBorder();

Ian Hickson's avatar
Ian Hickson committed
12 13 14 15 16 17 18
  @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
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
    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));
Ian Hickson's avatar
Ian Hickson committed
45 46

    expect(BoxBorder.lerp(null, null, -1.0), null);
47 48
    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));
49
    expect(BoxBorder.lerp(directionalWithTop10, null, -1.0), const BorderDirectional(top: BorderSide(width: 20.0)));
Ian Hickson's avatar
Ian Hickson committed
50 51 52
    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);
53
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithMagentaTop5, -1.0), const Border(top: BorderSide(color: Color(0xFFFFFF00), width: 5.0)));
Ian Hickson's avatar
Ian Hickson committed
54 55
    expect(BoxBorder.lerp(visualWithSides10, directionalWithSides10, -1.0), visualWithSides30);
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithSides10, -1.0), directionalWithYellowTop10);
56
    expect(() => BoxBorder.lerp(const SillyBorder(), const Border(), -1.0), throwsFlutterError);
Ian Hickson's avatar
Ian Hickson committed
57 58

    expect(BoxBorder.lerp(null, null, 0.0), null);
59 60
    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());
61
    expect(BoxBorder.lerp(directionalWithTop10, null, 0.0), const BorderDirectional(top: BorderSide(width: 10.0)));
Ian Hickson's avatar
Ian Hickson committed
62 63 64
    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);
65
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithMagentaTop5, 0.0), const Border(top: BorderSide(color: Color(0xFFFFFF00), width: 5.0)));
Ian Hickson's avatar
Ian Hickson committed
66 67
    expect(BoxBorder.lerp(visualWithSides10, directionalWithSides10, 0.0), visualWithSides10);
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithSides10, 0.0), directionalWithYellowTop5);
68
    expect(() => BoxBorder.lerp(const SillyBorder(), const Border(), 0.0), throwsFlutterError);
Ian Hickson's avatar
Ian Hickson committed
69 70

    expect(BoxBorder.lerp(null, null, 0.25), null);
71 72
    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));
73 74 75
    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)));
Ian Hickson's avatar
Ian Hickson committed
76
    expect(BoxBorder.lerp(visualWithSides10, directionalWithMagentaTop5, 0.25), visualWithSides10At75 + directionalWithMagentaTop5At25);
77
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithMagentaTop5, 0.25), Border(top: BorderSide(width: 5.0, color: Color.lerp(const Color(0xFFFFFF00), const Color(0xFFFF00FF), 0.25)!)));
Ian Hickson's avatar
Ian Hickson committed
78 79
    expect(BoxBorder.lerp(visualWithSides10, directionalWithSides10, 0.25), visualWithSides10At50);
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithSides10, 0.25), visualWithYellowTop5At75 + directionalWithSides10At25);
80
    expect(() => BoxBorder.lerp(const SillyBorder(), const Border(), 0.25), throwsFlutterError);
Ian Hickson's avatar
Ian Hickson committed
81 82

    expect(BoxBorder.lerp(null, null, 0.75), null);
83 84
    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));
85 86 87
    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)));
Ian Hickson's avatar
Ian Hickson committed
88
    expect(BoxBorder.lerp(visualWithSides10, directionalWithMagentaTop5, 0.75), visualWithSides10At25 + directionalWithMagentaTop5At75);
89
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithMagentaTop5, 0.75), Border(top: BorderSide(width: 5.0, color: Color.lerp(const Color(0xFFFFFF00), const Color(0xFFFF00FF), 0.75)!)));
Ian Hickson's avatar
Ian Hickson committed
90 91
    expect(BoxBorder.lerp(visualWithSides10, directionalWithSides10, 0.75), directionalWithSides10At50);
    expect(BoxBorder.lerp(visualWithYellowTop5, directionalWithSides10, 0.75), visualWithYellowTop5At25 + directionalWithSides10At75);
92
    expect(() => BoxBorder.lerp(const SillyBorder(), const Border(), 0.75), throwsFlutterError);
Ian Hickson's avatar
Ian Hickson committed
93 94

    expect(BoxBorder.lerp(null, null, 1.0), null);
95 96
    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));
Ian Hickson's avatar
Ian Hickson committed
97
    expect(BoxBorder.lerp(directionalWithTop10, null, 1.0), const BorderDirectional());
98
    expect(BoxBorder.lerp(null, directionalWithTop10, 1.0), const BorderDirectional(top: BorderSide(width: 10.0)));
Ian Hickson's avatar
Ian Hickson committed
99 100 101 102 103
    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);
104
    expect(() => BoxBorder.lerp(const SillyBorder(), const Border(), 1.0), throwsFlutterError);
Ian Hickson's avatar
Ian Hickson committed
105 106

    expect(BoxBorder.lerp(null, null, 2.0), null);
107 108
    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));
Ian Hickson's avatar
Ian Hickson committed
109
    expect(BoxBorder.lerp(directionalWithTop10, null, 2.0), const BorderDirectional());
110
    expect(BoxBorder.lerp(null, directionalWithTop10, 2.0), const BorderDirectional(top: BorderSide(width: 20.0)));
Ian Hickson's avatar
Ian Hickson committed
111 112 113 114 115
    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);
116
    expect(() => BoxBorder.lerp(const SillyBorder(), const Border(), 2.0), throwsFlutterError);
Ian Hickson's avatar
Ian Hickson committed
117 118
  });

119
  test('BoxBorder.lerp throws correct FlutterError message', () {
120
    late FlutterError error;
121
    try {
122
      BoxBorder.lerp(const SillyBorder(), const Border(), 2.0);
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
    } 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'
143
      '     Border.all(BorderSide(width: 0.0, style: none))\n'
144 145 146
      '   However, only Border and BorderDirectional classes are supported\n'
      '   by this method.\n'
      '   For a more general interpolation method, consider using\n'
147
      '   ShapeBorder.lerp instead.\n',
148 149 150
    ));
  });

Ian Hickson's avatar
Ian Hickson committed
151 152
  test('BoxBorder.getInnerPath / BoxBorder.getOuterPath', () {
    // for Border, BorderDirectional
153 154
    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));
Ian Hickson's avatar
Ian Hickson committed
155
    expect(
Dan Field's avatar
Dan Field committed
156
      border.getOuterPath(const Rect.fromLTRB(50.0, 60.0, 110.0, 190.0), textDirection: TextDirection.rtl),
Ian Hickson's avatar
Ian Hickson committed
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
      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),
173
          Offset.zero,
Ian Hickson's avatar
Ian Hickson committed
174 175 176 177 178 179
          const Offset(-10.0, -10.0),
          const Offset(0.0, -10.0),
          const Offset(-10.0, 0.0),
          const Offset(1000.0, 1000.0),
        ],
      ),
Ian Hickson's avatar
Ian Hickson committed
180
    );
Ian Hickson's avatar
Ian Hickson committed
181
    expect(
Dan Field's avatar
Dan Field committed
182
      border.getInnerPath(const Rect.fromLTRB(50.0, 60.0, 110.0, 190.0), textDirection: TextDirection.rtl),
Ian Hickson's avatar
Ian Hickson committed
183
      // inner path is a rect from 50.0,70.0 to 90.0,190.0
Ian Hickson's avatar
Ian Hickson committed
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
      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),
203
          Offset.zero,
Ian Hickson's avatar
Ian Hickson committed
204 205 206 207 208 209 210 211 212 213 214 215 216
          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),
        ],
217
      ),
Ian Hickson's avatar
Ian Hickson committed
218
    );
Ian Hickson's avatar
Ian Hickson committed
219
    expect(
Dan Field's avatar
Dan Field committed
220
      borderDirectional.getOuterPath(const Rect.fromLTRB(50.0, 60.0, 110.0, 190.0), textDirection: TextDirection.rtl),
Ian Hickson's avatar
Ian Hickson committed
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236
      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),
237
          Offset.zero,
Ian Hickson's avatar
Ian Hickson committed
238 239 240 241 242 243
          const Offset(-10.0, -10.0),
          const Offset(0.0, -10.0),
          const Offset(-10.0, 0.0),
          const Offset(1000.0, 1000.0),
        ],
      ),
Ian Hickson's avatar
Ian Hickson committed
244
    );
Ian Hickson's avatar
Ian Hickson committed
245
    expect(
Dan Field's avatar
Dan Field committed
246
      borderDirectional.getInnerPath(const Rect.fromLTRB(50.0, 60.0, 110.0, 190.0), textDirection: TextDirection.rtl),
Ian Hickson's avatar
Ian Hickson committed
247
      // inner path is a rect from 70.0,70.0 to 110.0,190.0
Ian Hickson's avatar
Ian Hickson committed
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
      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),
272
          Offset.zero,
Ian Hickson's avatar
Ian Hickson committed
273 274 275 276 277 278 279 280 281 282 283 284
          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),
        ],
      ),
Ian Hickson's avatar
Ian Hickson committed
285
    );
Ian Hickson's avatar
Ian Hickson committed
286
    expect(
Dan Field's avatar
Dan Field committed
287
      borderDirectional.getOuterPath(const Rect.fromLTRB(50.0, 60.0, 110.0, 190.0), textDirection: TextDirection.ltr),
Ian Hickson's avatar
Ian Hickson committed
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
      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),
304
          Offset.zero,
Ian Hickson's avatar
Ian Hickson committed
305 306 307 308 309 310
          const Offset(-10.0, -10.0),
          const Offset(0.0, -10.0),
          const Offset(-10.0, 0.0),
          const Offset(1000.0, 1000.0),
        ],
      ),
Ian Hickson's avatar
Ian Hickson committed
311
    );
Ian Hickson's avatar
Ian Hickson committed
312
    expect(
Dan Field's avatar
Dan Field committed
313
      borderDirectional.getInnerPath(const Rect.fromLTRB(50.0, 60.0, 110.0, 190.0), textDirection: TextDirection.ltr),
Ian Hickson's avatar
Ian Hickson committed
314
      // inner path is a rect from 50.0,70.0 to 90.0,190.0
Ian Hickson's avatar
Ian Hickson committed
315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333
      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),
334
          Offset.zero,
Ian Hickson's avatar
Ian Hickson committed
335 336 337 338 339 340 341 342 343 344 345 346 347 348
          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),
        ],
      ),
Ian Hickson's avatar
Ian Hickson committed
349
    );
350
  });
Ian Hickson's avatar
Ian Hickson committed
351 352

  test('BorderDirectional.merge', () {
353 354 355 356
    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);
Ian Hickson's avatar
Ian Hickson committed
357 358
    expect(
      BorderDirectional.merge(
359 360
        const BorderDirectional(top: yellow2),
        const BorderDirectional(end: magenta3),
Ian Hickson's avatar
Ian Hickson committed
361
      ),
362
      const BorderDirectional(top: yellow2, end: magenta3),
Ian Hickson's avatar
Ian Hickson committed
363 364 365
    );
    expect(
      BorderDirectional.merge(
366 367
        const BorderDirectional(bottom: magenta3),
        const BorderDirectional(bottom: magenta3),
Ian Hickson's avatar
Ian Hickson committed
368
      ),
369
      const BorderDirectional(bottom: magenta6),
Ian Hickson's avatar
Ian Hickson committed
370 371 372
    );
    expect(
      BorderDirectional.merge(
373 374
        const BorderDirectional(start: magenta3, end: yellowNone0),
        const BorderDirectional(end: yellow2),
Ian Hickson's avatar
Ian Hickson committed
375
      ),
376
      const BorderDirectional(start: magenta3, end: yellow2),
Ian Hickson's avatar
Ian Hickson committed
377 378 379 380 381 382 383
    );
    expect(
      BorderDirectional.merge(const BorderDirectional(), const BorderDirectional()),
      const BorderDirectional(),
    );
    expect(
      () => BorderDirectional.merge(
384 385
        const BorderDirectional(start: magenta3),
        const BorderDirectional(start: yellow2),
Ian Hickson's avatar
Ian Hickson committed
386 387 388
      ),
      throwsAssertionError,
    );
389
  });
Ian Hickson's avatar
Ian Hickson committed
390 391 392 393

  test('BorderDirectional.dimensions', () {
    expect(
      const BorderDirectional(
394 395 396 397
        top: BorderSide(width: 3.0),
        start: BorderSide(width: 2.0),
        end: BorderSide(width: 7.0),
        bottom: BorderSide(width: 5.0),
Ian Hickson's avatar
Ian Hickson committed
398 399 400
      ).dimensions,
      const EdgeInsetsDirectional.fromSTEB(2.0, 3.0, 7.0, 5.0),
    );
401
  });
Ian Hickson's avatar
Ian Hickson committed
402 403 404 405

  test('BorderDirectional.isUniform', () {
    expect(
      const BorderDirectional(
406 407 408 409
        top: BorderSide(width: 3.0),
        start: BorderSide(width: 3.0),
        end: BorderSide(width: 3.0),
        bottom: BorderSide(width: 3.1),
Ian Hickson's avatar
Ian Hickson committed
410 411 412 413 414
      ).isUniform,
      false,
    );
    expect(
      const BorderDirectional(
415 416 417 418
        top: BorderSide(width: 3.0),
        start: BorderSide(width: 3.0),
        end: BorderSide(width: 3.0),
        bottom: BorderSide(width: 3.0),
Ian Hickson's avatar
Ian Hickson committed
419 420 421 422 423
      ).isUniform,
      true,
    );
    expect(
      const BorderDirectional(
424 425 426 427
        top: BorderSide(color: Color(0xFFFFFFFF)),
        start: BorderSide(color: Color(0xFFFFFFFE)),
        end: BorderSide(color: Color(0xFFFFFFFF)),
        bottom: BorderSide(color: Color(0xFFFFFFFF)),
Ian Hickson's avatar
Ian Hickson committed
428 429 430 431 432
      ).isUniform,
      false,
    );
    expect(
      const BorderDirectional(
433 434 435 436
        top: BorderSide(color: Color(0xFFFFFFFF)),
        start: BorderSide(color: Color(0xFFFFFFFF)),
        end: BorderSide(color: Color(0xFFFFFFFF)),
        bottom: BorderSide(color: Color(0xFFFFFFFF)),
Ian Hickson's avatar
Ian Hickson committed
437 438 439 440 441
      ).isUniform,
      true,
    );
    expect(
      const BorderDirectional(
442 443 444
        top: BorderSide(style: BorderStyle.none),
        start: BorderSide(style: BorderStyle.none),
        end: BorderSide(style: BorderStyle.none),
445
        bottom: BorderSide(width: 0.0),
Ian Hickson's avatar
Ian Hickson committed
446 447 448 449 450
      ).isUniform,
      false,
    );
    expect(
      const BorderDirectional(
451 452 453
        top: BorderSide(style: BorderStyle.none),
        start: BorderSide(style: BorderStyle.none),
        end: BorderSide(style: BorderStyle.none),
Ian Hickson's avatar
Ian Hickson committed
454 455 456 457
      ).isUniform,
      false,
    );
    expect(
458
      const BorderDirectional().isUniform,
Ian Hickson's avatar
Ian Hickson committed
459 460 461 462 463 464
      true,
    );
    expect(
      const BorderDirectional().isUniform,
      true,
    );
465
  });
Ian Hickson's avatar
Ian Hickson committed
466 467

  test('BorderDirectional.add - all directional', () {
468 469 470 471
    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);
Ian Hickson's avatar
Ian Hickson committed
472
    expect(
473 474
      const BorderDirectional(top: yellow2) + const BorderDirectional(end: magenta3),
      const BorderDirectional(top: yellow2, end: magenta3),
Ian Hickson's avatar
Ian Hickson committed
475 476
    );
    expect(
477 478
      const BorderDirectional(bottom: magenta3) + const BorderDirectional(bottom: magenta3),
      const BorderDirectional(bottom: magenta6),
Ian Hickson's avatar
Ian Hickson committed
479 480
    );
    expect(
481 482
      const BorderDirectional(start: magenta3, end: yellowNone0) + const BorderDirectional(end: yellow2),
      const BorderDirectional(start: magenta3, end: yellow2),
Ian Hickson's avatar
Ian Hickson committed
483 484 485 486 487 488
    );
    expect(
      const BorderDirectional() + const BorderDirectional(),
      const BorderDirectional(),
    );
    expect(
489
      const BorderDirectional(start: magenta3) + const BorderDirectional(start: yellow2),
Dan Field's avatar
Dan Field committed
490
      isNot(isA<BorderDirectional>()), // see shape_border_test.dart for better tests of this case
Ian Hickson's avatar
Ian Hickson committed
491
    );
492 493
    const BorderDirectional b3 = BorderDirectional(top: magenta3);
    const BorderDirectional b6 = BorderDirectional(top: magenta6);
Ian Hickson's avatar
Ian Hickson committed
494
    expect(b3 + b3, b6);
495 496
    const BorderDirectional b0 = BorderDirectional(top: yellowNone0);
    const BorderDirectional bZ = BorderDirectional();
Ian Hickson's avatar
Ian Hickson committed
497 498 499 500
    expect(b0 + b0, bZ);
    expect(bZ + bZ, bZ);
    expect(b0 + bZ, bZ);
    expect(bZ + b0, bZ);
501
  });
Ian Hickson's avatar
Ian Hickson committed
502 503

  test('BorderDirectional.add', () {
504 505 506 507
    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);
Ian Hickson's avatar
Ian Hickson committed
508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526

    // 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));

527 528 529 530 531 532
    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);
Ian Hickson's avatar
Ian Hickson committed
533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552

    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)}');
553
  });
Ian Hickson's avatar
Ian Hickson committed
554 555

  test('BorderDirectional.scale', () {
556 557 558 559 560 561
    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);
Ian Hickson's avatar
Ian Hickson committed
562
    expect(b3.scale(2.0), b6);
563
    const BorderDirectional bY0 = BorderDirectional(top: yellowNone0);
Ian Hickson's avatar
Ian Hickson committed
564
    expect(bY0.scale(3.0), bY0);
565
    const BorderDirectional bY2 = BorderDirectional(top: yellow2);
Ian Hickson's avatar
Ian Hickson committed
566
    expect(bY2.scale(0.0), bY0);
567
  });
Ian Hickson's avatar
Ian Hickson committed
568 569

  test('BorderDirectional.lerp', () {
570 571 572 573 574 575 576
    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));
Ian Hickson's avatar
Ian Hickson committed
577 578

    expect(BorderDirectional.lerp(null, null, -1.0), null);
579
    expect(BorderDirectional.lerp(directionalWithTop10, null, -1.0), const BorderDirectional(top: BorderSide(width: 20.0)));
Ian Hickson's avatar
Ian Hickson committed
580 581 582 583
    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);
584
    expect(BorderDirectional.lerp(directionalWithTop10, null, 0.0), const BorderDirectional(top: BorderSide(width: 10.0)));
Ian Hickson's avatar
Ian Hickson committed
585 586 587 588
    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);
589 590
    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)));
Ian Hickson's avatar
Ian Hickson committed
591 592 593
    expect(BorderDirectional.lerp(at0, at100, 0.25), at25);

    expect(BorderDirectional.lerp(null, null, 0.75), null);
594 595
    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)));
Ian Hickson's avatar
Ian Hickson committed
596 597 598 599
    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());
600
    expect(BorderDirectional.lerp(null, directionalWithTop10, 1.0), const BorderDirectional(top: BorderSide(width: 10.0)));
Ian Hickson's avatar
Ian Hickson committed
601 602 603 604
    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());
605
    expect(BorderDirectional.lerp(null, directionalWithTop10, 2.0), const BorderDirectional(top: BorderSide(width: 20.0)));
Ian Hickson's avatar
Ian Hickson committed
606 607 608 609 610 611
    expect(BorderDirectional.lerp(at0, at100, 2.0), at200);
  });

  test('BorderDirectional.paint', () {
    expect(
      (Canvas canvas) {
612
        const BorderDirectional(end: BorderSide(width: 10.0, color: Color(0xFF00FF00)))
Dan Field's avatar
Dan Field committed
613
          .paint(canvas, const Rect.fromLTRB(10.0, 20.0, 30.0, 40.0), textDirection: TextDirection.rtl);
Ian Hickson's avatar
Ian Hickson committed
614 615 616 617 618 619
      },
      paints
        ..path(
          includes: <Offset>[const Offset(15.0, 30.0)],
          excludes: <Offset>[const Offset(25.0, 30.0)],
          color: const Color(0xFF00FF00),
620
        ),
Ian Hickson's avatar
Ian Hickson committed
621 622 623
    );
    expect(
      (Canvas canvas) {
624
        const BorderDirectional(end: BorderSide(width: 10.0, color: Color(0xFF00FF00)))
Dan Field's avatar
Dan Field committed
625
          .paint(canvas, const Rect.fromLTRB(10.0, 20.0, 30.0, 40.0), textDirection: TextDirection.ltr);
Ian Hickson's avatar
Ian Hickson committed
626 627 628 629 630 631
      },
      paints
        ..path(
          includes: <Offset>[const Offset(25.0, 30.0)],
          excludes: <Offset>[const Offset(15.0, 30.0)],
          color: const Color(0xFF00FF00),
632
        ),
Ian Hickson's avatar
Ian Hickson committed
633 634 635
    );
    expect(
      (Canvas canvas) {
636
        const BorderDirectional(end: BorderSide(width: 10.0, color: Color(0xFF00FF00)))
Dan Field's avatar
Dan Field committed
637
          .paint(canvas, const Rect.fromLTRB(10.0, 20.0, 30.0, 40.0));
Ian Hickson's avatar
Ian Hickson committed
638
      },
639
      paintsAssertion, // no TextDirection
Ian Hickson's avatar
Ian Hickson committed
640
    );
641
  });
Ian Hickson's avatar
Ian Hickson committed
642 643

  test('BorderDirectional hashCode', () {
644 645 646
    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));
Ian Hickson's avatar
Ian Hickson committed
647 648 649
  });

  test('BoxDecoration.border takes a BorderDirectional', () {
650 651
    const BoxDecoration decoration2 = BoxDecoration(
      border: BorderDirectional(start: BorderSide(width: 2.0)),
Ian Hickson's avatar
Ian Hickson committed
652
    );
653 654
    const BoxDecoration decoration4 = BoxDecoration(
      border: BorderDirectional(start: BorderSide(width: 4.0)),
Ian Hickson's avatar
Ian Hickson committed
655
    );
656 657
    const BoxDecoration decoration6 = BoxDecoration(
      border: BorderDirectional(start: BorderSide(width: 6.0)),
Ian Hickson's avatar
Ian Hickson committed
658 659 660 661 662 663 664
    );
    final BoxPainter painter = decoration2.createBoxPainter();
    expect(
      (Canvas canvas) {
        painter.paint(
          canvas,
          const Offset(30.0, 0.0),
665
          const ImageConfiguration(size: Size(20.0, 20.0), textDirection: TextDirection.rtl),
Ian Hickson's avatar
Ian Hickson committed
666 667 668 669 670 671
        );
      },
      paints
        ..path(
          includes: <Offset>[const Offset(49.0, 10.0)],
          excludes: <Offset>[const Offset(31.0, 10.0)],
672
        ),
Ian Hickson's avatar
Ian Hickson committed
673 674 675 676 677 678
    );
    expect(
      (Canvas canvas) {
        painter.paint(
          canvas,
          const Offset(30.0, 0.0),
679
          const ImageConfiguration(size: Size(20.0, 20.0), textDirection: TextDirection.ltr),
Ian Hickson's avatar
Ian Hickson committed
680 681 682 683 684 685
        );
      },
      paints
        ..path(
          includes: <Offset>[const Offset(31.0, 10.0)],
          excludes: <Offset>[const Offset(49.0, 10.0)],
686
        ),
Ian Hickson's avatar
Ian Hickson committed
687 688 689 690
    );
    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);
691
  });
692
}