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