1// Copyright 2013 The Flutter Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5import 'dart:math' as math show sqrt; 6import 'dart:math' show pi; 7import 'dart:ui'; 8 9import 'package:test/test.dart'; 10 11void main() { 12 group('Offset', () { 13 test('OffsetBase.>=', () { 14 expect(const Offset(0, 0) >= const Offset(0, -1), true); 15 expect(const Offset(0, 0) >= const Offset(-1, 0), true); 16 expect(const Offset(0, 0) >= const Offset(-1, -1), true); 17 expect(const Offset(0, 0) >= const Offset(0, 0), true); 18 expect(const Offset(0, 0) >= const Offset(0, double.nan), false); 19 expect(const Offset(0, 0) >= const Offset(double.nan, 0), false); 20 expect(const Offset(0, 0) >= const Offset(10, -10), false); 21 }); 22 23 test('OffsetBase.<=', () { 24 expect(const Offset(0, 0) <= const Offset(0, 1), true); 25 expect(const Offset(0, 0) <= const Offset(1, 0), true); 26 expect(const Offset(0, 0) <= const Offset(0, 0), true); 27 expect(const Offset(0, 0) <= const Offset(0, double.nan), false); 28 expect(const Offset(0, 0) <= const Offset(double.nan, 0), false); 29 expect(const Offset(0, 0) <= const Offset(10, -10), false); 30 }); 31 32 test('OffsetBase.>', () { 33 expect(const Offset(0, 0) > const Offset(-1, -1), true); 34 expect(const Offset(0, 0) > const Offset(0, -1), false); 35 expect(const Offset(0, 0) > const Offset(-1, 0), false); 36 expect(const Offset(0, 0) > const Offset(double.nan, -1), false); 37 }); 38 39 test('OffsetBase.<', () { 40 expect(const Offset(0, 0) < const Offset(1, 1), true); 41 expect(const Offset(0, 0) < const Offset(0, 1), false); 42 expect(const Offset(0, 0) < const Offset(1, 0), false); 43 expect(const Offset(0, 0) < const Offset(double.nan, 1), false); 44 }); 45 46 test('OffsetBase.==', () { 47 expect(const Offset(0, 0), equals(const Offset(0, 0))); 48 expect(const Offset(0, 0), isNot(equals(const Offset(1, 0)))); 49 expect(const Offset(0, 0), isNot(equals(const Offset(0, 1)))); 50 }); 51 52 test('Offset.direction', () { 53 expect(const Offset(0.0, 0.0).direction, 0.0); 54 expect(const Offset(0.0, 1.0).direction, pi / 2.0); 55 expect(const Offset(0.0, -1.0).direction, -pi / 2.0); 56 expect(const Offset(1.0, 0.0).direction, 0.0); 57 expect(const Offset(1.0, 1.0).direction, pi / 4.0); 58 expect(const Offset(1.0, -1.0).direction, -pi / 4.0); 59 expect(const Offset(-1.0, 0.0).direction, pi); 60 expect(const Offset(-1.0, 1.0).direction, pi * 3.0 / 4.0); 61 expect(const Offset(-1.0, -1.0).direction, -pi * 3.0 / 4.0); 62 }); 63 64 test('Offset.fromDirection', () { 65 expect(Offset.fromDirection(0.0, 0.0), const Offset(0.0, 0.0)); 66 expect(Offset.fromDirection(pi / 2.0).dx, closeTo(0.0, 1e-12)); // aah, floating point math. i love you so. 67 expect(Offset.fromDirection(pi / 2.0).dy, 1.0); 68 expect(Offset.fromDirection(-pi / 2.0).dx, closeTo(0.0, 1e-12)); 69 expect(Offset.fromDirection(-pi / 2.0).dy, -1.0); 70 expect(Offset.fromDirection(0.0), const Offset(1.0, 0.0)); 71 expect(Offset.fromDirection(pi / 4.0).dx, closeTo(1.0 / math.sqrt(2.0), 1e-12)); 72 expect(Offset.fromDirection(pi / 4.0).dy, closeTo(1.0 / math.sqrt(2.0), 1e-12)); 73 expect(Offset.fromDirection(-pi / 4.0).dx, closeTo(1.0 / math.sqrt(2.0), 1e-12)); 74 expect(Offset.fromDirection(-pi / 4.0).dy, closeTo(-1.0 / math.sqrt(2.0), 1e-12)); 75 expect(Offset.fromDirection(pi).dx, -1.0); 76 expect(Offset.fromDirection(pi).dy, closeTo(0.0, 1e-12)); 77 expect(Offset.fromDirection(pi * 3.0 / 4.0).dx, closeTo(-1.0 / math.sqrt(2.0), 1e-12)); 78 expect(Offset.fromDirection(pi * 3.0 / 4.0).dy, closeTo(1.0 / math.sqrt(2.0), 1e-12)); 79 expect(Offset.fromDirection(-pi * 3.0 / 4.0).dx, closeTo(-1.0 / math.sqrt(2.0), 1e-12)); 80 expect(Offset.fromDirection(-pi * 3.0 / 4.0).dy, closeTo(-1.0 / math.sqrt(2.0), 1e-12)); 81 expect(Offset.fromDirection(0.0, 2.0), const Offset(2.0, 0.0)); 82 expect(Offset.fromDirection(pi / 6, 2.0).dx, closeTo(math.sqrt(3.0), 1e-12)); 83 expect(Offset.fromDirection(pi / 6, 2.0).dy, closeTo(1.0, 1e-12)); 84 }); 85 }); 86 87 group('Size', () { 88 test('Size created from doubles', () { 89 const Size size = Size(5.0, 7.0); 90 expect(size.width, equals(5.0)); 91 expect(size.height, equals(7.0)); 92 expect(size.shortestSide, equals(5.0)); 93 expect(size.longestSide, equals(7.0)); 94 }); 95 96 test('Size.aspectRatio', () { 97 expect(const Size(0.0, 0.0).aspectRatio, 0.0); 98 expect(const Size(-0.0, 0.0).aspectRatio, 0.0); 99 expect(const Size(0.0, -0.0).aspectRatio, 0.0); 100 expect(const Size(-0.0, -0.0).aspectRatio, 0.0); 101 expect(const Size(0.0, 1.0).aspectRatio, 0.0); 102 expect(const Size(0.0, -1.0).aspectRatio, -0.0); 103 expect(const Size(1.0, 0.0).aspectRatio, double.infinity); 104 expect(const Size(1.0, 1.0).aspectRatio, 1.0); 105 expect(const Size(1.0, -1.0).aspectRatio, -1.0); 106 expect(const Size(-1.0, 0.0).aspectRatio, -double.infinity); 107 expect(const Size(-1.0, 1.0).aspectRatio, -1.0); 108 expect(const Size(-1.0, -1.0).aspectRatio, 1.0); 109 expect(const Size(3.0, 4.0).aspectRatio, 3.0 / 4.0); 110 }); 111 }); 112 113 group('Rect', () { 114 test('toString test', () { 115 const Rect r = Rect.fromLTRB(1.0, 3.0, 5.0, 7.0); 116 expect(r.toString(), 'Rect.fromLTRB(1.0, 3.0, 5.0, 7.0)'); 117 }); 118 119 test('Rect accessors', () { 120 const Rect r = Rect.fromLTRB(1.0, 3.0, 5.0, 7.0); 121 expect(r.left, equals(1.0)); 122 expect(r.top, equals(3.0)); 123 expect(r.right, equals(5.0)); 124 expect(r.bottom, equals(7.0)); 125 }); 126 127 test('Rect.fromCenter', () { 128 Rect rect = Rect.fromCenter(center: const Offset(1.0, 3.0), width: 5.0, height: 7.0); 129 expect(rect.left, -1.5); 130 expect(rect.top, -0.5); 131 expect(rect.right, 3.5); 132 expect(rect.bottom, 6.5); 133 134 rect = Rect.fromCenter(center: const Offset(0.0, 0.0), width: 0.0, height: 0.0); 135 expect(rect.left, 0.0); 136 expect(rect.top, 0.0); 137 expect(rect.right, 0.0); 138 expect(rect.bottom, 0.0); 139 140 rect = Rect.fromCenter(center: const Offset(double.nan, 0.0), width: 0.0, height: 0.0); 141 expect(rect.left, isNaN); 142 expect(rect.top, 0.0); 143 expect(rect.right, isNaN); 144 expect(rect.bottom, 0.0); 145 146 rect = Rect.fromCenter(center: const Offset(0.0, double.nan), width: 0.0, height: 0.0); 147 expect(rect.left, 0.0); 148 expect(rect.top, isNaN); 149 expect(rect.right, 0.0); 150 expect(rect.bottom, isNaN); 151 }); 152 153 test('Rect created by width and height', () { 154 const Rect r = Rect.fromLTWH(1.0, 3.0, 5.0, 7.0); 155 expect(r.left, equals(1.0)); 156 expect(r.top, equals(3.0)); 157 expect(r.right, equals(6.0)); 158 expect(r.bottom, equals(10.0)); 159 expect(r.shortestSide, equals(5.0)); 160 expect(r.longestSide, equals(7.0)); 161 }); 162 163 test('Rect intersection', () { 164 const Rect r1 = Rect.fromLTRB(0.0, 0.0, 100.0, 100.0); 165 const Rect r2 = Rect.fromLTRB(50.0, 50.0, 200.0, 200.0); 166 final Rect r3 = r1.intersect(r2); 167 expect(r3.left, equals(50.0)); 168 expect(r3.top, equals(50.0)); 169 expect(r3.right, equals(100.0)); 170 expect(r3.bottom, equals(100.0)); 171 final Rect r4 = r2.intersect(r1); 172 expect(r4, equals(r3)); 173 }); 174 175 test('Rect expandToInclude overlapping rects', () { 176 const Rect r1 = Rect.fromLTRB(0.0, 0.0, 100.0, 100.0); 177 const Rect r2 = Rect.fromLTRB(50.0, 50.0, 200.0, 200.0); 178 final Rect r3 = r1.expandToInclude(r2); 179 expect(r3.left, equals(0.0)); 180 expect(r3.top, equals(0.0)); 181 expect(r3.right, equals(200.0)); 182 expect(r3.bottom, equals(200.0)); 183 184 final Rect r4 = r2.expandToInclude(r1); 185 expect(r4, equals(r3)); 186 }); 187 188 test('Rect expandToInclude crossing rects', () { 189 const Rect r1 = Rect.fromLTRB(50.0, 0.0, 50.0, 200.0); 190 const Rect r2 = Rect.fromLTRB(0.0, 50.0, 200.0, 50.0); 191 final Rect r3 = r1.expandToInclude(r2); 192 expect(r3.left, equals(0.0)); 193 expect(r3.top, equals(0.0)); 194 expect(r3.right, equals(200.0)); 195 expect(r3.bottom, equals(200.0)); 196 197 final Rect r4 = r2.expandToInclude(r1); 198 expect(r4, equals(r3)); 199 }); 200 }); 201 202 group('RRect', () { 203 test('RRect.fromRectXY', () { 204 const Rect baseRect = Rect.fromLTWH(1.0, 3.0, 5.0, 7.0); 205 final RRect r = RRect.fromRectXY(baseRect, 1.0, 1.0); 206 expect(r.left, equals(1.0)); 207 expect(r.top, equals(3.0)); 208 expect(r.right, equals(6.0)); 209 expect(r.bottom, equals(10.0)); 210 expect(r.shortestSide, equals(5.0)); 211 expect(r.longestSide, equals(7.0)); 212 }); 213 214 test('RRect.contains()', () { 215 final RRect rrect = RRect.fromRectAndCorners( 216 const Rect.fromLTRB(1.0, 1.0, 2.0, 2.0), 217 topLeft: const Radius.circular(0.5), 218 topRight: const Radius.circular(0.25), 219 bottomRight: const Radius.elliptical(0.25, 0.75), 220 bottomLeft: Radius.zero, 221 ); 222 223 expect(rrect.contains(const Offset(1.0, 1.0)), isFalse); 224 expect(rrect.contains(const Offset(1.1, 1.1)), isFalse); 225 expect(rrect.contains(const Offset(1.15, 1.15)), isTrue); 226 expect(rrect.contains(const Offset(2.0, 1.0)), isFalse); 227 expect(rrect.contains(const Offset(1.93, 1.07)), isFalse); 228 expect(rrect.contains(const Offset(1.97, 1.7)), isFalse); 229 expect(rrect.contains(const Offset(1.7, 1.97)), isTrue); 230 expect(rrect.contains(const Offset(1.0, 1.99)), isTrue); 231 }); 232 233 test('RRect.contains() large radii', () { 234 final RRect rrect = RRect.fromRectAndCorners( 235 const Rect.fromLTRB(1.0, 1.0, 2.0, 2.0), 236 topLeft: const Radius.circular(5000.0), 237 topRight: const Radius.circular(2500.0), 238 bottomRight: const Radius.elliptical(2500.0, 7500.0), 239 bottomLeft: Radius.zero, 240 ); 241 242 expect(rrect.contains(const Offset(1.0, 1.0)), isFalse); 243 expect(rrect.contains(const Offset(1.1, 1.1)), isFalse); 244 expect(rrect.contains(const Offset(1.15, 1.15)), isTrue); 245 expect(rrect.contains(const Offset(2.0, 1.0)), isFalse); 246 expect(rrect.contains(const Offset(1.93, 1.07)), isFalse); 247 expect(rrect.contains(const Offset(1.97, 1.7)), isFalse); 248 expect(rrect.contains(const Offset(1.7, 1.97)), isTrue); 249 expect(rrect.contains(const Offset(1.0, 1.99)), isTrue); 250 }); 251 252 test('RRect.scaleRadii() properly constrained radii should remain unchanged', () { 253 final RRect rrect = RRect.fromRectAndCorners( 254 const Rect.fromLTRB(1.0, 1.0, 2.0, 2.0), 255 topLeft: const Radius.circular(0.5), 256 topRight: const Radius.circular(0.25), 257 bottomRight: const Radius.elliptical(0.25, 0.75), 258 bottomLeft: Radius.zero, 259 ).scaleRadii(); 260 261 // check sides 262 expect(rrect.left, 1.0); 263 expect(rrect.top, 1.0); 264 expect(rrect.right, 2.0); 265 expect(rrect.bottom, 2.0); 266 267 // check corner radii 268 expect(rrect.tlRadiusX, 0.5); 269 expect(rrect.tlRadiusY, 0.5); 270 expect(rrect.trRadiusX, 0.25); 271 expect(rrect.trRadiusY, 0.25); 272 expect(rrect.blRadiusX, 0.0); 273 expect(rrect.blRadiusY, 0.0); 274 expect(rrect.brRadiusX, 0.25); 275 expect(rrect.brRadiusY, 0.75); 276 }); 277 278 test('RRect.scaleRadii() sum of radii that exceed side length should properly scale', () { 279 final RRect rrect = RRect.fromRectAndCorners( 280 const Rect.fromLTRB(1.0, 1.0, 2.0, 2.0), 281 topLeft: const Radius.circular(5000.0), 282 topRight: const Radius.circular(2500.0), 283 bottomRight: const Radius.elliptical(2500.0, 7500.0), 284 bottomLeft: Radius.zero, 285 ).scaleRadii(); 286 287 // check sides 288 expect(rrect.left, 1.0); 289 expect(rrect.top, 1.0); 290 expect(rrect.right, 2.0); 291 expect(rrect.bottom, 2.0); 292 293 // check corner radii 294 expect(rrect.tlRadiusX, 0.5); 295 expect(rrect.tlRadiusY, 0.5); 296 expect(rrect.trRadiusX, 0.25); 297 expect(rrect.trRadiusY, 0.25); 298 expect(rrect.blRadiusX, 0.0); 299 expect(rrect.blRadiusY, 0.0); 300 expect(rrect.brRadiusX, 0.25); 301 expect(rrect.brRadiusY, 0.75); 302 }); 303 }); 304} 305