• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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