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