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