Bug 578761: PIC for JSOP_GETELEM. (r=dvander)
[mozilla-central.git] / gfx / tests / TestRect.cpp
blob8406b0f4430cc9ff8be83063dcf39c8db55ec8ae
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either of the GNU General Public License Version 2 or later (the "GPL"),
26 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 #include "TestHarness.h"
40 #include "nsRect.h"
41 #ifdef XP_WIN
42 #include <windows.h>
43 #endif
45 template <class RectType>
46 static PRBool
47 TestConstructors()
49 // Create a rectangle
50 RectType rect1(10, 20, 30, 40);
52 // Make sure the rectangle was properly initialized
53 if ((rect1.x != 10) || (rect1.y != 20) ||
54 (rect1.width != 30) || (rect1.height != 40)) {
55 fail("[1] Make sure the rectangle was properly initialized with constructor");
56 return PR_FALSE;
59 // Create a second rect using the copy constructor
60 RectType rect2(rect1);
62 // Make sure the rectangle was properly initialized
63 if ((rect2.x != rect1.x) || (rect2.y != rect1.y) ||
64 (rect2.width != rect1.width) || (rect2.height != rect1.height)) {
65 fail("[2] Make sure the rectangle was properly initialized with copy constructor");
66 return PR_FALSE;
69 passed("TestConstructors");
70 return PR_TRUE;
73 template <class RectType>
74 static PRBool
75 TestEqualityOperator()
77 RectType rect1(10, 20, 30, 40);
78 RectType rect2(rect1);
80 // Test the equality operator
81 if (!(rect1 == rect2)) {
82 fail("[1] Test the equality operator");
83 return PR_FALSE;
86 // Test the inequality operator
87 if (rect1 != rect2) {
88 fail("[2] Test the inequality operator");
89 return PR_FALSE;
92 // Make sure that two empty rects are equal
93 rect1.Empty();
94 rect2.Empty();
95 if (!(rect1 == rect2)) {
96 fail("[3] Make sure that two empty rects are equal");
97 return PR_FALSE;
100 passed("TestEqualityOperator");
101 return PR_TRUE;
104 template <class RectType>
105 static PRBool
106 TestContainment()
108 RectType rect1(10, 10, 50, 50);
110 // Test the point containment methods
113 // Basic test of a point in the middle of the rect
114 if (!rect1.Contains(rect1.x + rect1.width/2, rect1.y + rect1.height/2)) {
115 fail("[1] Basic test of a point in the middle of the rect");
116 return PR_FALSE;
119 // Test against a point at the left/top edges
120 if (!rect1.Contains(rect1.x, rect1.y)) {
121 fail("[2] Test against a point at the left/top edges");
122 return PR_FALSE;
125 // Test against a point at the right/bottom extents
126 if (rect1.Contains(rect1.XMost(), rect1.YMost())) {
127 fail("[3] Test against a point at the right/bottom extents");
128 return PR_FALSE;
131 // Test the rect containment methods
133 RectType rect2(rect1);
135 // Test against a rect that's the same as rect1
136 if (!rect1.Contains(rect2)) {
137 fail("[4] Test against a rect that's the same as rect1");
138 return PR_FALSE;
141 // Test against a rect whose left edge (only) is outside of rect1
142 rect2.x--;
143 if (rect1.Contains(rect2)) {
144 fail("[5] Test against a rect whose left edge (only) is outside of rect1");
145 return PR_FALSE;
147 rect2.x++;
149 // Test against a rect whose top edge (only) is outside of rect1
150 rect2.y--;
151 if (rect1.Contains(rect2)) {
152 fail("[6] Test against a rect whose top edge (only) is outside of rect1");
153 return PR_FALSE;
155 rect2.y++;
157 // Test against a rect whose right edge (only) is outside of rect1
158 rect2.x++;
159 if (rect1.Contains(rect2)) {
160 fail("[7] Test against a rect whose right edge (only) is outside of rect1");
161 return PR_FALSE;
163 rect2.x--;
165 // Test against a rect whose bottom edge (only) is outside of rect1
166 rect2.y++;
167 if (rect1.Contains(rect2)) {
168 fail("[8] Test against a rect whose bottom edge (only) is outside of rect1");
169 return PR_FALSE;
171 rect2.y--;
173 passed("TestContainment");
174 return PR_TRUE;
177 // Test the method that returns a boolean result but doesn't return a
178 // a rectangle
179 template <class RectType>
180 static PRBool
181 TestIntersects()
183 RectType rect1(10, 10, 50, 50);
184 RectType rect2(rect1);
186 // Test against a rect that's the same as rect1
187 if (!rect1.Intersects(rect2)) {
188 fail("[1] Test against a rect that's the same as rect1");
189 return PR_FALSE;
192 // Test against a rect that's enclosed by rect1
193 rect2.Inflate(-1, -1);
194 if (!rect1.Contains(rect2) || !rect1.Intersects(rect2)) {
195 fail("[2] Test against a rect that's enclosed by rect1");
196 return PR_FALSE;
198 rect2.Inflate(1, 1);
200 // Make sure inflate and deflate worked correctly
201 if (rect1 != rect2) {
202 fail("[3] Make sure inflate and deflate worked correctly");
203 return PR_FALSE;
206 // Test against a rect that overlaps the left edge of rect1
207 rect2.x--;
208 if (!rect1.Intersects(rect2)) {
209 fail("[4] Test against a rect that overlaps the left edge of rect1");
210 return PR_FALSE;
212 rect2.x++;
214 // Test against a rect that's outside of rect1 on the left
215 rect2.x -= rect2.width;
216 if (rect1.Intersects(rect2)) {
217 fail("[5] Test against a rect that's outside of rect1 on the left");
218 return PR_FALSE;
220 rect2.x += rect2.width;
222 // Test against a rect that overlaps the top edge of rect1
223 rect2.y--;
224 if (!rect1.Intersects(rect2)) {
225 fail("[6] Test against a rect that overlaps the top edge of rect1");
226 return PR_FALSE;
228 rect2.y++;
230 // Test against a rect that's outside of rect1 on the top
231 rect2.y -= rect2.height;
232 if (rect1.Intersects(rect2)) {
233 fail("[7] Test against a rect that's outside of rect1 on the top");
234 return PR_FALSE;
236 rect2.y += rect2.height;
238 // Test against a rect that overlaps the right edge of rect1
239 rect2.x++;
240 if (!rect1.Intersects(rect2)) {
241 fail("[8] Test against a rect that overlaps the right edge of rect1");
242 return PR_FALSE;
244 rect2.x--;
246 // Test against a rect that's outside of rect1 on the right
247 rect2.x += rect2.width;
248 if (rect1.Intersects(rect2)) {
249 fail("[9] Test against a rect that's outside of rect1 on the right");
250 return PR_FALSE;
252 rect2.x -= rect2.width;
254 // Test against a rect that overlaps the bottom edge of rect1
255 rect2.y++;
256 if (!rect1.Intersects(rect2)) {
257 fail("[10] Test against a rect that overlaps the bottom edge of rect1");
258 return PR_FALSE;
260 rect2.y--;
262 // Test against a rect that's outside of rect1 on the bottom
263 rect2.y += rect2.height;
264 if (rect1.Intersects(rect2)) {
265 fail("[11] Test against a rect that's outside of rect1 on the bottom");
266 return PR_FALSE;
268 rect2.y -= rect2.height;
270 passed("TestIntersects");
271 return PR_TRUE;
274 // Test the method that returns a boolean result and an intersection rect
275 template <class RectType>
276 static PRBool
277 TestIntersection()
279 RectType rect1(10, 10, 50, 50);
280 RectType rect2(rect1);
281 RectType dest;
283 // Test against a rect that's the same as rect1
284 if (!dest.IntersectRect(rect1, rect2) || (dest != rect1)) {
285 fail("[1] Test against a rect that's the same as rect1");
286 return PR_FALSE;
289 // Test against a rect that's enclosed by rect1
290 rect2.Inflate(-1, -1);
291 if (!dest.IntersectRect(rect1, rect2) || (dest != rect2)) {
292 fail("[2] Test against a rect that's enclosed by rect1");
293 return PR_FALSE;
295 rect2.Inflate(1, 1);
297 // Test against a rect that overlaps the left edge of rect1
298 rect2.x--;
299 if (!dest.IntersectRect(rect1, rect2) ||
300 (dest != RectType(rect1.x, rect1.y, rect1.width - 1, rect1.height))) {
301 fail("[3] Test against a rect that overlaps the left edge of rect1");
302 return PR_FALSE;
304 rect2.x++;
306 // Test against a rect that's outside of rect1 on the left
307 rect2.x -= rect2.width;
308 if (dest.IntersectRect(rect1, rect2)) {
309 fail("[4] Test against a rect that's outside of rect1 on the left");
310 return PR_FALSE;
312 // Make sure an empty rect is returned
313 if (!dest.IsEmpty()) {
314 fail("[4] Make sure an empty rect is returned");
315 return PR_FALSE;
317 rect2.x += rect2.width;
319 // Test against a rect that overlaps the top edge of rect1
320 rect2.y--;
321 if (!dest.IntersectRect(rect1, rect2) ||
322 (dest != RectType(rect1.x, rect1.y, rect1.width, rect1.height - 1))) {
323 fail("[5] Test against a rect that overlaps the top edge of rect1");
324 return PR_FALSE;
326 rect2.y++;
328 // Test against a rect that's outside of rect1 on the top
329 rect2.y -= rect2.height;
330 if (dest.IntersectRect(rect1, rect2)) {
331 fail("[6] Test against a rect that's outside of rect1 on the top");
332 return PR_FALSE;
334 // Make sure an empty rect is returned
335 if (!dest.IsEmpty()) {
336 fail("[6] Make sure an empty rect is returned");
337 return PR_FALSE;
339 rect2.y += rect2.height;
341 // Test against a rect that overlaps the right edge of rect1
342 rect2.x++;
343 if (!dest.IntersectRect(rect1, rect2) ||
344 (dest != RectType(rect1.x + 1, rect1.y, rect1.width - 1, rect1.height))) {
345 fail("[7] Test against a rect that overlaps the right edge of rect1");
346 return PR_FALSE;
348 rect2.x--;
350 // Test against a rect that's outside of rect1 on the right
351 rect2.x += rect2.width;
352 if (dest.IntersectRect(rect1, rect2)) {
353 fail("[8] Test against a rect that's outside of rect1 on the right");
354 return PR_FALSE;
356 // Make sure an empty rect is returned
357 if (!dest.IsEmpty()) {
358 fail("[8] Make sure an empty rect is returned");
359 return PR_FALSE;
361 rect2.x -= rect2.width;
363 // Test against a rect that overlaps the bottom edge of rect1
364 rect2.y++;
365 if (!dest.IntersectRect(rect1, rect2) ||
366 (dest != RectType(rect1.x, rect1.y + 1, rect1.width, rect1.height - 1))) {
367 fail("[9] Test against a rect that overlaps the bottom edge of rect1");
368 return PR_FALSE;
370 rect2.y--;
372 // Test against a rect that's outside of rect1 on the bottom
373 rect2.y += rect2.height;
374 if (dest.IntersectRect(rect1, rect2)) {
375 fail("[10] Test against a rect that's outside of rect1 on the bottom");
376 return PR_FALSE;
378 // Make sure an empty rect is returned
379 if (!dest.IsEmpty()) {
380 fail("[10] Make sure an empty rect is returned");
381 return PR_FALSE;
383 rect2.y -= rect2.height;
385 // Test against a rect with zero width or height
386 rect1.SetRect(100, 100, 100, 100);
387 rect2.SetRect(150, 100, 0, 100);
388 if (dest.IntersectRect(rect1, rect2) || !dest.IsEmpty()) {
389 fail("[11] Intersection of rects with zero width or height should be empty");
390 return PR_FALSE;
393 // Tests against a rect with negative width or height
396 // Test against a rect with negative width
397 rect1.SetRect(100, 100, 100, 100);
398 rect2.SetRect(100, 100, -100, 100);
399 if (dest.IntersectRect(rect1, rect2) || !dest.IsEmpty()) {
400 fail("[12] Intersection of rects with negative width or height should be empty");
401 return PR_FALSE;
404 // Those two rects exactly overlap in some way...
405 // but we still want to return an empty rect
406 rect1.SetRect(100, 100, 100, 100);
407 rect2.SetRect(200, 200, -100, -100);
408 if (dest.IntersectRect(rect1, rect2) || !dest.IsEmpty()) {
409 fail("[13] Intersection of rects with negative width or height should be empty");
410 return PR_FALSE;
413 // Test against two identical rects with negative height
414 rect1.SetRect(100, 100, 100, -100);
415 rect2.SetRect(100, 100, 100, -100);
416 if (dest.IntersectRect(rect1, rect2) || !dest.IsEmpty()) {
417 fail("[14] Intersection of rects with negative width or height should be empty");
418 return PR_FALSE;
421 passed("TestIntersection");
422 return PR_TRUE;
425 template <class RectType>
426 static PRBool
427 TestUnion()
429 RectType rect1;
430 RectType rect2(10, 10, 50, 50);
431 RectType dest;
433 // Check the case where the receiver is an empty rect
434 rect1.Empty();
435 if (!dest.UnionRect(rect1, rect2) || (dest != rect2)) {
436 fail("[1] Check the case where the receiver is an empty rect");
437 return PR_FALSE;
440 // Check the case where the source rect is an empty rect
441 rect1 = rect2;
442 rect2.Empty();
443 if (!dest.UnionRect(rect1, rect2) || (dest != rect1)) {
444 fail("[2] Check the case where the source rect is an empty rect");
445 return PR_FALSE;
448 // Test the case where both rects are empty
449 rect1.Empty();
450 rect2.Empty();
451 if (dest.UnionRect(rect1, rect2)) {
452 fail("[3] Test the case where both rects are empty");
453 return PR_FALSE;
456 // Test union case where the two rects don't overlap at all
457 rect1.SetRect(10, 10, 50, 50);
458 rect2.SetRect(100, 100, 50, 50);
459 if (!dest.UnionRect(rect1, rect2) ||
460 (dest != RectType(rect1.x, rect1.y, rect2.XMost() - rect1.x, rect2.YMost() - rect1.y))) {
461 fail("[4] Test union case where the two rects don't overlap at all");
462 return PR_FALSE;
465 // Test union case where the two rects overlap
466 rect1.SetRect(30, 30, 50, 50);
467 rect2.SetRect(10, 10, 50, 50);
468 if (!dest.UnionRect(rect1, rect2) ||
469 (dest != RectType(rect2.x, rect2.y, rect1.XMost() - rect2.x, rect1.YMost() - rect2.y))) {
470 fail("[5] Test union case where the two rects overlap");
471 return PR_FALSE;
474 passed("TestUnion");
475 return PR_TRUE;
478 int main(int argc, char** argv)
480 ScopedXPCOM xpcom("TestRect");
481 if (xpcom.failed())
482 return -1;
484 int rv = 0;
486 //-----------------------
487 // Test nsRect
489 printf("===== nsRect tests =====\n");
491 if (!TestConstructors<nsRect>())
492 rv = -1;
494 if (!TestEqualityOperator<nsRect>())
495 rv = -1;
497 if (!TestContainment<nsRect>())
498 rv = -1;
500 if (!TestIntersects<nsRect>())
501 rv = -1;
503 if (!TestIntersection<nsRect>())
504 rv = -1;
506 if (!TestUnion<nsRect>())
507 rv = -1;
509 //-----------------------
510 // Test nsIntRect
512 printf("===== nsIntRect tests =====\n");
514 if (!TestConstructors<nsIntRect>())
515 rv = -1;
517 if (!TestEqualityOperator<nsIntRect>())
518 rv = -1;
520 if (!TestContainment<nsIntRect>())
521 rv = -1;
523 if (!TestIntersects<nsIntRect>())
524 rv = -1;
526 if (!TestIntersection<nsIntRect>())
527 rv = -1;
529 if (!TestUnion<nsIntRect>())
530 rv = -1;
532 return rv;