xref: /haiku/src/tests/kits/interface/bregion/RegionTestcase.cpp (revision 67bce78b48ed6d01b5a8eef89f5694c372b7e0a1)
1 /*
2 	$Id: RegionTestcase.cpp,v 1.2 2004/03/31 06:53:40 jackburton Exp $
3 
4 	This file implements a base class for all tests of the OpenBeOS
5 	BRegion code.
6 
7 	*/
8 
9 
10 #include "RegionTestcase.h"
11 #include <Region.h>
12 #include <Rect.h>
13 #include <math.h>
14 
15 
16 /*
17  *  Method:  RegionTestcase::RegionTestcase()
18  *   Descr:  This is the constructor for this class.
19  */
20 
21 RegionTestcase::RegionTestcase(std::string name) :
22 	TestCase(name)
23 {
24 	const int numTestRegions = 8;
25 	const int numRectsPerRegion = 3;
26 
27 	float theRegions[numTestRegions][numRectsPerRegion][4] =
28 		{
29 			{
30 				{10.0, 10.0, 50.0, 50.0},
31 				{25.0, 10.0, 75.0, 40.0},
32 				{70.0, 100.0, 90.0, 120.0}
33 			},
34 			{
35 				{15.0, 15.0, 45.0, 45.0},
36 				{30.0, 15.0, 70.0, 35.0},
37 				{75.0, 105.0, 85.0, 115.0}
38 			},
39 			{
40 				{15.0, 15.0, 55.0, 55.0},
41 				{30.0, 15.0, 80.0, 45.0},
42 				{75.0, 105.0, 95.0, 125.0}
43 			},
44 			{
45 				{210.0, 210.0, 250.0, 250.0},
46 				{225.0, 210.0, 275.0, 240.0},
47 				{270.0, 300.0, 290.0, 320.0}
48 			},
49 			{
50 				{-50.0, -50.0, -10.0, -10.0},
51 				{-75.0, -40.0, -25.0, -10.0},
52 				{-90.0, -120.0, -70.0, -100.0}
53 			},
54 			{
55 				{-50.0, -30.0, 100.0, 120.0},
56 				{-140.0, 120.0, 340.0, 905.0},
57 				{-90.0, -120.0, 90.0, 120.0}
58 			},
59 			{
60 				// A test to see if our BRegion can handle non integers
61 				// rects coordinates (as R5 do)
62 				{10.3, 10.8, 50.2, 50.9},
63 				{25.1, 10.7, 75.8, 40.4},
64 				{70.6, 100.6, 90.1, 120.3}
65 			},
66 			{
67 				{15.0, 25.0, 75.0, 80.0},
68 				{30.0, 15.0, 80.0, 45.0},
69 				{60.0, 20.0, 95.0, 225.0}
70 			}
71 		};
72 
73 	listOfRegions.AddItem(new BRegion);
74 	for(int regionNum = 0; regionNum < numTestRegions; regionNum++) {
75 		BRegion *tempRegion = new BRegion;
76 		for(int rectNum = 0; rectNum < numRectsPerRegion; rectNum++) {
77 			tempRegion->Include(BRect(theRegions[regionNum][rectNum][0],
78 			                          theRegions[regionNum][rectNum][1],
79 			                          theRegions[regionNum][rectNum][2],
80 			                          theRegions[regionNum][rectNum][3]));
81 		}
82 		listOfRegions.AddItem(tempRegion);
83 	}
84 }
85 
86 
87 /*
88  *  Method:  RegionTestcase::~RegionTestcase()
89  *   Descr:  This is the destructor for this class.
90  */
91 
92 RegionTestcase::~RegionTestcase()
93 {
94 	while(!listOfRegions.IsEmpty()) {
95 		delete static_cast<BRegion *>(listOfRegions.RemoveItem((long int)0));
96 	}
97 }
98 
99 
100 /*
101  *  Method:  RegionTestcase::GetPointsInRect()
102  *   Descr:  This member function returns an array of BPoints on the edge and
103  *           inside the passed in BRect.  It also returns the number of points
104  *           in the array.
105  */
106 
107 int RegionTestcase::GetPointsInRect(BRect theRect, BPoint **pointArrayPtr)
108 {
109 	*pointArrayPtr = pointArray;
110 	if (!theRect.IsValid()) {
111 		return(0);
112 	}
113 
114 	float xIncrement = (theRect.Width() + 1.0) / (numPointsPerSide - 1);
115 	float yIncrement = (theRect.Height() + 1.0) / (numPointsPerSide - 1);
116 
117 	int numPoints = 0;
118 
119 	for(int i = 0; i < numPointsPerSide; i++) {
120 		float xCoord = theRect.left + (i * xIncrement);
121 		if (i == numPointsPerSide - 1) {
122 			xCoord = theRect.right;
123 		}
124 		for(int j = 0; j < numPointsPerSide; j++) {
125 			float yCoord = theRect.top + (j * yIncrement);
126 			if (j == numPointsPerSide - 1) {
127 				yCoord = theRect.bottom;
128 			}
129 			pointArray[numPoints].Set(floor(xCoord), floor(yCoord));
130 			assert(theRect.Contains(pointArray[numPoints]));
131 			numPoints++;
132 		}
133 	}
134 	return(numPoints);
135 }
136 
137 
138 /*
139  *  Method:  RegionTestcase::CheckFrame()
140  *   Descr:  This member function checks that the BRegion's frame matches
141  *           the regions contents.
142  */
143 
144 void RegionTestcase::CheckFrame(BRegion *theRegion)
145 {
146 	BRect theFrame = theRegion->Frame();
147 	if (theFrame.IsValid()) {
148 		assert(!RegionIsEmpty(theRegion));
149 
150 		BRect testFrame = theRegion->RectAt(0);
151 		assert(theFrame.Contains(testFrame));
152 
153 		for(int i = 1; i < theRegion->CountRects(); i++) {
154 			BRect tempRect = theRegion->RectAt(i);
155 			assert(theFrame.Contains(tempRect));
156 			testFrame = testFrame | tempRect;
157 		}
158 		assert(testFrame == theFrame);
159 	} else {
160 		assert(RegionIsEmpty(theRegion));
161 	}
162 }
163 
164 
165 /*
166  *  Method:  RegionTestcase::RegionsAreEqual()
167  *   Descr:  This member function returns true if the two BRegion's passed
168  *           in are the same, otherwise it returns false.
169  */
170 
171 bool RegionTestcase::RegionsAreEqual(BRegion *regionA, BRegion *regionB)
172 {
173 	bool result = false;
174 
175 	if (regionA->CountRects() == regionB->CountRects()) {
176 		bool gotAMatch = true;
177 		for(int i = 0; i < regionA->CountRects(); i++) {
178 			gotAMatch = false;
179 			for(int j = 0; j < regionB->CountRects(); j++) {
180 				if (regionA->RectAt(i) == regionB->RectAt(j)) {
181 					gotAMatch = true;
182 					break;
183 				}
184 			}
185 			if (!gotAMatch) {
186 				break;
187 			}
188 		}
189 		if (gotAMatch) {
190 			result = true;
191 		}
192 	}
193 
194 	if (!result) {
195 		BRegion tempRegion(*regionA);
196 
197 		tempRegion.Exclude(regionB);
198 		if (RegionIsEmpty(&tempRegion)) {
199 			tempRegion = *regionB;
200 			tempRegion.Exclude(regionA);
201 			if (RegionIsEmpty(&tempRegion)) {
202 				result = true;
203 			}
204 		}
205 	}
206 
207 	if (result) {
208 		assert(regionA->Frame() == regionB->Frame());
209 		if (regionA->CountRects() == 0) {
210 			assert(RegionIsEmpty(regionA));
211 			assert(RegionIsEmpty(regionB));
212 		}
213 	}
214 	return(result);
215 }
216 
217 
218 /*
219  *  Method:  RegionTestcase::RegionsIsEmpty()
220  *   Descr:  This member function returns true if the BRegion passed
221  *           in is an empty region, otherwise it returns false.
222  */
223 
224 bool RegionTestcase::RegionIsEmpty(BRegion *theRegion)
225 {
226 	if (theRegion->CountRects() == 0) {
227 		assert(!theRegion->Frame().IsValid());
228 		return(true);
229 	}
230 	assert(theRegion->Frame().IsValid());
231 	return(false);
232 }
233 
234 
235 /*
236  *  Method:  RegionTestcase::PerformTest()
237  *   Descr:  This member function iterates over the set of BRegion's for
238  *           testing and calls testOneRegion() for each region.  Then it
239  *           calls testTwoRegions() for each pair of regions (including
240  *           when the two regions are the same).
241  */
242 
243 void RegionTestcase::PerformTest(void)
244 {
245 	int numItems = listOfRegions.CountItems();
246 
247 	for(int i = 0; i < numItems; i++) {
248 		BRegion *testRegion = static_cast<BRegion *>(listOfRegions.ItemAt(i));
249 
250 		CheckFrame(testRegion);
251 		testOneRegion(testRegion);
252 	}
253 	for(int i = 0; i < numItems; i++) {
254 		BRegion *testRegionA = static_cast<BRegion *>(listOfRegions.ItemAt(i));
255 
256 		for(int j = 0; j < numItems; j++) {
257 			BRegion *testRegionB = static_cast<BRegion *>(listOfRegions.ItemAt(j));
258 
259 			testTwoRegions(testRegionA, testRegionB);
260 		}
261 	}
262 }
263