xref: /haiku/src/tests/kits/translation/TranslatorRosterTest.cpp (revision c90684742e7361651849be4116d0e5de3a817194)
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/:/system/add-ons/Translators/") == B_OK);
450 
451 	NextSubTest();
452 	int32 instcount = 0;
453 	translator_id* translators = NULL;
454 	proster->GetAllTranslators(&translators, &instcount);
455 	CPPUNIT_ASSERT(translators);
456 	CPPUNIT_ASSERT(instcount > 0);
457 	// TODO: count the number of files in all of the directories specified
458 	// TODO: above and make certain that it matches instcount
459 	delete[] translators;
460 	translators = NULL;
461 
462 	//delete and create new, this time don't specify path
463 	NextSubTest();
464 	delete proster;
465 	proster = new BTranslatorRoster();
466 	CPPUNIT_ASSERT(proster->AddTranslators() == B_OK);
467 
468 	// make sure that every translator in the Default BTranslatorRoster is in
469 	// proster, and make certain that it is in there ONLY ONCE
470 	NextSubTest();
471 	CompareWithDefault(proster);
472 	delete proster;
473 	proster = NULL;
474 }
475 
476 /**
477  * Tests:
478  * virtual status_t Archive(BMessage *into, bool deep = true) const
479  *
480  * @return B_OK if everything went ok, B_ERROR if not
481  */
482 void
483 TranslatorRosterTest::ArchiveTest()
484 {
485 	NextSubTest();
486 	//archive default, and count entries (must be more than 1!)
487 	BMessage translator_message;
488 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
489 	CPPUNIT_ASSERT(pDefRoster);
490 	CPPUNIT_ASSERT(pDefRoster->Archive(&translator_message) == B_OK);
491 
492 	// make sure instantiate makes an "exact" copy of the default translator
493 	NextSubTest();
494 	BTranslatorRoster *proster = NULL;
495 	proster = dynamic_cast<BTranslatorRoster *>
496 		(BTranslatorRoster::Instantiate(&translator_message));
497 	CPPUNIT_ASSERT(proster);
498 
499 	// make sure that every translator in the pDefRoster is in
500 	// proster, and make certain that it is in there ONLY ONCE
501 	NextSubTest();
502 	CompareWithDefault(proster);
503 	delete proster;
504 	proster = NULL;
505 }
506 
507 /**
508  * Tests:
509  * virtual status_t GetAllTranslators(translator_id **outList, int32 *outCount)
510  *
511  * @return B_OK if everything went ok, B_ERROR if not
512  */
513 void
514 TranslatorRosterTest::GetAllTranslatorsTest()
515 {
516 	// bad parameters
517 	NextSubTest();
518 	int32 nloaded = 42;
519 	translator_id* pids = NULL;
520 	BTranslatorRoster roster;
521 	CPPUNIT_ASSERT(roster.GetAllTranslators(NULL, &nloaded) == B_BAD_VALUE);
522 	CPPUNIT_ASSERT(nloaded == 42);
523 	CPPUNIT_ASSERT(roster.GetAllTranslators(&pids, NULL) == B_BAD_VALUE);
524 	CPPUNIT_ASSERT(pids == NULL);
525 	CPPUNIT_ASSERT(roster.GetAllTranslators(NULL, NULL) == B_BAD_VALUE);
526 
527 	// no translators
528 	NextSubTest();
529 	CPPUNIT_ASSERT(
530 		roster.GetAllTranslators(&pids, &nloaded) == B_NO_ERROR);
531 	CPPUNIT_ASSERT(nloaded == 0);
532 	delete[] pids;
533 	pids = NULL;
534 
535 	// default translators
536 	NextSubTest();
537 	nloaded = 42;
538 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
539 	CPPUNIT_ASSERT(
540 		pDefRoster->GetAllTranslators(&pids, &nloaded) == B_NO_ERROR);
541 	CPPUNIT_ASSERT(nloaded > 0);
542 	CPPUNIT_ASSERT(pids != NULL);
543 
544 	// Make sure the correct translators were loaded
545 	NextSubTest();
546 	const char *kaTranslatorNames[] = {
547 		"Gobe MS-WORD Translator",
548 		"Gobe Text Translator",
549 		"TIFF Images",
550 		"Gobe SYLK Translator",
551 		"StyledEdit Files",
552 		"Gobe RTF Translator",
553 		"PPM Images",
554 		"JPEG Images",
555 		"Gobe HTML Translator",
556 		"Gobe Excel Translator",
557 		"TGA Images",
558 		"MNGTranslator",
559 		"GIMPPatternHandler",
560 		"TestBmpTranslator",
561 		"BMP Images",
562 		"BBitmap Images"
563 	};
564 	CPPUNIT_ASSERT(nloaded == sizeof(kaTranslatorNames) /
565 		sizeof(const char *));
566 
567 	for (int32 i = 0; i < nloaded; i++) {
568 		const char *kTranslatorName, *kTranslatorInfo;
569 		int32 nTranslatorVersion;
570 
571 		CPPUNIT_ASSERT(pids[i] > 0);
572 
573 		kTranslatorName = kTranslatorInfo = NULL;
574 		nTranslatorVersion = -246;
575 
576 		pDefRoster->GetTranslatorInfo(pids[i], &kTranslatorName,
577 			&kTranslatorInfo, &nTranslatorVersion);
578 
579 		CPPUNIT_ASSERT(kTranslatorName);
580 		CPPUNIT_ASSERT(kTranslatorInfo);
581 		CPPUNIT_ASSERT(nTranslatorVersion > 0);
582 
583 		// make sure each translator is loaded exactly once
584 		// no more, no less
585 		int32 npassed = 0;
586 		for (int32 k = 0; k < nloaded; k++) {
587 			if (!strcmp(kaTranslatorNames[k], kTranslatorName))
588 				npassed++;
589 		}
590 		CPPUNIT_ASSERT(npassed == 1);
591 	}
592 
593 	delete[] pids;
594 	pids = NULL;
595 }
596 
597 /**
598  * Tests:
599  * virtual status_t GetConfigurationMessage(translator_id forTranslator,
600  * BMessage *ioExtension)
601  *
602  * @return B_OK if everything went ok, B_ERROR if not
603  */
604 void
605 TranslatorRosterTest::GetConfigurationMessageTest()
606 {
607 	NextSubTest();
608 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
609 	CPPUNIT_ASSERT(pDefRoster);
610 
611 	NextSubTest();
612 	//get id for a translator (just use the first one)
613 	int32 num_translators = -1;
614 	translator_id* translators = NULL;
615 	CPPUNIT_ASSERT(pDefRoster->GetAllTranslators(&translators,
616 		&num_translators) == B_OK);
617 	CPPUNIT_ASSERT(translators);
618 	CPPUNIT_ASSERT(num_translators > 0);
619 
620 	NextSubTest();
621 	translator_id translatorid = translators[0];
622 	delete[] translators;
623 	translators = NULL;
624 	//get conf for invalid translator
625 	BMessage translator_message;
626 	CPPUNIT_ASSERT(pDefRoster->GetConfigurationMessage(-1,
627 		&translator_message) == B_NO_TRANSLATOR);
628 	CPPUNIT_ASSERT(translator_message.IsEmpty());
629 
630 	//get conf for invalid ioExtension (BMessage)
631 	NextSubTest();
632 	CPPUNIT_ASSERT(
633 		pDefRoster->GetConfigurationMessage(translatorid, NULL) == B_BAD_VALUE);
634 
635 	//get config for actual translator
636 	NextSubTest();
637 	CPPUNIT_ASSERT(translator_message.MakeEmpty() == B_OK);
638 	CPPUNIT_ASSERT(pDefRoster->GetConfigurationMessage(translatorid,
639 		&translator_message) == B_OK);
640 }
641 
642 // Code used by both GetInputFormatsTest and GetOutputFormatsTest
643 void
644 GetInputOutputFormatsTest(TranslatorRosterTest *prt, bool binput)
645 {
646 	prt->NextSubTest();
647 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
648 	CPPUNIT_ASSERT(pDefRoster);
649 
650 	prt->NextSubTest();
651 	translator_id* translators = NULL;
652 	int32 num_translators = -1;
653 	CPPUNIT_ASSERT(pDefRoster->GetAllTranslators(&translators,
654 		&num_translators) == B_OK);
655 	CPPUNIT_ASSERT(translators);
656 	CPPUNIT_ASSERT(num_translators > 0);
657 
658 	// Run get Input/output format test on each translator
659 	for (int32 i = 0; i < num_translators; i++) {
660 		const translation_format *fmts = NULL;
661 		int32 num_fmts = -1;
662 		status_t result;
663 		prt->NextSubTest();
664 		if (binput)
665 			result = pDefRoster->GetInputFormats(translators[i], &fmts,
666 				&num_fmts);
667 		else
668 			result = pDefRoster->GetOutputFormats(translators[i], &fmts,
669 				&num_fmts);
670 		CPPUNIT_ASSERT(result == B_OK);
671 
672 		// test input/output formats
673 		CPPUNIT_ASSERT(num_fmts >= 0);
674 		CPPUNIT_ASSERT(num_fmts == 0 || fmts);
675 		for (int32 k = 0; k < num_fmts; k++) {
676 			CPPUNIT_ASSERT(fmts[k].type);
677 			CPPUNIT_ASSERT(fmts[k].group);
678 			CPPUNIT_ASSERT(fmts[k].quality >= 0 && fmts[k].quality <= 1);
679 			CPPUNIT_ASSERT(fmts[k].capability >= 0 && fmts[k].capability <= 1);
680 			CPPUNIT_ASSERT(strlen(fmts[k].MIME) >= 0);
681 			CPPUNIT_ASSERT(strlen(fmts[k].name) > 0);
682 		}
683 	}
684 	delete[] translators;
685 	translators = NULL;
686 }
687 
688 /**
689  * Tests:
690  * virtual status_t GetInputFormats(translator_id forTranslator,
691  * const translation_format **outFormats, int32 *outNumFormats)
692  *
693  * @return B_OK if everything went ok, B_ERROR if not
694  */
695 void
696 TranslatorRosterTest::GetInputFormatsTest()
697 {
698 	GetInputOutputFormatsTest(this, true);
699 }
700 
701 /**
702  * Tests:
703  * virtual status_t GetOutputFormats(translator_id forTranslator,
704  * const translation_format **outFormats, int32 *outNumFormats)
705  *
706  * @return B_OK if everything went ok, B_ERROR if not
707  */
708 void
709 TranslatorRosterTest::GetOutputFormatsTest()
710 {
711 	GetInputOutputFormatsTest(this, false);
712 }
713 
714 /**
715  * Tests:
716  * virtual status_t GetTranslatorInfo(translator_id forTranslator,
717  * const char **outName, const char **outInfo, int32 *outVersion)
718  *
719  * @return B_OK if everything went ok, B_ERROR if not
720  */
721 void
722 TranslatorRosterTest::GetTranslatorInfoTest()
723 {
724 	NextSubTest();
725 	translator_id* translators = NULL;
726 	int32 num_translators = -1;
727 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
728 	CPPUNIT_ASSERT(pDefRoster);
729 
730 	NextSubTest();
731 	CPPUNIT_ASSERT(pDefRoster->GetAllTranslators(&translators,
732 		&num_translators) == B_OK);
733 	CPPUNIT_ASSERT(translators);
734 	CPPUNIT_ASSERT(num_translators > 0);
735 	for (int32 i = 0; i < num_translators; i++) {
736 		const char *outName = NULL;
737 		const char *outInfo = NULL;
738 		int32 outVersion = -1;
739 
740 		NextSubTest();
741 		CPPUNIT_ASSERT(pDefRoster->GetTranslatorInfo(-1, &outName, &outInfo,
742 			&outVersion) == B_NO_TRANSLATOR);
743 
744 		// B_BAD_VALUE cases
745 		CPPUNIT_ASSERT(pDefRoster->GetTranslatorInfo(translators[i],
746 			NULL, &outInfo, &outVersion) == B_BAD_VALUE);
747 		CPPUNIT_ASSERT(outInfo == NULL && outVersion == -1);
748 
749 		CPPUNIT_ASSERT(pDefRoster->GetTranslatorInfo(translators[i],
750 			&outName, NULL, &outVersion) == B_BAD_VALUE);
751 		CPPUNIT_ASSERT(outName == NULL && outVersion == -1);
752 
753 		CPPUNIT_ASSERT(pDefRoster->GetTranslatorInfo(translators[i],
754 			&outName, &outInfo, NULL) == B_BAD_VALUE);
755 		CPPUNIT_ASSERT(outName == NULL && outInfo == NULL);
756 
757 		CPPUNIT_ASSERT(pDefRoster->GetTranslatorInfo(translators[i],
758 			NULL, NULL, NULL) == B_BAD_VALUE);
759 
760 		// Good values
761 		CPPUNIT_ASSERT(pDefRoster->GetTranslatorInfo(translators[i],
762 			&outName, &outInfo, &outVersion) == B_OK);
763 		CPPUNIT_ASSERT(outName);
764 	}
765 	delete[] translators;
766 	translators = NULL;
767 }
768 
769 void
770 CheckTranslatorInfo(translator_info *pinfo, int32 nitems)
771 {
772 	for (int32 k = 0; k < nitems; k++) {
773 		CPPUNIT_ASSERT(pinfo[k].translator > 0);
774 		CPPUNIT_ASSERT(pinfo[k].type);
775 		CPPUNIT_ASSERT(pinfo[k].group);
776 		CPPUNIT_ASSERT(pinfo[k].quality >= 0 && pinfo[k].quality <= 1);
777 		CPPUNIT_ASSERT(pinfo[k].capability >= 0 && pinfo[k].capability <= 1);
778 		CPPUNIT_ASSERT(strlen(pinfo[k].MIME) >= 0);
779 		CPPUNIT_ASSERT(strlen(pinfo[k].name) > 0);
780 	}
781 }
782 
783 /**
784  * Tests:
785  * virtual status_t GetTranslators(BPositionIO *inSource,
786  * BMessage *ioExtension, translator_info **outInfo, int32 *outNumInfo,
787  * uint32 inHintType = 0, const char *inHintMIME = NULL, uint32 inWantType = 0)
788  *
789  * @return B_OK if everything went ok, B_ERROR if not
790  */
791 void
792 TranslatorRosterTest::GetTranslatorsTest()
793 {
794 	NextSubTest();
795 	BApplication app(
796 		"application/x-vnd.OpenBeOS-translationkit_translatorrostertest");
797 	//open image to get a translator for
798 	BFile image("../src/tests/kits/translation/data/images/image.png",
799 		B_READ_ONLY);
800 	CPPUNIT_ASSERT(image.InitCheck() == B_OK);
801 
802 	BFile garbled("../src/tests/kits/translation/data/garbled_data",
803 		B_READ_ONLY);
804 	CPPUNIT_ASSERT(garbled.InitCheck() == B_OK);
805 
806 	NextSubTest();
807 	translator_info* pinfo = NULL;
808 	int32 outCount = -1;
809 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
810 	CPPUNIT_ASSERT(pDefRoster);
811 
812 	//get translator, specifying wrong args
813 	NextSubTest();
814 	CPPUNIT_ASSERT(pDefRoster->GetTranslators(&garbled, NULL, NULL,
815 		&outCount) == B_BAD_VALUE);
816 
817 	//get translator, specifying wrong args
818 	NextSubTest();
819 	CPPUNIT_ASSERT(pDefRoster->GetTranslators(&garbled, NULL, &pinfo,
820 		NULL) == B_BAD_VALUE);
821 
822 	//get translator for garbled data
823 	NextSubTest();
824 	CPPUNIT_ASSERT(pDefRoster->GetTranslators(&garbled, NULL, &pinfo,
825 		&outCount) == B_NO_TRANSLATOR);
826 
827 	//get translator for image
828 	NextSubTest();
829 	CPPUNIT_ASSERT(pDefRoster->GetTranslators(&image, NULL, &pinfo,
830 		&outCount) == B_OK);
831 	CPPUNIT_ASSERT(outCount > 0);
832 	CheckTranslatorInfo(pinfo, outCount);
833 	delete[] pinfo;
834 	pinfo = NULL;
835 	outCount = -1;
836 
837 	//specify a valid BMessage
838 	NextSubTest();
839 	BMessage bmsg;
840 	CPPUNIT_ASSERT(
841 		bmsg.AddBool(B_TRANSLATOR_EXT_DATA_ONLY, true) == B_OK);
842 	CPPUNIT_ASSERT(pDefRoster->GetTranslators(&image, &bmsg, &pinfo,
843 		&outCount, 0, NULL, B_TRANSLATOR_BITMAP) == B_OK);
844 	CPPUNIT_ASSERT(outCount > 0);
845 	CheckTranslatorInfo(pinfo, outCount);
846 	delete[] pinfo;
847 	pinfo = NULL;
848 }
849 
850 /**
851  * Tests:
852  * virtual status_t Identify(BPositionIO *inSource, BMessage *ioExtension,
853  * translator_info *outInfo, uint32 inHintType = 0,
854  * const char *inHintMIME = NULL, uint32 inWantType = 0)
855  *
856  * @return B_OK if everything went ok, B_ERROR if not
857  */
858 void
859 TranslatorRosterTest::IdentifyTest()
860 {
861 	NextSubTest();
862 	BApplication app(
863 		"application/x-vnd.OpenBeOS-translationkit_translatorrostertest");
864 	//open image to get a translator for
865 	BFile image("../src/tests/kits/translation/data/images/image.png",
866 		B_READ_ONLY);
867 	CPPUNIT_ASSERT(image.InitCheck() == B_OK);
868 
869 	BFile garbled("../src/tests/kits/translation/data/garbled_data",
870 		B_READ_ONLY);
871 	CPPUNIT_ASSERT(garbled.InitCheck() == B_OK);
872 
873 	NextSubTest();
874 	translator_info info;
875 	memset(&info, 0, sizeof(translator_info));
876 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
877 	CPPUNIT_ASSERT(pDefRoster);
878 
879 	//get translator, specifying wrong args
880 	NextSubTest();
881 	CPPUNIT_ASSERT(pDefRoster->Identify(&garbled, NULL, NULL) == B_BAD_VALUE);
882 
883 	//get translator for garbled data
884 	NextSubTest();
885 	CPPUNIT_ASSERT(pDefRoster->Identify(&garbled, NULL,
886 		&info) == B_NO_TRANSLATOR);
887 
888 	//get translator for image
889 	NextSubTest();
890 	memset(&info, 0, sizeof(translator_info));
891 	CPPUNIT_ASSERT(pDefRoster->Identify(&image, NULL, &info) == B_OK);
892 	CheckTranslatorInfo(&info, 1);
893 
894 	//supply desired output type
895 	NextSubTest();
896 	memset(&info, 0, sizeof(translator_info));
897 	CPPUNIT_ASSERT(pDefRoster->Identify(&image, NULL, &info,
898 		0, NULL, B_TRANSLATOR_BITMAP) == B_OK);
899 	CheckTranslatorInfo(&info, 1);
900 
901 	// TODO: Add a test where I actually use pinfo and a BMessage
902 	// TODO: and check their contents
903 }
904 
905 /**
906  * Tests:
907  * virtual status_t MakeConfigurationView(translator_id forTranslator,
908  * BMessage *ioExtension, BView **outView, BRect *outExtent)
909  *
910  * @return B_OK if everything went ok, B_ERROR if not
911  */
912 void
913 TranslatorRosterTest::MakeConfigurationViewTest()
914 {
915 	//create invalid rect - if it is valid after the
916 	//MakeConfigurationView call the test has succeded
917 	NextSubTest();
918 	BApplication app(
919 		"application/x-vnd.OpenBeOS-translationkit_translatorrostertest");
920 	BRect extent(-1, -1, -1, -1);
921 	//create config view
922 	BView *view = NULL;
923 	translator_id *translators = NULL;
924 	int32 num_translators = -1;
925 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
926 	CPPUNIT_ASSERT(pDefRoster);
927 
928 	NextSubTest();
929 	CPPUNIT_ASSERT(
930 		pDefRoster->GetAllTranslators(&translators, &num_translators) == B_OK);
931 	CPPUNIT_ASSERT(translators);
932 	CPPUNIT_ASSERT(num_translators > 0);
933 
934 	// bad parameters
935 	NextSubTest();
936 	CPPUNIT_ASSERT(pDefRoster->MakeConfigurationView(translators[0], NULL,
937 		&view, NULL) == B_BAD_VALUE);
938 	CPPUNIT_ASSERT(pDefRoster->MakeConfigurationView(translators[0], NULL,
939 		NULL, &extent) == B_BAD_VALUE);
940 	CPPUNIT_ASSERT(pDefRoster->MakeConfigurationView(translators[0], NULL,
941 		NULL, NULL) == B_BAD_VALUE);
942 
943 	// bad translator id
944 	NextSubTest();
945 	CPPUNIT_ASSERT(pDefRoster->MakeConfigurationView(-1, NULL, &view,
946 		&extent) == B_NO_TRANSLATOR);
947 
948 	// should work
949 	NextSubTest();
950 	CPPUNIT_ASSERT(pDefRoster->MakeConfigurationView(translators[0], NULL,
951 		&view, &extent) == B_OK);
952 	CPPUNIT_ASSERT(extent.IsValid() == true);
953 
954 	// TODO: Add a test that uses a valid BMessage with actual settings in it
955 
956 	//clean up after ourselves
957 	delete[] translators;
958 	translators = NULL;
959 }
960 
961 /**
962  * Tests:
963  * virtual status_t Translate(BPositionIO *inSource,
964  * const translator_info *inInfo, BMessage *ioExtension,
965  * BPositionIO *outDestination, uint32 inWantOutType,
966  * uint32 inHintType = 0, const char *inHintMIME = NULL)
967  *
968  * virtual status_t Translate(translator_id inTranslator,
969  * BPositionIO *inSource, BMessage *ioExtension,
970  * BPositionIO *outDestination, uint32 inWantOutType)
971  *
972  * @return B_OK if everything went ok, B_ERROR if not
973  */
974 void
975 TranslatorRosterTest::TranslateTest()
976 {
977 	NextSubTest();
978 	BApplication app(
979 		"application/x-vnd.OpenBeOS-translationkit_translatorrostertest");
980 	//input
981 	BFile input("../src/tests/kits/translation/data/images/image.jpg",
982 		B_READ_ONLY);
983 	CPPUNIT_ASSERT(input.InitCheck() == B_OK);
984 
985 	//temp file for generic format
986 	NextSubTest();
987 	BFile temp("/tmp/TranslatorRosterTest.temp",
988 		B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE);
989 	CPPUNIT_ASSERT(temp.InitCheck() == B_OK);
990 
991 	//output file
992 	NextSubTest();
993 	BFile output("../src/tests/kits/translation/data/images/image.out.tga",
994 		B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
995 	CPPUNIT_ASSERT(output.InitCheck() == B_OK);
996 
997 	//get default translators
998 	NextSubTest();
999 	BTranslatorRoster *pDefRoster = BTranslatorRoster::Default();
1000 	CPPUNIT_ASSERT(pDefRoster != NULL);
1001 
1002 	//translate to generic
1003 	NextSubTest();
1004 	CPPUNIT_ASSERT(pDefRoster->Translate(&input, NULL, NULL, &temp,
1005 		B_TRANSLATOR_BITMAP) == B_OK);
1006 
1007 	//translate to specific
1008 	NextSubTest();
1009 	CPPUNIT_ASSERT(pDefRoster->Translate(&temp, NULL, NULL, &output,
1010 		B_TGA_FORMAT) == B_OK);
1011 
1012 	// TODO: add Translate using ioExtension BMessage and whatever
1013 	// TODO: the other NULL parameter is
1014 }
1015 
1016 int
1017 main()
1018 {
1019 	//needed by MakeConfigurationView
1020 	TranslatorRosterTest test;
1021 	test.InitializeTest();
1022 	test.ConstructorTest();
1023 	test.DefaultTest();
1024 	test.InstantiateTest();
1025 	test.VersionTest();
1026 	test.AddTranslatorsTest();
1027 	test.ArchiveTest();
1028 
1029 	return 0;
1030 }
1031