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