1 // TranslatorTestAddOn.cpp 2 3 #include <stdio.h> 4 #include <Translator.h> 5 #include <OS.h> 6 #include "TranslatorTestAddOn.h" 7 8 // ##### Include headers for your tests here ##### 9 #include "bmptranslator/BMPTranslatorTest.h" 10 #include "pngtranslator/PNGTranslatorTest.h" 11 #include "stxttranslator/STXTTranslatorTest.h" 12 #include "tgatranslator/TGATranslatorTest.h" 13 #include "tifftranslator/TIFFTranslatorTest.h" 14 15 BTestSuite * 16 getTestSuite() 17 { 18 BTestSuite *suite = new BTestSuite("Translators"); 19 20 // ##### Add test suites here ##### 21 suite->addTest("BMPTranslator", BMPTranslatorTest::Suite()); 22 suite->addTest("PNGTranslator", PNGTranslatorTest::Suite()); 23 suite->addTest("STXTTranslator", STXTTranslatorTest::Suite()); 24 suite->addTest("TGATranslator", TGATranslatorTest::Suite()); 25 suite->addTest("TIFFTranslator", TIFFTranslatorTest::Suite()); 26 27 return suite; 28 } 29 30 // helper function used by multiple tests to 31 // determine if the given streams are exactly 32 // the same 33 bool 34 CompareStreams(BPositionIO &a, BPositionIO &b) 35 { 36 off_t alen = 0, blen = 0; 37 const uint32 kbuflen = 2048; 38 uint8 abuf[kbuflen], bbuf[kbuflen]; 39 40 a.Seek(0, SEEK_END); 41 alen = a.Position(); 42 b.Seek(0, SEEK_END); 43 blen = b.Position(); 44 if (alen != blen) 45 return false; 46 47 if (a.Seek(0, SEEK_SET) != 0) 48 return false; 49 if (b.Seek(0, SEEK_SET) != 0) 50 return false; 51 52 ssize_t read = 0; 53 while (alen > 0) { 54 read = a.Read(abuf, kbuflen); 55 if (read < 0) 56 return false; 57 if (b.Read(bbuf, read) != read) 58 return false; 59 60 if (memcmp(abuf, bbuf, read) != 0) 61 return false; 62 63 alen -= read; 64 } 65 66 return true; 67 } 68 69 // Check each member of translator_info to see that it matches 70 // what is expected 71 void 72 CheckTranslatorInfo(translator_info *pti, uint32 type, uint32 group, 73 float quality, float capability, const char *name, const char *mime) 74 { 75 CPPUNIT_ASSERT(pti->type == type); 76 CPPUNIT_ASSERT(pti->translator != 0); 77 CPPUNIT_ASSERT(pti->group == group); 78 CPPUNIT_ASSERT(pti->quality > quality - 0.01f && 79 pti->quality < quality + 0.01f); 80 CPPUNIT_ASSERT(pti->capability > capability - 0.01f && 81 pti->capability < capability + 0.01f); 82 CPPUNIT_ASSERT(strcmp(pti->name, name) == 0); 83 CPPUNIT_ASSERT(strcmp(pti->MIME, mime) == 0); 84 } 85 86 // Returns true if the translation_formats are 87 // identical (or nearly identical). Returns false if 88 // they are different 89 bool 90 CompareTranslationFormat(const translation_format *pleft, 91 const translation_format *pright) 92 { 93 CPPUNIT_ASSERT(pleft->MIME); 94 CPPUNIT_ASSERT(pright->MIME); 95 CPPUNIT_ASSERT(pleft->name); 96 CPPUNIT_ASSERT(pright->name); 97 98 if (pleft->group != pright->group) 99 return false; 100 if (pleft->type != pright->type) 101 return false; 102 if (pleft->quality < pright->quality - 0.01f || 103 pleft->quality > pright->quality + 0.01f) 104 return false; 105 if (pleft->capability < pright->capability - 0.01f || 106 pleft->capability > pright->capability + 0.01f) 107 return false; 108 if (strcmp(pleft->MIME, pright->MIME) != 0) 109 return false; 110 if (strcmp(pleft->name, pright->name) != 0) 111 return false; 112 113 return true; 114 } 115 116 // Apply a number of tests to a BTranslator * to a TGATranslator object 117 void 118 TestBTranslator(BTestCase *ptest, BTranslator *ptran, 119 const translation_format *pExpectedIns, uint32 nExpectedIns, 120 const translation_format *pExpectedOuts, uint32 nExpectedOuts, 121 int32 expectedVer) 122 { 123 const uint32 knmatches = 50; 124 uint8 matches[knmatches]; 125 CPPUNIT_ASSERT(nExpectedIns <= knmatches && nExpectedOuts <= knmatches); 126 127 // The translator should only have one reference 128 ptest->NextSubTest(); 129 CPPUNIT_ASSERT(ptran->ReferenceCount() == 1); 130 131 // Make sure Acquire returns a BTranslator even though its 132 // already been Acquired once 133 ptest->NextSubTest(); 134 CPPUNIT_ASSERT(ptran->Acquire() == ptran); 135 136 // Acquired twice, refcount should be 2 137 ptest->NextSubTest(); 138 CPPUNIT_ASSERT(ptran->ReferenceCount() == 2); 139 140 // Release should return ptran because it is still acquired 141 ptest->NextSubTest(); 142 CPPUNIT_ASSERT(ptran->Release() == ptran); 143 144 ptest->NextSubTest(); 145 CPPUNIT_ASSERT(ptran->ReferenceCount() == 1); 146 147 ptest->NextSubTest(); 148 CPPUNIT_ASSERT(ptran->Acquire() == ptran); 149 150 ptest->NextSubTest(); 151 CPPUNIT_ASSERT(ptran->ReferenceCount() == 2); 152 153 ptest->NextSubTest(); 154 CPPUNIT_ASSERT(ptran->Release() == ptran); 155 156 ptest->NextSubTest(); 157 CPPUNIT_ASSERT(ptran->ReferenceCount() == 1); 158 159 // A name would be nice 160 ptest->NextSubTest(); 161 const char *tranname = ptran->TranslatorName(); 162 CPPUNIT_ASSERT(tranname); 163 printf(" {%s} ", tranname); 164 165 // More info would be nice 166 ptest->NextSubTest(); 167 const char *traninfo = ptran->TranslatorInfo(); 168 CPPUNIT_ASSERT(traninfo); 169 printf(" {%s} ", traninfo); 170 171 // What version are you? 172 // (when ver == 100, that means that version is 1.00) 173 ptest->NextSubTest(); 174 int32 ver = ptran->TranslatorVersion(); 175 CPPUNIT_ASSERT(ver == expectedVer); 176 printf(" {0x%.8lx} ", ver); 177 178 // Input formats? 179 ptest->NextSubTest(); 180 { 181 printf("input:"); 182 183 int32 incount = 0; 184 const translation_format *pins = ptran->InputFormats(&incount); 185 CPPUNIT_ASSERT((unsigned)incount == nExpectedIns); 186 CPPUNIT_ASSERT(pins); 187 188 memset(matches, 0, sizeof(uint8) * nExpectedIns); 189 for (int32 i = 0; i < incount; i++) { 190 bool bmatch = false; 191 for (uint32 k = 0; bmatch == false && k < nExpectedIns; k++) { 192 bmatch = CompareTranslationFormat(pins + i, pExpectedIns + k); 193 if (bmatch) 194 matches[k] = 1; 195 } 196 197 CPPUNIT_ASSERT(bmatch); 198 } 199 200 // make sure that each expected input format was matched 201 for (uint32 i = 0; i < nExpectedIns; i++) 202 CPPUNIT_ASSERT(matches[i]); 203 } 204 205 // Output formats? 206 ptest->NextSubTest(); 207 { 208 printf("output:"); 209 210 int32 outcount = 0; 211 const translation_format *pouts = ptran->OutputFormats(&outcount); 212 CPPUNIT_ASSERT((unsigned)outcount == nExpectedOuts); 213 CPPUNIT_ASSERT(pouts); 214 215 memset(matches, 0, sizeof(uint8) * nExpectedOuts); 216 for (int32 i = 0; i < outcount; i++) { 217 bool bmatch = false; 218 for (uint32 k = 0; bmatch == false && k < nExpectedOuts; k++) { 219 bmatch = CompareTranslationFormat(pouts + i, pExpectedOuts + k); 220 if (bmatch) 221 matches[k] = 1; 222 } 223 224 CPPUNIT_ASSERT(bmatch); 225 } 226 227 // make sure that each expected input format was matched 228 for (uint32 i = 0; i < nExpectedOuts; i++) 229 CPPUNIT_ASSERT(matches[i]); 230 } 231 232 // Release should return NULL because Release has been called 233 // as many times as it has been acquired 234 ptest->NextSubTest(); 235 CPPUNIT_ASSERT(ptran->Release() == NULL); 236 ptran = NULL; 237 } 238 239 void 240 TranslatorLoadAddOnTest(const char *path, BTestCase *ptest, 241 const translation_format *pExpectedIns, uint32 nExpectedIns, 242 const translation_format *pExpectedOuts, uint32 nExpectedOuts, 243 int32 expectedVer) 244 { 245 // Make sure the add_on loads 246 ptest->NextSubTest(); 247 image_id image = load_add_on(path); 248 CPPUNIT_ASSERT(image >= 0); 249 250 // Load in function to make the object 251 ptest->NextSubTest(); 252 BTranslator *(*pMakeNthTranslator)(int32 n,image_id you,uint32 flags,...); 253 status_t err = get_image_symbol(image, "make_nth_translator", 254 B_SYMBOL_TYPE_TEXT, (void **)&pMakeNthTranslator); 255 CPPUNIT_ASSERT(!err); 256 257 // Make sure the function returns a pointer to a BTranslator 258 ptest->NextSubTest(); 259 BTranslator *ptran = pMakeNthTranslator(0, image, 0); 260 CPPUNIT_ASSERT(ptran); 261 262 // Make sure the function only returns one BTranslator 263 ptest->NextSubTest(); 264 CPPUNIT_ASSERT(!pMakeNthTranslator(1, image, 0)); 265 CPPUNIT_ASSERT(!pMakeNthTranslator(2, image, 0)); 266 CPPUNIT_ASSERT(!pMakeNthTranslator(3, image, 0)); 267 CPPUNIT_ASSERT(!pMakeNthTranslator(16, image, 0)); 268 CPPUNIT_ASSERT(!pMakeNthTranslator(1023, image, 0)); 269 270 // Run a number of tests on the BTranslator object 271 TestBTranslator(ptest, ptran, pExpectedIns, nExpectedIns, 272 pExpectedOuts, nExpectedOuts, expectedVer); 273 // NOTE: this function Release()s ptran 274 ptran = NULL; 275 276 // Unload Add-on 277 ptest->NextSubTest(); 278 CPPUNIT_ASSERT(unload_add_on(image) == B_OK); 279 } 280