1 // Copyright (c) 2006-2008 The Chromium 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
5 #include "base/basictypes.h"
6 #include "base/gfx/rect.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8
9 typedef testing::Test RectTest;
10
TEST(RectTest,Contains)11 TEST(RectTest, Contains) {
12 static const struct ContainsCase {
13 int rect_x;
14 int rect_y;
15 int rect_width;
16 int rect_height;
17 int point_x;
18 int point_y;
19 bool contained;
20 } contains_cases[] = {
21 {0, 0, 10, 10, 0, 0, true},
22 {0, 0, 10, 10, 5, 5, true},
23 {0, 0, 10, 10, 9, 9, true},
24 {0, 0, 10, 10, 5, 10, false},
25 {0, 0, 10, 10, 10, 5, false},
26 {0, 0, 10, 10, -1, -1, false},
27 {0, 0, 10, 10, 50, 50, false},
28 #ifdef NDEBUG
29 {0, 0, -10, -10, 0, 0, false},
30 #endif // NDEBUG
31 };
32 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(contains_cases); ++i) {
33 const ContainsCase& value = contains_cases[i];
34 gfx::Rect rect(value.rect_x, value.rect_y,
35 value.rect_width, value.rect_height);
36 EXPECT_EQ(value.contained, rect.Contains(value.point_x, value.point_y));
37 }
38 }
39
TEST(RectTest,Intersects)40 TEST(RectTest, Intersects) {
41 static const struct {
42 int x1; // rect 1
43 int y1;
44 int w1;
45 int h1;
46 int x2; // rect 2
47 int y2;
48 int w2;
49 int h2;
50 bool intersects;
51 } tests[] = {
52 { 0, 0, 0, 0, 0, 0, 0, 0, false },
53 { 0, 0, 10, 10, 0, 0, 10, 10, true },
54 { 0, 0, 10, 10, 10, 10, 10, 10, false },
55 { 10, 10, 10, 10, 0, 0, 10, 10, false },
56 { 10, 10, 10, 10, 5, 5, 10, 10, true },
57 { 10, 10, 10, 10, 15, 15, 10, 10, true },
58 { 10, 10, 10, 10, 20, 15, 10, 10, false },
59 { 10, 10, 10, 10, 21, 15, 10, 10, false }
60 };
61 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
62 gfx::Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
63 gfx::Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
64 EXPECT_EQ(tests[i].intersects, r1.Intersects(r2));
65 }
66 }
67
TEST(RectTest,Intersect)68 TEST(RectTest, Intersect) {
69 static const struct {
70 int x1; // rect 1
71 int y1;
72 int w1;
73 int h1;
74 int x2; // rect 2
75 int y2;
76 int w2;
77 int h2;
78 int x3; // rect 3: the union of rects 1 and 2
79 int y3;
80 int w3;
81 int h3;
82 } tests[] = {
83 { 0, 0, 0, 0, // zeros
84 0, 0, 0, 0,
85 0, 0, 0, 0 },
86 { 0, 0, 4, 4, // equal
87 0, 0, 4, 4,
88 0, 0, 4, 4 },
89 { 0, 0, 4, 4, // neighboring
90 4, 4, 4, 4,
91 0, 0, 0, 0 },
92 { 0, 0, 4, 4, // overlapping corners
93 2, 2, 4, 4,
94 2, 2, 2, 2 },
95 { 0, 0, 4, 4, // T junction
96 3, 1, 4, 2,
97 3, 1, 1, 2 },
98 { 3, 0, 2, 2, // gap
99 0, 0, 2, 2,
100 0, 0, 0, 0 }
101 };
102 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
103 gfx::Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
104 gfx::Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
105 gfx::Rect r3(tests[i].x3, tests[i].y3, tests[i].w3, tests[i].h3);
106 gfx::Rect ir = r1.Intersect(r2);
107 EXPECT_EQ(r3.x(), ir.x());
108 EXPECT_EQ(r3.y(), ir.y());
109 EXPECT_EQ(r3.width(), ir.width());
110 EXPECT_EQ(r3.height(), ir.height());
111 }
112 }
113
TEST(RectTest,Union)114 TEST(RectTest, Union) {
115 static const struct Test {
116 int x1; // rect 1
117 int y1;
118 int w1;
119 int h1;
120 int x2; // rect 2
121 int y2;
122 int w2;
123 int h2;
124 int x3; // rect 3: the union of rects 1 and 2
125 int y3;
126 int w3;
127 int h3;
128 } tests[] = {
129 { 0, 0, 0, 0,
130 0, 0, 0, 0,
131 0, 0, 0, 0 },
132 { 0, 0, 4, 4,
133 0, 0, 4, 4,
134 0, 0, 4, 4 },
135 { 0, 0, 4, 4,
136 4, 4, 4, 4,
137 0, 0, 8, 8 },
138 { 0, 0, 4, 4,
139 0, 5, 4, 4,
140 0, 0, 4, 9 },
141 { 0, 0, 2, 2,
142 3, 3, 2, 2,
143 0, 0, 5, 5 },
144 { 3, 3, 2, 2, // reverse r1 and r2 from previous test
145 0, 0, 2, 2,
146 0, 0, 5, 5 },
147 { 0, 0, 0, 0, // union with empty rect
148 2, 2, 2, 2,
149 2, 2, 2, 2 }
150 };
151 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
152 gfx::Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
153 gfx::Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
154 gfx::Rect r3(tests[i].x3, tests[i].y3, tests[i].w3, tests[i].h3);
155 gfx::Rect u = r1.Union(r2);
156 EXPECT_EQ(r3.x(), u.x());
157 EXPECT_EQ(r3.y(), u.y());
158 EXPECT_EQ(r3.width(), u.width());
159 EXPECT_EQ(r3.height(), u.height());
160 }
161 }
162
TEST(RectTest,Equals)163 TEST(RectTest, Equals) {
164 ASSERT_TRUE(gfx::Rect(0, 0, 0, 0).Equals(gfx::Rect(0, 0, 0, 0)));
165 ASSERT_TRUE(gfx::Rect(1, 2, 3, 4).Equals(gfx::Rect(1, 2, 3, 4)));
166 ASSERT_FALSE(gfx::Rect(0, 0, 0, 0).Equals(gfx::Rect(0, 0, 0, 1)));
167 ASSERT_FALSE(gfx::Rect(0, 0, 0, 0).Equals(gfx::Rect(0, 0, 1, 0)));
168 ASSERT_FALSE(gfx::Rect(0, 0, 0, 0).Equals(gfx::Rect(0, 1, 0, 0)));
169 ASSERT_FALSE(gfx::Rect(0, 0, 0, 0).Equals(gfx::Rect(1, 0, 0, 0)));
170 }
171
TEST(RectTest,AdjustToFit)172 TEST(RectTest, AdjustToFit) {
173 static const struct Test {
174 int x1; // source
175 int y1;
176 int w1;
177 int h1;
178 int x2; // target
179 int y2;
180 int w2;
181 int h2;
182 int x3; // rect 3: results of invoking AdjustToFit
183 int y3;
184 int w3;
185 int h3;
186 } tests[] = {
187 { 0, 0, 2, 2,
188 0, 0, 2, 2,
189 0, 0, 2, 2 },
190 { 2, 2, 3, 3,
191 0, 0, 4, 4,
192 1, 1, 3, 3 },
193 { -1, -1, 5, 5,
194 0, 0, 4, 4,
195 0, 0, 4, 4 },
196 { 2, 2, 4, 4,
197 0, 0, 3, 3,
198 0, 0, 3, 3 },
199 { 2, 2, 1, 1,
200 0, 0, 3, 3,
201 2, 2, 1, 1 }
202 };
203 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
204 gfx::Rect r1(tests[i].x1, tests[i].y1, tests[i].w1, tests[i].h1);
205 gfx::Rect r2(tests[i].x2, tests[i].y2, tests[i].w2, tests[i].h2);
206 gfx::Rect r3(tests[i].x3, tests[i].y3, tests[i].w3, tests[i].h3);
207 gfx::Rect u(r1.AdjustToFit(r2));
208 EXPECT_EQ(r3.x(), u.x());
209 EXPECT_EQ(r3.y(), u.y());
210 EXPECT_EQ(r3.width(), u.width());
211 EXPECT_EQ(r3.height(), u.height());
212 }
213 }
214
TEST(RectTest,Subtract)215 TEST(RectTest, Subtract) {
216 // Matching
217 EXPECT_TRUE(
218 gfx::Rect(10, 10, 20, 20).Subtract(
219 gfx::Rect(10, 10, 20, 20)).Equals(
220 gfx::Rect(0, 0, 0, 0)));
221
222 // Contains
223 EXPECT_TRUE(
224 gfx::Rect(10, 10, 20, 20).Subtract(
225 gfx::Rect(5, 5, 30, 30)).Equals(
226 gfx::Rect(0, 0, 0, 0)));
227
228 // No intersection
229 EXPECT_TRUE(
230 gfx::Rect(10, 10, 20, 20).Subtract(
231 gfx::Rect(30, 30, 20, 20)).Equals(
232 gfx::Rect(10, 10, 20, 20)));
233
234 // Not a complete intersection in either direction
235 EXPECT_TRUE(
236 gfx::Rect(10, 10, 20, 20).Subtract(
237 gfx::Rect(15, 15, 20, 20)).Equals(
238 gfx::Rect(10, 10, 20, 20)));
239
240 // Complete intersection in the x-direction
241 EXPECT_TRUE(
242 gfx::Rect(10, 10, 20, 20).Subtract(
243 gfx::Rect(10, 15, 20, 20)).Equals(
244 gfx::Rect(10, 10, 20, 5)));
245
246 // Complete intersection in the x-direction
247 EXPECT_TRUE(
248 gfx::Rect(10, 10, 20, 20).Subtract(
249 gfx::Rect(5, 15, 30, 20)).Equals(
250 gfx::Rect(10, 10, 20, 5)));
251
252 // Complete intersection in the x-direction
253 EXPECT_TRUE(
254 gfx::Rect(10, 10, 20, 20).Subtract(
255 gfx::Rect(5, 5, 30, 20)).Equals(
256 gfx::Rect(10, 25, 20, 5)));
257
258 // Complete intersection in the y-direction
259 EXPECT_TRUE(
260 gfx::Rect(10, 10, 20, 20).Subtract(
261 gfx::Rect(10, 10, 10, 30)).Equals(
262 gfx::Rect(20, 10, 10, 20)));
263
264 // Complete intersection in the y-direction
265 EXPECT_TRUE(
266 gfx::Rect(10, 10, 20, 20).Subtract(
267 gfx::Rect(5, 5, 20, 30)).Equals(
268 gfx::Rect(25, 10, 5, 20)));
269 }
270
TEST(RectTest,IsEmpty)271 TEST(RectTest, IsEmpty) {
272 EXPECT_TRUE(gfx::Rect(0, 0, 0, 0).IsEmpty());
273 EXPECT_TRUE(gfx::Rect(0, 0, 0, 0).size().IsEmpty());
274 EXPECT_TRUE(gfx::Rect(0, 0, 10, 0).IsEmpty());
275 EXPECT_TRUE(gfx::Rect(0, 0, 10, 0).size().IsEmpty());
276 EXPECT_TRUE(gfx::Rect(0, 0, 0, 10).IsEmpty());
277 EXPECT_TRUE(gfx::Rect(0, 0, 0, 10).size().IsEmpty());
278 EXPECT_FALSE(gfx::Rect(0, 0, 10, 10).IsEmpty());
279 EXPECT_FALSE(gfx::Rect(0, 0, 10, 10).size().IsEmpty());
280 }
281
TEST(RectTest,SharesEdgeWith)282 TEST(RectTest, SharesEdgeWith) {
283 gfx::Rect r(2, 3, 4, 5);
284
285 // Must be non-overlapping
286 EXPECT_FALSE(r.SharesEdgeWith(r));
287
288 gfx::Rect just_above(2, 1, 4, 2);
289 gfx::Rect just_below(2, 8, 4, 2);
290 gfx::Rect just_left(0, 3, 2, 5);
291 gfx::Rect just_right(6, 3, 2, 5);
292
293 EXPECT_TRUE(r.SharesEdgeWith(just_above));
294 EXPECT_TRUE(r.SharesEdgeWith(just_below));
295 EXPECT_TRUE(r.SharesEdgeWith(just_left));
296 EXPECT_TRUE(r.SharesEdgeWith(just_right));
297
298 // Wrong placement
299 gfx::Rect same_height_no_edge(0, 0, 1, 5);
300 gfx::Rect same_width_no_edge(0, 0, 4, 1);
301
302 EXPECT_FALSE(r.SharesEdgeWith(same_height_no_edge));
303 EXPECT_FALSE(r.SharesEdgeWith(same_width_no_edge));
304
305 gfx::Rect just_above_no_edge(2, 1, 5, 2); // too wide
306 gfx::Rect just_below_no_edge(2, 8, 3, 2); // too narrow
307 gfx::Rect just_left_no_edge(0, 3, 2, 6); // too tall
308 gfx::Rect just_right_no_edge(6, 3, 2, 4); // too short
309
310 EXPECT_FALSE(r.SharesEdgeWith(just_above_no_edge));
311 EXPECT_FALSE(r.SharesEdgeWith(just_below_no_edge));
312 EXPECT_FALSE(r.SharesEdgeWith(just_left_no_edge));
313 EXPECT_FALSE(r.SharesEdgeWith(just_right_no_edge));
314 }
315