xref: /haiku/src/tests/kits/translation/TranslatorRosterTest.cpp (revision 268f99dd7dc4bd7474a8bd2742d3f1ec1de6752a)
1 /*****************************************************************************/
2 // Haiku Translation Kit Test
3 // Author: Brian Matzon <brian@matzon.dk>
4 // Version: 0.1.0
5 //
6 // This is the Test application for BTranslatorRoster
7 //
8 //
9 // This application and all source files used in its construction, except
10 // where noted, are licensed under the MIT License, and have been written
11 // and are:
12 //
13 // Copyright (c) 2002 Haiku Project
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining a
16 // copy of this software and associated documentation files (the "Software"),
17 // to deal in the Software without restriction, including without limitation
18 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
19 // and/or sell copies of the Software, and to permit persons to whom the
20 // Software is furnished to do so, subject to the following conditions:
21 //
22 // The above copyright notice and this permission notice shall be included
23 // in all copies or substantial portions of the Software.
24 //
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
26 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
29 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
30 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
31 // DEALINGS IN THE SOFTWARE.
32 /*****************************************************************************/
33 #include "TranslatorRosterTest.h"
34 
35 #include <stdio.h>
36 #include <string.h>
37 
38 #include <Application.h>
39 #include <Archivable.h>
40 #include <File.h>
41 #include <Message.h>
42 #include <OS.h>
43 #include <TranslatorFormats.h>
44 
45 /* cppunit framework */
46 #include <cppunit/Test.h>
47 #include <cppunit/TestCaller.h>
48 #include <cppunit/TestSuite.h>
49 
50 /**
51  * TestCase constructor - no work
52  */
TranslatorRosterTest(std::string name)53 TranslatorRosterTest::TranslatorRosterTest(std::string name)
54 	: BTestCase(name)
55 {
56 }
57 
58 /**
59  * Default destructor - no work
60  */
~TranslatorRosterTest()61 TranslatorRosterTest::~TranslatorRosterTest()
62 {
63 }
64 
65 CppUnit::Test *
Suite()66 TranslatorRosterTest::Suite()
67 {
68 	/* create our suite */
69 	CppUnit::TestSuite *suite = new CppUnit::TestSuite("TranslatorRoster");
70 
71 	/* add suckers */
72 	suite->addTest(new CppUnit::TestCaller<TranslatorRosterTest>(
73 		"TranslatorRosterTest::Initialize Test",
74 		&TranslatorRosterTest::InitializeTest));
75 
76 	suite->addTest(new CppUnit::TestCaller<TranslatorRosterTest>(
77 		"TranslatorRosterTest::Constructor Test",
78 		&TranslatorRosterTest::ConstructorTest));
79 
80 	suite->addTest(new CppUnit::TestCaller<TranslatorRosterTest>(
81 		"TranslatorRosterTest::Default Test",
82 		&TranslatorRosterTest::DefaultTest));
83 
84 	suite->addTest(new CppUnit::TestCaller<TranslatorRosterTest>(
85 		"TranslatorRosterTest::Instantiate Test",
86 		&TranslatorRosterTest::InstantiateTest));
87 
88 	suite->addTest(new CppUnit::TestCaller<TranslatorRosterTest>(
89 		"TranslatorRosterTest::Version Test",
90 		&TranslatorRosterTest::VersionTest));
91 
92 	suite->addTest(new CppUnit::TestCaller<TranslatorRosterTest>(
93 		"TranslatorRosterTest::AddTranslators Test",
94 		&TranslatorRosterTest::AddTranslatorsTest));
95 
96 	suite->addTest(new CppUnit::TestCaller<TranslatorRosterTest>(
97 		"TranslatorRosterTest::Archive Test",
98 		&TranslatorRosterTest::ArchiveTest));
99 
100 	suite->addTest(new CppUnit::TestCaller<TranslatorRosterTest>(
101 		"TranslatorRosterTest::GetAllTranslators Test",
102 		&TranslatorRosterTest::GetAllTranslatorsTest));
103 
104 	suite->addTest(new CppUnit::TestCaller<TranslatorRosterTest>(
105 		"TranslatorRosterTest::GetConfigurationMessage Test",
106 		&TranslatorRosterTest::GetConfigurationMessageTest));
107 
108 	suite->addTest(new CppUnit::TestCaller<TranslatorRosterTest>(
109 		"TranslatorRosterTest::GetInputFormats Test",
110 		&TranslatorRosterTest::GetInputFormatsTest));
111 
112 	suite->addTest(new CppUnit::TestCaller<TranslatorRosterTest>(
113 		"TranslatorRosterTest::GetOutputFormats Test",
114 		&TranslatorRosterTest::GetOutputFormatsTest));
115 
116 	suite->addTest(new CppUnit::TestCaller<TranslatorRosterTest>(
117 		"TranslatorRosterTest::GetTranslatorInfo Test",
118 		&TranslatorRosterTest::GetTranslatorInfoTest));
119 
120 	suite->addTest(new CppUnit::TestCaller<TranslatorRosterTest>(
121 		"TranslatorRosterTest::GetTranslators Test",
122 		&TranslatorRosterTest::GetTranslatorsTest));
123 
124 	suite->addTest(new CppUnit::TestCaller<TranslatorRosterTest>(
125 		"TranslatorRosterTest::Identify Test",
126 		&TranslatorRosterTest::IdentifyTest));
127 
128 	suite->addTest(new CppUnit::TestCaller<TranslatorRosterTest>(
129 		"TranslatorRosterTest::MakeConfigurationView Test",
130 		&TranslatorRosterTest::MakeConfigurationViewTest));
131 
132 	suite->addTest(new CppUnit::TestCaller<TranslatorRosterTest>(
133 		"TranslatorRosterTest::Translate Test",
134 		&TranslatorRosterTest::TranslateTest));
135 
136 	return suite;
137 }
138 
139 /**
140  * Tries to aquire the default roster
141  */
142 void
InitializeTest()143 TranslatorRosterTest::InitializeTest()
144 {
145 	//aquire default roster
146 	NextSubTest();
147 	BTranslatorRoster *proster = BTranslatorRoster::Default();
148 	CPPUNIT_ASSERT(proster);
149 }
150 
151 /**
152  * Construct proster using different kinds of constructors
153  */
154 void
ConstructorTest()155 TranslatorRosterTest::ConstructorTest()
156 {
157 	//shared instance of TranslatorRoster
158 	BTranslatorRoster *proster;
159 
160 	// Create TranslatorRoster using noargs constructor
161 	// (GetAllTranslatorsTest also tests this constructor)
162 	NextSubTest();
163 	proster = new BTranslatorRoster();
164 	CPPUNIT_ASSERT(proster != NULL);
165 	delete proster;
166 	proster = NULL;
167 
168 	//Create TranslatorRoster using BMessage constructor
169 	NextSubTest();
170 	BMessage translator_message;
171 	translator_message.AddString("be:translator_path",
172 		"/boot/home/config/add-ons/Translators");
173 	proster = new BTranslatorRoster(&translator_message);
174 	CPPUNIT_ASSERT(proster != NULL);
175 
176 	// Make sure the correct number of translators were loaded
177 	NextSubTest();
178 	int32 nloaded = -42;
179 	translator_id *pids = NULL;
180 	CPPUNIT_ASSERT(proster->GetAllTranslators(&pids, &nloaded) == B_NO_ERROR);
181 	CPPUNIT_ASSERT(nloaded > 0);
182 	CPPUNIT_ASSERT(pids != NULL);
183 
184 	// Make sure the correct translators were loaded
185 	NextSubTest();
186 	const char *kaTranslatorNames[] = {
187 		"TGA Images",
188 		"MNGTranslator",
189 		"BMP Images",
190 		"TestBmpTranslator",
191 		"BBitmap Images",
192 		"GIMPPatternHandler"
193 	};
194 	int32 naCounts[sizeof(kaTranslatorNames) /
195 		sizeof(const char *)] = { 0 };
196 	CPPUNIT_ASSERT(nloaded == sizeof(kaTranslatorNames) /
197 		sizeof(const char *));
198 
199 	for (int32 i = 0; i < nloaded; i++) {
200 		const char *kTranslatorName, *kTranslatorInfo;
201 		int32 nTranslatorVersion;
202 
203 		CPPUNIT_ASSERT(pids[i] > 0);
204 
205 		kTranslatorName = kTranslatorInfo = NULL;
206 		nTranslatorVersion = -246;
207 
208 		proster->GetTranslatorInfo(pids[i], &kTranslatorName,
209 			&kTranslatorInfo, &nTranslatorVersion);
210 
211 		CPPUNIT_ASSERT(kTranslatorName);
212 		CPPUNIT_ASSERT(kTranslatorInfo);
213 		CPPUNIT_ASSERT(nTranslatorVersion > 0);
214 
215 		// make sure that the translator matches
216 		// one from the list
217 		int32 npresent = 0;
218 		for (int32 k = 0; k < nloaded; k++) {
219 			if (!strcmp(kaTranslatorNames[k], kTranslatorName)) {
220 				npresent++;
221 				naCounts[k]++;
222 			}
223 		}
224 		CPPUNIT_ASSERT(npresent == 1);
225 	}
226 
227 	// make certain that each translator in kaTranslatorNames
228 	// is loaded exactly once
229 	for (int32 i = 0; i < nloaded; i++)
230 		CPPUNIT_ASSERT(naCounts[i] == 1);
231 
232 	delete proster;
233 	proster = NULL;
234 }
235 
236 /**
237  * Tests:
238  * BTranslatorRoster *Default()
239  */
240 void
DefaultTest()241 TranslatorRosterTest::DefaultTest()
242 {
243 	NextSubTest();
244 	BTranslatorRoster *proster = BTranslatorRoster::Default();
245 	CPPUNIT_ASSERT(proster != NULL);
246 	// TODO: actually check if all the right translators are loaded
247 
248 	// delete the default BTranslatorRoster
249 	// (may not always be the appropriate thing to do,
250 	// but it should work without blowing up)
251 	NextSubTest();
252 	delete proster;
253 	proster = NULL;
254 
255 	// If the default BTranslatorRoster was not
256 	// deleted properly, it would likely show up in
257 	// this test or the next
258 	NextSubTest();
259 	proster = BTranslatorRoster::Default();
260 	CPPUNIT_ASSERT(proster);
261 
262 	// Make sure the default BTranslatorRoster works
263 	// after a delete has been performed
264 	// TODO: actually check if all the right translators are loaded
265 	NextSubTest();
266 	translator_id *pids = NULL;
267 	int32 ncount = -1;
268 	CPPUNIT_ASSERT(proster->GetAllTranslators(&pids, &ncount) == B_OK);
269 	CPPUNIT_ASSERT(pids);
270 	CPPUNIT_ASSERT(ncount > 0);
271 	delete[] pids;
272 	pids = NULL;
273 
274 	// Delete again to be sure that it still won't blow up
275 	NextSubTest();
276 	delete proster;
277 	proster = NULL;
278 }
279 
280 /**
281  * Tests:
282  * BTranslatorRoster *Instantiate(BMessage *from)
283  *
284  * @return B_OK if everything went ok, B_ERROR if not
285  */
286 // ArchiveTest() also tests BTranslatorRoster::Instantiate()
287 void
InstantiateTest()288 TranslatorRosterTest::InstantiateTest()
289 {
290 	//shared instance of TranslatorRoster
291 	BTranslatorRoster* proster = NULL;
292 	BMessage bmsg;
293 
294 	//create BTranslatorRoster using empty message (must return NULL)
295 	NextSubTest();
296 	proster = dynamic_cast<BTranslatorRoster *>
297 		(BTranslatorRoster::Instantiate(&bmsg));
298 	CPPUNIT_ASSERT(proster == NULL);
299 	delete proster;
300 	proster = NULL;
301 
302 	// BMessage containing a single Translator to load
303 	NextSubTest();
304 	status_t result;
305 	result = bmsg.AddString("class", "BTranslatorRoster");
306 	CPPUNIT_ASSERT(result == B_OK);
307 	result = bmsg.AddString("be:translator_path",
308 		"/boot/home/config/add-ons/Translators/BMPTranslator");
309 	CPPUNIT_ASSERT(result == B_OK);
310 	proster = dynamic_cast<BTranslatorRoster *>
311 		(BTranslatorRoster::Instantiate(&bmsg));
312 	CPPUNIT_ASSERT(proster);
313 
314 	translator_id *pids = NULL;
315 	int32 ncount = -1;
316 	result = proster->GetAllTranslators(&pids, &ncount);
317 	CPPUNIT_ASSERT(result == B_OK);
318 	CPPUNIT_ASSERT(pids);
319 	CPPUNIT_ASSERT(ncount == 1);
320 	const char *strName = NULL, *strInfo = NULL;
321 	int32 nversion = -1;
322 	result = proster->GetTranslatorInfo(pids[0], &strName, &strInfo,
323 		&nversion);
324 	CPPUNIT_ASSERT(result == B_OK);
325 	CPPUNIT_ASSERT(strName);
326 	CPPUNIT_ASSERT(strInfo);
327 	CPPUNIT_ASSERT(nversion > 0);
328 	CPPUNIT_ASSERT(strcmp("BMP Images", strName) == 0);
329 	delete proster;
330 	proster = NULL;
331 
332 	// BMessage is valid, but does not contain any translators
333 	NextSubTest();
334 	result = bmsg.MakeEmpty();
335 	CPPUNIT_ASSERT(result == B_OK);
336 	result = bmsg.AddString("class", "BTranslatorRoster");
337 	CPPUNIT_ASSERT(result == B_OK);
338 	proster = dynamic_cast<BTranslatorRoster *>
339 		(BTranslatorRoster::Instantiate(&bmsg));
340 	CPPUNIT_ASSERT(proster);
341 	delete proster;
342 	proster = NULL;
343 
344 	// TODO: add a case with a BMessage containing multiple Translators to load
345 
346 	// slightly corrupt BMessage, Instantiate
347 	// should fail because class information is missing
348 	NextSubTest();
349 	result = bmsg.MakeEmpty();
350 	CPPUNIT_ASSERT(result == B_OK);
351 	result = bmsg.AddString("be:translator_path",
352 		"/boot/home/config/add-ons/Translators/BMPTranslator");
353 	CPPUNIT_ASSERT(result == B_OK);
354 	proster = dynamic_cast<BTranslatorRoster *>
355 		(BTranslatorRoster::Instantiate(&bmsg));
356 	CPPUNIT_ASSERT(proster == NULL);
357 	delete proster;
358 	proster = NULL;
359 }
360 
361 /**
362  * Tests:
363  * const char *Version(int32 *outCurVersion, int32 *outMinVersion,
364  * int32 *inAppVersion = B_TRANSLATION_CURRENT_VERSION)
365  *
366  * @return B_OK if everything went ok, B_ERROR if not
367  */
368 void
VersionTest()369 TranslatorRosterTest::VersionTest()
370 {
371 #if 0
372 	NextSubTest();
373 	int32 outCurVersion = 0;
374 	int32 outMinVersion = 0;
375 	const char* info = NULL;
376 
377 	info = BTranslatorRoster::Version(&outCurVersion, &outMinVersion);
378 	CPPUNIT_ASSERT(info != NULL);
379 	CPPUNIT_ASSERT(outCurVersion > 0);
380 	CPPUNIT_ASSERT(outMinVersion > 0);
381 #endif
382 }
383 
384 //
385 // Compares proster to the default BTranslatorRoster to
386 // ensure that they have the same translators and the
387 // same number of translators
388 //
389 void
CompareWithDefault(BTranslatorRoster * proster)390 CompareWithDefault(BTranslatorRoster *proster)
391 {
392 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
393 	CPPUNIT_ASSERT(pDefRoster);
394 
395 	translator_id *pInstids = NULL, *pDefids = NULL;
396 	int32 instcount = 0, defcount = 0, ndummy = 0;
397 	const char *strDefName = NULL, *strInstName = NULL, *strDummy = NULL;
398 
399 	CPPUNIT_ASSERT(proster->GetAllTranslators(&pInstids, &instcount) == B_OK);
400 	CPPUNIT_ASSERT(pInstids);
401 	CPPUNIT_ASSERT(instcount > 0);
402 
403 	CPPUNIT_ASSERT(pDefRoster->GetAllTranslators(&pDefids, &defcount) == B_OK);
404 	CPPUNIT_ASSERT(pDefids);
405 	CPPUNIT_ASSERT(defcount > 0);
406 	CPPUNIT_ASSERT(defcount == instcount);
407 
408 	// make sure that every translator that is in the default
409 	// BTranslatorRoster is in proster, once and only once
410 	for (int32 i = 0; i < defcount; i++) {
411 		int32 matches;
412 		matches = 0;
413 		CPPUNIT_ASSERT(pDefRoster->GetTranslatorInfo(pDefids[i], &strDefName,
414 			&strDummy, &ndummy) == B_OK);
415 		CPPUNIT_ASSERT(strDefName);
416 		for (int32 k = 0; k < instcount; k++) {
417 			CPPUNIT_ASSERT(proster->GetTranslatorInfo(pInstids[k],
418 				&strInstName, &strDummy, &ndummy) == B_OK);
419 			CPPUNIT_ASSERT(strInstName);
420 
421 			if (strcmp(strDefName, strInstName) == 0)
422 				matches++;
423 		}
424 		CPPUNIT_ASSERT(matches == 1);
425 	}
426 
427 	delete[] pInstids;
428 	pInstids = NULL;
429 	delete[] pDefids;
430 	pDefids = NULL;
431 }
432 
433 /**
434  * Tests:
435  * virtual status_t AddTranslators(const char *load_path = NULL)
436  *
437  * @return B_OK if everything went ok, B_ERROR if not
438  */
439 void
AddTranslatorsTest()440 TranslatorRosterTest::AddTranslatorsTest()
441 {
442 	//create basic translatorroster
443 	NextSubTest();
444 	BTranslatorRoster* proster = new BTranslatorRoster();
445 	CPPUNIT_ASSERT(proster);
446 	CPPUNIT_ASSERT(proster->AddTranslators(
447 		"/boot/home/config/add-ons/Translators/:"
448 		"/system/add-ons/Translators/") == B_OK);
449 
450 	NextSubTest();
451 	int32 instcount = 0;
452 	translator_id* translators = NULL;
453 	proster->GetAllTranslators(&translators, &instcount);
454 	CPPUNIT_ASSERT(translators);
455 	CPPUNIT_ASSERT(instcount > 0);
456 	// TODO: count the number of files in all of the directories specified
457 	// TODO: above and make certain that it matches instcount
458 	delete[] translators;
459 	translators = NULL;
460 
461 	//delete and create new, this time don't specify path
462 	NextSubTest();
463 	delete proster;
464 	proster = new BTranslatorRoster();
465 	CPPUNIT_ASSERT(proster->AddTranslators() == B_OK);
466 
467 	// make sure that every translator in the Default BTranslatorRoster is in
468 	// proster, and make certain that it is in there ONLY ONCE
469 	NextSubTest();
470 	CompareWithDefault(proster);
471 	delete proster;
472 	proster = NULL;
473 }
474 
475 /**
476  * Tests:
477  * virtual status_t Archive(BMessage *into, bool deep = true) const
478  *
479  * @return B_OK if everything went ok, B_ERROR if not
480  */
481 void
ArchiveTest()482 TranslatorRosterTest::ArchiveTest()
483 {
484 	NextSubTest();
485 	//archive default, and count entries (must be more than 1!)
486 	BMessage translator_message;
487 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
488 	CPPUNIT_ASSERT(pDefRoster);
489 	CPPUNIT_ASSERT(pDefRoster->Archive(&translator_message) == B_OK);
490 
491 	// make sure instantiate makes an "exact" copy of the default translator
492 	NextSubTest();
493 	BTranslatorRoster *proster = NULL;
494 	proster = dynamic_cast<BTranslatorRoster *>
495 		(BTranslatorRoster::Instantiate(&translator_message));
496 	CPPUNIT_ASSERT(proster);
497 
498 	// make sure that every translator in the pDefRoster is in
499 	// proster, and make certain that it is in there ONLY ONCE
500 	NextSubTest();
501 	CompareWithDefault(proster);
502 	delete proster;
503 	proster = NULL;
504 }
505 
506 /**
507  * Tests:
508  * virtual status_t GetAllTranslators(translator_id **outList, int32 *outCount)
509  *
510  * @return B_OK if everything went ok, B_ERROR if not
511  */
512 void
GetAllTranslatorsTest()513 TranslatorRosterTest::GetAllTranslatorsTest()
514 {
515 	// bad parameters
516 	NextSubTest();
517 	int32 nloaded = 42;
518 	translator_id* pids = NULL;
519 	BTranslatorRoster roster;
520 	CPPUNIT_ASSERT(roster.GetAllTranslators(NULL, &nloaded) == B_BAD_VALUE);
521 	CPPUNIT_ASSERT(nloaded == 42);
522 	CPPUNIT_ASSERT(roster.GetAllTranslators(&pids, NULL) == B_BAD_VALUE);
523 	CPPUNIT_ASSERT(pids == NULL);
524 	CPPUNIT_ASSERT(roster.GetAllTranslators(NULL, NULL) == B_BAD_VALUE);
525 
526 	// no translators
527 	NextSubTest();
528 	CPPUNIT_ASSERT(
529 		roster.GetAllTranslators(&pids, &nloaded) == B_NO_ERROR);
530 	CPPUNIT_ASSERT(nloaded == 0);
531 	delete[] pids;
532 	pids = NULL;
533 
534 	// default translators
535 	NextSubTest();
536 	nloaded = 42;
537 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
538 	CPPUNIT_ASSERT(
539 		pDefRoster->GetAllTranslators(&pids, &nloaded) == B_NO_ERROR);
540 	CPPUNIT_ASSERT(nloaded > 0);
541 	CPPUNIT_ASSERT(pids != NULL);
542 
543 	// Make sure the correct translators were loaded
544 	NextSubTest();
545 	const char *kaTranslatorNames[] = {
546 		"Gobe MS-WORD Translator",
547 		"Gobe Text Translator",
548 		"TIFF Images",
549 		"Gobe SYLK Translator",
550 		"StyledEdit Files",
551 		"Gobe RTF Translator",
552 		"PPM Images",
553 		"JPEG Images",
554 		"Gobe HTML Translator",
555 		"Gobe Excel Translator",
556 		"TGA Images",
557 		"MNGTranslator",
558 		"GIMPPatternHandler",
559 		"TestBmpTranslator",
560 		"BMP Images",
561 		"BBitmap Images"
562 	};
563 	CPPUNIT_ASSERT(nloaded == sizeof(kaTranslatorNames) /
564 		sizeof(const char *));
565 
566 	for (int32 i = 0; i < nloaded; i++) {
567 		const char *kTranslatorName, *kTranslatorInfo;
568 		int32 nTranslatorVersion;
569 
570 		CPPUNIT_ASSERT(pids[i] > 0);
571 
572 		kTranslatorName = kTranslatorInfo = NULL;
573 		nTranslatorVersion = -246;
574 
575 		pDefRoster->GetTranslatorInfo(pids[i], &kTranslatorName,
576 			&kTranslatorInfo, &nTranslatorVersion);
577 
578 		CPPUNIT_ASSERT(kTranslatorName);
579 		CPPUNIT_ASSERT(kTranslatorInfo);
580 		CPPUNIT_ASSERT(nTranslatorVersion > 0);
581 
582 		// make sure each translator is loaded exactly once
583 		// no more, no less
584 		int32 npassed = 0;
585 		for (int32 k = 0; k < nloaded; k++) {
586 			if (!strcmp(kaTranslatorNames[k], kTranslatorName))
587 				npassed++;
588 		}
589 		CPPUNIT_ASSERT(npassed == 1);
590 	}
591 
592 	delete[] pids;
593 	pids = NULL;
594 }
595 
596 /**
597  * Tests:
598  * virtual status_t GetConfigurationMessage(translator_id forTranslator,
599  * BMessage *ioExtension)
600  *
601  * @return B_OK if everything went ok, B_ERROR if not
602  */
603 void
GetConfigurationMessageTest()604 TranslatorRosterTest::GetConfigurationMessageTest()
605 {
606 	NextSubTest();
607 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
608 	CPPUNIT_ASSERT(pDefRoster);
609 
610 	NextSubTest();
611 	//get id for a translator (just use the first one)
612 	int32 num_translators = -1;
613 	translator_id* translators = NULL;
614 	CPPUNIT_ASSERT(pDefRoster->GetAllTranslators(&translators,
615 		&num_translators) == B_OK);
616 	CPPUNIT_ASSERT(translators);
617 	CPPUNIT_ASSERT(num_translators > 0);
618 
619 	NextSubTest();
620 	translator_id translatorid = translators[0];
621 	delete[] translators;
622 	translators = NULL;
623 	//get conf for invalid translator
624 	BMessage translator_message;
625 	CPPUNIT_ASSERT(pDefRoster->GetConfigurationMessage(-1,
626 		&translator_message) == B_NO_TRANSLATOR);
627 	CPPUNIT_ASSERT(translator_message.IsEmpty());
628 
629 	//get conf for invalid ioExtension (BMessage)
630 	NextSubTest();
631 	CPPUNIT_ASSERT(
632 		pDefRoster->GetConfigurationMessage(translatorid, NULL) == B_BAD_VALUE);
633 
634 	//get config for actual translator
635 	NextSubTest();
636 	CPPUNIT_ASSERT(translator_message.MakeEmpty() == B_OK);
637 	CPPUNIT_ASSERT(pDefRoster->GetConfigurationMessage(translatorid,
638 		&translator_message) == B_OK);
639 }
640 
641 // Code used by both GetInputFormatsTest and GetOutputFormatsTest
642 void
GetInputOutputFormatsTest(TranslatorRosterTest * prt,bool binput)643 GetInputOutputFormatsTest(TranslatorRosterTest *prt, bool binput)
644 {
645 	prt->NextSubTest();
646 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
647 	CPPUNIT_ASSERT(pDefRoster);
648 
649 	prt->NextSubTest();
650 	translator_id* translators = NULL;
651 	int32 num_translators = -1;
652 	CPPUNIT_ASSERT(pDefRoster->GetAllTranslators(&translators,
653 		&num_translators) == B_OK);
654 	CPPUNIT_ASSERT(translators);
655 	CPPUNIT_ASSERT(num_translators > 0);
656 
657 	// Run get Input/output format test on each translator
658 	for (int32 i = 0; i < num_translators; i++) {
659 		const translation_format *fmts = NULL;
660 		int32 num_fmts = -1;
661 		status_t result;
662 		prt->NextSubTest();
663 		if (binput)
664 			result = pDefRoster->GetInputFormats(translators[i], &fmts,
665 				&num_fmts);
666 		else
667 			result = pDefRoster->GetOutputFormats(translators[i], &fmts,
668 				&num_fmts);
669 		CPPUNIT_ASSERT(result == B_OK);
670 
671 		// test input/output formats
672 		CPPUNIT_ASSERT(num_fmts >= 0);
673 		CPPUNIT_ASSERT(num_fmts == 0 || fmts);
674 		for (int32 k = 0; k < num_fmts; k++) {
675 			CPPUNIT_ASSERT(fmts[k].type);
676 			CPPUNIT_ASSERT(fmts[k].group);
677 			CPPUNIT_ASSERT(fmts[k].quality >= 0 && fmts[k].quality <= 1);
678 			CPPUNIT_ASSERT(fmts[k].capability >= 0 && fmts[k].capability <= 1);
679 			CPPUNIT_ASSERT(strlen(fmts[k].MIME) >= 0);
680 			CPPUNIT_ASSERT(strlen(fmts[k].name) > 0);
681 		}
682 	}
683 	delete[] translators;
684 	translators = NULL;
685 }
686 
687 /**
688  * Tests:
689  * virtual status_t GetInputFormats(translator_id forTranslator,
690  * const translation_format **outFormats, int32 *outNumFormats)
691  *
692  * @return B_OK if everything went ok, B_ERROR if not
693  */
694 void
GetInputFormatsTest()695 TranslatorRosterTest::GetInputFormatsTest()
696 {
697 	GetInputOutputFormatsTest(this, true);
698 }
699 
700 /**
701  * Tests:
702  * virtual status_t GetOutputFormats(translator_id forTranslator,
703  * const translation_format **outFormats, int32 *outNumFormats)
704  *
705  * @return B_OK if everything went ok, B_ERROR if not
706  */
707 void
GetOutputFormatsTest()708 TranslatorRosterTest::GetOutputFormatsTest()
709 {
710 	GetInputOutputFormatsTest(this, false);
711 }
712 
713 /**
714  * Tests:
715  * virtual status_t GetTranslatorInfo(translator_id forTranslator,
716  * const char **outName, const char **outInfo, int32 *outVersion)
717  *
718  * @return B_OK if everything went ok, B_ERROR if not
719  */
720 void
GetTranslatorInfoTest()721 TranslatorRosterTest::GetTranslatorInfoTest()
722 {
723 	NextSubTest();
724 	translator_id* translators = NULL;
725 	int32 num_translators = -1;
726 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
727 	CPPUNIT_ASSERT(pDefRoster);
728 
729 	NextSubTest();
730 	CPPUNIT_ASSERT(pDefRoster->GetAllTranslators(&translators,
731 		&num_translators) == B_OK);
732 	CPPUNIT_ASSERT(translators);
733 	CPPUNIT_ASSERT(num_translators > 0);
734 	for (int32 i = 0; i < num_translators; i++) {
735 		const char *outName = NULL;
736 		const char *outInfo = NULL;
737 		int32 outVersion = -1;
738 
739 		NextSubTest();
740 		CPPUNIT_ASSERT(pDefRoster->GetTranslatorInfo(-1, &outName, &outInfo,
741 			&outVersion) == B_NO_TRANSLATOR);
742 
743 		// B_BAD_VALUE cases
744 		CPPUNIT_ASSERT(pDefRoster->GetTranslatorInfo(translators[i],
745 			NULL, &outInfo, &outVersion) == B_BAD_VALUE);
746 		CPPUNIT_ASSERT(outInfo == NULL && outVersion == -1);
747 
748 		CPPUNIT_ASSERT(pDefRoster->GetTranslatorInfo(translators[i],
749 			&outName, NULL, &outVersion) == B_BAD_VALUE);
750 		CPPUNIT_ASSERT(outName == NULL && outVersion == -1);
751 
752 		CPPUNIT_ASSERT(pDefRoster->GetTranslatorInfo(translators[i],
753 			&outName, &outInfo, NULL) == B_BAD_VALUE);
754 		CPPUNIT_ASSERT(outName == NULL && outInfo == NULL);
755 
756 		CPPUNIT_ASSERT(pDefRoster->GetTranslatorInfo(translators[i],
757 			NULL, NULL, NULL) == B_BAD_VALUE);
758 
759 		// Good values
760 		CPPUNIT_ASSERT(pDefRoster->GetTranslatorInfo(translators[i],
761 			&outName, &outInfo, &outVersion) == B_OK);
762 		CPPUNIT_ASSERT(outName);
763 	}
764 	delete[] translators;
765 	translators = NULL;
766 }
767 
768 void
CheckTranslatorInfo(translator_info * pinfo,int32 nitems)769 CheckTranslatorInfo(translator_info *pinfo, int32 nitems)
770 {
771 	for (int32 k = 0; k < nitems; k++) {
772 		CPPUNIT_ASSERT(pinfo[k].translator > 0);
773 		CPPUNIT_ASSERT(pinfo[k].type);
774 		CPPUNIT_ASSERT(pinfo[k].group);
775 		CPPUNIT_ASSERT(pinfo[k].quality >= 0 && pinfo[k].quality <= 1);
776 		CPPUNIT_ASSERT(pinfo[k].capability >= 0 && pinfo[k].capability <= 1);
777 		CPPUNIT_ASSERT(strlen(pinfo[k].MIME) >= 0);
778 		CPPUNIT_ASSERT(strlen(pinfo[k].name) > 0);
779 	}
780 }
781 
782 /**
783  * Tests:
784  * virtual status_t GetTranslators(BPositionIO *inSource,
785  * BMessage *ioExtension, translator_info **outInfo, int32 *outNumInfo,
786  * uint32 inHintType = 0, const char *inHintMIME = NULL, uint32 inWantType = 0)
787  *
788  * @return B_OK if everything went ok, B_ERROR if not
789  */
790 void
GetTranslatorsTest()791 TranslatorRosterTest::GetTranslatorsTest()
792 {
793 	NextSubTest();
794 	BApplication app(
795 		"application/x-vnd.OpenBeOS-translationkit_translatorrostertest");
796 	//open image to get a translator for
797 	BFile image("../src/tests/kits/translation/data/images/image.png",
798 		B_READ_ONLY);
799 	CPPUNIT_ASSERT(image.InitCheck() == B_OK);
800 
801 	BFile garbled("../src/tests/kits/translation/data/garbled_data",
802 		B_READ_ONLY);
803 	CPPUNIT_ASSERT(garbled.InitCheck() == B_OK);
804 
805 	NextSubTest();
806 	translator_info* pinfo = NULL;
807 	int32 outCount = -1;
808 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
809 	CPPUNIT_ASSERT(pDefRoster);
810 
811 	//get translator, specifying wrong args
812 	NextSubTest();
813 	CPPUNIT_ASSERT(pDefRoster->GetTranslators(&garbled, NULL, NULL,
814 		&outCount) == B_BAD_VALUE);
815 
816 	//get translator, specifying wrong args
817 	NextSubTest();
818 	CPPUNIT_ASSERT(pDefRoster->GetTranslators(&garbled, NULL, &pinfo,
819 		NULL) == B_BAD_VALUE);
820 
821 	//get translator for garbled data
822 	NextSubTest();
823 	CPPUNIT_ASSERT(pDefRoster->GetTranslators(&garbled, NULL, &pinfo,
824 		&outCount) == B_NO_TRANSLATOR);
825 
826 	//get translator for image
827 	NextSubTest();
828 	CPPUNIT_ASSERT(pDefRoster->GetTranslators(&image, NULL, &pinfo,
829 		&outCount) == B_OK);
830 	CPPUNIT_ASSERT(outCount > 0);
831 	CheckTranslatorInfo(pinfo, outCount);
832 	delete[] pinfo;
833 	pinfo = NULL;
834 	outCount = -1;
835 
836 	//specify a valid BMessage
837 	NextSubTest();
838 	BMessage bmsg;
839 	CPPUNIT_ASSERT(
840 		bmsg.AddBool(B_TRANSLATOR_EXT_DATA_ONLY, true) == B_OK);
841 	CPPUNIT_ASSERT(pDefRoster->GetTranslators(&image, &bmsg, &pinfo,
842 		&outCount, 0, NULL, B_TRANSLATOR_BITMAP) == B_OK);
843 	CPPUNIT_ASSERT(outCount > 0);
844 	CheckTranslatorInfo(pinfo, outCount);
845 	delete[] pinfo;
846 	pinfo = NULL;
847 }
848 
849 /**
850  * Tests:
851  * virtual status_t Identify(BPositionIO *inSource, BMessage *ioExtension,
852  * translator_info *outInfo, uint32 inHintType = 0,
853  * const char *inHintMIME = NULL, uint32 inWantType = 0)
854  *
855  * @return B_OK if everything went ok, B_ERROR if not
856  */
857 void
IdentifyTest()858 TranslatorRosterTest::IdentifyTest()
859 {
860 	NextSubTest();
861 	BApplication app(
862 		"application/x-vnd.OpenBeOS-translationkit_translatorrostertest");
863 	//open image to get a translator for
864 	BFile image("../src/tests/kits/translation/data/images/image.png",
865 		B_READ_ONLY);
866 	CPPUNIT_ASSERT(image.InitCheck() == B_OK);
867 
868 	BFile garbled("../src/tests/kits/translation/data/garbled_data",
869 		B_READ_ONLY);
870 	CPPUNIT_ASSERT(garbled.InitCheck() == B_OK);
871 
872 	NextSubTest();
873 	translator_info info;
874 	memset(&info, 0, sizeof(translator_info));
875 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
876 	CPPUNIT_ASSERT(pDefRoster);
877 
878 	//get translator, specifying wrong args
879 	NextSubTest();
880 	CPPUNIT_ASSERT(pDefRoster->Identify(&garbled, NULL, NULL) == B_BAD_VALUE);
881 
882 	//get translator for garbled data
883 	NextSubTest();
884 	CPPUNIT_ASSERT(pDefRoster->Identify(&garbled, NULL,
885 		&info) == B_NO_TRANSLATOR);
886 
887 	//get translator for image
888 	NextSubTest();
889 	memset(&info, 0, sizeof(translator_info));
890 	CPPUNIT_ASSERT(pDefRoster->Identify(&image, NULL, &info) == B_OK);
891 	CheckTranslatorInfo(&info, 1);
892 
893 	//supply desired output type
894 	NextSubTest();
895 	memset(&info, 0, sizeof(translator_info));
896 	CPPUNIT_ASSERT(pDefRoster->Identify(&image, NULL, &info,
897 		0, NULL, B_TRANSLATOR_BITMAP) == B_OK);
898 	CheckTranslatorInfo(&info, 1);
899 
900 	// TODO: Add a test where I actually use pinfo and a BMessage
901 	// TODO: and check their contents
902 }
903 
904 /**
905  * Tests:
906  * virtual status_t MakeConfigurationView(translator_id forTranslator,
907  * BMessage *ioExtension, BView **outView, BRect *outExtent)
908  *
909  * @return B_OK if everything went ok, B_ERROR if not
910  */
911 void
MakeConfigurationViewTest()912 TranslatorRosterTest::MakeConfigurationViewTest()
913 {
914 	//create invalid rect - if it is valid after the
915 	//MakeConfigurationView call the test has succeded
916 	NextSubTest();
917 	BApplication app(
918 		"application/x-vnd.OpenBeOS-translationkit_translatorrostertest");
919 	BRect extent(-1, -1, -1, -1);
920 	//create config view
921 	BView *view = NULL;
922 	translator_id *translators = NULL;
923 	int32 num_translators = -1;
924 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
925 	CPPUNIT_ASSERT(pDefRoster);
926 
927 	NextSubTest();
928 	CPPUNIT_ASSERT(
929 		pDefRoster->GetAllTranslators(&translators, &num_translators) == B_OK);
930 	CPPUNIT_ASSERT(translators);
931 	CPPUNIT_ASSERT(num_translators > 0);
932 
933 	// bad parameters
934 	NextSubTest();
935 	CPPUNIT_ASSERT(pDefRoster->MakeConfigurationView(translators[0], NULL,
936 		&view, NULL) == B_BAD_VALUE);
937 	CPPUNIT_ASSERT(pDefRoster->MakeConfigurationView(translators[0], NULL,
938 		NULL, &extent) == B_BAD_VALUE);
939 	CPPUNIT_ASSERT(pDefRoster->MakeConfigurationView(translators[0], NULL,
940 		NULL, NULL) == B_BAD_VALUE);
941 
942 	// bad translator id
943 	NextSubTest();
944 	CPPUNIT_ASSERT(pDefRoster->MakeConfigurationView(-1, NULL, &view,
945 		&extent) == B_NO_TRANSLATOR);
946 
947 	// should work
948 	NextSubTest();
949 	CPPUNIT_ASSERT(pDefRoster->MakeConfigurationView(translators[0], NULL,
950 		&view, &extent) == B_OK);
951 	CPPUNIT_ASSERT(extent.IsValid() == true);
952 
953 	// TODO: Add a test that uses a valid BMessage with actual settings in it
954 
955 	//clean up after ourselves
956 	delete[] translators;
957 	translators = NULL;
958 }
959 
960 /**
961  * Tests:
962  * virtual status_t Translate(BPositionIO *inSource,
963  * const translator_info *inInfo, BMessage *ioExtension,
964  * BPositionIO *outDestination, uint32 inWantOutType,
965  * uint32 inHintType = 0, const char *inHintMIME = NULL)
966  *
967  * virtual status_t Translate(translator_id inTranslator,
968  * BPositionIO *inSource, BMessage *ioExtension,
969  * BPositionIO *outDestination, uint32 inWantOutType)
970  *
971  * @return B_OK if everything went ok, B_ERROR if not
972  */
973 void
TranslateTest()974 TranslatorRosterTest::TranslateTest()
975 {
976 	NextSubTest();
977 	BApplication app(
978 		"application/x-vnd.OpenBeOS-translationkit_translatorrostertest");
979 	//input
980 	BFile input("../src/tests/kits/translation/data/images/image.jpg",
981 		B_READ_ONLY);
982 	CPPUNIT_ASSERT(input.InitCheck() == B_OK);
983 
984 	//temp file for generic format
985 	NextSubTest();
986 	BFile temp("/tmp/TranslatorRosterTest.temp",
987 		B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE);
988 	CPPUNIT_ASSERT(temp.InitCheck() == B_OK);
989 
990 	//output file
991 	NextSubTest();
992 	BFile output("../src/tests/kits/translation/data/images/image.out.tga",
993 		B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
994 	CPPUNIT_ASSERT(output.InitCheck() == B_OK);
995 
996 	//get default translators
997 	NextSubTest();
998 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
999 	CPPUNIT_ASSERT(pDefRoster != NULL);
1000 
1001 	//translate to generic
1002 	NextSubTest();
1003 	CPPUNIT_ASSERT(pDefRoster->Translate(&input, NULL, NULL, &temp,
1004 		B_TRANSLATOR_BITMAP) == B_OK);
1005 
1006 	//translate to specific
1007 	NextSubTest();
1008 	CPPUNIT_ASSERT(pDefRoster->Translate(&temp, NULL, NULL, &output,
1009 		B_TGA_FORMAT) == B_OK);
1010 
1011 	// TODO: add Translate using ioExtension BMessage and whatever
1012 	// TODO: the other NULL parameter is
1013 }
1014 
1015 int
main()1016 main()
1017 {
1018 	//needed by MakeConfigurationView
1019 	TranslatorRosterTest test;
1020 	test.InitializeTest();
1021 	test.ConstructorTest();
1022 	test.DefaultTest();
1023 	test.InstantiateTest();
1024 	test.VersionTest();
1025 	test.AddTranslatorsTest();
1026 	test.ArchiveTest();
1027 
1028 	return 0;
1029 }
1030